xref: /illumos-gate/usr/src/lib/libslp/clib/slp_config.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * Provides accessors to configuration properties.
30  *
31  * slp_readConfig:	attempts to locate slp.conf, and reads in all
32  *				properties specified therein.
33  * slp_get_mtu:		returns the MTU
34  * slp_get_next_onlist:	parses a comma separated list of integers (in
35  *				string form), returning one at a time.
36  * slp_parse_static_das: parses the list of DAs given in the DAAddresses
37  *				property.
38  *
39  * Also see the config wrapper macros in slp-internal.h.
40  */
41 
42 #include <stdio.h>
43 #include <syslog.h>
44 #include <string.h>
45 #include <stdlib.h>
46 #include <ctype.h>
47 #include <slp-internal.h>
48 
49 /*
50  * Reads from fp and dynamically reallocates the buffer if necessary.
51  * Returns 1 on success, 0 on read completion, and -1 on failure.
52  */
53 static int super_fgets(char **buf, size_t *bufsize, FILE *fp) {
54 	char *r, *p;
55 	size_t real_bufsize, readlen = 0;
56 
57 	p = *buf;
58 	real_bufsize = *bufsize;
59 	for (;;) {
60 		r = fgets(p, (int)real_bufsize, fp);
61 		if (feof(fp) && !r)
62 			return (0);
63 		if (!r)
64 			return (-1);
65 		readlen += strlen(r);
66 		if ((*buf)[readlen - 1] == '\n')
67 			return (1);
68 
69 		/* else	buf is too small */
70 		*bufsize *= 2;
71 		if (!(*buf = realloc(*buf, *bufsize))) {
72 			slp_err(LOG_CRIT, 0, "super_fgets", "out of memory");
73 			return (-1);
74 		}
75 		p = *buf + readlen;
76 		real_bufsize = *bufsize - readlen;
77 	}
78 }
79 
80 static void skip_space(char **p) {
81 	while (*p && **p != '\n' && isspace(**p))
82 		(*p)++;
83 }
84 
85 static void null_space(char *p) {
86 	for (; *p; p++)
87 		if (isspace(*p))
88 			*p = 0;
89 }
90 
91 /*
92  * Reads into the local property store all properties defined in
93  * the config file.
94  */
95 void slp_readConfig() {
96 	char *cfile, *buf;
97 	FILE *fp;
98 	size_t buflen = 512;
99 
100 	/* check env for alternate config file */
101 	fp = NULL;
102 	if (cfile = getenv("SLP_CONF_FILE"))
103 		fp = fopen(cfile, "rF");
104 	if (!fp)
105 		if (!(fp = fopen(SLP_DEFAULT_CONFIG_FILE, "rF"))) {
106 			slp_err(LOG_INFO, 0, "readConfig",
107 				"cannot open config file");
108 			return;
109 		}
110 
111 	if (!(buf = malloc(buflen))) {
112 		slp_err(LOG_CRIT, 0, "readConfig", "out of memory");
113 		(void) fclose(fp);
114 		return;
115 	}
116 
117 	while (!feof(fp)) {
118 		char *val, *p;
119 		int err;
120 
121 		/* read a line */
122 		err = super_fgets(&buf, &buflen, fp);
123 		if (err == 0) continue;
124 		if (err == -1) {
125 			slp_err(LOG_INFO, 0, "readConfig",
126 				"error reading file: %d",
127 				ferror(fp));
128 			(void) fclose(fp);
129 			free(buf);
130 			return;
131 		}
132 
133 		/* skip comments and newlines */
134 		p = buf;
135 		skip_space(&p);
136 		if (*p == '#' || *p == ';' || *p == '\n')
137 			continue;
138 
139 		/* get property and value */
140 		if (val = strchr(p, '=')) {
141 			*val++ = 0;
142 			skip_space(&val);
143 			/* remove the trailing newline */
144 			val[strlen(val) - 1] = 0;
145 		}
146 		null_space(p);
147 
148 		SLPSetProperty(p, val ? val : "");
149 	}
150 
151 	(void) fclose(fp);
152 	free(buf);
153 }
154 
155 /*
156  * Config convenience wrappers
157  */
158 size_t slp_get_mtu() {
159 	size_t size;
160 	size = atoi(SLPGetProperty(SLP_CONFIG_MTU));
161 	size = size ? size : SLP_DEFAULT_SENDMTU;
162 
163 	return (size);
164 }
165 
166 /*
167  * On the first invocation, *state should == the value of the property
168  * to parse.
169  * If there are no more timeouts, returns -1, otherwise the timeout.
170  * If the value in the property is invalid, returns the default 2000.
171  */
172 int slp_get_next_onlist(char **state) {
173 	char *p, buf[33];
174 	size_t l;
175 	int answer;
176 
177 	if (!*state)
178 		return (-1);
179 
180 	if (**state == ',') {
181 		(*state)++;	/* skip the ',' */
182 	}
183 	p = *state;
184 	*state = slp_utf_strchr(*state, ',');
185 	if (!*state)
186 		l = strlen(p);
187 	else {
188 		l = *state - p;
189 		l = (l > 32 ? 32 : l);
190 	}
191 	(void) strncpy(buf, p, l);
192 	buf[l] = 0;
193 	answer = atoi(buf);
194 
195 	return (answer != 0 ? answer : 2000);
196 }
197 
198 int slp_get_maxResults() {
199 	int num = atoi(SLPGetProperty(SLP_CONFIG_MAXRESULTS));
200 
201 	return (num <= 0 ? -1 : num);
202 }
203