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.c663
1 files changed, 329 insertions, 334 deletions
diff --git a/src/util/configuration.c b/src/util/configuration.c
index 88bde1c38..b3b9d5ea8 100644
--- a/src/util/configuration.c
+++ b/src/util/configuration.c
@@ -168,90 +168,89 @@ GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg,
168 return GNUNET_SYSERR; 168 return GNUNET_SYSERR;
169 dirty = cfg->dirty; /* back up value! */ 169 dirty = cfg->dirty; /* back up value! */
170 if (NULL == (fp = FOPEN (fn, "r"))) 170 if (NULL == (fp = FOPEN (fn, "r")))
171 { 171 {
172 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fopen", fn); 172 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fopen", fn);
173 GNUNET_free (fn); 173 GNUNET_free (fn);
174 return GNUNET_SYSERR; 174 return GNUNET_SYSERR;
175 } 175 }
176 GNUNET_free (fn); 176 GNUNET_free (fn);
177 ret = GNUNET_OK; 177 ret = GNUNET_OK;
178 section = GNUNET_strdup (""); 178 section = GNUNET_strdup ("");
179 memset (line, 0, 256); 179 memset (line, 0, 256);
180 nr = 0; 180 nr = 0;
181 while (NULL != fgets (line, 255, fp)) 181 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))
182 { 200 {
183 nr++; 201 /* @INLINE@ value */
184 for (i = 0; i < 255; i++) 202 if (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, value))
185 if (line[i] == '\t') 203 ret = GNUNET_SYSERR; /* failed to parse included config */
186 line[i] = ' '; 204 }
187 if (line[0] == '\n' || line[0] == '#' || line[0] == '%' || 205 else if (1 == sscanf (line, "[%99[^]]]", value))
188 line[0] == '\r') 206 {
189 continue; 207 /* [value] */
190 emptyline = 1; 208 GNUNET_free (section);
191 for (i = 0; (i < 255 && line[i] != 0); i++) 209 section = GNUNET_strdup (value);
192 if (line[i] != ' ' && line[i] != '\n' && line[i] != '\r') 210 }
193 emptyline = 0; 211 else if (2 == sscanf (line, " %63[^= ] = %191[^\n]", tag, value))
194 if (emptyline == 1) 212 {
195 continue; 213 /* tag = value */
196 /* remove tailing whitespace */ 214 /* Strip LF */
197 for (i = strlen (line) - 1; (i >= 0) && (isspace ( (unsigned char) line[i])); i--) 215 i = strlen (value) - 1;
198 line[i] = '\0'; 216 while ((i >= 0) && (isspace ((unsigned char) value[i])))
199 if (1 == sscanf (line, "@INLINE@ %191[^\n]", value)) 217 value[i--] = '\0';
200 { 218 /* remove quotes */
201 /* @INLINE@ value */ 219 i = 0;
202 if (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, value)) 220 if (value[0] == '"')
203 ret = GNUNET_SYSERR; /* failed to parse included config */ 221 {
204 } 222 i = 1;
205 else if (1 == sscanf (line, "[%99[^]]]", value)) 223 while ((value[i] != '\0') && (value[i] != '"'))
224 i++;
225 if (value[i] == '"')
206 { 226 {
207 /* [value] */ 227 value[i] = '\0';
208 GNUNET_free (section); 228 i = 1;
209 section = GNUNET_strdup (value);
210 } 229 }
211 else if (2 == sscanf (line, " %63[^= ] = %191[^\n]", tag, value)) 230 else
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; 231 i = 0;
220 if (value[0] == '"') 232 }
221 { 233 GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, &value[i]);
222 i = 1; 234 }
223 while ((value[i] != '\0') && (value[i] != '"')) 235 else if (1 == sscanf (line, " %63[^= ] =[^\n]", tag))
224 i++; 236 {
225 if (value[i] == '"') 237 /* tag = */
226 { 238 GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, "");
227 value[i] = '\0'; 239 }
228 i = 1; 240 else
229 } 241 {
230 else 242 /* parse error */
231 i = 0; 243 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
232 } 244 _
233 GNUNET_CONFIGURATION_set_value_string (cfg, 245 ("Syntax error in configuration file `%s' at line %u.\n"),
234 section, tag, &value[i]); 246 filename, nr);
235 } 247 ret = GNUNET_SYSERR;
236 else if (1 == sscanf (line, " %63[^= ] =[^\n]", tag)) 248 break;
237 {
238 /* tag = */
239 GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, "");
240 }
241 else
242 {
243 /* parse error */
244 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
245 _
246 ("Syntax error in configuration file `%s' at line %u.\n"),
247 filename, nr);
248 ret = GNUNET_SYSERR;
249 break;
250 }
251 } 249 }
250 }
252 GNUNET_assert (0 == fclose (fp)); 251 GNUNET_assert (0 == fclose (fp));
253 /* restore dirty flag - anything we set in the meantime 252 /* restore dirty flag - anything we set in the meantime
254 came from disk */ 253 * came from disk */
255 cfg->dirty = dirty; 254 cfg->dirty = dirty;
256 GNUNET_free (section); 255 GNUNET_free (section);
257 return ret; 256 return ret;
@@ -295,66 +294,66 @@ GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg,
295 if (fn == NULL) 294 if (fn == NULL)
296 return GNUNET_SYSERR; 295 return GNUNET_SYSERR;
297 if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn)) 296 if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (fn))
298 { 297 {
299 GNUNET_free (fn); 298 GNUNET_free (fn);
300 return GNUNET_SYSERR; 299 return GNUNET_SYSERR;
301 } 300 }
302 if (NULL == (fp = FOPEN (fn, "w"))) 301 if (NULL == (fp = FOPEN (fn, "w")))
303 { 302 {
304 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fopen", fn); 303 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fopen", fn);
305 GNUNET_free (fn); 304 GNUNET_free (fn);
306 return GNUNET_SYSERR; 305 return GNUNET_SYSERR;
307 } 306 }
308 GNUNET_free (fn); 307 GNUNET_free (fn);
309 error = 0; 308 error = 0;
310 sec = cfg->sections; 309 sec = cfg->sections;
311 while (sec != NULL) 310 while (sec != NULL)
311 {
312 if (0 > fprintf (fp, "[%s]\n", sec->name))
312 { 313 {
313 if (0 > fprintf (fp, "[%s]\n", sec->name)) 314 error = 1;
314 { 315 break;
315 error = 1; 316 }
316 break; 317 ent = sec->entries;
317 } 318 while (ent != NULL)
318 ent = sec->entries; 319 {
319 while (ent != NULL) 320 if (ent->val != NULL)
321 {
322 val = GNUNET_malloc (strlen (ent->val) * 2 + 1);
323 strcpy (val, ent->val);
324 while (NULL != (pos = strstr (val, "\n")))
320 { 325 {
321 if (ent->val != NULL) 326 memmove (&pos[2], &pos[1], strlen (&pos[1]));
322 { 327 pos[0] = '\\';
323 val = GNUNET_malloc (strlen (ent->val) * 2 + 1); 328 pos[1] = 'n';
324 strcpy (val, ent->val);
325 while (NULL != (pos = strstr (val, "\n")))
326 {
327 memmove (&pos[2], &pos[1], strlen (&pos[1]));
328 pos[0] = '\\';
329 pos[1] = 'n';
330 }
331 if (0 > fprintf (fp, "%s = %s\n", ent->key, val))
332 {
333 error = 1;
334 GNUNET_free (val);
335 break;
336 }
337 GNUNET_free (val);
338 }
339 ent = ent->next;
340 } 329 }
341 if (error != 0) 330 if (0 > fprintf (fp, "%s = %s\n", ent->key, val))
342 break;
343 if (0 > fprintf (fp, "\n"))
344 { 331 {
345 error = 1; 332 error = 1;
333 GNUNET_free (val);
346 break; 334 break;
347 } 335 }
348 sec = sec->next; 336 GNUNET_free (val);
337 }
338 ent = ent->next;
339 }
340 if (error != 0)
341 break;
342 if (0 > fprintf (fp, "\n"))
343 {
344 error = 1;
345 break;
349 } 346 }
347 sec = sec->next;
348 }
350 if (error != 0) 349 if (error != 0)
351 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fprintf", filename); 350 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fprintf", filename);
352 GNUNET_assert (0 == fclose (fp)); 351 GNUNET_assert (0 == fclose (fp));
353 if (error != 0) 352 if (error != 0)
354 { 353 {
355 cfg->dirty = GNUNET_SYSERR; /* last write failed */ 354 cfg->dirty = GNUNET_SYSERR; /* last write failed */
356 return GNUNET_SYSERR; 355 return GNUNET_SYSERR;
357 } 356 }
358 cfg->dirty = GNUNET_NO; /* last write succeeded */ 357 cfg->dirty = GNUNET_NO; /* last write succeeded */
359 return GNUNET_OK; 358 return GNUNET_OK;
360} 359}
@@ -377,15 +376,15 @@ GNUNET_CONFIGURATION_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg,
377 376
378 spos = cfg->sections; 377 spos = cfg->sections;
379 while (spos != NULL) 378 while (spos != NULL)
379 {
380 epos = spos->entries;
381 while (epos != NULL)
380 { 382 {
381 epos = spos->entries; 383 iter (iter_cls, spos->name, epos->key, epos->val);
382 while (epos != NULL) 384 epos = epos->next;
383 {
384 iter (iter_cls, spos->name, epos->key, epos->val);
385 epos = epos->next;
386 }
387 spos = spos->next;
388 } 385 }
386 spos = spos->next;
387 }
389} 388}
390 389
391 390
@@ -398,10 +397,11 @@ GNUNET_CONFIGURATION_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg,
398 * @param iter_cls closure for iter 397 * @param iter_cls closure for iter
399 */ 398 */
400void 399void
401GNUNET_CONFIGURATION_iterate_section_values (const struct GNUNET_CONFIGURATION_Handle *cfg, 400GNUNET_CONFIGURATION_iterate_section_values (const struct
402 const char *section, 401 GNUNET_CONFIGURATION_Handle *cfg,
403 GNUNET_CONFIGURATION_Iterator iter, 402 const char *section,
404 void *iter_cls) 403 GNUNET_CONFIGURATION_Iterator iter,
404 void *iter_cls)
405{ 405{
406 struct ConfigSection *spos; 406 struct ConfigSection *spos;
407 struct ConfigEntry *epos; 407 struct ConfigEntry *epos;
@@ -415,10 +415,10 @@ GNUNET_CONFIGURATION_iterate_section_values (const struct GNUNET_CONFIGURATION_H
415 415
416 epos = spos->entries; 416 epos = spos->entries;
417 while (epos != NULL) 417 while (epos != NULL)
418 { 418 {
419 iter (iter_cls, spos->name, epos->key, epos->val); 419 iter (iter_cls, spos->name, epos->key, epos->val);
420 epos = epos->next; 420 epos = epos->next;
421 } 421 }
422} 422}
423 423
424 424
@@ -430,20 +430,21 @@ GNUNET_CONFIGURATION_iterate_section_values (const struct GNUNET_CONFIGURATION_H
430 * @param iter_cls closure for iter 430 * @param iter_cls closure for iter
431 */ 431 */
432void 432void
433GNUNET_CONFIGURATION_iterate_sections (const struct GNUNET_CONFIGURATION_Handle *cfg, 433GNUNET_CONFIGURATION_iterate_sections (const struct GNUNET_CONFIGURATION_Handle
434 GNUNET_CONFIGURATION_Section_Iterator iter, 434 *cfg,
435 void *iter_cls) 435 GNUNET_CONFIGURATION_Section_Iterator
436 iter, void *iter_cls)
436{ 437{
437 struct ConfigSection *spos; 438 struct ConfigSection *spos;
438 struct ConfigSection *next; 439 struct ConfigSection *next;
439 440
440 next = cfg->sections; 441 next = cfg->sections;
441 while (next != NULL) 442 while (next != NULL)
442 { 443 {
443 spos = next; 444 spos = next;
444 next = spos->next; 445 next = spos->next;
445 iter (iter_cls, spos->name); 446 iter (iter_cls, spos->name);
446 } 447 }
447} 448}
448 449
449/** 450/**
@@ -452,39 +453,39 @@ GNUNET_CONFIGURATION_iterate_sections (const struct GNUNET_CONFIGURATION_Handle
452 * @param cfg configuration to inspect 453 * @param cfg configuration to inspect
453 * @param section name of the section to remove 454 * @param section name of the section to remove
454 */ 455 */
455void GNUNET_CONFIGURATION_remove_section (struct GNUNET_CONFIGURATION_Handle *cfg, 456void
456 const char *section) 457GNUNET_CONFIGURATION_remove_section (struct GNUNET_CONFIGURATION_Handle *cfg,
458 const char *section)
457{ 459{
458 struct ConfigSection *spos; 460 struct ConfigSection *spos;
459 struct ConfigSection *prev; 461 struct ConfigSection *prev;
460 struct ConfigEntry *ent; 462 struct ConfigEntry *ent;
461 463
462 prev = NULL; 464 prev = NULL;
463 spos = cfg->sections; 465 spos = cfg->sections;
464 while (spos != NULL) 466 while (spos != NULL)
467 {
468 if (0 == strcmp (section, spos->name))
465 { 469 {
466 if (0 == strcmp (section, 470 if (prev == NULL)
467 spos->name)) 471 cfg->sections = spos->next;
468 { 472 else
469 if (prev == NULL) 473 prev->next = spos->next;
470 cfg->sections = spos->next; 474 while (NULL != (ent = spos->entries))
471 else 475 {
472 prev->next = spos->next; 476 spos->entries = ent->next;
473 while (NULL != (ent = spos->entries)) 477 GNUNET_free (ent->key);
474 { 478 GNUNET_free_non_null (ent->val);
475 spos->entries = ent->next; 479 GNUNET_free (ent);
476 GNUNET_free (ent->key); 480 cfg->dirty = GNUNET_YES;
477 GNUNET_free_non_null (ent->val); 481 }
478 GNUNET_free (ent); 482 GNUNET_free (spos->name);
479 cfg->dirty = GNUNET_YES; 483 GNUNET_free (spos);
480 } 484 return;
481 GNUNET_free (spos->name);
482 GNUNET_free (spos);
483 return;
484 }
485 prev = spos;
486 spos = spos->next;
487 } 485 }
486 prev = spos;
487 spos = spos->next;
488 }
488} 489}
489 490
490 491
@@ -502,6 +503,7 @@ copy_entry (void *cls,
502 const char *section, const char *option, const char *value) 503 const char *section, const char *option, const char *value)
503{ 504{
504 struct GNUNET_CONFIGURATION_Handle *dst = cls; 505 struct GNUNET_CONFIGURATION_Handle *dst = cls;
506
505 GNUNET_CONFIGURATION_set_value_string (dst, section, option, value); 507 GNUNET_CONFIGURATION_set_value_string (dst, section, option, value);
506} 508}
507 509
@@ -531,8 +533,7 @@ GNUNET_CONFIGURATION_dup (const struct GNUNET_CONFIGURATION_Handle *cfg)
531 * @return matching entry, NULL if not found 533 * @return matching entry, NULL if not found
532 */ 534 */
533static struct ConfigSection * 535static struct ConfigSection *
534findSection (const struct GNUNET_CONFIGURATION_Handle *cfg, 536findSection (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section)
535 const char *section)
536{ 537{
537 struct ConfigSection *pos; 538 struct ConfigSection *pos;
538 539
@@ -584,15 +585,11 @@ compareEntries (void *cls,
584{ 585{
585 struct DiffHandle *dh = cls; 586 struct DiffHandle *dh = cls;
586 struct ConfigEntry *entNew; 587 struct ConfigEntry *entNew;
587 588
588 entNew = findEntry (dh->cfgDefault, section, option); 589 entNew = findEntry (dh->cfgDefault, section, option);
589 if ( (entNew != NULL) && 590 if ((entNew != NULL) && (strcmp (entNew->val, value) == 0))
590 (strcmp (entNew->val, value) == 0) )
591 return; 591 return;
592 GNUNET_CONFIGURATION_set_value_string (dh->cfgDiff, 592 GNUNET_CONFIGURATION_set_value_string (dh->cfgDiff, section, option, value);
593 section,
594 option,
595 value);
596} 593}
597 594
598 595
@@ -606,8 +603,8 @@ compareEntries (void *cls,
606int 603int
607GNUNET_CONFIGURATION_write_diffs (const struct GNUNET_CONFIGURATION_Handle 604GNUNET_CONFIGURATION_write_diffs (const struct GNUNET_CONFIGURATION_Handle
608 *cfgDefault, 605 *cfgDefault,
609 const struct GNUNET_CONFIGURATION_Handle *cfgNew, 606 const struct GNUNET_CONFIGURATION_Handle
610 const char *filename) 607 *cfgNew, const char *filename)
611{ 608{
612 int ret; 609 int ret;
613 struct DiffHandle diffHandle; 610 struct DiffHandle diffHandle;
@@ -640,19 +637,19 @@ GNUNET_CONFIGURATION_set_value_string (struct GNUNET_CONFIGURATION_Handle
640 637
641 e = findEntry (cfg, section, option); 638 e = findEntry (cfg, section, option);
642 if (e != NULL) 639 if (e != NULL)
643 { 640 {
644 GNUNET_free_non_null (e->val); 641 GNUNET_free_non_null (e->val);
645 e->val = GNUNET_strdup (value); 642 e->val = GNUNET_strdup (value);
646 return; 643 return;
647 } 644 }
648 sec = findSection (cfg, section); 645 sec = findSection (cfg, section);
649 if (sec == NULL) 646 if (sec == NULL)
650 { 647 {
651 sec = GNUNET_malloc (sizeof (struct ConfigSection)); 648 sec = GNUNET_malloc (sizeof (struct ConfigSection));
652 sec->name = GNUNET_strdup (section); 649 sec->name = GNUNET_strdup (section);
653 sec->next = cfg->sections; 650 sec->next = cfg->sections;
654 cfg->sections = sec; 651 cfg->sections = sec;
655 } 652 }
656 e = GNUNET_malloc (sizeof (struct ConfigEntry)); 653 e = GNUNET_malloc (sizeof (struct ConfigEntry));
657 e->key = GNUNET_strdup (option); 654 e->key = GNUNET_strdup (option);
658 e->val = GNUNET_strdup (value); 655 e->val = GNUNET_strdup (value);
@@ -676,6 +673,7 @@ GNUNET_CONFIGURATION_set_value_number (struct GNUNET_CONFIGURATION_Handle
676 unsigned long long number) 673 unsigned long long number)
677{ 674{
678 char s[64]; 675 char s[64];
676
679 GNUNET_snprintf (s, 64, "%llu", number); 677 GNUNET_snprintf (s, 64, "%llu", number);
680 GNUNET_CONFIGURATION_set_value_string (cfg, section, option, s); 678 GNUNET_CONFIGURATION_set_value_string (cfg, section, option, s);
681} 679}
@@ -729,12 +727,12 @@ GNUNET_CONFIGURATION_get_value_time (const struct GNUNET_CONFIGURATION_Handle
729 e = findEntry (cfg, section, option); 727 e = findEntry (cfg, section, option);
730 if (e == NULL) 728 if (e == NULL)
731 return GNUNET_SYSERR; 729 return GNUNET_SYSERR;
732 if ( (0 == strcasecmp (e->val, "infinity")) || 730 if ((0 == strcasecmp (e->val, "infinity")) ||
733 (0 == strcasecmp (e->val, "forever")) ) 731 (0 == strcasecmp (e->val, "forever")))
734 { 732 {
735 *time = GNUNET_TIME_UNIT_FOREVER_REL; 733 *time = GNUNET_TIME_UNIT_FOREVER_REL;
736 return GNUNET_OK; 734 return GNUNET_OK;
737 } 735 }
738 if (1 != SSCANF (e->val, "%llu", &num)) 736 if (1 != SSCANF (e->val, "%llu", &num))
739 return GNUNET_SYSERR; 737 return GNUNET_SYSERR;
740 time->rel_value = (uint64_t) num; 738 time->rel_value = (uint64_t) num;
@@ -762,10 +760,10 @@ GNUNET_CONFIGURATION_get_value_string (const struct
762 760
763 e = findEntry (cfg, section, option); 761 e = findEntry (cfg, section, option);
764 if ((e == NULL) || (e->val == NULL)) 762 if ((e == NULL) || (e->val == NULL))
765 { 763 {
766 *value = NULL; 764 *value = NULL;
767 return GNUNET_SYSERR; 765 return GNUNET_SYSERR;
768 } 766 }
769 *value = GNUNET_strdup (e->val); 767 *value = GNUNET_strdup (e->val);
770 return GNUNET_OK; 768 return GNUNET_OK;
771} 769}
@@ -788,8 +786,7 @@ GNUNET_CONFIGURATION_get_value_choice (const struct
788 GNUNET_CONFIGURATION_Handle *cfg, 786 GNUNET_CONFIGURATION_Handle *cfg,
789 const char *section, 787 const char *section,
790 const char *option, 788 const char *option,
791 const char **choices, 789 const char **choices, const char **value)
792 const char **value)
793{ 790{
794 struct ConfigEntry *e; 791 struct ConfigEntry *e;
795 int i; 792 int i;
@@ -799,19 +796,19 @@ GNUNET_CONFIGURATION_get_value_choice (const struct
799 return GNUNET_SYSERR; 796 return GNUNET_SYSERR;
800 i = 0; 797 i = 0;
801 while (choices[i] != NULL) 798 while (choices[i] != NULL)
802 { 799 {
803 if (0 == strcasecmp (choices[i], e->val)) 800 if (0 == strcasecmp (choices[i], e->val))
804 break; 801 break;
805 i++; 802 i++;
806 } 803 }
807 if (choices[i] == NULL) 804 if (choices[i] == NULL)
808 { 805 {
809 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 806 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
810 _("Configuration value '%s' for '%s'" 807 _("Configuration value '%s' for '%s'"
811 " in section '%s' is not in set of legal choices\n"), 808 " in section '%s' is not in set of legal choices\n"),
812 e->val, option, section); 809 e->val, option, section);
813 return GNUNET_SYSERR; 810 return GNUNET_SYSERR;
814 } 811 }
815 *value = choices[i]; 812 *value = choices[i];
816 return GNUNET_OK; 813 return GNUNET_OK;
817} 814}
@@ -826,10 +823,10 @@ GNUNET_CONFIGURATION_get_value_choice (const struct
826 */ 823 */
827int 824int
828GNUNET_CONFIGURATION_have_value (const struct GNUNET_CONFIGURATION_Handle 825GNUNET_CONFIGURATION_have_value (const struct GNUNET_CONFIGURATION_Handle
829 *cfg, const char *section, 826 *cfg, const char *section, const char *option)
830 const char *option)
831{ 827{
832 struct ConfigEntry *e; 828 struct ConfigEntry *e;
829
833 if ((NULL == (e = findEntry (cfg, section, option))) || (e->val == NULL)) 830 if ((NULL == (e = findEntry (cfg, section, option))) || (e->val == NULL))
834 return GNUNET_NO; 831 return GNUNET_NO;
835 return GNUNET_YES; 832 return GNUNET_YES;
@@ -861,25 +858,25 @@ GNUNET_CONFIGURATION_expand_dollar (const struct GNUNET_CONFIGURATION_Handle
861 while ((orig[i] != '/') && (orig[i] != '\\') && (orig[i] != '\0')) 858 while ((orig[i] != '/') && (orig[i] != '\\') && (orig[i] != '\0'))
862 i++; 859 i++;
863 if (orig[i] == '\0') 860 if (orig[i] == '\0')
864 { 861 {
865 post = ""; 862 post = "";
866 } 863 }
867 else 864 else
868 { 865 {
869 orig[i] = '\0'; 866 orig[i] = '\0';
870 post = &orig[i + 1]; 867 post = &orig[i + 1];
871 } 868 }
872 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, 869 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg,
873 "PATHS", 870 "PATHS",
874 &orig[1], &prefix)) 871 &orig[1], &prefix))
872 {
873 if (NULL == (env = getenv (&orig[1])))
875 { 874 {
876 if (NULL == (env = getenv (&orig[1]))) 875 orig[i] = DIR_SEPARATOR;
877 { 876 return orig;
878 orig[i] = DIR_SEPARATOR;
879 return orig;
880 }
881 prefix = GNUNET_strdup (env);
882 } 877 }
878 prefix = GNUNET_strdup (env);
879 }
883 result = GNUNET_malloc (strlen (prefix) + strlen (post) + 2); 880 result = GNUNET_malloc (strlen (prefix) + strlen (post) + 2);
884 strcpy (result, prefix); 881 strcpy (result, prefix);
885 if ((strlen (prefix) == 0) || 882 if ((strlen (prefix) == 0) ||
@@ -912,10 +909,10 @@ GNUNET_CONFIGURATION_get_value_filename (const struct
912 909
913 if (GNUNET_OK != 910 if (GNUNET_OK !=
914 GNUNET_CONFIGURATION_get_value_string (cfg, section, option, &tmp)) 911 GNUNET_CONFIGURATION_get_value_string (cfg, section, option, &tmp))
915 { 912 {
916 *value = NULL; 913 *value = NULL;
917 return GNUNET_SYSERR; 914 return GNUNET_SYSERR;
918 } 915 }
919 tmp = GNUNET_CONFIGURATION_expand_dollar (cfg, tmp); 916 tmp = GNUNET_CONFIGURATION_expand_dollar (cfg, tmp);
920 *value = GNUNET_STRINGS_filename_expand (tmp); 917 *value = GNUNET_STRINGS_filename_expand (tmp);
921 GNUNET_free (tmp); 918 GNUNET_free (tmp);
@@ -984,46 +981,46 @@ GNUNET_CONFIGURATION_iterate_value_filenames (const struct
984 ret = 0; 981 ret = 0;
985 pos = list; 982 pos = list;
986 while (1) 983 while (1)
984 {
985 while (pos[0] == ' ')
986 pos++;
987 if (strlen (pos) == 0)
988 break;
989 end = pos + 1;
990 while ((end[0] != ' ') && (end[0] != '\0'))
987 { 991 {
988 while (pos[0] == ' ') 992 if (end[0] == '\\')
989 pos++; 993 {
990 if (strlen (pos) == 0) 994 switch (end[1])
991 break;
992 end = pos + 1;
993 while ((end[0] != ' ') && (end[0] != '\0'))
994 { 995 {
995 if (end[0] == '\\') 996 case '\\':
996 { 997 case ' ':
997 switch (end[1]) 998 memmove (end, &end[1], strlen (&end[1]) + 1);
998 { 999 case '\0':
999 case '\\': 1000 /* illegal, but just keep it */
1000 case ' ': 1001 break;
1001 memmove (end, &end[1], strlen (&end[1]) + 1); 1002 default:
1002 case '\0': 1003 /* illegal, but just ignore that there was a '/' */
1003 /* illegal, but just keep it */ 1004 break;
1004 break;
1005 default:
1006 /* illegal, but just ignore that there was a '/' */
1007 break;
1008 }
1009 }
1010 end++;
1011 }
1012 old = end[0];
1013 end[0] = '\0';
1014 if (strlen (pos) > 0)
1015 {
1016 ret++;
1017 if ((cb != NULL) && (GNUNET_OK != cb (cb_cls, pos)))
1018 {
1019 ret = GNUNET_SYSERR;
1020 break;
1021 }
1022 } 1005 }
1023 if (old == '\0') 1006 }
1007 end++;
1008 }
1009 old = end[0];
1010 end[0] = '\0';
1011 if (strlen (pos) > 0)
1012 {
1013 ret++;
1014 if ((cb != NULL) && (GNUNET_OK != cb (cb_cls, pos)))
1015 {
1016 ret = GNUNET_SYSERR;
1024 break; 1017 break;
1025 pos = end + 1; 1018 }
1026 } 1019 }
1020 if (old == '\0')
1021 break;
1022 pos = end + 1;
1023 }
1027 GNUNET_free (list); 1024 GNUNET_free (list);
1028 return ret; 1025 return ret;
1029} 1026}
@@ -1047,21 +1044,21 @@ escape_name (const char *value)
1047 rpos = value; 1044 rpos = value;
1048 wpos = escaped; 1045 wpos = escaped;
1049 while (rpos[0] != '\0') 1046 while (rpos[0] != '\0')
1047 {
1048 switch (rpos[0])
1050 { 1049 {
1051 switch (rpos[0]) 1050 case '\\':
1052 { 1051 case ' ':
1053 case '\\': 1052 wpos[0] = '\\';
1054 case ' ': 1053 wpos[1] = rpos[0];
1055 wpos[0] = '\\'; 1054 wpos += 2;
1056 wpos[1] = rpos[0]; 1055 break;
1057 wpos += 2; 1056 default:
1058 break; 1057 wpos[0] = rpos[0];
1059 default: 1058 wpos++;
1060 wpos[0] = rpos[0];
1061 wpos++;
1062 }
1063 rpos++;
1064 } 1059 }
1060 rpos++;
1061 }
1065 return escaped; 1062 return escaped;
1066} 1063}
1067 1064
@@ -1077,6 +1074,7 @@ static int
1077test_match (void *cls, const char *fn) 1074test_match (void *cls, const char *fn)
1078{ 1075{
1079 const char *of = cls; 1076 const char *of = cls;
1077
1080 return (0 == strcmp (of, fn)) ? GNUNET_SYSERR : GNUNET_OK; 1078 return (0 == strcmp (of, fn)) ? GNUNET_SYSERR : GNUNET_OK;
1081} 1079}
1082 1080
@@ -1159,56 +1157,55 @@ GNUNET_CONFIGURATION_remove_value_filename (struct GNUNET_CONFIGURATION_Handle
1159 match = escape_name (value); 1157 match = escape_name (value);
1160 pos = list; 1158 pos = list;
1161 while (1) 1159 while (1)
1160 {
1161 while (pos[0] == ' ')
1162 pos++;
1163 if (strlen (pos) == 0)
1164 break;
1165 end = pos + 1;
1166 while ((end[0] != ' ') && (end[0] != '\0'))
1162 { 1167 {
1163 while (pos[0] == ' ') 1168 if (end[0] == '\\')
1164 pos++; 1169 {
1165 if (strlen (pos) == 0) 1170 switch (end[1])
1166 break;
1167 end = pos + 1;
1168 while ((end[0] != ' ') && (end[0] != '\0'))
1169 { 1171 {
1170 if (end[0] == '\\') 1172 case '\\':
1171 { 1173 case ' ':
1172 switch (end[1])
1173 {
1174 case '\\':
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++; 1174 end++;
1175 break;
1176 case '\0':
1177 /* illegal, but just keep it */
1178 break;
1179 default:
1180 /* illegal, but just ignore that there was a '/' */
1181 break;
1187 } 1182 }
1188 old = end[0]; 1183 }
1189 end[0] = '\0'; 1184 end++;
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,
1202 section, option, list);
1203 GNUNET_free (list);
1204 GNUNET_free (match);
1205 return GNUNET_OK;
1206 }
1207 if (old == '\0')
1208 break;
1209 end[0] = old;
1210 pos = end + 1;
1211 } 1185 }
1186 old = end[0];
1187 end[0] = '\0';
1188 if (0 == strcmp (pos, match))
1189 {
1190 if (old != '\0')
1191 memmove (pos, &end[1], strlen (&end[1]) + 1);
1192 else
1193 {
1194 if (pos != list)
1195 pos[-1] = '\0';
1196 else
1197 pos[0] = '\0';
1198 }
1199 GNUNET_CONFIGURATION_set_value_string (cfg, section, option, list);
1200 GNUNET_free (list);
1201 GNUNET_free (match);
1202 return GNUNET_OK;
1203 }
1204 if (old == '\0')
1205 break;
1206 end[0] = old;
1207 pos = end + 1;
1208 }
1212 GNUNET_free (list); 1209 GNUNET_free (list);
1213 GNUNET_free (match); 1210 GNUNET_free (match);
1214 return GNUNET_NO; 1211 return GNUNET_NO;
@@ -1241,19 +1238,17 @@ GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg,
1241 GNUNET_CONFIGURATION_parse (cfg, baseconfig)) || 1238 GNUNET_CONFIGURATION_parse (cfg, baseconfig)) ||
1242 (!((filename == NULL) || 1239 (!((filename == NULL) ||
1243 (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, filename))))) 1240 (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, filename)))))
1244 { 1241 {
1245 GNUNET_free (baseconfig); 1242 GNUNET_free (baseconfig);
1246 return (filename == NULL) ? GNUNET_OK : GNUNET_SYSERR; 1243 return (filename == NULL) ? GNUNET_OK : GNUNET_SYSERR;
1247 } 1244 }
1248 GNUNET_free (baseconfig); 1245 GNUNET_free (baseconfig);
1249 if ( ((GNUNET_YES != GNUNET_CONFIGURATION_have_value (cfg, 1246 if (((GNUNET_YES != GNUNET_CONFIGURATION_have_value (cfg,
1250 "PATHS", 1247 "PATHS",
1251 "DEFAULTCONFIG"))) && 1248 "DEFAULTCONFIG"))) &&
1252 (filename != NULL) ) 1249 (filename != NULL))
1253 GNUNET_CONFIGURATION_set_value_string (cfg, 1250 GNUNET_CONFIGURATION_set_value_string (cfg,
1254 "PATHS", 1251 "PATHS", "DEFAULTCONFIG", filename);
1255 "DEFAULTCONFIG",
1256 filename);
1257 if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value (cfg, 1252 if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value (cfg,
1258 "TESTING", 1253 "TESTING",
1259 "WEAKRANDOM")) && 1254 "WEAKRANDOM")) &&