/* * Copyright (c) 2002-2005 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. */ #include "sm/generic.h" SM_RCSID("@(#)$Id: qmgr.c,v 1.39 2007/04/14 16:57:04 ca Exp $") #include "sm/common.h" #include "sm/error.h" #include "sm/assert.h" #include "sm/sysexits.h" #include "sm/version.h" #include "sm/io.h" #include "sm/qmgr.h" #include "sm/qmgr-int.h" #include "qmgr.h" #include "log.h" /* fixme: where to define? */ cdb_id_P null_cdb_id; /* ** QMGR_LOOP -- QMGR loop; starts event thread loop ** ** Parameters: ** qmgr_ctx -- QMGR context ** ** Returns: ** usual sm_error code */ static sm_ret_T qmgr_loop(qmgr_ctx_P qmgr_ctx) { SM_IS_QMGR_CTX(qmgr_ctx); SM_REQUIRE(qmgr_ctx->qmgr_ev_ctx != NULL); if (qmgr_ctx->qmgr_status != QMGR_ST_START) return sm_error_perm(SM_EM_Q, SM_E_STARTFAIL); qmgr_ctx->qmgr_status = QMGR_ST_OK; sm_log_write(qmgr_ctx->qmgr_lctx, QM_LCAT_INIT, QM_LMOD_START, SM_LOG_INFO, 9, "sev=INFO, func=qmgr_loop, version=%s, status=started" , MTA_VERSION_STR); /* wait for events, schedule tasks */ return evthr_loop(qmgr_ctx->qmgr_ev_ctx); } /* ** MAIN -- QMGR ** ** Parameters: ** argc -- number of arguments ** argv -- vector of arguments ** ** Returns: ** exit code */ int main(int argc, char *argv[]) { sm_ret_T ret; int exitcode; qmgr_ctx_T qmgr_ctx; char *prg; prg = argv[0]; exitcode = 0; if (getuid() == 0 || geteuid() == 0) { sm_io_fprintf(smioerr, SM_DONTRUNASROOT "\n", prg); exit(EX_USAGE); } NOTE(NO_COMPETING_THREADS_NOW) /* basic initialization */ ret = qmgr_init0(&qmgr_ctx); if (sm_is_err(ret)) goto error0; #if SM_HEAP_CHECK SmHeapCheck = 1; if (HEAP_CHECK) sm_heap_report(smioerr, 3); #endif /* read config */ ret = qmgr_rdcf(&qmgr_ctx, argc, argv); if (sm_is_err(ret)) { /* USAGE or CONFIG? */ exitcode = sm_is_perm_err(ret) ? EX_USAGE : EX_TEMPFAIL; goto error0; } QM_LEV_DPRINTF(5, (QM_DEBFP, "sev=DBG, func=qmgr, uid=%ld, gid=%ld, euid=%ld, egid=%ld\n", (long) getuid(), (long) getgid(), (long) geteuid(), (long) getegid())); /* initialize system */ ret = qmgr_init1(&qmgr_ctx); if (sm_is_err(ret)) { sm_io_fprintf(smioerr, "sev=ERROR, func=main, qmgr_init1=%M\n", ret); goto error; } /* startup qmgr */ ret = qmgr_start(&qmgr_ctx); if (sm_is_err(ret)) { sm_io_fprintf(smioerr, "sev=ERROR, func=main, qmgr_start=%M\n", ret); goto error; } /* run main loop */ ret = qmgr_loop(&qmgr_ctx); if (sm_is_err(ret)) { sm_io_fprintf(smioerr, "sev=ERROR, func=main, qmgr_loop=%M\n", ret); goto error; } ret = qmgr_stop(&qmgr_ctx); if (sm_is_err(ret) && sm_error_value(ret) == SM_E_RSR_PRB) exitcode = EX_TEMPFAIL; #if SM_HEAP_CHECK if (HEAP_CHECK) sm_heap_report(smioerr, 3); #endif return exitcode; error: /* ignore shutdown errors... */ (void) qmgr_stop(&qmgr_ctx); error0: /* select an appropriate error here... */ return (0 == exitcode) ? sm_error_value(ret) : exitcode; }