xref: /freebsd/contrib/sendmail/libsm/cf.c (revision 5d3e7166)
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>
12 SM_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 #include <sm/sendmail.h>
22 
23 /*
24 **  SM_CF_GETOPT -- look up option values in the sendmail.cf file
25 **
26 **	Open the sendmail.cf file and parse all of the 'O' directives.
27 **	Each time one of the options named in the option vector optv
28 **	is found, store a malloced copy of the option value in optv.
29 **
30 **	Parameters:
31 **		path -- pathname of sendmail.cf file
32 **		optc -- size of option vector
33 **		optv -- pointer to option vector
34 **
35 **	Results:
36 **		0 on success, or an errno value on failure.
37 **		An exception is raised on malloc failure.
38 */
39 
40 int
41 sm_cf_getopt(path, optc, optv)
42 	char *path;
43 	int optc;
44 	SM_CF_OPT_T *optv;
45 {
46 	SM_FILE_T *cfp;
47 	char buf[2048];
48 	char *p;
49 	char *id;
50 	char *idend;
51 	char *val;
52 	int i;
53 
54 	cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, path, SM_IO_RDONLY, NULL);
55 	if (cfp == NULL)
56 		return errno;
57 
58 	while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0)
59 	{
60 		p = strchr(buf, '\n');
61 		if (p != NULL)
62 			*p = '\0';
63 
64 		if (buf[0] != 'O' || buf[1] != ' ')
65 			continue;
66 
67 		id = &buf[2];
68 		val = strchr(id, '=');
69 		if (val == NULL)
70 			val = idend = id + strlen(id);
71 		else
72 		{
73 			idend = val;
74 			++val;
75 			while (*val == ' ')
76 				++val;
77 			while (idend > id && idend[-1] == ' ')
78 				--idend;
79 			*idend = '\0';
80 		}
81 
82 		for (i = 0; i < optc; ++i)
83 		{
84 			if (SM_STRCASEEQ(optv[i].opt_name, id))
85 			{
86 				optv[i].opt_val = sm_strdup_x(val);
87 				break;
88 			}
89 		}
90 	}
91 	if (sm_io_error(cfp))
92 	{
93 		int save_errno = errno;
94 
95 		(void) sm_io_close(cfp, SM_TIME_DEFAULT);
96 		errno = save_errno;
97 		return errno;
98 	}
99 	(void) sm_io_close(cfp, SM_TIME_DEFAULT);
100 	return 0;
101 }
102