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