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 /*
27 * Provides accessors to configuration properties.
28 *
29 * slp_readConfig: attempts to locate slp.conf, and reads in all
30 * properties specified therein.
31 * slp_get_mtu: returns the MTU
32 * slp_get_next_onlist: parses a comma separated list of integers (in
33 * string form), returning one at a time.
34 * slp_parse_static_das: parses the list of DAs given in the DAAddresses
35 * property.
36 *
37 * Also see the config wrapper macros in slp-internal.h.
38 */
39
40 #include <stdio.h>
41 #include <syslog.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <ctype.h>
45 #include <slp-internal.h>
46
47 /*
48 * Reads from fp and dynamically reallocates the buffer if necessary.
49 * Returns 1 on success, 0 on read completion, and -1 on failure.
50 */
super_fgets(char ** buf,size_t * bufsize,FILE * fp)51 static int super_fgets(char **buf, size_t *bufsize, FILE *fp) {
52 char *r, *p;
53 size_t real_bufsize, readlen = 0;
54
55 p = *buf;
56 real_bufsize = *bufsize;
57 for (;;) {
58 r = fgets(p, (int)real_bufsize, fp);
59 if (feof(fp) && !r)
60 return (0);
61 if (!r)
62 return (-1);
63 readlen += strlen(r);
64 if ((*buf)[readlen - 1] == '\n')
65 return (1);
66
67 /* else buf is too small */
68 *bufsize *= 2;
69 if (!(*buf = realloc(*buf, *bufsize))) {
70 slp_err(LOG_CRIT, 0, "super_fgets", "out of memory");
71 return (-1);
72 }
73 p = *buf + readlen;
74 real_bufsize = *bufsize - readlen;
75 }
76 }
77
skip_space(char ** p)78 static void skip_space(char **p) {
79 while (*p && **p != '\n' && isspace(**p))
80 (*p)++;
81 }
82
null_space(char * p)83 static void null_space(char *p) {
84 for (; *p; p++)
85 if (isspace(*p))
86 *p = 0;
87 }
88
89 /*
90 * Reads into the local property store all properties defined in
91 * the config file.
92 */
slp_readConfig()93 void slp_readConfig() {
94 char *cfile, *buf;
95 FILE *fp;
96 size_t buflen = 512;
97
98 /* check env for alternate config file */
99 fp = NULL;
100 if (cfile = getenv("SLP_CONF_FILE"))
101 fp = fopen(cfile, "rF");
102 if (!fp)
103 if (!(fp = fopen(SLP_DEFAULT_CONFIG_FILE, "rF"))) {
104 slp_err(LOG_INFO, 0, "readConfig",
105 "cannot open config file");
106 return;
107 }
108
109 if (!(buf = malloc(buflen))) {
110 slp_err(LOG_CRIT, 0, "readConfig", "out of memory");
111 (void) fclose(fp);
112 return;
113 }
114
115 while (!feof(fp)) {
116 char *val, *p;
117 int err;
118
119 /* read a line */
120 err = super_fgets(&buf, &buflen, fp);
121 if (err == 0) continue;
122 if (err == -1) {
123 slp_err(LOG_INFO, 0, "readConfig",
124 "error reading file: %d",
125 ferror(fp));
126 (void) fclose(fp);
127 free(buf);
128 return;
129 }
130
131 /* skip comments and newlines */
132 p = buf;
133 skip_space(&p);
134 if (*p == '#' || *p == ';' || *p == '\n')
135 continue;
136
137 /* get property and value */
138 if (val = strchr(p, '=')) {
139 *val++ = 0;
140 skip_space(&val);
141 /* remove the trailing newline */
142 val[strlen(val) - 1] = 0;
143 }
144 null_space(p);
145
146 SLPSetProperty(p, val ? val : "");
147 }
148
149 (void) fclose(fp);
150 free(buf);
151 }
152
153 /*
154 * Config convenience wrappers
155 */
slp_get_mtu()156 size_t slp_get_mtu() {
157 size_t size;
158 size = atoi(SLPGetProperty(SLP_CONFIG_MTU));
159 size = size ? size : SLP_DEFAULT_SENDMTU;
160
161 return (size);
162 }
163
164 /*
165 * On the first invocation, *state should == the value of the property
166 * to parse.
167 * If there are no more timeouts, returns -1, otherwise the timeout.
168 * If the value in the property is invalid, returns the default 2000.
169 */
slp_get_next_onlist(char ** state)170 int slp_get_next_onlist(char **state) {
171 char *p, buf[33];
172 size_t l;
173 int answer;
174
175 if (!*state)
176 return (-1);
177
178 if (**state == ',') {
179 (*state)++; /* skip the ',' */
180 }
181 p = *state;
182 *state = slp_utf_strchr(*state, ',');
183 if (!*state)
184 l = strlen(p);
185 else {
186 l = *state - p;
187 l = (l > 32 ? 32 : l);
188 }
189 (void) strncpy(buf, p, l);
190 buf[l] = 0;
191 answer = atoi(buf);
192
193 return (answer != 0 ? answer : 2000);
194 }
195
slp_get_maxResults()196 int slp_get_maxResults() {
197 int num = atoi(SLPGetProperty(SLP_CONFIG_MAXRESULTS));
198
199 return (num <= 0 ? -1 : num);
200 }
201