190792Sgshapiro/*
2261363Sgshapiro * Copyright (c) 2001 Proofpoint, Inc. and its suppliers.
390792Sgshapiro *      All rights reserved.
490792Sgshapiro *
590792Sgshapiro * By using this file, you agree to the terms and conditions set
690792Sgshapiro * forth in the LICENSE file which can be found at the top level of
790792Sgshapiro * the sendmail distribution.
890792Sgshapiro *
990792Sgshapiro */
1090792Sgshapiro
1190792Sgshapiro#include <sm/gen.h>
12266692SgshapiroSM_RCSID("@(#)$Id: cf.c,v 1.8 2013-11-22 20:51:42 ca Exp $")
1390792Sgshapiro
1490792Sgshapiro#include <ctype.h>
1590792Sgshapiro#include <errno.h>
1690792Sgshapiro
1790792Sgshapiro#include <sm/cf.h>
1890792Sgshapiro#include <sm/io.h>
1990792Sgshapiro#include <sm/string.h>
2090792Sgshapiro#include <sm/heap.h>
2190792Sgshapiro
2290792Sgshapiro/*
2390792Sgshapiro**  SM_CF_GETOPT -- look up option values in the sendmail.cf file
2490792Sgshapiro**
2590792Sgshapiro**	Open the sendmail.cf file and parse all of the 'O' directives.
2690792Sgshapiro**	Each time one of the options named in the option vector optv
2790792Sgshapiro**	is found, store a malloced copy of the option value in optv.
2890792Sgshapiro**
2990792Sgshapiro**	Parameters:
3090792Sgshapiro**		path -- pathname of sendmail.cf file
3190792Sgshapiro**		optc -- size of option vector
3290792Sgshapiro**		optv -- pointer to option vector
3390792Sgshapiro**
3490792Sgshapiro**	Results:
3590792Sgshapiro**		0 on success, or an errno value on failure.
3690792Sgshapiro**		An exception is raised on malloc failure.
3790792Sgshapiro*/
3890792Sgshapiro
3990792Sgshapiroint
4090792Sgshapirosm_cf_getopt(path, optc, optv)
4190792Sgshapiro	char *path;
4290792Sgshapiro	int optc;
4390792Sgshapiro	SM_CF_OPT_T *optv;
4490792Sgshapiro{
4590792Sgshapiro	SM_FILE_T *cfp;
4690792Sgshapiro	char buf[2048];
4790792Sgshapiro	char *p;
4890792Sgshapiro	char *id;
4990792Sgshapiro	char *idend;
5090792Sgshapiro	char *val;
5190792Sgshapiro	int i;
5290792Sgshapiro
5390792Sgshapiro	cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, path, SM_IO_RDONLY, NULL);
5490792Sgshapiro	if (cfp == NULL)
5590792Sgshapiro		return errno;
5690792Sgshapiro
57249729Sgshapiro	while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0)
5890792Sgshapiro	{
5990792Sgshapiro		p = strchr(buf, '\n');
6090792Sgshapiro		if (p != NULL)
6190792Sgshapiro			*p = '\0';
6290792Sgshapiro
6390792Sgshapiro		if (buf[0] != 'O' || buf[1] != ' ')
6490792Sgshapiro			continue;
6590792Sgshapiro
6690792Sgshapiro		id = &buf[2];
6790792Sgshapiro		val = strchr(id, '=');
6890792Sgshapiro		if (val == NULL)
6990792Sgshapiro			val = idend = id + strlen(id);
7090792Sgshapiro		else
7190792Sgshapiro		{
7290792Sgshapiro			idend = val;
7390792Sgshapiro			++val;
7490792Sgshapiro			while (*val == ' ')
7590792Sgshapiro				++val;
7690792Sgshapiro			while (idend > id && idend[-1] == ' ')
7790792Sgshapiro				--idend;
7890792Sgshapiro			*idend = '\0';
7990792Sgshapiro		}
8090792Sgshapiro
8190792Sgshapiro		for (i = 0; i < optc; ++i)
8290792Sgshapiro		{
8390792Sgshapiro			if (sm_strcasecmp(optv[i].opt_name, id) == 0)
8490792Sgshapiro			{
8590792Sgshapiro				optv[i].opt_val = sm_strdup_x(val);
8690792Sgshapiro				break;
8790792Sgshapiro			}
8890792Sgshapiro		}
8990792Sgshapiro	}
9090792Sgshapiro	if (sm_io_error(cfp))
9190792Sgshapiro	{
9290792Sgshapiro		int save_errno = errno;
9390792Sgshapiro
9490792Sgshapiro		(void) sm_io_close(cfp, SM_TIME_DEFAULT);
9590792Sgshapiro		errno = save_errno;
9690792Sgshapiro		return errno;
9790792Sgshapiro	}
9890792Sgshapiro	(void) sm_io_close(cfp, SM_TIME_DEFAULT);
9990792Sgshapiro	return 0;
10090792Sgshapiro}
101