aboutsummaryrefslogtreecommitdiff
path: root/src/util/configuration.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/configuration.c')
-rw-r--r--src/util/configuration.c769
1 files changed, 391 insertions, 378 deletions
diff --git a/src/util/configuration.c b/src/util/configuration.c
index c69042175..adfd4ea5a 100644
--- a/src/util/configuration.c
+++ b/src/util/configuration.c
@@ -33,6 +33,9 @@
33#include "gnunet_os_lib.h" 33#include "gnunet_os_lib.h"
34#include "gnunet_strings_lib.h" 34#include "gnunet_strings_lib.h"
35 35
36#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
37
38#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
36 39
37/** 40/**
38 * @brief configuration entry 41 * @brief configuration entry
@@ -149,7 +152,7 @@ GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg)
149 */ 152 */
150int 153int
151GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg, 154GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg,
152 const char *filename) 155 const char *filename)
153{ 156{
154 int dirty; 157 int dirty;
155 char line[256]; 158 char line[256];
@@ -166,87 +169,89 @@ GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg,
166 fn = GNUNET_STRINGS_filename_expand (filename); 169 fn = GNUNET_STRINGS_filename_expand (filename);
167 if (fn == NULL) 170 if (fn == NULL)
168 return GNUNET_SYSERR; 171 return GNUNET_SYSERR;
169 dirty = cfg->dirty; /* back up value! */ 172 dirty = cfg->dirty; /* back up value! */
170 if (NULL == (fp = FOPEN (fn, "r"))) 173 if (NULL == (fp = FOPEN (fn, "r")))
171 { 174 {
172 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fopen", fn); 175 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fopen", fn);
173 GNUNET_free (fn); 176 GNUNET_free (fn);
174 return GNUNET_SYSERR; 177 return GNUNET_SYSERR;
175 } 178 }
176 GNUNET_free (fn); 179 GNUNET_free (fn);
177 ret = GNUNET_OK; 180 ret = GNUNET_OK;
178 section = GNUNET_strdup (""); 181 section = GNUNET_strdup ("");
179 memset (line, 0, 256); 182 memset (line, 0, 256);
180 nr = 0; 183 nr = 0;
181 while (NULL != fgets (line, 255, fp)) 184 while (NULL != fgets (line, 255, fp))
182 {
183 nr++;
184 for (i = 0; i < 255; i++)
185 if (line[i] == '\t')
186 line[i] = ' ';
187 if (line[0] == '\n' || line[0] == '#' || line[0] == '%' || line[0] == '\r')
188 continue;
189 emptyline = 1;
190 for (i = 0; (i < 255 && line[i] != 0); i++)
191 if (line[i] != ' ' && line[i] != '\n' && line[i] != '\r')
192 emptyline = 0;
193 if (emptyline == 1)
194 continue;
195 /* remove tailing whitespace */
196 for (i = strlen (line) - 1; (i >= 0) && (isspace ((unsigned char) line[i]));
197 i--)
198 line[i] = '\0';
199 if (1 == sscanf (line, "@INLINE@ %191[^\n]", value))
200 {
201 /* @INLINE@ value */
202 if (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, value))
203 ret = GNUNET_SYSERR; /* failed to parse included config */
204 }
205 else if (1 == sscanf (line, "[%99[^]]]", value))
206 {
207 /* [value] */
208 GNUNET_free (section);
209 section = GNUNET_strdup (value);
210 }
211 else if (2 == sscanf (line, " %63[^= ] = %191[^\n]", tag, value))
212 {
213 /* tag = value */
214 /* Strip LF */
215 i = strlen (value) - 1;
216 while ((i >= 0) && (isspace ((unsigned char) value[i])))
217 value[i--] = '\0';
218 /* remove quotes */
219 i = 0;
220 if (value[0] == '"')
221 {
222 i = 1;
223 while ((value[i] != '\0') && (value[i] != '"'))
224 i++;
225 if (value[i] == '"')
226 {
227 value[i] = '\0';
228 i = 1;
229 }
230 else
231 i = 0;
232 }
233 GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, &value[i]);
234 }
235 else if (1 == sscanf (line, " %63[^= ] =[^\n]", tag))
236 {
237 /* tag = */
238 GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, "");
239 }
240 else
241 { 185 {
242 /* parse error */ 186 nr++;
243 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 187 for (i = 0; i < 255; i++)
244 _("Syntax error in configuration file `%s' at line %u.\n"), 188 if (line[i] == '\t')
245 filename, nr); 189 line[i] = ' ';
246 ret = GNUNET_SYSERR; 190 if (line[0] == '\n' || line[0] == '#' || line[0] == '%'
247 break; 191 || line[0] == '\r')
192 continue;
193 emptyline = 1;
194 for (i = 0; (i < 255 && line[i] != 0); i++)
195 if (line[i] != ' ' && line[i] != '\n' && line[i] != '\r')
196 emptyline = 0;
197 if (emptyline == 1)
198 continue;
199 /* remove tailing whitespace */
200 for (i = strlen (line) - 1;
201 (i >= 0) && (isspace ((unsigned char) line[i])); i--)
202 line[i] = '\0';
203 if (1 == sscanf (line, "@INLINE@ %191[^\n]", value))
204 {
205 /* @INLINE@ value */
206 if (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, value))
207 ret = GNUNET_SYSERR; /* failed to parse included config */
208 }
209 else if (1 == sscanf (line, "[%99[^]]]", value))
210 {
211 /* [value] */
212 GNUNET_free (section);
213 section = GNUNET_strdup (value);
214 }
215 else if (2 == sscanf (line, " %63[^= ] = %191[^\n]", tag, value))
216 {
217 /* tag = value */
218 /* Strip LF */
219 i = strlen (value) - 1;
220 while ((i >= 0) && (isspace ((unsigned char) value[i])))
221 value[i--] = '\0';
222 /* remove quotes */
223 i = 0;
224 if (value[0] == '"')
225 {
226 i = 1;
227 while ((value[i] != '\0') && (value[i] != '"'))
228 i++;
229 if (value[i] == '"')
230 {
231 value[i] = '\0';
232 i = 1;
233 }
234 else
235 i = 0;
236 }
237 GNUNET_CONFIGURATION_set_value_string (cfg, section, tag,
238 &value[i]);
239 }
240 else if (1 == sscanf (line, " %63[^= ] =[^\n]", tag))
241 {
242 /* tag = */
243 GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, "");
244 }
245 else
246 {
247 /* parse error */
248 LOG (GNUNET_ERROR_TYPE_WARNING,
249 _("Syntax error in configuration file `%s' at line %u.\n"),
250 filename, nr);
251 ret = GNUNET_SYSERR;
252 break;
253 }
248 } 254 }
249 }
250 GNUNET_assert (0 == fclose (fp)); 255 GNUNET_assert (0 == fclose (fp));
251 /* restore dirty flag - anything we set in the meantime 256 /* restore dirty flag - anything we set in the meantime
252 * came from disk */ 257 * came from disk */
@@ -279,7 +284,7 @@ GNUNET_CONFIGURATION_is_dirty (const struct GNUNET_CONFIGURATION_Handle *cfg)
279 */ 284 */
280int 285int
281GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg, 286GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg,
282 const char *filename) 287 const char *filename)
283{ 288{
284 struct ConfigSection *sec; 289 struct ConfigSection *sec;
285 struct ConfigEntry *ent; 290 struct ConfigEntry *ent;
@@ -293,67 +298,67 @@ GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg,
293 if (fn == NULL) 298 if (fn == NULL)
294 return GNUNET_SYSERR; 299 return GNUNET_SYSERR;
295 if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn)) 300 if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn))
296 { 301 {
297 GNUNET_free (fn); 302 GNUNET_free (fn);
298 return GNUNET_SYSERR; 303 return GNUNET_SYSERR;
299 } 304 }
300 if (NULL == (fp = FOPEN (fn, "w"))) 305 if (NULL == (fp = FOPEN (fn, "w")))
301 { 306 {
302 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fopen", fn); 307 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fopen", fn);
303 GNUNET_free (fn); 308 GNUNET_free (fn);
304 return GNUNET_SYSERR; 309 return GNUNET_SYSERR;
305 } 310 }
306 GNUNET_free (fn); 311 GNUNET_free (fn);
307 error = 0; 312 error = 0;
308 sec = cfg->sections; 313 sec = cfg->sections;
309 while (sec != NULL) 314 while (sec != NULL)
310 {
311 if (0 > fprintf (fp, "[%s]\n", sec->name))
312 {
313 error = 1;
314 break;
315 }
316 ent = sec->entries;
317 while (ent != NULL)
318 {
319 if (ent->val != NULL)
320 {
321 val = GNUNET_malloc (strlen (ent->val) * 2 + 1);
322 strcpy (val, ent->val);
323 while (NULL != (pos = strstr (val, "\n")))
324 {
325 memmove (&pos[2], &pos[1], strlen (&pos[1]));
326 pos[0] = '\\';
327 pos[1] = 'n';
328 }
329 if (0 > fprintf (fp, "%s = %s\n", ent->key, val))
330 {
331 error = 1;
332 GNUNET_free (val);
333 break;
334 }
335 GNUNET_free (val);
336 }
337 ent = ent->next;
338 }
339 if (error != 0)
340 break;
341 if (0 > fprintf (fp, "\n"))
342 { 315 {
343 error = 1; 316 if (0 > fprintf (fp, "[%s]\n", sec->name))
344 break; 317 {
318 error = 1;
319 break;
320 }
321 ent = sec->entries;
322 while (ent != NULL)
323 {
324 if (ent->val != NULL)
325 {
326 val = GNUNET_malloc (strlen (ent->val) * 2 + 1);
327 strcpy (val, ent->val);
328 while (NULL != (pos = strstr (val, "\n")))
329 {
330 memmove (&pos[2], &pos[1], strlen (&pos[1]));
331 pos[0] = '\\';
332 pos[1] = 'n';
333 }
334 if (0 > fprintf (fp, "%s = %s\n", ent->key, val))
335 {
336 error = 1;
337 GNUNET_free (val);
338 break;
339 }
340 GNUNET_free (val);
341 }
342 ent = ent->next;
343 }
344 if (error != 0)
345 break;
346 if (0 > fprintf (fp, "\n"))
347 {
348 error = 1;
349 break;
350 }
351 sec = sec->next;
345 } 352 }
346 sec = sec->next;
347 }
348 if (error != 0) 353 if (error != 0)
349 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fprintf", filename); 354 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fprintf", filename);
350 GNUNET_assert (0 == fclose (fp)); 355 GNUNET_assert (0 == fclose (fp));
351 if (error != 0) 356 if (error != 0)
352 { 357 {
353 cfg->dirty = GNUNET_SYSERR; /* last write failed */ 358 cfg->dirty = GNUNET_SYSERR; /* last write failed */
354 return GNUNET_SYSERR; 359 return GNUNET_SYSERR;
355 } 360 }
356 cfg->dirty = GNUNET_NO; /* last write succeeded */ 361 cfg->dirty = GNUNET_NO; /* last write succeeded */
357 return GNUNET_OK; 362 return GNUNET_OK;
358} 363}
359 364
@@ -367,23 +372,23 @@ GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg,
367 */ 372 */
368void 373void
369GNUNET_CONFIGURATION_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg, 374GNUNET_CONFIGURATION_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg,
370 GNUNET_CONFIGURATION_Iterator iter, 375 GNUNET_CONFIGURATION_Iterator iter,
371 void *iter_cls) 376 void *iter_cls)
372{ 377{
373 struct ConfigSection *spos; 378 struct ConfigSection *spos;
374 struct ConfigEntry *epos; 379 struct ConfigEntry *epos;
375 380
376 spos = cfg->sections; 381 spos = cfg->sections;
377 while (spos != NULL) 382 while (spos != NULL)
378 {
379 epos = spos->entries;
380 while (epos != NULL)
381 { 383 {
382 iter (iter_cls, spos->name, epos->key, epos->val); 384 epos = spos->entries;
383 epos = epos->next; 385 while (epos != NULL)
386 {
387 iter (iter_cls, spos->name, epos->key, epos->val);
388 epos = epos->next;
389 }
390 spos = spos->next;
384 } 391 }
385 spos = spos->next;
386 }
387} 392}
388 393
389 394
@@ -397,10 +402,10 @@ GNUNET_CONFIGURATION_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg,
397 */ 402 */
398void 403void
399GNUNET_CONFIGURATION_iterate_section_values (const struct 404GNUNET_CONFIGURATION_iterate_section_values (const struct
400 GNUNET_CONFIGURATION_Handle *cfg, 405 GNUNET_CONFIGURATION_Handle *cfg,
401 const char *section, 406 const char *section,
402 GNUNET_CONFIGURATION_Iterator iter, 407 GNUNET_CONFIGURATION_Iterator
403 void *iter_cls) 408 iter, void *iter_cls)
404{ 409{
405 struct ConfigSection *spos; 410 struct ConfigSection *spos;
406 struct ConfigEntry *epos; 411 struct ConfigEntry *epos;
@@ -414,10 +419,10 @@ GNUNET_CONFIGURATION_iterate_section_values (const struct
414 419
415 epos = spos->entries; 420 epos = spos->entries;
416 while (epos != NULL) 421 while (epos != NULL)
417 { 422 {
418 iter (iter_cls, spos->name, epos->key, epos->val); 423 iter (iter_cls, spos->name, epos->key, epos->val);
419 epos = epos->next; 424 epos = epos->next;
420 } 425 }
421} 426}
422 427
423 428
@@ -429,21 +434,21 @@ GNUNET_CONFIGURATION_iterate_section_values (const struct
429 * @param iter_cls closure for iter 434 * @param iter_cls closure for iter
430 */ 435 */
431void 436void
432GNUNET_CONFIGURATION_iterate_sections (const struct GNUNET_CONFIGURATION_Handle 437GNUNET_CONFIGURATION_iterate_sections (const struct
433 *cfg, 438 GNUNET_CONFIGURATION_Handle *cfg,
434 GNUNET_CONFIGURATION_Section_Iterator 439 GNUNET_CONFIGURATION_Section_Iterator
435 iter, void *iter_cls) 440 iter, void *iter_cls)
436{ 441{
437 struct ConfigSection *spos; 442 struct ConfigSection *spos;
438 struct ConfigSection *next; 443 struct ConfigSection *next;
439 444
440 next = cfg->sections; 445 next = cfg->sections;
441 while (next != NULL) 446 while (next != NULL)
442 { 447 {
443 spos = next; 448 spos = next;
444 next = spos->next; 449 next = spos->next;
445 iter (iter_cls, spos->name); 450 iter (iter_cls, spos->name);
446 } 451 }
447} 452}
448 453
449/** 454/**
@@ -454,7 +459,7 @@ GNUNET_CONFIGURATION_iterate_sections (const struct GNUNET_CONFIGURATION_Handle
454 */ 459 */
455void 460void
456GNUNET_CONFIGURATION_remove_section (struct GNUNET_CONFIGURATION_Handle *cfg, 461GNUNET_CONFIGURATION_remove_section (struct GNUNET_CONFIGURATION_Handle *cfg,
457 const char *section) 462 const char *section)
458{ 463{
459 struct ConfigSection *spos; 464 struct ConfigSection *spos;
460 struct ConfigSection *prev; 465 struct ConfigSection *prev;
@@ -463,28 +468,28 @@ GNUNET_CONFIGURATION_remove_section (struct GNUNET_CONFIGURATION_Handle *cfg,
463 prev = NULL; 468 prev = NULL;
464 spos = cfg->sections; 469 spos = cfg->sections;
465 while (spos != NULL) 470 while (spos != NULL)
466 {
467 if (0 == strcmp (section, spos->name))
468 { 471 {
469 if (prev == NULL) 472 if (0 == strcmp (section, spos->name))
470 cfg->sections = spos->next; 473 {
471 else 474 if (prev == NULL)
472 prev->next = spos->next; 475 cfg->sections = spos->next;
473 while (NULL != (ent = spos->entries)) 476 else
474 { 477 prev->next = spos->next;
475 spos->entries = ent->next; 478 while (NULL != (ent = spos->entries))
476 GNUNET_free (ent->key); 479 {
477 GNUNET_free_non_null (ent->val); 480 spos->entries = ent->next;
478 GNUNET_free (ent); 481 GNUNET_free (ent->key);
479 cfg->dirty = GNUNET_YES; 482 GNUNET_free_non_null (ent->val);
480 } 483 GNUNET_free (ent);
481 GNUNET_free (spos->name); 484 cfg->dirty = GNUNET_YES;
482 GNUNET_free (spos); 485 }
483 return; 486 GNUNET_free (spos->name);
487 GNUNET_free (spos);
488 return;
489 }
490 prev = spos;
491 spos = spos->next;
484 } 492 }
485 prev = spos;
486 spos = spos->next;
487 }
488} 493}
489 494
490 495
@@ -499,7 +504,7 @@ GNUNET_CONFIGURATION_remove_section (struct GNUNET_CONFIGURATION_Handle *cfg,
499 */ 504 */
500static void 505static void
501copy_entry (void *cls, const char *section, const char *option, 506copy_entry (void *cls, const char *section, const char *option,
502 const char *value) 507 const char *value)
503{ 508{
504 struct GNUNET_CONFIGURATION_Handle *dst = cls; 509 struct GNUNET_CONFIGURATION_Handle *dst = cls;
505 510
@@ -532,7 +537,8 @@ GNUNET_CONFIGURATION_dup (const struct GNUNET_CONFIGURATION_Handle *cfg)
532 * @return matching entry, NULL if not found 537 * @return matching entry, NULL if not found
533 */ 538 */
534static struct ConfigSection * 539static struct ConfigSection *
535findSection (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section) 540findSection (const struct GNUNET_CONFIGURATION_Handle *cfg,
541 const char *section)
536{ 542{
537 struct ConfigSection *pos; 543 struct ConfigSection *pos;
538 544
@@ -553,7 +559,7 @@ findSection (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section)
553 */ 559 */
554static struct ConfigEntry * 560static struct ConfigEntry *
555findEntry (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, 561findEntry (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section,
556 const char *key) 562 const char *key)
557{ 563{
558 struct ConfigSection *sec; 564 struct ConfigSection *sec;
559 struct ConfigEntry *pos; 565 struct ConfigEntry *pos;
@@ -580,7 +586,7 @@ findEntry (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section,
580 */ 586 */
581static void 587static void
582compareEntries (void *cls, const char *section, const char *option, 588compareEntries (void *cls, const char *section, const char *option,
583 const char *value) 589 const char *value)
584{ 590{
585 struct DiffHandle *dh = cls; 591 struct DiffHandle *dh = cls;
586 struct ConfigEntry *entNew; 592 struct ConfigEntry *entNew;
@@ -601,9 +607,9 @@ compareEntries (void *cls, const char *section, const char *option,
601 */ 607 */
602int 608int
603GNUNET_CONFIGURATION_write_diffs (const struct GNUNET_CONFIGURATION_Handle 609GNUNET_CONFIGURATION_write_diffs (const struct GNUNET_CONFIGURATION_Handle
604 *cfgDefault, 610 *cfgDefault,
605 const struct GNUNET_CONFIGURATION_Handle 611 const struct GNUNET_CONFIGURATION_Handle
606 *cfgNew, const char *filename) 612 *cfgNew, const char *filename)
607{ 613{
608 int ret; 614 int ret;
609 struct DiffHandle diffHandle; 615 struct DiffHandle diffHandle;
@@ -626,28 +632,28 @@ GNUNET_CONFIGURATION_write_diffs (const struct GNUNET_CONFIGURATION_Handle
626 * @param value value to set 632 * @param value value to set
627 */ 633 */
628void 634void
629GNUNET_CONFIGURATION_set_value_string (struct GNUNET_CONFIGURATION_Handle *cfg, 635GNUNET_CONFIGURATION_set_value_string (struct GNUNET_CONFIGURATION_Handle
630 const char *section, const char *option, 636 *cfg, const char *section,
631 const char *value) 637 const char *option, const char *value)
632{ 638{
633 struct ConfigSection *sec; 639 struct ConfigSection *sec;
634 struct ConfigEntry *e; 640 struct ConfigEntry *e;
635 641
636 e = findEntry (cfg, section, option); 642 e = findEntry (cfg, section, option);
637 if (e != NULL) 643 if (e != NULL)
638 { 644 {
639 GNUNET_free_non_null (e->val); 645 GNUNET_free_non_null (e->val);
640 e->val = GNUNET_strdup (value); 646 e->val = GNUNET_strdup (value);
641 return; 647 return;
642 } 648 }
643 sec = findSection (cfg, section); 649 sec = findSection (cfg, section);
644 if (sec == NULL) 650 if (sec == NULL)
645 { 651 {
646 sec = GNUNET_malloc (sizeof (struct ConfigSection)); 652 sec = GNUNET_malloc (sizeof (struct ConfigSection));
647 sec->name = GNUNET_strdup (section); 653 sec->name = GNUNET_strdup (section);
648 sec->next = cfg->sections; 654 sec->next = cfg->sections;
649 cfg->sections = sec; 655 cfg->sections = sec;
650 } 656 }
651 e = GNUNET_malloc (sizeof (struct ConfigEntry)); 657 e = GNUNET_malloc (sizeof (struct ConfigEntry));
652 e->key = GNUNET_strdup (option); 658 e->key = GNUNET_strdup (option);
653 e->val = GNUNET_strdup (value); 659 e->val = GNUNET_strdup (value);
@@ -665,9 +671,10 @@ GNUNET_CONFIGURATION_set_value_string (struct GNUNET_CONFIGURATION_Handle *cfg,
665 * @param number value to set 671 * @param number value to set
666 */ 672 */
667void 673void
668GNUNET_CONFIGURATION_set_value_number (struct GNUNET_CONFIGURATION_Handle *cfg, 674GNUNET_CONFIGURATION_set_value_number (struct GNUNET_CONFIGURATION_Handle
669 const char *section, const char *option, 675 *cfg, const char *section,
670 unsigned long long number) 676 const char *option,
677 unsigned long long number)
671{ 678{
672 char s[64]; 679 char s[64];
673 680
@@ -686,10 +693,11 @@ GNUNET_CONFIGURATION_set_value_number (struct GNUNET_CONFIGURATION_Handle *cfg,
686 * @return GNUNET_OK on success, GNUNET_SYSERR on error 693 * @return GNUNET_OK on success, GNUNET_SYSERR on error
687 */ 694 */
688int 695int
689GNUNET_CONFIGURATION_get_value_number (const struct GNUNET_CONFIGURATION_Handle 696GNUNET_CONFIGURATION_get_value_number (const struct
690 *cfg, const char *section, 697 GNUNET_CONFIGURATION_Handle *cfg,
691 const char *option, 698 const char *section,
692 unsigned long long *number) 699 const char *option,
700 unsigned long long *number)
693{ 701{
694 struct ConfigEntry *e; 702 struct ConfigEntry *e;
695 703
@@ -713,9 +721,9 @@ GNUNET_CONFIGURATION_get_value_number (const struct GNUNET_CONFIGURATION_Handle
713 */ 721 */
714int 722int
715GNUNET_CONFIGURATION_get_value_time (const struct GNUNET_CONFIGURATION_Handle 723GNUNET_CONFIGURATION_get_value_time (const struct GNUNET_CONFIGURATION_Handle
716 *cfg, const char *section, 724 *cfg, const char *section,
717 const char *option, 725 const char *option,
718 struct GNUNET_TIME_Relative *time) 726 struct GNUNET_TIME_Relative *time)
719{ 727{
720 struct ConfigEntry *e; 728 struct ConfigEntry *e;
721 unsigned long long num; 729 unsigned long long num;
@@ -725,10 +733,10 @@ GNUNET_CONFIGURATION_get_value_time (const struct GNUNET_CONFIGURATION_Handle
725 return GNUNET_SYSERR; 733 return GNUNET_SYSERR;
726 if ((0 == strcasecmp (e->val, "infinity")) || 734 if ((0 == strcasecmp (e->val, "infinity")) ||
727 (0 == strcasecmp (e->val, "forever"))) 735 (0 == strcasecmp (e->val, "forever")))
728 { 736 {
729 *time = GNUNET_TIME_UNIT_FOREVER_REL; 737 *time = GNUNET_TIME_UNIT_FOREVER_REL;
730 return GNUNET_OK; 738 return GNUNET_OK;
731 } 739 }
732 if (1 != SSCANF (e->val, "%llu", &num)) 740 if (1 != SSCANF (e->val, "%llu", &num))
733 return GNUNET_SYSERR; 741 return GNUNET_SYSERR;
734 time->rel_value = (uint64_t) num; 742 time->rel_value = (uint64_t) num;
@@ -747,18 +755,19 @@ GNUNET_CONFIGURATION_get_value_time (const struct GNUNET_CONFIGURATION_Handle
747 * @return GNUNET_OK on success, GNUNET_SYSERR on error 755 * @return GNUNET_OK on success, GNUNET_SYSERR on error
748 */ 756 */
749int 757int
750GNUNET_CONFIGURATION_get_value_string (const struct GNUNET_CONFIGURATION_Handle 758GNUNET_CONFIGURATION_get_value_string (const struct
751 *cfg, const char *section, 759 GNUNET_CONFIGURATION_Handle *cfg,
752 const char *option, char **value) 760 const char *section,
761 const char *option, char **value)
753{ 762{
754 struct ConfigEntry *e; 763 struct ConfigEntry *e;
755 764
756 e = findEntry (cfg, section, option); 765 e = findEntry (cfg, section, option);
757 if ((e == NULL) || (e->val == NULL)) 766 if ((e == NULL) || (e->val == NULL))
758 { 767 {
759 *value = NULL; 768 *value = NULL;
760 return GNUNET_SYSERR; 769 return GNUNET_SYSERR;
761 } 770 }
762 *value = GNUNET_strdup (e->val); 771 *value = GNUNET_strdup (e->val);
763 return GNUNET_OK; 772 return GNUNET_OK;
764} 773}
@@ -777,10 +786,12 @@ GNUNET_CONFIGURATION_get_value_string (const struct GNUNET_CONFIGURATION_Handle
777 * @return GNUNET_OK on success, GNUNET_SYSERR on error 786 * @return GNUNET_OK on success, GNUNET_SYSERR on error
778 */ 787 */
779int 788int
780GNUNET_CONFIGURATION_get_value_choice (const struct GNUNET_CONFIGURATION_Handle 789GNUNET_CONFIGURATION_get_value_choice (const struct
781 *cfg, const char *section, 790 GNUNET_CONFIGURATION_Handle *cfg,
782 const char *option, const char **choices, 791 const char *section,
783 const char **value) 792 const char *option,
793 const char **choices,
794 const char **value)
784{ 795{
785 struct ConfigEntry *e; 796 struct ConfigEntry *e;
786 int i; 797 int i;
@@ -790,19 +801,19 @@ GNUNET_CONFIGURATION_get_value_choice (const struct GNUNET_CONFIGURATION_Handle
790 return GNUNET_SYSERR; 801 return GNUNET_SYSERR;
791 i = 0; 802 i = 0;
792 while (choices[i] != NULL) 803 while (choices[i] != NULL)
793 { 804 {
794 if (0 == strcasecmp (choices[i], e->val)) 805 if (0 == strcasecmp (choices[i], e->val))
795 break; 806 break;
796 i++; 807 i++;
797 } 808 }
798 if (choices[i] == NULL) 809 if (choices[i] == NULL)
799 { 810 {
800 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 811 LOG (GNUNET_ERROR_TYPE_ERROR,
801 _("Configuration value '%s' for '%s'" 812 _("Configuration value '%s' for '%s'"
802 " in section '%s' is not in set of legal choices\n"), e->val, 813 " in section '%s' is not in set of legal choices\n"), e->val,
803 option, section); 814 option, section);
804 return GNUNET_SYSERR; 815 return GNUNET_SYSERR;
805 } 816 }
806 *value = choices[i]; 817 *value = choices[i];
807 return GNUNET_OK; 818 return GNUNET_OK;
808} 819}
@@ -816,8 +827,9 @@ GNUNET_CONFIGURATION_get_value_choice (const struct GNUNET_CONFIGURATION_Handle
816 * @return GNUNET_YES if so, GNUNET_NO if not. 827 * @return GNUNET_YES if so, GNUNET_NO if not.
817 */ 828 */
818int 829int
819GNUNET_CONFIGURATION_have_value (const struct GNUNET_CONFIGURATION_Handle *cfg, 830GNUNET_CONFIGURATION_have_value (const struct GNUNET_CONFIGURATION_Handle
820 const char *section, const char *option) 831 *cfg, const char *section,
832 const char *option)
821{ 833{
822 struct ConfigEntry *e; 834 struct ConfigEntry *e;
823 835
@@ -838,7 +850,7 @@ GNUNET_CONFIGURATION_have_value (const struct GNUNET_CONFIGURATION_Handle *cfg,
838 */ 850 */
839char * 851char *
840GNUNET_CONFIGURATION_expand_dollar (const struct GNUNET_CONFIGURATION_Handle 852GNUNET_CONFIGURATION_expand_dollar (const struct GNUNET_CONFIGURATION_Handle
841 *cfg, char *orig) 853 *cfg, char *orig)
842{ 854{
843 int i; 855 int i;
844 char *prefix; 856 char *prefix;
@@ -852,24 +864,25 @@ GNUNET_CONFIGURATION_expand_dollar (const struct GNUNET_CONFIGURATION_Handle
852 while ((orig[i] != '/') && (orig[i] != '\\') && (orig[i] != '\0')) 864 while ((orig[i] != '/') && (orig[i] != '\\') && (orig[i] != '\0'))
853 i++; 865 i++;
854 if (orig[i] == '\0') 866 if (orig[i] == '\0')
855 { 867 {
856 post = ""; 868 post = "";
857 } 869 }
858 else 870 else
859 { 871 {
860 orig[i] = '\0'; 872 orig[i] = '\0';
861 post = &orig[i + 1]; 873 post = &orig[i + 1];
862 } 874 }
863 if (GNUNET_OK != 875 if (GNUNET_OK !=
864 GNUNET_CONFIGURATION_get_value_filename (cfg, "PATHS", &orig[1], &prefix)) 876 GNUNET_CONFIGURATION_get_value_filename (cfg, "PATHS", &orig[1],
865 { 877 &prefix))
866 if (NULL == (env = getenv (&orig[1])))
867 { 878 {
868 orig[i] = DIR_SEPARATOR; 879 if (NULL == (env = getenv (&orig[1])))
869 return orig; 880 {
881 orig[i] = DIR_SEPARATOR;
882 return orig;
883 }
884 prefix = GNUNET_strdup (env);
870 } 885 }
871 prefix = GNUNET_strdup (env);
872 }
873 result = GNUNET_malloc (strlen (prefix) + strlen (post) + 2); 886 result = GNUNET_malloc (strlen (prefix) + strlen (post) + 2);
874 strcpy (result, prefix); 887 strcpy (result, prefix);
875 if ((strlen (prefix) == 0) || 888 if ((strlen (prefix) == 0) ||
@@ -894,18 +907,18 @@ GNUNET_CONFIGURATION_expand_dollar (const struct GNUNET_CONFIGURATION_Handle
894 */ 907 */
895int 908int
896GNUNET_CONFIGURATION_get_value_filename (const struct 909GNUNET_CONFIGURATION_get_value_filename (const struct
897 GNUNET_CONFIGURATION_Handle *cfg, 910 GNUNET_CONFIGURATION_Handle *cfg,
898 const char *section, 911 const char *section,
899 const char *option, char **value) 912 const char *option, char **value)
900{ 913{
901 char *tmp; 914 char *tmp;
902 915
903 if (GNUNET_OK != 916 if (GNUNET_OK !=
904 GNUNET_CONFIGURATION_get_value_string (cfg, section, option, &tmp)) 917 GNUNET_CONFIGURATION_get_value_string (cfg, section, option, &tmp))
905 { 918 {
906 *value = NULL; 919 *value = NULL;
907 return GNUNET_SYSERR; 920 return GNUNET_SYSERR;
908 } 921 }
909 tmp = GNUNET_CONFIGURATION_expand_dollar (cfg, tmp); 922 tmp = GNUNET_CONFIGURATION_expand_dollar (cfg, tmp);
910 *value = GNUNET_STRINGS_filename_expand (tmp); 923 *value = GNUNET_STRINGS_filename_expand (tmp);
911 GNUNET_free (tmp); 924 GNUNET_free (tmp);
@@ -926,15 +939,15 @@ GNUNET_CONFIGURATION_get_value_filename (const struct
926 */ 939 */
927int 940int
928GNUNET_CONFIGURATION_get_value_yesno (const struct GNUNET_CONFIGURATION_Handle 941GNUNET_CONFIGURATION_get_value_yesno (const struct GNUNET_CONFIGURATION_Handle
929 *cfg, const char *section, 942 *cfg, const char *section,
930 const char *option) 943 const char *option)
931{ 944{
932 static const char *yesno[] = { "YES", "NO", NULL }; 945 static const char *yesno[] = { "YES", "NO", NULL };
933 const char *val; 946 const char *val;
934 int ret; 947 int ret;
935 948
936 ret = 949 ret =
937 GNUNET_CONFIGURATION_get_value_choice (cfg, section, option, yesno, &val); 950 GNUNET_CONFIGURATION_get_value_choice (cfg, section, option, yesno, &val);
938 if (ret == GNUNET_SYSERR) 951 if (ret == GNUNET_SYSERR)
939 return ret; 952 return ret;
940 if (val == yesno[0]) 953 if (val == yesno[0])
@@ -955,11 +968,11 @@ GNUNET_CONFIGURATION_get_value_yesno (const struct GNUNET_CONFIGURATION_Handle
955 */ 968 */
956int 969int
957GNUNET_CONFIGURATION_iterate_value_filenames (const struct 970GNUNET_CONFIGURATION_iterate_value_filenames (const struct
958 GNUNET_CONFIGURATION_Handle *cfg, 971 GNUNET_CONFIGURATION_Handle
959 const char *section, 972 *cfg, const char *section,
960 const char *option, 973 const char *option,
961 GNUNET_FileNameCallback cb, 974 GNUNET_FileNameCallback cb,
962 void *cb_cls) 975 void *cb_cls)
963{ 976{
964 char *list; 977 char *list;
965 char *pos; 978 char *pos;
@@ -974,46 +987,46 @@ GNUNET_CONFIGURATION_iterate_value_filenames (const struct
974 ret = 0; 987 ret = 0;
975 pos = list; 988 pos = list;
976 while (1) 989 while (1)
977 {
978 while (pos[0] == ' ')
979 pos++;
980 if (strlen (pos) == 0)
981 break;
982 end = pos + 1;
983 while ((end[0] != ' ') && (end[0] != '\0'))
984 { 990 {
985 if (end[0] == '\\') 991 while (pos[0] == ' ')
986 { 992 pos++;
987 switch (end[1]) 993 if (strlen (pos) == 0)
988 { 994 break;
989 case '\\': 995 end = pos + 1;
990 case ' ': 996 while ((end[0] != ' ') && (end[0] != '\0'))
991 memmove (end, &end[1], strlen (&end[1]) + 1); 997 {
992 case '\0': 998 if (end[0] == '\\')
993 /* illegal, but just keep it */ 999 {
994 break; 1000 switch (end[1])
995 default: 1001 {
996 /* illegal, but just ignore that there was a '/' */ 1002 case '\\':
997 break; 1003 case ' ':
998 } 1004 memmove (end, &end[1], strlen (&end[1]) + 1);
999 } 1005 case '\0':
1000 end++; 1006 /* illegal, but just keep it */
1007 break;
1008 default:
1009 /* illegal, but just ignore that there was a '/' */
1010 break;
1011 }
1012 }
1013 end++;
1014 }
1015 old = end[0];
1016 end[0] = '\0';
1017 if (strlen (pos) > 0)
1018 {
1019 ret++;
1020 if ((cb != NULL) && (GNUNET_OK != cb (cb_cls, pos)))
1021 {
1022 ret = GNUNET_SYSERR;
1023 break;
1024 }
1025 }
1026 if (old == '\0')
1027 break;
1028 pos = end + 1;
1001 } 1029 }
1002 old = end[0];
1003 end[0] = '\0';
1004 if (strlen (pos) > 0)
1005 {
1006 ret++;
1007 if ((cb != NULL) && (GNUNET_OK != cb (cb_cls, pos)))
1008 {
1009 ret = GNUNET_SYSERR;
1010 break;
1011 }
1012 }
1013 if (old == '\0')
1014 break;
1015 pos = end + 1;
1016 }
1017 GNUNET_free (list); 1030 GNUNET_free (list);
1018 return ret; 1031 return ret;
1019} 1032}
@@ -1037,21 +1050,21 @@ escape_name (const char *value)
1037 rpos = value; 1050 rpos = value;
1038 wpos = escaped; 1051 wpos = escaped;
1039 while (rpos[0] != '\0') 1052 while (rpos[0] != '\0')
1040 {
1041 switch (rpos[0])
1042 { 1053 {
1043 case '\\': 1054 switch (rpos[0])
1044 case ' ': 1055 {
1045 wpos[0] = '\\'; 1056 case '\\':
1046 wpos[1] = rpos[0]; 1057 case ' ':
1047 wpos += 2; 1058 wpos[0] = '\\';
1048 break; 1059 wpos[1] = rpos[0];
1049 default: 1060 wpos += 2;
1050 wpos[0] = rpos[0]; 1061 break;
1051 wpos++; 1062 default:
1063 wpos[0] = rpos[0];
1064 wpos++;
1065 }
1066 rpos++;
1052 } 1067 }
1053 rpos++;
1054 }
1055 return escaped; 1068 return escaped;
1056} 1069}
1057 1070
@@ -1086,9 +1099,9 @@ test_match (void *cls, const char *fn)
1086 */ 1099 */
1087int 1100int
1088GNUNET_CONFIGURATION_append_value_filename (struct GNUNET_CONFIGURATION_Handle 1101GNUNET_CONFIGURATION_append_value_filename (struct GNUNET_CONFIGURATION_Handle
1089 *cfg, const char *section, 1102 *cfg, const char *section,
1090 const char *option, 1103 const char *option,
1091 const char *value) 1104 const char *value)
1092{ 1105{
1093 char *escaped; 1106 char *escaped;
1094 char *old; 1107 char *old;
@@ -1096,9 +1109,9 @@ GNUNET_CONFIGURATION_append_value_filename (struct GNUNET_CONFIGURATION_Handle
1096 1109
1097 if (GNUNET_SYSERR == 1110 if (GNUNET_SYSERR ==
1098 GNUNET_CONFIGURATION_iterate_value_filenames (cfg, section, option, 1111 GNUNET_CONFIGURATION_iterate_value_filenames (cfg, section, option,
1099 &test_match, 1112 &test_match,
1100 (void *) value)) 1113 (void *) value))
1101 return GNUNET_NO; /* already exists */ 1114 return GNUNET_NO; /* already exists */
1102 if (GNUNET_OK != 1115 if (GNUNET_OK !=
1103 GNUNET_CONFIGURATION_get_value_string (cfg, section, option, &old)) 1116 GNUNET_CONFIGURATION_get_value_string (cfg, section, option, &old))
1104 old = GNUNET_strdup (""); 1117 old = GNUNET_strdup ("");
@@ -1130,9 +1143,9 @@ GNUNET_CONFIGURATION_append_value_filename (struct GNUNET_CONFIGURATION_Handle
1130 */ 1143 */
1131int 1144int
1132GNUNET_CONFIGURATION_remove_value_filename (struct GNUNET_CONFIGURATION_Handle 1145GNUNET_CONFIGURATION_remove_value_filename (struct GNUNET_CONFIGURATION_Handle
1133 *cfg, const char *section, 1146 *cfg, const char *section,
1134 const char *option, 1147 const char *option,
1135 const char *value) 1148 const char *value)
1136{ 1149{
1137 char *list; 1150 char *list;
1138 char *pos; 1151 char *pos;
@@ -1146,55 +1159,55 @@ GNUNET_CONFIGURATION_remove_value_filename (struct GNUNET_CONFIGURATION_Handle
1146 match = escape_name (value); 1159 match = escape_name (value);
1147 pos = list; 1160 pos = list;
1148 while (1) 1161 while (1)
1149 {
1150 while (pos[0] == ' ')
1151 pos++;
1152 if (strlen (pos) == 0)
1153 break;
1154 end = pos + 1;
1155 while ((end[0] != ' ') && (end[0] != '\0'))
1156 {
1157 if (end[0] == '\\')
1158 {
1159 switch (end[1])
1160 {
1161 case '\\':
1162 case ' ':
1163 end++;
1164 break;
1165 case '\0':
1166 /* illegal, but just keep it */
1167 break;
1168 default:
1169 /* illegal, but just ignore that there was a '/' */
1170 break;
1171 }
1172 }
1173 end++;
1174 }
1175 old = end[0];
1176 end[0] = '\0';
1177 if (0 == strcmp (pos, match))
1178 { 1162 {
1179 if (old != '\0') 1163 while (pos[0] == ' ')
1180 memmove (pos, &end[1], strlen (&end[1]) + 1); 1164 pos++;
1181 else 1165 if (strlen (pos) == 0)
1182 { 1166 break;
1183 if (pos != list) 1167 end = pos + 1;
1184 pos[-1] = '\0'; 1168 while ((end[0] != ' ') && (end[0] != '\0'))
1185 else 1169 {
1186 pos[0] = '\0'; 1170 if (end[0] == '\\')
1187 } 1171 {
1188 GNUNET_CONFIGURATION_set_value_string (cfg, section, option, list); 1172 switch (end[1])
1189 GNUNET_free (list); 1173 {
1190 GNUNET_free (match); 1174 case '\\':
1191 return GNUNET_OK; 1175 case ' ':
1176 end++;
1177 break;
1178 case '\0':
1179 /* illegal, but just keep it */
1180 break;
1181 default:
1182 /* illegal, but just ignore that there was a '/' */
1183 break;
1184 }
1185 }
1186 end++;
1187 }
1188 old = end[0];
1189 end[0] = '\0';
1190 if (0 == strcmp (pos, match))
1191 {
1192 if (old != '\0')
1193 memmove (pos, &end[1], strlen (&end[1]) + 1);
1194 else
1195 {
1196 if (pos != list)
1197 pos[-1] = '\0';
1198 else
1199 pos[0] = '\0';
1200 }
1201 GNUNET_CONFIGURATION_set_value_string (cfg, section, option, list);
1202 GNUNET_free (list);
1203 GNUNET_free (match);
1204 return GNUNET_OK;
1205 }
1206 if (old == '\0')
1207 break;
1208 end[0] = old;
1209 pos = end + 1;
1192 } 1210 }
1193 if (old == '\0')
1194 break;
1195 end[0] = old;
1196 pos = end + 1;
1197 }
1198 GNUNET_free (list); 1211 GNUNET_free (list);
1199 GNUNET_free (match); 1212 GNUNET_free (match);
1200 return GNUNET_NO; 1213 return GNUNET_NO;
@@ -1211,7 +1224,7 @@ GNUNET_CONFIGURATION_remove_value_filename (struct GNUNET_CONFIGURATION_Handle
1211 */ 1224 */
1212int 1225int
1213GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg, 1226GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg,
1214 const char *filename) 1227 const char *filename)
1215{ 1228{
1216 char *baseconfig; 1229 char *baseconfig;
1217 char *ipath; 1230 char *ipath;
@@ -1221,21 +1234,21 @@ GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg,
1221 return GNUNET_SYSERR; 1234 return GNUNET_SYSERR;
1222 baseconfig = NULL; 1235 baseconfig = NULL;
1223 GNUNET_asprintf (&baseconfig, "%s%s%s", ipath, DIR_SEPARATOR_STR, 1236 GNUNET_asprintf (&baseconfig, "%s%s%s", ipath, DIR_SEPARATOR_STR,
1224 "defaults.conf"); 1237 "defaults.conf");
1225 GNUNET_free (ipath); 1238 GNUNET_free (ipath);
1226 if ((GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, baseconfig)) || 1239 if ((GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, baseconfig)) ||
1227 (!((filename == NULL) || 1240 (!((filename == NULL) ||
1228 (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, filename))))) 1241 (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, filename)))))
1229 { 1242 {
1230 GNUNET_free (baseconfig); 1243 GNUNET_free (baseconfig);
1231 return (filename == NULL) ? GNUNET_OK : GNUNET_SYSERR; 1244 return (filename == NULL) ? GNUNET_OK : GNUNET_SYSERR;
1232 } 1245 }
1233 GNUNET_free (baseconfig); 1246 GNUNET_free (baseconfig);
1234 if (((GNUNET_YES != 1247 if (((GNUNET_YES !=
1235 GNUNET_CONFIGURATION_have_value (cfg, "PATHS", "DEFAULTCONFIG"))) && 1248 GNUNET_CONFIGURATION_have_value (cfg, "PATHS", "DEFAULTCONFIG"))) &&
1236 (filename != NULL)) 1249 (filename != NULL))
1237 GNUNET_CONFIGURATION_set_value_string (cfg, "PATHS", "DEFAULTCONFIG", 1250 GNUNET_CONFIGURATION_set_value_string (cfg, "PATHS", "DEFAULTCONFIG",
1238 filename); 1251 filename);
1239 if ((GNUNET_YES == 1252 if ((GNUNET_YES ==
1240 GNUNET_CONFIGURATION_have_value (cfg, "TESTING", "WEAKRANDOM")) && 1253 GNUNET_CONFIGURATION_have_value (cfg, "TESTING", "WEAKRANDOM")) &&
1241 (GNUNET_YES == 1254 (GNUNET_YES ==