/*
 * 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