/* * 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); /* ** -> ** "" 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; }