/*
 * 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: qss_dtaid.c,v 1.53 2007/03/26 03:20:55 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/reccom.h"
#include "qmgr.h"

/*
**  QM_SS_DTAID -- discard SMTPS transaction
**
**	Parameters:
**		qss_ctx -- QMGR/SMTPS context
**		qss_ta -- transaction
**		rmflags -- flags for IQDB fcts (QSS_, for qss_rcpt_free() etc)
**
**	Returns:
**		usual sm_error code
**
**	Last code review:
**	Last code change: 2005-09-29 04:11:22
*/

sm_ret_T
qm_ss_dtaid(qss_ctx_P qss_ctx, qss_ta_P qss_ta, uint rmflags)
{
	sm_ret_T ret;
	bool hasrcpts;
	rcpt_idx_T rcpt_idx_high;
	ibdb_ta_T ibdb_ta;

	if (qss_ta == NULL)
	{
		/*
		**  this may happen if we couldn't allocate the TA,
		**  so let's just tell SMTPS we discarded the TA.
		*/

		return SM_SUCCESS;
	}
	SM_IS_QSS_CTX(qss_ctx);
	SM_IS_QS_TA(qss_ta);

	/* need to copy qssta_rcpts_tot before qss_rcpts_free() */
	if (qss_ta->qssta_mail != NULL)
		ibdb_ta.ibt_nrcpts = qss_ta->qssta_rcpts_tot;
	hasrcpts = qss_ta->qssta_rcpts_tot > 0;

	/* free all recipients; won't fail (2004-04-23) */
	/* XXX qss_ta_free() free()s rcpts too? (2005-04-01) */
	ret = qss_rcpts_free(qss_ta, QSS_RMFIQDB|QSS_DECR_RCPTS_TOT|rmflags,
				&rcpt_idx_high);
	if (sm_is_err(ret))
		goto error;
	hasrcpts = hasrcpts && ret != SM_NOTDONE;

	/*
	**  should we also write one record for each recipient?
	**  probably not worth the effort, let the recovery program
	**  deal with it.
	*/

	/* XXX check status? */
	if (qss_ta->qssta_mail != NULL && hasrcpts)
	{
		ibdb_ta.ibt_ta_id = qss_ta->qssta_id;
		ibdb_ta.ibt_mail_pa = qss_ta->qssta_mail->qsm_pa;
		ibdb_ta.ibt_cdb_id = (qss_ta->qssta_cdb_id == NULL)
				? SM_CSTR_DUP(null_cdb_id)
				: SM_CSTR_DUP(qss_ta->qssta_cdb_id);
		ret = ibdb_ta_status(qss_ctx->qss_qmgr_ctx->qmgr_ibdb,
				&ibdb_ta, IBDB_TA_CANCEL, IBDB_FL_NONE,
				rcpt_idx_high, THR_LOCK_UNLOCK);
		/* XXX COMPLAIN if error? ret is checked below */

		SM_CSTR_FREE(ibdb_ta.ibt_cdb_id);
	}

	/* remove transaction from iqdb */
	(void) iqdb_trans_rm(qss_ctx->qss_qmgr_ctx->qmgr_iqdb,
			qss_ta->qssta_id, SMTP_STID_SIZE,
			SM_IS_FLAG(rmflags, QSS_IQDB_NOLOCK)
				? THR_NO_LOCK : THR_LOCK_UNLOCK);
	QSS_TA_SET_FLAG(qss_ta, QSS_TA_FL_IQDB_RM);
	if (QMGR_IS_RFLAG_I(qss_ctx->qss_qmgr_ctx, QMGR_RFL_IQD))
	{
		(void) qm_resource(qss_ctx->qss_qmgr_ctx, QMGR_UN_THROTTLE,
				iqdb_usage(qss_ctx->qss_qmgr_ctx->qmgr_iqdb),
				QMGR_RFL_IQD);
	}

	(void) qss_ta_free(qss_ta, false, 0 /* XXX */, rmflags);
	if (sm_is_err(ret))
		goto error;

	return SM_SUCCESS;

  error:
	return ret;
}


syntax highlighted by Code2HTML, v. 0.9.1