"SfR Fresh" - the SfR Freeware/Shareware Archive 
Member "bogom-1.9.2/conf.c" of archive bogom-1.9.2.tar.gz:
As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers.
Alternatively you can here view or download the uninterpreted source code file.
That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
1 /* $Id: conf.c,v 1.11 2007/10/01 20:50:41 reidrac Exp reidrac $ */
2
3 /*
4 * conf.c, configuration reader and parser
5 * Copyright (C) 2004-2007 Juan J. Martinez <jjm*at*usebox*dot*net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License Version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22 #include<stdio.h>
23 #include<stdlib.h>
24 #include<string.h>
25 #include<errno.h>
26 #include<ctype.h>
27
28 #include "libmilter/mfapi.h"
29 #include "conf.h"
30
31 #define new_string_list(x) do {\
32 x=(struct string_list *) \
33 malloc(sizeof(struct string_list));\
34 x->n=NULL;\
35 } while(0)
36
37 static char * pstrncpy(char *, const char *, size_t);
38 static int parse_string(char *p);
39 static int parse_qstring(char *p);
40 static int parse_bool(char *p);
41 static char * parse_conf(struct conftoken *conf, char *p);
42
43 static const char rcsid[]="$Id: conf.c,v 1.11 2007/10/01 20:50:41 reidrac Exp reidrac $";
44
45 /*
46 * strncpy alike function that parses scaped quotes
47 */
48 static char *
49 pstrncpy(char *d, const char *s, size_t l)
50 {
51 size_t i, j;
52
53 for(i=0, j=0; i<l && s[i]; i++, j++)
54 {
55 if(s[i]=='\\' && i+1<l)
56 if(s[i+1]=='\'' || s[i+1]=='\"')
57 i++;
58 d[j]=s[i];
59 }
60
61 d[j]=0;
62
63 return d;
64 }
65
66 /*
67 * parses a string and returns its length
68 */
69 static int
70 parse_string(char *p)
71 {
72 char *t;
73
74 for(t=p; *t && !isspace(*t); t++);
75
76 return (int)(t-p);
77 }
78
79 /*
80 * parses a quoted string and returns its length
81 * on error:
82 * -1 close quote expected
83 * 0 empty quotes
84 */
85 static int
86 parse_qstring(char *p)
87 {
88 char *t;
89 char q=*p;
90
91 for(t=++p; *t; t++)
92 {
93 if(*t==q)
94 break;
95
96 if(*t=='\\' && t[1]==q)
97 t++;
98 }
99
100 if(*t!=q)
101 return -1;
102
103 if(t==p)
104 return 0;
105
106 return (int)(t-p);
107 }
108
109 /*
110 * parses a bool and returns 0/1
111 * all values ne 0 are true
112 */
113 static int
114 parse_bool(char *p)
115 {
116 if(!p[0] || !isspace(p[1]))
117 return -1;
118
119 if(*p=='0')
120 return 0;
121 else
122 return 1;
123 }
124
125 /*
126 * parses one line each call
127 */
128 static char *
129 parse_conf(struct conftoken *conf, char *p)
130 {
131 int i, len;
132 struct string_list *t;
133
134 if(!p)
135 return NULL;
136
137 if(!p[0] || p[0]=='\n' || p[0]=='#')
138 return NULL;
139
140 while(isspace(*p))
141 p++;
142
143 len=parse_string(p);
144 if(!len)
145 return NULL;
146
147 for(i=0; conf[i].word; i++)
148 if(!strncmp(conf[i].word, p, strlen(conf[i].word)))
149 {
150 p+=len;
151 while(isspace(*p))
152 p++;
153
154 switch(conf[i].required)
155 {
156 case REQ_NONE:
157 /* nothing required */
158 break;
159
160 case REQ_BOOL:
161 len=parse_bool(p);
162 if(len<0)
163 {
164 fprintf(stderr,
165 "bool expected\n");
166 return p;
167 }
168
169 conf[i].bool=len;
170 p++;
171 break;
172
173 case REQ_STRING:
174 len=parse_string(p);
175 if(!len)
176 {
177 fprintf(stderr,
178 "string expected\n");
179 return p;
180 }
181
182 if(conf[i].str)
183 free(conf[i].str);
184 conf[i].str=(char *)malloc(len+1);
185 if(!conf[i].str)
186 {
187 fprintf(stderr, "malloc\n");
188 return p;
189 }
190 strncpy(conf[i].str, p, len);
191 p+=len;
192 break;
193
194 case REQ_QSTRING:
195 if(*p!='\"' && *p!='\'')
196 {
197 fprintf(stderr,
198 "quoted string"
199 " expected\n");
200 return p;
201 }
202
203 len=parse_qstring(p);
204 p++;
205
206 if(len==-1)
207 {
208 fprintf(stderr,
209 "end quote expected\n");
210 return p;
211 }
212
213 if(!len)
214 {
215 fprintf(stderr,
216 "empty quotes\n");
217 return p;
218 }
219
220 if(conf[i].str)
221 free(conf[i].str);
222 conf[i].str=(char *)malloc(len+1);
223 if(!conf[i].str)
224 {
225 fprintf(stderr, "malloc\n");
226 return p;
227 }
228 pstrncpy(conf[i].str, p, len);
229 p+=len+1;
230 break;
231
232 case REQ_LSTQSTRING:
233 if(*p!='\"' && *p!='\'')
234 {
235 fprintf(stderr,
236 "quoted string"
237 " expected\n");
238 return p;
239 }
240
241 len=parse_qstring(p);
242 p++;
243
244 if(len==-1)
245 {
246 fprintf(stderr,
247 "end quote expected\n");
248 return p;
249 }
250
251 if(!len)
252 {
253 fprintf(stderr,
254 "empty quotes\n");
255 return p;
256 }
257
258 if(!conf[i].sl)
259 {
260 new_string_list(conf[i].sl);
261 if(!conf[i].sl)
262 {
263 fprintf(stderr,
264 "malloc");
265 return p;
266 }
267 }
268 else
269 {
270 new_string_list(t);
271 if(!t)
272 {
273 fprintf(stderr,
274 "malloc");
275 return p;
276 }
277 t->n=conf[i].sl;
278 conf[i].sl=t;
279 }
280
281 conf[i].sl->s=(char *)malloc(len+1);
282 if(!conf[i].sl->s)
283 {
284 fprintf(stderr, "malloc\n");
285 return p;
286 }
287 pstrncpy(conf[i].sl->s, p, len);
288 p+=len+1;
289 break;
290 }
291 break;
292 }
293
294 if(conf[i].word)
295 {
296 while(isspace(*p))
297 p++;
298
299 if(!p[0])
300 return NULL;
301
302 fprintf(stderr, "parse error\n");
303 return p;
304 }
305
306 fprintf(stderr, "unknown token\n");
307
308 p[len]=0;
309 return p;
310 }
311
312 /*
313 * reads and parses the configuration file
314 */
315 int
316 read_conf(const char *filename, struct conftoken *conf)
317 {
318 FILE *fd;
319 char buffer[1024];
320 char *ret;
321 int line, i;
322
323 fd=fopen(filename, "r");
324 if(!fd)
325 return 0;
326
327 line=1;
328 while(!feof(fd))
329 {
330 i=0;
331 *buffer=0;
332 do
333 {
334 if(i>1023)
335 {
336 fclose(fd);
337 fprintf(stderr, "conf line %i is too long\n",
338 line);
339 return 1;
340 }
341
342 fscanf(fd, "%c", &buffer[i]);
343
344 } while(buffer[i++]!='\n' && !feof(fd));
345
346 buffer[i]=0;
347
348 ret=parse_conf(conf, buffer);
349 if(ret)
350 {
351 fclose(fd);
352 fprintf(stderr, "conf error at line %i, near: %s\n",
353 line, ret);
354 return 1;
355 }
356
357 line++;
358 }
359
360 fclose(fd);
361
362 return 0;
363 }
364
365 /* EOF */