/*
 * 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: hdrmodh.c,v 1.4 2005/11/14 22:31:52 ca Exp $")

#include "sm/assert.h"
#include "sm/error.h"
#include "sm/hdrmod.h"

/*
**  SM_HDRMOD_NEW -- create new hdrmod entry and append it to the list
**
**	Parameters:
**		psm_hdrmodhd -- (pointer to) head of header modification list
**		append -- append to list?
**		psm_hdrmod -- (pointer to) header modification entry (output)
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
sm_hdrmod_new(sm_hdrmodhd_P *psm_hdrmodhd, bool append, sm_hdrmod_P *psm_hdrmod)
{
	sm_ret_T ret;
	sm_hdrmod_P sm_hdrmod;
	sm_hdrmodhd_P sm_hdrmodhd;

	SM_ASSERT(psm_hdrmod != NULL);
	SM_ASSERT(psm_hdrmodhd != NULL);
	sm_hdrmod = NULL;
	sm_hdrmodhd = NULL;
	if (NULL == *psm_hdrmodhd)
	{
		sm_hdrmodhd = sm_zalloc(sizeof(*sm_hdrmodhd));
		if (sm_hdrmodhd == NULL)
			goto enomem;
		HDRMODL_INIT(sm_hdrmodhd);
	}
	else
		sm_hdrmodhd = *psm_hdrmodhd;
	sm_hdrmod = sm_zalloc(sizeof(*sm_hdrmod));
	if (sm_hdrmod == NULL)
		goto enomem;
	if (append)
		HDRMODL_APP(sm_hdrmodhd, sm_hdrmod);
	*psm_hdrmod = sm_hdrmod;
	if (NULL == *psm_hdrmodhd)
		*psm_hdrmodhd = sm_hdrmodhd;
	return SM_SUCCESS;

  enomem:
	ret = sm_error_temp(SM_EM_SMTPC, ENOMEM);
	if (sm_hdrmodhd != NULL)
		sm_free_size(sm_hdrmodhd, sizeof(*sm_hdrmodhd));
	if (sm_hdrmod != NULL)
		sm_free_size(sm_hdrmod, sizeof(*sm_hdrmod));
	return ret;
}

/*
**  SM_HDRMOD_RM -- remove first hdrmod entry
**
**	Parameters:
**		psm_hdrmodhd -- (pointer to) head of header modification list
**
**	Returns:
**		SM_SUCCESS
*/

sm_ret_T
sm_hdrmod_rm(sm_hdrmodhd_P *psm_hdrmodhd)
{
	sm_hdrmod_P sm_hdrmod;
	sm_hdrmodhd_P sm_hdrmodhd;

	if (psm_hdrmodhd == NULL)
		return SM_SUCCESS;
	sm_hdrmodhd = *psm_hdrmodhd;
	if (HDRMODL_EMPTY(sm_hdrmodhd))
		return SM_SUCCESS;
	sm_hdrmod = HDRMODL_FIRST(sm_hdrmodhd);
	HDRMODL_REMOVE(sm_hdrmodhd);
	SM_CSTR_FREE(sm_hdrmod->sm_hm_hdr);
	SM_FREE(sm_hdrmod);
	if (HDRMODL_EMPTY(sm_hdrmodhd))
	{
		sm_free_size(sm_hdrmodhd, sizeof(*sm_hdrmodhd));
		*psm_hdrmodhd = NULL;
	}
	return SM_SUCCESS;
}

/*
**  SM_HDRMOD_RM_LAST -- remove last hdrmod entry
**
**	Parameters:
**		psm_hdrmodhd -- (pointer to) head of header modification list
**
**	Returns:
**		SM_SUCCESS
*/

sm_ret_T
sm_hdrmod_rm_last(sm_hdrmodhd_P *psm_hdrmodhd)
{
	sm_hdrmod_P sm_hdrmod;
	sm_hdrmodhd_P sm_hdrmodhd;

	if (psm_hdrmodhd == NULL)
		return SM_SUCCESS;
	sm_hdrmodhd = *psm_hdrmodhd;
	if (HDRMODL_EMPTY(sm_hdrmodhd))
		return SM_SUCCESS;
	sm_hdrmod = HDRMODL_LAST(sm_hdrmodhd);
	HDRMODL_RM_LAST(sm_hdrmodhd);
	SM_CSTR_FREE(sm_hdrmod->sm_hm_hdr);
	SM_FREE(sm_hdrmod);
	if (HDRMODL_EMPTY(sm_hdrmodhd))
	{
		sm_free_size(sm_hdrmodhd, sizeof(*sm_hdrmodhd));
		*psm_hdrmodhd = NULL;
	}
	return SM_SUCCESS;
}

/*
**  SM_HDRMOD_RM_ELEM -- remove specified hdrmod entry
**
**	Parameters:
**		psm_hdrmodhd -- (pointer to) head of header modification list
**		sm_hdrmod -- header modification entry to remove
**
**	Returns:
**		SM_SUCCESS
*/

sm_ret_T
sm_hdrmod_rm_elem(sm_hdrmodhd_P *psm_hdrmodhd, sm_hdrmod_P sm_hdrmod)
{
	sm_hdrmodhd_P sm_hdrmodhd;

	if (NULL == sm_hdrmod)
		return SM_SUCCESS;
	if (psm_hdrmodhd == NULL)
		return SM_SUCCESS;
	sm_hdrmodhd = *psm_hdrmodhd;
	SM_ASSERT(sm_hdrmodhd != NULL);
	if (HDRMODL_EMPTY(sm_hdrmodhd))
		return SM_SUCCESS;
	HDRMODL_RM_ELEM(sm_hdrmodhd, sm_hdrmod);
	SM_CSTR_FREE(sm_hdrmod->sm_hm_hdr);
	SM_FREE(sm_hdrmod);
	if (HDRMODL_EMPTY(sm_hdrmodhd))
	{
		sm_free_size(sm_hdrmodhd, sizeof(*sm_hdrmodhd));
		*psm_hdrmodhd = NULL;
	}
	return SM_SUCCESS;
}


/*
**  SM_HDRMODL_FREE -- free entire header modification list
**
**	Parameters:
**		psm_hdrmodhd -- (pointer to) head of header modification list
**
**	Returns:
**		SM_SUCCESS
*/

sm_ret_T
sm_hdrmodl_free(sm_hdrmodhd_P *psm_hdrmodhd)
{
	sm_hdrmod_P sm_hdrmod;
	sm_hdrmodhd_P sm_hdrmodhd;

	if (psm_hdrmodhd == NULL)
		return SM_SUCCESS;
	sm_hdrmodhd = *psm_hdrmodhd;
	if (sm_hdrmodhd == NULL)
		return SM_SUCCESS;
	while (!HDRMODL_EMPTY(sm_hdrmodhd))
	{
		sm_hdrmod = HDRMODL_FIRST(sm_hdrmodhd);
		HDRMODL_REMOVE(sm_hdrmodhd);
		SM_CSTR_FREE(sm_hdrmod->sm_hm_hdr);
		SM_FREE(sm_hdrmod);
	}
	sm_free_size(sm_hdrmodhd, sizeof(*sm_hdrmodhd));
	*psm_hdrmodhd = NULL;
	return SM_SUCCESS;
}


syntax highlighted by Code2HTML, v. 0.9.1