/*
 * 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;
}


syntax highlighted by Code2HTML, v. 0.9.1