/*
 * 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: genconfpath.c,v 1.5 2007/06/18 04:42:31 ca Exp $")

#include "sm/error.h"
#include "sm/assert.h"
#include "sm/string.h"
#include "sm/cstr.h"
#include "sm/confsetpath.h"

/*
**  SM_GEN_CONF_PATH -- generate absolute path for filename
**  If no filename is provided in the configuration (cnfname)
**  then use the default (dflt) but prepend the directory in which the
**  configuration file was found (basedir).
**  The resulting pathname is assigned to abspath.
**  This means a configuration struct needs 3 fields for one element:
**  1. cnfname itself (the specification in the configuration file)
**  2. cnfname_abspath: the data to actually use
**  3. cnfname_absalloc: allocated data (see below: pabsallocated)
**  in many cases cnfname_abspath is stored elsewhere.
**
**	Parameters:
**		basedir -- base directory to use
**		cnfname -- pathname set in configuration file
**		dflt -- default value
**		pabspath -- path to use (output)
**		pabsallocated -- assign allocated storage to this (output).
**			This can be used to clean up, i.e., if it is not NULL
**			then free()ing it releases the allocated storage.
**			If this doesn't matter (because the path is only allocated
**			at startup and hence implicitly free()d at shutdown), then
**			this variable can be NULL.
**
**	Returns:
**		usual return code
*/

sm_ret_T
sm_gen_conf_path(const char *basedir, const char *cnfname, const char *dflt, const char **pabspath, char **pabsallocated)
{
	char *cnfabspath;

	SM_REQUIRE(pabspath != NULL);
	if (pabsallocated != NULL)
		*pabsallocated = NULL;
	if (cnfname == NULL && dflt == NULL)
		*pabspath = NULL;
	else if (cnfname == NULL || *cnfname != '/')
	{
		const char *cnf;

		cnf = (cnfname == NULL) ? dflt : cnfname;
		SM_ASSERT(cnf != NULL);
		if (basedir != NULL && *basedir != '\0') {
			size_t mpl, sl;

			mpl = strlen(basedir) + strlen(cnf) + 1;
			SM_ASSERT(mpl > strlen(basedir));
			SM_ASSERT(mpl > strlen(cnf));
			cnfabspath = (char *) sm_malloc(mpl);
			if (cnfabspath == NULL)
				return sm_err_temp(ENOMEM);
			sl = strlcpy(cnfabspath, basedir, mpl);
			SM_ASSERT(sl < mpl);
			sl = strlcat(cnfabspath, cnf, mpl);
			SM_ASSERT(sl < mpl);
			*pabspath = cnfabspath;
			if (pabsallocated != NULL)
				*pabsallocated = cnfabspath;
		}
		else
			*pabspath = cnf;
	}
	else
		*pabspath = cnfname;
	return SM_SUCCESS;
}


syntax highlighted by Code2HTML, v. 0.9.1