xref: /freebsd/contrib/sendmail/libsm/cf.c (revision 595e514d0df2bac5b813d35f83e32875dbf16a83)
1 /*
2  * Copyright (c) 2001 Sendmail, 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.7 2013/03/12 15:24:50 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 
39 int
40 sm_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