"Fossies" - the Fresh Open Source Software Archive 
Member "fusesmb-0.8.7/configfile.c" (4 May 2006, 12338 Bytes) of package /linux/privat/old/fusesmb-0.8.7.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "configfile.c" see the
Fossies "Dox" file reference documentation.
1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2006 Vincent Wagelaar
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 #include <stdio.h>
27 #include <string.h>
28 #include <sys/param.h>
29 #include "stringlist.h"
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <unistd.h>
33 #include <ctype.h>
34 #include "configfile.h"
35
36
37 static char *strip_whitespace_check_comment(const char *str)
38 {
39 char *start = (char *)str;
40 char *end = start + strlen(str) -1;
41 while (*start == '\t' || *start == ' ')
42 start++;
43 while (isspace(*end))
44 {
45 *end = '\0';
46 end--;
47 }
48 if (*start == '#' || *start == ';' || *start == '\0')
49 return NULL;
50 return start;
51 }
52
53 static char *strip_whitespace(const char *str)
54 {
55 char *start = (char *)str;
56 char *end = start + strlen(str) -1;
57 while (*start == '\t' || *start == ' ')
58 start++;
59 while (isspace(*end))
60 {
61 *end = '\0';
62 end--;
63 }
64 if (*start == '\0')
65 return NULL;
66 return start;
67 }
68
69 static int config_read_file(config_t *cf)
70 {
71 char buf[4096];
72 FILE *fp = fopen(cf->file, "r");
73 if (NULL == fp)
74 return -1;
75 sl_clear(cf->lines);
76 while (!feof(fp))
77 {
78 if (NULL == fgets(buf, sizeof(buf), fp))
79 continue;
80 char *stripped_string = strip_whitespace_check_comment(buf);
81 if (stripped_string == NULL)
82 continue;
83 /* Section */
84 if (*stripped_string == '[')
85 {
86 stripped_string++;
87 while (*stripped_string == '\t' || *stripped_string == ' ')
88 {
89 stripped_string++;
90 }
91 char *end = stripped_string + strlen(stripped_string) -1;
92 while (*end == '\t' || *end == ' ' || *end == ']')
93 {
94 *end = '\0';
95 end--;
96 }
97 char section_string[4096];
98 snprintf(section_string, sizeof(section_string), "[%s]", stripped_string);
99 if (-1 == sl_add(cf->lines, section_string, 1))
100 continue;
101 } /* Key */
102 else
103 {
104
105 char value_string[4096];
106 char *isequal = index(stripped_string, '=');
107 if (isequal == NULL)
108 continue;
109 *isequal = '\0';
110 isequal++;
111 char *key = strip_whitespace(stripped_string);
112 char *value = strip_whitespace(isequal);
113 if (NULL == key || NULL == value)
114 continue;
115 snprintf(value_string, sizeof(value_string), "%s=%s", key, value);
116 if (-1 == sl_add(cf->lines, value_string, 1))
117 continue;
118 }
119 }
120 fclose(fp);
121 return 0;
122 }
123
124
125 /**
126 * Init configuration interface
127 * @return -1 on failure, 0 on success
128 */
129 int config_init(config_t *cf, const char *file)
130 {
131 struct stat st;
132 if (-1 == stat(file, &st))
133 return -1;
134 cf->mtime = st.st_mtime;
135 cf->lines = sl_init();
136 if (cf->lines == NULL)
137 return -1;
138 strncpy(cf->file, file, MAXPATHLEN);
139 config_read_file(cf);
140 return 0;
141 }
142
143 /**
144 * @param config_t *, pointer to config_t
145 * @return -1 if not needed/failure, 0 file has changed
146 */
147
148 int config_reload_ifneeded(config_t *cf)
149 {
150 struct stat st;
151 if (-1 == stat(cf->file, &st))
152 return -1;
153 if (cf->mtime == st.st_mtime)
154 return -1;
155 cf->mtime = st.st_mtime;
156 return config_read_file(cf);
157 }
158 /**
159 * @return -1 on failure, 0 on success
160 */
161 int config_has_section(config_t *cf, const char *section)
162 {
163 char buf[strlen(section)+3];
164 strcpy(buf, "[");
165 strcat(buf, section);
166 strcat(buf, "]");
167 if (NULL != sl_find(cf->lines, buf))
168 {
169 return 0;
170 }
171 return -1;
172 }
173
174 /**
175 * @return -1 on failure, 0 on success with value now with a malloced string
176 */
177 int config_read_string(config_t *cf, const char *section, const char *key, char **value)
178 {
179 size_t i;
180 char cmp_section[strlen(section)+3];
181 char cmp_key[strlen(key)+2];
182 strcpy(cmp_section, "[");
183 strcat(cmp_section, section);
184 strcat(cmp_section, "]");
185 strcpy(cmp_key, key);
186 strcat(cmp_key, "=");
187 char section_found = 0;
188 for (i=0; i<sl_count(cf->lines); i++)
189 {
190 if (0 == strncasecmp(sl_item(cf->lines, i), cmp_section, sizeof(cmp_section))
191 && section_found == 0)
192 {
193 section_found = 1;
194 i++;
195 }
196 /* Check if we're not over the last line */
197 if (section_found == 1 && i < sl_count(cf->lines))
198 {
199 if (0 == strncasecmp(sl_item(cf->lines, i), "[", 1))
200 {
201 return -1;
202 }
203 if (0 == strncasecmp(sl_item(cf->lines, i), cmp_key, strlen(cmp_key)))
204 {
205 char *retval = index(sl_item(cf->lines, i), '=');
206 if (retval == NULL)
207 return -1;
208 retval++;
209 if (strlen(retval))
210 {
211 *value = strdup(retval);
212 return 0;
213 }
214 return -1;
215 }
216 }
217 }
218 return -1;
219 }
220
221 /**
222 * @return -1 on failure, 0 on success
223 */
224 int config_read_int(config_t *cf, const char *section, const char *key, int *value)
225 {
226 char *str;
227 if (0 == config_read_string(cf, section, key, &str))
228 {
229 char *p;
230 int ret = strtol(str, &p, 10);
231 if (*p != '\0')
232 return -1;
233 *value = ret;
234 free(str);
235 return 0;
236 }
237 return -1;
238 }
239
240 /**
241 * @return -1 on failure, 0 on success
242 */
243 int config_read_bool(config_t *cf, const char *section, const char *key, int *value)
244 {
245 char *str;
246 if (0 == config_read_string(cf, section, key, &str))
247 {
248 if (strcasecmp("true", str) == 0 || strcmp("1", str) == 0)
249 {
250 *value = 1;
251 free(str);
252 return 0;
253 }
254 if (strcasecmp("false", str) == 0 || strcmp("0", str) == 0)
255 {
256 *value = 0;
257 free(str);
258 return 0;
259 }
260 free(str);
261 }
262 return -1;
263 }
264
265 int config_read_stringlist(config_t *cf, const char *section, const char *key, stringlist_t **value, char sep)
266 {
267 char *str;
268 if (0 == config_read_string(cf, section, key, &str))
269 {
270 *value = sl_init();
271 char *next, *start;
272 start = str;
273 while (NULL != (next = index(start, sep)))
274 {
275 *next = '\0';
276 next++;
277 /* Remove extra separators */
278 while (*next == sep)
279 {
280 *next = '\0';
281 next++;
282 }
283 char *stripped;
284 if (NULL != (stripped = strip_whitespace(start)))
285 sl_add(*value, stripped, 1);
286
287 start = next;
288 }
289 if (strlen(start))
290 {
291 char *stripped = strip_whitespace(start);
292 sl_add(*value, stripped, 1);
293 }
294 free(str);
295 return 0;
296 }
297 return -1;
298 }
299 int config_read_section_keys(config_t *cf, const char *section, stringlist_t **value)
300 {
301 size_t i;
302 char cmp_section[strlen(section)+3];
303 strcpy(cmp_section, "[");
304 strcat(cmp_section, section);
305 strcat(cmp_section, "]");
306 char section_found = 0;
307 *value = sl_init();
308 if (NULL == *value)
309 return -1;
310
311 for (i=0; i<sl_count(cf->lines); i++)
312 {
313 if (0 == strncasecmp(sl_item(cf->lines, i), cmp_section, sizeof(cmp_section))
314 && section_found == 0)
315 {
316 section_found = 1;
317 i++;
318 }
319 if (section_found == 1)
320 {
321 if (0 == strncasecmp(sl_item(cf->lines, i), "[", 1))
322 {
323 break;
324 }
325 char buf[4096];
326 strncpy(buf, sl_item(cf->lines, i), 4096);
327 char *sep = index(buf, '=');
328 if (sep == NULL)
329 continue;
330 *sep = '\0';
331 if (strlen(buf))
332 {
333 if (-1 == sl_add(*value, buf, 1))
334 continue;
335 }
336 }
337 }
338 if (sl_count(*value) > 0)
339 return 0;
340
341 /* No keys found for this sections so freeing up the stringlist */
342 sl_free(*value);
343 *value = NULL;
344 return -1;
345 }
346
347 void config_free(config_t *cf)
348 {
349 sl_free(cf->lines);
350 }
351
352 #ifdef RUN_TEST
353
354 static void config_show_parsed(config_t *cf)
355 {
356 size_t i;
357 for (i=0; i<sl_count(cf->lines); i++)
358 {
359 printf("%s\n", sl_item(cf->lines, i));
360 }
361 }
362
363
364 int keeprunning =1;
365
366 #include <signal.h>
367 #include <errno.h>
368 void int_handler(int sig)
369 {
370 signal(sig, SIG_IGN);
371 printf("CTRL_C pressed\n");
372 keeprunning =0;
373 }
374
375 int main(void)
376 {
377 signal(SIGINT, int_handler);
378 config_t c;
379 if (-1 == config_init(&c, "fusesmb.conf.test"))
380 {
381 perror("config_init");
382 //fprintf(stderr, "Could not open fusesmb.conf [%s]\n", strerror(errno));
383 exit(EXIT_FAILURE);
384 }
385 config_show_parsed(&c);
386 while(keeprunning){
387 char *user, *pass;
388 stringlist_t *workgroups, *servers;
389
390 int timeout, showhiddenshares;
391 if (0 == config_read_string(&c, "global", "username", &user))
392 {
393 printf("Found username: %s\n", user);
394 free(user);
395 }
396 else
397 printf("Could not find username\n");
398
399 if (0 == config_read_string(&c, "global", "password", &pass))
400 {
401 printf("Found password: %s\n", pass);
402 free(pass);
403 }
404 else
405 printf("Could not find password\n");
406 if (0 == config_reload_ifneeded(&c))
407 printf("Configuration has changed\n");
408 if (0 == config_read_int(&c, "global", "timeout", &timeout))
409 printf("Found timeout: %i\n", timeout);
410 else
411 printf("Could not find timeout\n");
412 if (0 == config_read_bool(&c, "global", "showhiddenshares", &showhiddenshares))
413 printf("Found showhiddenshares: %i\n", showhiddenshares);
414 else
415 printf("Could not find showhiddenshares\n");
416
417 if (0 == config_read_stringlist(&c, "ignore", "workgroups", &workgroups, ','))
418 {
419 size_t i;
420 printf("Found workgroups:\n");
421 for (i=0; i<sl_count(workgroups); i++)
422 printf(" %s\n", sl_item(workgroups, i));
423 sl_free(workgroups);
424 }
425 else
426 {
427 printf("Could not find ignore workgroups\n");
428 }
429 if (0 == config_read_stringlist(&c, "ignore", "servers", &servers, ','))
430 {
431 size_t i;
432 printf("Found servers:\n");
433 sl_casesort(servers);
434 for (i=0; i<sl_count(servers); i++)
435 printf(" %s\n", sl_item(servers, i));
436 char *find;
437 if (NULL != (find = sl_casefind(servers, "TARdis")))
438 printf("Found TARdis: %s\n", find);
439 if (NULL != (find = sl_casefind(servers, "BANANA")))
440 printf("Found TARdis: %s\n", find);
441
442 sl_free(servers);
443 }
444 else
445 {
446 printf("Could not find ignore servers\n");
447 }
448 stringlist_t *global_keys;
449 if (0 == config_read_section_keys(&c, "global", &global_keys))
450 {
451 size_t i;
452 for (i=0; i<sl_count(global_keys); i++)
453 printf("key: %s\n", sl_item(global_keys, i));
454 sl_free(global_keys);
455 }
456 sleep(10);
457 }
458 printf("Cleaning up\n");
459 config_show_parsed(&c);
460 config_free(&c);
461 exit(EXIT_SUCCESS);
462 }
463 #endif