/*
* Copyright (c) 2003-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: adbupd.c,v 1.26 2006/12/11 01:22:06 ca Exp $")
#include "sm/types.h"
#include "sm/assert.h"
#include "sm/magic.h"
#include "sm/str.h"
#include "sm/time.h"
#include "sm/mta.h"
#include "sm/memops.h"
#include "sm/qmgr.h"
#include "sm/actdb-int.h"
#include "sm/qmgr-int.h"
#include "adb.h"
/*
** AQ_RSND_CTX_FREE -- Free aq_rsnd_ctx
**
** Parameters:
** aq_rsnd_ctx -- aq recipient send RCB to SMTPC context
**
** Returns:
** SM_SUCCESS
**
** Last code review: 2005-04-14 20:31:18
** Last code change:
*/
sm_ret_T
aq_rsnd_ctx_free(aq_rsnd_ctx_P aq_rsnd_ctx)
{
if (aq_rsnd_ctx != NULL)
sm_free_size(aq_rsnd_ctx, sizeof(*aq_rsnd_ctx));
return SM_SUCCESS;
}
/*
** AQ_RSND_CTX_NEW -- Create new aq_rsnd_ctx
**
** Parameters:
** aq_ctx -- AQ context
** aq_rcpt -- AQ rcpt
** paq_rsnd_ctx -- (ptr to) rcpt send RCB to SMTPC context (output)
**
** Returns:
** usual sm_error code; ENOMEM
**
** Last code review: 2005-04-14 20:31:00
** Last code change:
*/
sm_ret_T
aq_rsnd_ctx_new(aq_ctx_P aq_ctx, aq_rcpt_P aq_rcpt, aq_rsnd_ctx_P *paq_rsnd_ctx)
{
aq_rsnd_ctx_P aq_rsnd_ctx;
SM_IS_AQ(aq_ctx);
SM_REQUIRE(paq_rsnd_ctx != NULL);
aq_rsnd_ctx = (aq_rsnd_ctx_P)sm_zalloc(sizeof(*aq_rsnd_ctx));
if (aq_rsnd_ctx == NULL)
return sm_error_temp(SM_EM_AQ, ENOMEM);
aq_rsnd_ctx->aqrsc_aq_ctx = aq_ctx;
aq_rsnd_ctx->aqrsc_rcpt = aq_rcpt;
*paq_rsnd_ctx = aq_rsnd_ctx;
return SM_SUCCESS;
}
/*
** AQ_RCPTSENT2DA -- change status flags for recipients sent to a DA.
** This is a callback that is invoked after an RCB has been sent.
** See qm_to_sc() for a discussion.
**
** Parameters:
** ctx -- aq recipient send RCB to SMTPC context
**
** Returns:
** usual sm_error code
**
** Locking: locks entire aq_ctx.
**
** Last code review: 2005-04-15 20:13:50
** Last code change:
*/
sm_ret_T
aq_rcptsent2da(void *ctx)
{
int r;
sm_ret_T ret;
time_T tm;
aq_ctx_P aq_ctx;
thr_lock_T locktype;
aq_rcpt_P aq_rcpt, aq_rcpt_nxt;
aq_rsnd_ctx_P aq_rsnd_ctx;
qmgr_ctx_P qmgr_ctx;
SM_REQUIRE(ctx != NULL);
aq_rsnd_ctx = (aq_rsnd_ctx_P)ctx;
aq_ctx = aq_rsnd_ctx->aqrsc_aq_ctx;
aq_rcpt = aq_rsnd_ctx->aqrsc_rcpt;
qmgr_ctx = aq_ctx->aq_qmgr_ctx;
SM_IS_AQ(aq_ctx);
SM_IS_AQ_RCPT(aq_rcpt);
SM_IS_QMGR_CTX(qmgr_ctx);
locktype = THR_LOCK_UNLOCK;
if (thr_lock_it(locktype))
{
r = pthread_mutex_lock(&aq_ctx->aq_mutex);
SM_LOCK_OK(r);
if (r != 0)
return sm_error_perm(SM_EM_AQ, r);
}
ret = SM_SUCCESS;
tm = evthr_time(qmgr_ctx->qmgr_ev_ctx);
/* go through the list of entries in the DA transaction */
aq_rcpt_nxt = aq_rcpt;
do
{
#if QMGR_DEBUG > 1
QM_LEV_DPRINTF(3, (QM_DEBFP, "sev=DBG, func=aq_rcptsent2da, aq_rcpt=%p, aq_rcpt_nxt=%p\n", aq_rcpt, aq_rcpt_nxt));
aq_rcpt_print(aq_rcpt);
#endif /* QMGR_DEBUG > 1 */
ret = aq_waitq_add(aq_ctx, aq_rcpt_nxt, tm, AQWQ_DA, false);
/* AQR_SET_FLAG(aq_rcpt_nxt, AQR_FL_WAIT4UPD); */
QM_LEV_DPRINTF(3, (QM_DEBFP, "sev=DBG, func=aq_rcptsent2da, aq_rcpt_nxt=%p, aq_waitq_add=%x\n", aq_rcpt_nxt, ret));
aq_rcpt_nxt = AQR_DA_SUCC(aq_rcpt_nxt);
} while (aq_rcpt_nxt != aq_rcpt);
tm = aq_waitq_first_tmo(aq_ctx, AQWQ_DA, false);
if (tm > 0)
ret = qmgr_set_aq_cleanup(aq_ctx->aq_qmgr_ctx->qmgr_cleanup_ctx, tm, true);
else
QM_LEV_DPRINTF(3, (QM_DEBFP, "sev=DBG, func=aq_rcptsent2da, expt=%7ld\n", (long) tm));
if ((!sm_is_err(ret) && thr_unl_no_err(locktype))
|| (sm_is_err(ret) && thr_unl_if_err(locktype)))
{
r = pthread_mutex_unlock(&aq_ctx->aq_mutex);
SM_ASSERT(r == 0);
if (r != 0 && sm_is_success(ret))
ret = sm_error_perm(SM_EM_AQ, r);
}
aq_rsnd_ctx_free(aq_rsnd_ctx);
return ret;
}
syntax highlighted by Code2HTML, v. 0.9.1