/*
 * 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: mapconfopen.c,v 1.12 2007/01/11 17:51:20 ca Exp $")

#include "sm/error.h"
#include "sm/string.h"
#include "sm/net.h"
#include "sm/memops.h"
#include "sm/maps.h"
#include "sm/mapc.h"
#include "sm/map.h"
#include "map.h"
#include "sm/sm-conf.h"
#include "sm/mapcnf.h"
#include "sm/mapconf.h"
#include "sm/confsetpath.h"

/*
**  SM_MAPCONFOPEN -- open all maps that are in a map declaration
**
**	Parameters:
**		mapdef -- map configuration
**		maps -- map system context
**		confdir -- directory of configuration file (for relative paths)
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
sm_mapconfopen(map_decl_P mapdef, sm_maps_P maps, const char *confdir)
{
	uint n, i;
	sm_ret_T ret;
	mapspec_P md_maps;
	sm_map_P map;
	sm_cstr_P mtype, mname, sname;

	SM_REQUIRE(mapdef != NULL);
	SM_REQUIRE(maps != NULL);
	mtype = mname = sname = NULL;
	for (n = 0; n < mapdef->mapdecl_n; n++) {
		md_maps = mapdef->mapdecl_maps + n;
		if (NULL == md_maps)
			continue;
		mname = NULL;
		mtype = sm_cstr_scpyn0((const uchar *)md_maps->mst_type,
				strlen(md_maps->mst_type));
		ret = sm_error_temp(SM_EM_MAP, ENOMEM);
		if (NULL == mtype)
			goto error;
		mname = sm_cstr_scpyn0((const uchar *)md_maps->mst_name,
				strlen(md_maps->mst_name));
		if (NULL == mname)
			goto error;
		map = NULL;
		ret = sm_map_create(maps, mtype, 0, &map);
		if (sm_is_err(ret))
			goto error;

		switch (md_maps->mst_kind) {
		  case MST_HASH:
			if (md_maps->mst_hash.mst_hash_fn == NULL ||
			    *md_maps->mst_hash.mst_hash_fn == '\0')
			{
				ret = sm_error_temp(SM_EM_MAP, EINVAL);
				goto error;
			}
			else {
				const char *mpath;

				SM_GEN_MAP_PATH(mpath,
					md_maps->mst_hash.mst_hash_path,
					confdir, md_maps->mst_hash.mst_hash_fn,
					NULL, error);
				ret = sm_map_open(maps, mname, mtype, 0, mpath,
					SMAP_MODE_RDONLY, &map, SMPO_END);
			}
			break;

		  case MST_PASSWD:
			ret = sm_map_open(maps, mname, mtype, 0, NULL,
				SMAP_MODE_RDONLY, &map, SMPO_END);
			break;

		  case MST_SOCKET:
			ret = sm_map_open(maps, mname, mtype, 0,
				md_maps->mst_socket.mst_socket_mapname,
				SMAP_MODE_RDONLY, &map,
				SMPO_SOCKPATH,
					md_maps->mst_socket.mst_socket_path,
				SMPO_PORT, md_maps->mst_socket.mst_socket_port,
				SMPO_IPV4, md_maps->mst_socket.mst_socket_ipv4,
				SMPO_END);
			break;

		  case MST_SEQUENCE:
			ret = SM_SUCCESS;
			for (i = 0;
			     md_maps->mst_seq.mst_seq_maps[i] != NULL && ret == SM_SUCCESS;
			     i++)
			{
				char *mn;

				mn = md_maps->mst_seq.mst_seq_maps[i];
				sname = sm_cstr_scpyn0((const uchar *)mn,
						strlen(mn));
				if (NULL == sname) {
					ret = sm_error_temp(SM_EM_MAP, ENOMEM);
					goto error;
				}
				ret = sm_map_setopt(map, SMPO_MAPNAME, sname, SMPO_END);
				SM_CSTR_FREE(sname);
			}
			if (sm_is_err(ret))
				break;
			ret = sm_map_open(maps, mname, mtype, 0, NULL, SMAP_MODE_RDONLY,
					&map, SMPO_END);
			break;

		  default:
			ret = sm_error_perm(SM_EM_MAP, EINVAL);
			break;
		}
		if (sm_is_err(ret))
			goto error;
		SM_CSTR_FREE(mtype);
		SM_CSTR_FREE(mname);
		ret = sm_mapname_add(maps, map);
		if (sm_is_err(ret))
			goto error;
	}
	return SM_SUCCESS;

  error:
	SM_CSTR_FREE(mtype);
	SM_CSTR_FREE(mname);
	SM_CSTR_FREE(sname);
	return ret;
}


syntax highlighted by Code2HTML, v. 0.9.1