/* * 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: qm_qss_ctx.c,v 1.33 2006/11/05 17:23:32 ca Exp $") #include "sm/error.h" #include "sm/assert.h" #include "sm/io.h" #include "sm/rcb.h" #include "sm/qmgr.h" #include "sm/qmgr-int.h" #include "sm/rcbcomm.h" #include "qmgr.h" #include "log.h" /* ** QSS_CTX_NEW -- Allocate a new QMGR - SMTPS context ** ** Parameters: ** qmgr_ctx -- QMGR context ** pqss_ctx -- QMGR/SMTPS context (output) ** ** Returns: ** usual sm_error code ** ** Last code review: 2003-10-17 15:51:17 */ sm_ret_T qss_ctx_new(qmgr_ctx_P qmgr_ctx, qss_ctx_P *pqss_ctx) { qss_ctx_P qss_ctx; sm_ret_T ret; SM_IS_QMGR_CTX(qmgr_ctx); SM_REQUIRE(pqss_ctx != NULL); qss_ctx = (qss_ctx_P) sm_zalloc(sizeof(*qss_ctx)); if (qss_ctx == NULL) return sm_error_temp(SM_EM_Q_Q2SS, ENOMEM); qss_ctx->qss_qmgr_ctx = qmgr_ctx; ret = sm_rcbcom_open(&qss_ctx->qss_com); if (sm_is_err(ret)) goto error; qss_ctx->qss_status = QSS_ST_NONE; qss_ctx->qss_id = QSS_ID_NONE; qss_ctx->sm_magic = SM_QSS_CTX_MAGIC; *pqss_ctx = qss_ctx; return SM_SUCCESS; error: SM_FREE_SIZE(qss_ctx, sizeof(*qss_ctx)); return ret; } /* ** QSS_CTX_FREE -- Free a QMGR - SMTPS context ** ** Parameters: ** qss_ctx -- QMGR/SMTPS context ** ** Returns: ** usual sm_error code (always SM_SUCCESS) ** ** Locking: qss_ctx must be under control of the caller. ** ** Last code review: 2003-10-17 15:52:26, see below */ sm_ret_T qss_ctx_free(qss_ctx_P qss_ctx) { if (qss_ctx == NULL) return SM_SUCCESS; (void) sm_rcbcom_close(&qss_ctx->qss_com); qss_ctx->sm_magic = SM_MAGIC_NULL; sm_free_size(qss_ctx, sizeof(*qss_ctx)); return SM_SUCCESS; } /* ** IQDB_CLOSE_SS -- close all data for one smtps (callback for "walk" function) ** ** Parameters: ** key -- ignored ** value -- value in IQDB ** ctx -- qmgr context ** walk_ctx -- qss_ctx ** type -- type of entry ** ** Returns: ** none ** ** Locking: none (up to caller) ** ** Last code review: ** Last code change: */ static void iqdb_close_ss(const char *key, const void *value, void *ctx, void *walk_ctx, uint type) { qss_ta_P qss_ta; qss_ctx_P qss_ctx; qss_sess_P qss_sess; qmgr_ctx_P qmgr_ctx; int ss_id2close, ss_id; qmgr_ctx = (qmgr_ctx_P) ctx; SM_IS_QMGR_CTX(qmgr_ctx); qss_ctx = (qss_ctx_P) walk_ctx; ss_id2close = qss_ctx->qss_id; switch (type) { case IQDB_T_SESS: qss_sess = (qss_sess_P) value; SM_IS_QS_SE(qss_sess); ss_id = sm_getsmtpsid(qss_sess->qsses_id); if (ss_id != ss_id2close) break; (void) iqdb_session_rm(qmgr_ctx->qmgr_iqdb, qss_sess->qsses_id, SMTP_STID_SIZE, THR_NO_LOCK); (void) qss_sess_free(qss_sess); break; case IQDB_T_TA: qss_ta = (qss_ta_P) value; SM_IS_QS_TA(qss_ta); ss_id = sm_getsmtpsid(qss_ta->qssta_id); if (ss_id != ss_id2close) break; if (QSS_TA_IS_FLAG(qss_ta, QSS_TA_FL_AQ)) { /* already in AQ? */ sm_log_write(qmgr_ctx->qmgr_lctx, QM_LCAT_CLEANUP, QM_LMOD_CLEANUP, SM_LOG_WARN, 7, "sev=WARN, func=iqdb_close_ss, qss_ta=%p, flags=%#x, ta_id=%s, status=in_AQ" , qss_ta, qss_ta->qssta_flags, qss_ta->qssta_id); break; } (void) qm_ss_dtaid(qss_ctx, qss_ta, QSS_IQDB_NOLOCK); break; #if 0 case IQDB_T_RCPT: /* will be removed when qss_ta is removed */ #endif } } /* ** QSS_CTX_CLOSE -- Close a QMGR - SMTPS context ** ** Parameters: ** qss_ctx -- QMGR/SMTPS context ** ** Returns: ** usual sm_error code (always SM_SUCCESS) ** ** Locking: qss_ctx must be under control of the caller. ** ** Last code review: */ sm_ret_T qss_ctx_close(qss_ctx_P qss_ctx) { qmgr_ctx_P qmgr_ctx; if (qss_ctx == NULL) return SM_SUCCESS; SM_IS_QSS_CTX(qss_ctx); if (qss_ctx->qss_status == QSS_ST_NONE || qss_ctx->qss_id == QSS_ID_NONE) return SM_SUCCESS; qmgr_ctx = qss_ctx->qss_qmgr_ctx; SM_IS_QMGR_CTX(qmgr_ctx); iqdb_walk(qmgr_ctx->qmgr_iqdb, iqdb_close_ss, (void *) qss_ctx, THR_LOCK_UNLOCK); if (QMGR_IS_RFLAG_I(qmgr_ctx, QMGR_RFL_IQD)) { (void) qm_resource(qmgr_ctx, QMGR_UN_THROTTLE, iqdb_usage(qmgr_ctx->qmgr_iqdb), QMGR_RFL_IQD); } return SM_SUCCESS; }