/*
 */

#include "sm/generic.h"
SM_RCSID("@(#)$Id: qss_ntaid.c,v 1.59 2007/03/26 03:34:28 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 "sm/rfc2821.h"
#include "qmgr.h"
#include "log.h"

/*
**  QM_SS_1TAID -- One TAID from SMTPS, put qss_ta into IQDB
**
**	Parameters:
**		qss_ctx -- QMGR/SMTPS context
**		qss_ta -- transaction
**
**	Returns:
**		usual sm_error code
**
**	Called by: qss_react
**
**	Side Effects:
**		if IQDB is full qss_control() is called.
**		qss_ta is only in IQDB if the function is successful.
*/

sm_ret_T
qm_ss_1taid(qss_ctx_P qss_ctx, qss_ta_P qss_ta)
{
	sm_ret_T ret;
	int flags;
	sm_a2821_T addr;
	qss_ta_P rta;

	SM_IS_QSS_CTX(qss_ctx);
	SM_IS_QS_TA(qss_ta);
	rta = NULL;

	/* XXX do a check on the sender address here? */

	A2821_INIT_RP(&(addr), NULL);
	ret = t2821_scan((sm_rdstr_P) qss_ta->qssta_mail->qsm_pa, &addr, 0);
	QM_LEV_DPRINTFC(QDC_S2Q, 3, (QM_DEBFP, "func=qm_ss_1taid, mail=%@N, t2821_scan=%r\n", qss_ta->qssta_mail->qsm_pa, ret));
	if (sm_is_err(ret))
		goto reject;
	flags = R2821_CORRECT | R2821_EMPTY;
	ret = t2821_parse(&addr, flags);
	QM_LEV_DPRINTFC(QDC_S2Q, 3, (QM_DEBFP, "func=qm_ss_1taid, mail=%@N, t2821_parse=%r\n", qss_ta->qssta_mail->qsm_pa, ret));

	/* addr isn't used anymore... */
	(void) a2821_free(&addr);
	if (sm_is_err(ret))
		goto reject;

	ret = iqdb_trans_new(qss_ctx->qss_qmgr_ctx->qmgr_iqdb, qss_ta->qssta_id,
			SMTP_STID_SIZE, qss_ta, (void **) &rta, THR_LOCK_UNLOCK);
	if (sm_is_err(ret)) {
		if (sm_error_value(ret) == SM_E_FULL || sm_error_value(ret) == ENOMEM)
			(void) qss_control(qss_ctx, QMGR_THROTTLE, 100,
					QMGR_RFL_IQD_I, THR_LOCK_UNLOCK);
		goto reject;
	}
	QSS_TA_SET_FLAG(qss_ta, QSS_TA_FL_IQDB);
	QM_LEV_DPRINTFC(QDC_S2Q, 1, (QM_DEBFP, "func=qm_ss_1taid, status=accept, mail=%@N, ret=%d\n", qss_ta->qssta_mail->qsm_pa, ret));
#if 0
	sm_log_write(qss_ctx->qss_qmgr_ctx->qmgr_lctx,
		QM_LCAT_SMTPS, QM_LMOD_FROM_SMTPS,
		SM_LOG_INFO, 12,
		"func=qm_ss_1taid, mail=%@N, ret=%d",
		qss_ta->qssta_mail->qsm_pa, ret);
#endif /* 0 */
	return SM_SUCCESS;

  reject:
	ret = sm_is_temp_err(ret) ? SMTP_R_SSD : SMTP_R_REJECT;
	sm_log_write(qss_ctx->qss_qmgr_ctx->qmgr_lctx,
		QM_LCAT_SMTPS, QM_LMOD_FROM_SMTPS,
		SM_LOG_INFO, 11,
		"func=qm_ss_1taid, mail=%@N, error=%d",
		qss_ta->qssta_mail->qsm_pa, ret);

	QM_LEV_DPRINTFC(QDC_S2Q, 0, (QM_DEBFP, "func=qm_ss_1taid, status=reject, mail=%@N\n", qss_ta->qssta_mail->qsm_pa));

#if 0
  error:
	/* qss_ta removed in caller */
	/* 2003-10-20 03:20:02 XXX Why? It's better to do it here!(?) */
	/*
	**  2003-10-22 17:35:12 rta MUST be NULL for now because there is no
	**  no function called between iqdb_trans_new() and here.
	*/

//	if (rta != NULL)
//	{
//		(void) iqdb_trans_rm(qss_ctx->qss_q_ctx->qmgr_iqdb,
//				qss_ta->qssta_id, SMTP_STID_SIZE,
//				THR_LOCK_UNLOCK);
//	}
#else /* 0 */
	SM_ASSERT(rta == NULL);
#endif /* 0 */

	/*
	**  This might have been freed already, but it's ok to call the
	**  function again.  Alternatively we could use a pointer and set
	**  it to NULL after freeing the address.
	*/

	(void) a2821_free(&addr);
	return ret;
}


syntax highlighted by Code2HTML, v. 0.9.1