/*
* Copyright (c) 2005, 2006 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_rcptmod.c,v 1.5 2006/10/05 04:27:38 ca Exp $")
#include "sm/error.h"
#include "sm/assert.h"
#include "pmilter.h"
#include "sm/pmfdef.h"
#include "sm/pmfapi.h"
#include "sm/pmilter.h"
#if MTA_USE_PMILTER
/*
** PM_RCPTS_NEW -- add a new recipient to the recipient list
**
** Parameters:
** pmse_ctx -- SMTP server transaction context
** rcpt_pa -- recipient (printable address, RFC 2821)
** len -- len of rcpt_pa
** ppm_rcpt -- (pointer to) new recipient (output)
**
** Returns:
** usual return code
*/
static sm_ret_T
pm_rcpt_add(pmse_ctx_P pmse_ctx, const char *rcpt_pa, uint len, rcpt_idx_T rcpt_idx, pm_rcpt_P *ppm_rcpt)
{
pm_rcpt_P pm_rcpt;
SM_REQUIRE(ppm_rcpt != NULL);
pm_rcpt = (pm_rcpt_P) sm_zalloc(sizeof(*pm_rcpt));
if (NULL == pm_rcpt)
return sm_err_temp(ENOMEM);
pm_rcpt->pmr_pa = sm_str_scpyn0(NULL, rcpt_pa, len + 1, len + 2);
if (NULL == pm_rcpt->pmr_pa)
goto error;
PM_RCPTS_INSERT_TAIL(&pmse_ctx->pmse_rcpts_hd, pm_rcpt);
pm_rcpt->pmr_idx = rcpt_idx;
*ppm_rcpt = pm_rcpt;
return SM_SUCCESS;
error:
SM_STR_FREE(pm_rcpt->pmr_pa);
SM_FREE(pm_rcpt);
*ppm_rcpt = NULL;
return sm_err_temp(ENOMEM);
}
/*
** PM_RCPTS_FREE -- free an entire recipient list
**
** Parameters:
** pmse_ctx -- SMTP server transaction context
**
** Returns:
** usual return code
*/
sm_ret_T
pm_rcpts_free(pmse_ctx_P pmse_ctx)
{
pm_rcpt_P pm_rcpt;
while (!PM_RCPTS_EMPTY(&pmse_ctx->pmse_rcpts_hd))
{
pm_rcpt = PM_RCPTS_FIRST(&pmse_ctx->pmse_rcpts_hd);
PM_RCPTS_REMOVE_HEAD(&pmse_ctx->pmse_rcpts_hd);
SM_STR_FREE(pm_rcpt->pmr_pa);
SM_FREE(pm_rcpt);
}
PM_RCPTS_INIT(&pmse_ctx->pmse_rcpts_hd);
return SM_SUCCESS;
}
/*
** PM_RCPT_MOD -- Add or delete recipient
**
** Parameters:
** pmse_ctx -- pmilter/SMTP server session context
** rcpt_pa -- recipient (rfc 2821 format)
** rcpt_idx -- recipient index
** type -- add/delete
**
** Returns:
** usual sm_error code
*/
static sm_ret_T
pm_rcpt_mod(pmse_ctx_P pmse_ctx, const char *rcpt_pa, rcpt_idx_T rcpt_idx, uint type)
{
sm_ret_T ret;
pm_rcpt_P pm_rcpt;
size_t len;
SM_IS_PMSE_CTX(pmse_ctx);
if (NULL == rcpt_pa)
return sm_error_perm(SM_EM_PMILTER, EINVAL);
if (!SM_IS_FLAG(pmse_ctx->pmse_pmss_ctx->pmss_pmcap,
SM_SCAP_PM_RCPTMOD))
return sm_error_perm(SM_EM_PMILTER, SM_E_PR_ERR);
if (pmse_ctx->pmse_state != PMSE_ST_DOT)
return sm_error_perm(SM_EM_PMILTER, SM_E_PR_ERR);
pm_rcpt = NULL;
len = strlen((const char *) rcpt_pa);
if (len < 5 || len > MAXADDRLEN)
return sm_error_perm(SM_EM_PMILTER, EINVAL);
if (rcpt_pa[0] != '<' || rcpt_pa[len - 1] != '>')
return sm_error_perm(SM_EM_PMILTER, EINVAL);
/* do a full syntax check here?? */
ret = pm_rcpt_add(pmse_ctx, rcpt_pa, len, rcpt_idx, &pm_rcpt);
if (sm_is_err(ret))
return ret;
pm_rcpt->pmr_type = type;
return SM_SUCCESS;
}
/*
** SM_PMFI_RCPT_ADD -- Add recipient
**
** Parameters:
** pmse_ctx -- pmilter/SMTP server session context
** rcpt_pa -- recipient (rfc 2821 format)
** argv -- list of SMTP parameter for RCPT; NULL terminated list.
** (currently ignored)
**
** Returns:
** usual sm_error code
*/
sm_ret_T
sm_pmfi_rcpt_add(pmse_ctx_P pmse_ctx, const char *rcpt_pa, char **argv)
{
return pm_rcpt_mod(pmse_ctx, rcpt_pa, 0, PM_RCPT_ADD);
}
/*
** SM_PMFI_RCPT_DEL -- Delete recipient
**
** Parameters:
** pmse_ctx -- pmilter/SMTP server session context
** rcpt_pa -- recipient (rfc 2821 format)
** rcpt_idx -- recipient index
**
** Returns:
** usual sm_error code
*/
sm_ret_T
sm_pmfi_rcpt_del(pmse_ctx_P pmse_ctx, const char *rcpt_pa, rcpt_idx_T rcpt_idx)
{
return pm_rcpt_mod(pmse_ctx, rcpt_pa, rcpt_idx, PM_RCPT_DEL);
}
#endif /* MTA_USE_PMILTER */
syntax highlighted by Code2HTML, v. 0.9.1