/*
 * 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: smar_stop.c,v 1.26 2006/04/02 06:34:20 ca Exp $")
#include "sm/error.h"
#include "sm/assert.h"
#include "smar.h"
#include "sm/maps.h"

/* XXX HACK see below */
#include "../libsmmap/map.h"

/*
**  SMAR_MT_FREE -- free entry of "mailertable"
**
**	Parameters:
**		value -- value in mailertable
**		key -- key
**		ctx -- NULL
**
**	Returns:
**		none.
*/

static void
smar_mt_free(void *value, void *key, void *ctx)
{
	if (value != NULL)
		sm_free((char *) value);
	if (key != NULL)
		sm_free((char *) key);
}

/*
**  SMAR_STOP -- stop SMAR
**
**	Parameters:
**		smar_ctx -- SMAR context
**
**	Returns:
**		usual sm_error code
*/

/* should we pass type of shutdown? immediate, normal, ...? */
sm_ret_T
smar_stop(smar_ctx_P smar_ctx)
{
	sm_ret_T ret;
	int r;

	SM_IS_SMAR_CTX(smar_ctx);
	smar_ctx->smar_status = SMAR_ST_SH_DOWN;

	/*
	**  How to properly shut down the system?
	*/

	if (smar_ctx->smar_ev_ctx != NULL)
		ret = evthr_stop(smar_ctx->smar_ev_ctx);
	/* complain on error? */

#if 0
	ret = sm_log_closesyslog();
#endif
	ret = sm_log_destroy(smar_ctx->smar_lctx);

	/* destroy mutex first? */
	ret = thr_stop();
	if (sm_is_err(ret))
		goto error;

	smar_ctx->smar_status = SMAR_ST_STOPPED;

	if (smar_ctx->smar_mt_map != NULL)
	{
		if (smar_ctx->smar_cnf.smar_cnf_mt_name == NULL)
		{
			/* ONLY for bht type! */
			bht_destroy(smar_ctx->smar_mt_map->sm_map_db,
				smar_mt_free, NULL);
		}

		(void) sm_map_close(smar_ctx->smar_mt_map, 0);
		smar_ctx->smar_mt_map = NULL;
	}
#if 0
	ret = sm_rcbcom_close(&smar_ctx->smar_qmgr_com);
#endif

	for (r = 0; r < SMAR_MAX_CLTS; r++)
	{
		ret = smar_clt_free(smar_ctx->smar_clt_ctx[r]);
	}


	(void) pthread_mutex_destroy(&smar_ctx->smar_mutex);
#if SMAR_USE_DNS
	if (smar_ctx->smar_dns_mgr_ctx != NULL)
		dns_mgr_ctx_del(smar_ctx->smar_dns_mgr_ctx);
#endif
	if (smar_ctx->smar_access != NULL)
	{
		(void) sm_map_close(smar_ctx->smar_access, 0);
		smar_ctx->smar_access = NULL;
	}
	if (smar_ctx->smar_aliases != NULL)
	{
		(void) sm_map_close(smar_ctx->smar_aliases, 0);
		smar_ctx->smar_aliases = NULL;
	}
	if (smar_ctx->smar_maps != NULL)
	{
		(void) sm_maps_term(smar_ctx->smar_maps);
		smar_ctx->smar_maps = NULL;
	}
	if (smar_ctx->smar_greyctx != NULL)
	{
		(void) sm_greyctl_free(smar_ctx->smar_greyctx);
		smar_ctx->smar_greyctx = NULL;
	}
	SM_CSTR_FREE(smar_ctx->smar_strmaptype);
	return SM_SUCCESS;

  error:
	return ret;
}


syntax highlighted by Code2HTML, v. 0.9.1