/*
* Copyright (c) 2002, 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: rfc2821dom.c,v 1.8 2005/03/15 19:56:07 ca Exp $")
#include "sm/assert.h"
#include "sm/error.h"
#include "sm/memops.h"
#include "sm/ctype.h"
#include "sm/rfc2821.h"
#include "sm/rfc2822.h"
/*
** T2821_CP_TOKEN -- copy a token
**
** Parameters:
** rpool -- rpool
** src_tok -- source token
** dst_tok -- destination token (output)
**
** Returns:
** usual error code
*/
sm_ret_T
t2821_cp_token(sm_rpool_P rpool, sm_t2821_P src_tok,sm_t2821_P *pdst_tok)
{
sm_t2821_P new_tok;
int curtype;
SM_REQUIRE(pdst_tok != NULL);
curtype = src_tok->sm_t2821_type;
new_tok = (sm_t2821_P) sm_rpool_zalloc(rpool, sizeof(*new_tok));
if (new_tok == NULL)
goto error;
new_tok->sm_t2821_type = curtype;
if (curtype >= T2821_MINTOK)
{
new_tok->sm_t2821_val = sm_str_dup(rpool,
src_tok->sm_t2821_val);
if (new_tok->sm_t2821_val == NULL)
goto error;
}
*pdst_tok = new_tok;
return SM_SUCCESS;
error:
/* remove unconnected token */
if (new_tok != NULL)
t2821_free(rpool, new_tok);
return sm_error_temp(SM_EM_ADDR, ENOMEM);
}
/*
** T2821_EXTRACT_DOMAIN -- extract a domain from a valid address
**
** Parameters:
** rpool -- rpool
** addr -- address
** pdomain -- domain part of address (output)
**
** Returns:
** usual error code
*/
sm_ret_T
t2821_extract_domain(sm_rpool_P rpool, sm_a2821_T *addr, sm_a2821_T **pdomain)
{
sm_t2821_P tok;
sm_t2821_P t;
sm_ret_T ret;
SM_REQUIRE(addr != NULL);
SM_REQUIRE(pdomain != NULL);
tok = A2821_FIRST(addr);
/*
** Search for '@'. This doesn't work for "route addresses", but
** those are supposed to be stripped before this function is called.
*/
while (tok != NULL && tok != A2821_END(addr)
&& tok->sm_t2821_type != T2821_AT)
tok = T2821_NEXT(tok);
if (tok == NULL || tok == A2821_END(addr))
return sm_error_perm(SM_EM_ADDR, R2821_ERR_FQDN); /* XXX? */
/* skip over '@' */
tok = T2821_NEXT(tok);
/* copy rest of address (domain part) */
while (tok != NULL && tok != A2821_END(addr)
&& tok->sm_t2821_type != T2821_RIGHT)
{
ret = t2821_cp_token(rpool, tok, &t);
if (sm_is_err(ret))
goto error;
tok = T2821_NEXT(tok);
A2821_INSERT_TAIL(*pdomain, t);
}
return SM_SUCCESS;
error:
/* remove unconnected token */
if (t != NULL)
t2821_free(rpool, t);
/* should cleanup addr, need to remember old value, free new ones */
return ret;
}
syntax highlighted by Code2HTML, v. 0.9.1