/*
* Copyright (c) 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: verpify.c,v 1.3 2007/11/14 06:03:08 ca Exp $")
#include "sm/assert.h"
#include "sm/error.h"
#include "sm/memops.h"
#include "sm/ctype.h"
#include "sm/str.h"
#include "sm/misc.h"
/*
** SM_VERPIFY -- convert sender address in to VERP format
**
** Parameters:
** mail_pa -- (MAIL) address
** rcpt_pa -- RCPT address
** delim1 -- first delimiter ('+')
** delim2 -- second delimiter ('=')
** verp_pa -- VERP address (output)
**
** Returns:
** usual error code
*/
sm_ret_T
sm_verpify(sm_str_P mail_pa, sm_str_P rcpt_pa, uchar delim1, uchar delim2, sm_str_P verp_pa)
{
sm_ret_T ret;
uint mail_at, rcpt_at, mail_len, rcpt_len;
SM_REQUIRE(mail_pa != NULL);
SM_REQUIRE(rcpt_pa != NULL);
SM_REQUIRE(verp_pa != NULL);
mail_len = sm_str_getlen(mail_pa);
rcpt_len = sm_str_getlen(rcpt_pa);
SM_REQUIRE(mail_len > 2);
SM_REQUIRE(rcpt_len > 2);
if ('\0' == delim1)
delim1 = (uchar)'+';
if ('\0' == delim2)
delim2 = (uchar)'=';
/*
** "assume" that the addresses are in the correct format,
** do not try to parse them.
*/
ret = sm_str_lchr(mail_pa, (const uchar *)"@", &mail_at);
if (sm_is_err(ret))
goto error;
if (mail_at < 2 || mail_at + 1 >= mail_len)
goto error;
ret = sm_str_lchr(rcpt_pa, (const uchar *)"@", &rcpt_at);
if (sm_is_err(ret))
goto error;
if (rcpt_at < 2 || rcpt_at + 1 >= rcpt_len)
goto error;
sm_str_clr(verp_pa);
/*
** <lm@mail> <lr@rcpt> -> <lm+lr=rcpt@mail>
** "<lm" 0 - mail_at-1
** "lr" 1 - rcpt_at-1
** "rcpt" rcpt_at+1 - rcpt_len-2
** "@mail>" mail_at - mail_len-1
*/
ret = sm_str_catpart(verp_pa, (const sm_rdstr_P) mail_pa, 0,
mail_at - 1);
if (sm_is_err(ret))
goto error;
ret = sm_str_put(verp_pa, delim1);
if (sm_is_err(ret))
goto error;
ret = sm_str_catpart(verp_pa, (const sm_rdstr_P) rcpt_pa, 1,
rcpt_at - 1);
if (sm_is_err(ret))
goto error;
ret = sm_str_put(verp_pa, delim2);
if (sm_is_err(ret))
goto error;
ret = sm_str_catpart(verp_pa, (const sm_rdstr_P) rcpt_pa, rcpt_at + 1,
rcpt_len - 2);
if (sm_is_err(ret))
goto error;
ret = sm_str_catpart(verp_pa, (const sm_rdstr_P) mail_pa, mail_at,
mail_len - 1);
if (sm_is_err(ret))
goto error;
return ret;
error:
if (sm_is_success(ret))
ret = sm_err_perm(EINVAL);
return ret;
}
syntax highlighted by Code2HTML, v. 0.9.1