/*
 * Copyright (c) 2004, 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: pmilter_ss.c,v 1.13 2007/08/04 00:07:42 ca Exp $")
#include "sm/error.h"
#include "sm/assert.h"
#include "sm/io.h"
#include "sm/rcb.h"
#include "pmilter.h"

#if MTA_USE_PMILTER
/*
**  SM_PMSS_NEW -- Allocate a new task context pmilter/SMTP server
**
**	Parameters:
**		pmg_ctx -- pmilter (library) context
**		ppmss_ctx -- task context pmilter/SMTP server (output)
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
sm_pmss_new(pmg_ctx_P pmg_ctx, pmss_ctx_P *ppmss_ctx)
{
	pmss_ctx_P pmss_ctx;
	sm_ret_T ret;

	SM_IS_PMG_CTX(pmg_ctx);
	SM_REQUIRE(ppmss_ctx != NULL);
#if PMM_END != 0
 ERROR _PMM_END must be 0
#endif
	pmss_ctx = (pmss_ctx_P) sm_zalloc(sizeof(*pmss_ctx));
	if (pmss_ctx == NULL)
		return sm_error_temp(SM_EM_Q_Q2SS, ENOMEM);
	pmss_ctx->pmss_pmg_ctx = pmg_ctx;
	ret = sm_rcbcom_open(&pmss_ctx->pmss_com);
	if (sm_is_err(ret))
		goto error;
	PMSEL_INIT(&pmss_ctx->pmss_ss_hd);
	pmss_ctx->pmss_id = PMSS_ID_NONE;
	pmss_ctx->sm_magic = SM_PMSS_CTX_MAGIC;
	*ppmss_ctx = pmss_ctx;
	return SM_SUCCESS;

  error:
	SM_FREE(pmss_ctx);
	return ret;
}

/*
**  SM_PMSS_FREE -- Free a task context pmilter/SMTP server
**
**	Parameters:
**		pmss_ctx -- task context pmilter/SMTP server
**
**	Returns:
**		always SM_SUCCESS
*/

sm_ret_T
sm_pmss_free(pmss_ctx_P pmss_ctx)
{
	/* XXX this routine assumes nobody accesses pmss_ctx! */
	if (pmss_ctx == NULL)
		return SM_SUCCESS;
	(void) sm_rcbcom_close(&pmss_ctx->pmss_com);

	/* XXX free entire list of pmse_ctx? */

	pmss_ctx->sm_magic = SM_MAGIC_NULL;
	sm_free_size(pmss_ctx, sizeof(*pmss_ctx));
	return SM_SUCCESS;
}

/*
**  SM_PMSS_CLR -- clear a task context pmilter/SMTP server for reuse
**
**	Parameters:
**		pmss_ctx -- task context pmilter/SMTP server
**
**	Returns:
**		always SM_SUCCESS
*/

static sm_ret_T
sm_pmss_clr(pmss_ctx_P pmss_ctx)
{
	/* XXX this routine assumes nobody accesses pmss_ctx! */
	if (pmss_ctx == NULL)
		return SM_SUCCESS;

	pmss_ctx->pmss_appl_ctx = NULL;
	pmss_ctx->pmss_bit = 0;
	pmss_ctx->pmss_cap = 0;
	pmss_ctx->pmss_fct = 0;
	pmss_ctx->pmss_feat = 0;
	pmss_ctx->pmss_misc = 0;
	pmss_ctx->pmss_pmcap = 0;
	pmss_ctx->pmss_pmfct = 0;
	pmss_ctx->pmss_pmfeat = 0;
	pmss_ctx->pmss_pmmisc = 0;
	pmss_ctx->pmss_max_thrs = 0;
	pmss_ctx->pmss_cur_session = 0;
	sm_memzero(pmss_ctx->pmss_mac_names, sizeof(pmss_ctx->pmss_mac_names));

	PMSEL_INIT(&pmss_ctx->pmss_ss_hd);
	pmss_ctx->pmss_status = PMSS_ST_NONE;
	pmss_ctx->pmss_id = PMSS_ID_NONE;
	return SM_SUCCESS;
}

/*
**  SM_PMSS_CLOSE -- Close all SE/TA for one SMTP server context
**
**	Parameters:
**		pmss_ctx -- PMILTER - SMTP server context
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
sm_pmss_close(pmss_ctx_P pmss_ctx)
{
	pmse_ctx_P pmse_ctx;

	SM_IS_PMSS_CTX(pmss_ctx);
	while (!PMSEL_EMPTY(&pmss_ctx->pmss_ss_hd)) {
		pmse_ctx = PMSEL_FIRST(&pmss_ctx->pmss_ss_hd);

		/*
		**  When to really call these?
		**  Need to keep some kind of session/transaction state.
		*/

		(void) sm_pmilt_abort_ta(pmss_ctx, pmse_ctx);
		(void) sm_pmilt_cseid(pmss_ctx, pmse_ctx);

		/* this removes pmse_ctx from the list! */
		(void) sm_pmse_free(pmss_ctx, pmse_ctx);
	}
	PM_LEV_DPRINTF(3, (PM_DEBFP, "sev=INFO, func=sm_pmss_close, status=%d, id=%d\n", pmss_ctx->pmss_status, pmss_ctx->pmss_id));
	sm_pmss_clr(pmss_ctx);
	return SM_SUCCESS;
}
#endif /* MTA_USE_PMILTER */


syntax highlighted by Code2HTML, v. 0.9.1