1/*
2 * Copyright (c) 2001 Proofpoint, Inc. and its suppliers.
3 *      All rights reserved.
4 *
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
8 *
9 */
10
11#include <sm/gen.h>
12SM_RCSID("@(#)$Id: cf.c,v 1.8 2013-11-22 20:51:42 ca Exp $")
13
14#include <ctype.h>
15#include <errno.h>
16
17#include <sm/cf.h>
18#include <sm/io.h>
19#include <sm/string.h>
20#include <sm/heap.h>
21
22/*
23**  SM_CF_GETOPT -- look up option values in the sendmail.cf file
24**
25**	Open the sendmail.cf file and parse all of the 'O' directives.
26**	Each time one of the options named in the option vector optv
27**	is found, store a malloced copy of the option value in optv.
28**
29**	Parameters:
30**		path -- pathname of sendmail.cf file
31**		optc -- size of option vector
32**		optv -- pointer to option vector
33**
34**	Results:
35**		0 on success, or an errno value on failure.
36**		An exception is raised on malloc failure.
37*/
38
39int
40sm_cf_getopt(path, optc, optv)
41	char *path;
42	int optc;
43	SM_CF_OPT_T *optv;
44{
45	SM_FILE_T *cfp;
46	char buf[2048];
47	char *p;
48	char *id;
49	char *idend;
50	char *val;
51	int i;
52
53	cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, path, SM_IO_RDONLY, NULL);
54	if (cfp == NULL)
55		return errno;
56
57	while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0)
58	{
59		p = strchr(buf, '\n');
60		if (p != NULL)
61			*p = '\0';
62
63		if (buf[0] != 'O' || buf[1] != ' ')
64			continue;
65
66		id = &buf[2];
67		val = strchr(id, '=');
68		if (val == NULL)
69			val = idend = id + strlen(id);
70		else
71		{
72			idend = val;
73			++val;
74			while (*val == ' ')
75				++val;
76			while (idend > id && idend[-1] == ' ')
77				--idend;
78			*idend = '\0';
79		}
80
81		for (i = 0; i < optc; ++i)
82		{
83			if (sm_strcasecmp(optv[i].opt_name, id) == 0)
84			{
85				optv[i].opt_val = sm_strdup_x(val);
86				break;
87			}
88		}
89	}
90	if (sm_io_error(cfp))
91	{
92		int save_errno = errno;
93
94		(void) sm_io_close(cfp, SM_TIME_DEFAULT);
95		errno = save_errno;
96		return errno;
97	}
98	(void) sm_io_close(cfp, SM_TIME_DEFAULT);
99	return 0;
100}
101