/*
 * Copyright (c) 2004, 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: mapopt.c,v 1.10 2006/05/02 17:13:41 ca Exp $")

#include "sm/assert.h"
#include "sm/error.h"
#include "sm/varargs.h"
#include "map.h"
#include "sm/map.h"
#include "sm/mapc.h"

/*
**  MAP_SETOPT -- set options for map
**
**	Parameters:
**		map -- map
**		... -- options
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
sm_map_setopt(sm_map_P map, ...)
{
	sm_ret_T ret;
	sm_mapc_P mapc;
	int i, opttype;
	va_list ap;

	SM_IS_MAP(map);
	mapc = map->sm_map_class;
	SM_IS_MAPC(mapc);
	sm_memzero(&map->sm_map_opts, sizeof(map->sm_map_opts));
	va_start(ap, map);
	for (i = 0; i < SM_MAP_MAX_OPT; i++)
	{
		opttype = va_arg(ap, int);
		map->sm_map_opts[i].sm_map_opt_type = opttype;
		if (opttype == SMPO_END)
			break;
		switch (SMPO_GET_TYPE(opttype))
		{
		  case SMPO_INT:
			map->sm_map_opts[i].sm_map_opt_int = va_arg(ap, int);
			break;
		  case SMPO_PTR:
			map->sm_map_opts[i].sm_map_opt_ptr = va_arg(ap,
								void *);
			break;
		  default:
			/* crash and burn */
			SM_ASSERT(opttype == SMPO_END);
			break;
		}
	}
	va_end(ap);
	if (i >= SM_MAP_MAX_OPT)
		return sm_error_perm(SM_EM_MAP, SM_E_FULL);

	if (mapc->sm_mapc_setoptf != NULL)
	{
		va_start(ap, map);
		ret = mapc->sm_mapc_setoptf(map, ap);
		va_end(ap);
	}
	else
		ret = sm_error_perm(SM_EM_MAP, EINVAL);	/* XXX */
	return ret;
}

/*
**  MAP_SETONEOPT -- set one option for a map
**
**	Parameters:
**		map -- map
**		... -- options
**
**	Returns:
**		usual sm_error code
*/

static sm_ret_T
sm_map_setoneopt(sm_map_P map, ...)
{
	sm_ret_T ret;
	sm_mapc_P mapc;
	va_list ap;

	SM_IS_MAP(map);
	mapc = map->sm_map_class;
	SM_IS_MAPC(mapc);
	if (mapc->sm_mapc_setoptf != NULL)
	{
		va_start(ap, map);
		ret = mapc->sm_mapc_setoptf(map, ap);
		va_end(ap);
	}
	else
		ret = sm_error_perm(SM_EM_MAP, EINVAL);	/* XXX */
	return ret;
}

/*
**  MAP_SETOPTS -- set options for map
**
**	Parameters:
**		map -- map
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
sm_map_setopts(sm_map_P map)
{
	sm_ret_T ret;
	sm_mapc_P mapc;
	int i, opttype;

	SM_IS_MAP(map);
	mapc = map->sm_map_class;
	SM_IS_MAPC(mapc);
	ret = SM_SUCCESS;
	if (mapc->sm_mapc_setoptf != NULL)
	{
		for (i = 0; i < SM_MAP_MAX_OPT; i++)
		{
			opttype = map->sm_map_opts[i].sm_map_opt_type;
			if (opttype == SMPO_END)
				break;
			switch (SMPO_GET_TYPE(opttype))
			{
			  case SMPO_INT:
				ret = sm_map_setoneopt(map, opttype,
					map->sm_map_opts[i].sm_map_opt_int,
					SMPO_END);
				break;
			  case SMPO_PTR:
				ret = sm_map_setoneopt(map, opttype,
					map->sm_map_opts[i].sm_map_opt_ptr,
					SMPO_END);
				break;
			  default:
				/* crash and burn */
				SM_ASSERT(opttype == SMPO_END);
				break;
			}
			if (sm_is_err(ret))
				break;
		}
	}
	return ret;
}


/*
**  MAP_GETOPT -- get options for map
**
**	Parameters:
**		map -- map
**		which -- which option?
**		valp -- pointer to place where result should be stored
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
sm_map_getopt(sm_map_P map, int which, void *valp)
{
	sm_ret_T ret;
	sm_mapc_P mapc;

	SM_IS_MAP(map);
	mapc = map->sm_map_class;
	SM_IS_MAPC(mapc);
	if (mapc->sm_mapc_getoptf != NULL)
		ret = mapc->sm_mapc_getoptf(map, which, valp);
	else
		ret = sm_error_perm(SM_EM_MAP, EINVAL);	/* XXX */
	return ret;
}


syntax highlighted by Code2HTML, v. 0.9.1