GNUnet debian-0.24.3-28-g4f2a77692
 
Loading...
Searching...
No Matches
configuration.c File Reference
#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_configuration_lib.h"
Include dependency graph for configuration.c:

Go to the source code of this file.

Data Structures

struct  ConfigEntry
 configuration entry More...
 
struct  ConfigSection
 configuration section More...
 
struct  ConfigFile
 
struct  GNUNET_CONFIGURATION_Handle
 configuration data More...
 
struct  DiffHandle
 Used for diffing a configuration object against the default one. More...
 
struct  CollectFilesContext
 Closure to collect_files_cb. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "util", __VA_ARGS__)
 
#define LOG_STRERROR_FILE(kind, syscall, filename)    GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
 

Functions

void GNUNET_CONFIGURATION_enable_diagnostics (struct GNUNET_CONFIGURATION_Handle *cfg)
 Enable extra diagnostics.
 
struct GNUNET_CONFIGURATION_HandleGNUNET_CONFIGURATION_create (const struct GNUNET_OS_ProjectData *pd)
 Create a new configuration object.
 
void GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg)
 Destroy configuration object.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_parse_and_run (const struct GNUNET_OS_ProjectData *pd, const char *filename, GNUNET_CONFIGURATION_Callback cb, void *cb_cls)
 Parse a configuration file filename and run the function cb with the resulting configuration object.
 
static enum GNUNET_GenericReturnValue collect_files_cb (void *cls, const char *filename)
 Function called with a filename.
 
static struct ConfigSectionfind_section (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section)
 Find a section entry from a configuration.
 
static int pstrcmp (const void *a, const void *b)
 
static enum GNUNET_GenericReturnValue handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, const char *path_or_glob, bool path_is_glob, const char *restrict_section, const char *source_filename, unsigned int source_lineno)
 Handle an inline directive.
 
static struct ConfigEntryfind_entry (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *key)
 Find an entry from a configuration.
 
static void set_entry_hint (struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *hint_filename, unsigned int hint_line)
 Set a configuration hint.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, const char *mem, size_t size, const char *source_filename)
 De-serializes configuration.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
 Parse a configuration file, add all of the options in the file to the configuration environment.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_is_dirty (const struct GNUNET_CONFIGURATION_Handle *cfg)
 Test if there are configuration options that were changed since the last save.
 
static bool do_skip (const char *sec, const char *key)
 Should we skip this configuration entry when serializing?
 
char * GNUNET_CONFIGURATION_serialize (const struct GNUNET_CONFIGURATION_Handle *cfg, size_t *size)
 Serializes the given configuration.
 
static void dump_os_ipk (const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_Buffer *buf, enum GNUNET_OS_InstallationPathKind ipk)
 Dump an os installation path to a buffer.
 
char * GNUNET_CONFIGURATION_serialize_diagnostics (const struct GNUNET_CONFIGURATION_Handle *cfg)
 Serializes the given configuration with diagnostics information.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
 Write configuration file.
 
void GNUNET_CONFIGURATION_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CONFIGURATION_Iterator iter, void *iter_cls)
 Iterate over all options in the configuration.
 
void GNUNET_CONFIGURATION_iterate_section_values (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, GNUNET_CONFIGURATION_Iterator iter, void *iter_cls)
 Iterate over values of a section in the configuration.
 
void GNUNET_CONFIGURATION_iterate_sections (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CONFIGURATION_SectionIterator iter, void *iter_cls)
 Iterate over all sections in the configuration.
 
void GNUNET_CONFIGURATION_remove_section (struct GNUNET_CONFIGURATION_Handle *cfg, const char *section)
 Remove the given section and all options in it.
 
static void copy_entry (void *cls, const char *section, const char *option, const char *value)
 Copy a configuration value to the given target configuration.
 
struct GNUNET_CONFIGURATION_HandleGNUNET_CONFIGURATION_dup (const struct GNUNET_CONFIGURATION_Handle *cfg)
 Duplicate an existing configuration object.
 
static void compare_entries (void *cls, const char *section, const char *option, const char *value)
 A callback function, compares entries from two configurations (default against a new configuration) and write the diffs in a diff-configuration object (the callback object).
 
struct GNUNET_CONFIGURATION_HandleGNUNET_CONFIGURATION_get_diff (const struct GNUNET_CONFIGURATION_Handle *cfg_default, const struct GNUNET_CONFIGURATION_Handle *cfg_new)
 Compute configuration with only entries that have been changed.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_write_diffs (const struct GNUNET_CONFIGURATION_Handle *cfg_default, const struct GNUNET_CONFIGURATION_Handle *cfg_new, const char *filename)
 Write only configuration entries that have been changed to configuration file.
 
void GNUNET_CONFIGURATION_set_value_string (struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *value)
 Set a configuration value that should be a string.
 
void GNUNET_CONFIGURATION_set_value_number (struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long number)
 Set a configuration value that should be a number.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
 Get a configuration value that should be a number.
 
void GNUNET_CONFIGURATION_set_value_float (struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, float number)
 Set a configuration value that should be a float.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_float (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, float *number)
 Get a configuration value that should be a floating point number.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
 Get a configuration value that should be a relative time.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_size (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *size)
 Get a configuration value that should be a size in bytes.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
 Get a configuration value that should be a string.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_choice (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *const *choices, const char **value)
 Get a configuration value that should be in a set of predefined strings.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_data (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, void *buf, size_t buf_size)
 Get Crockford32-encoded fixed-size binary data from a configuration.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_have_value (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
 Test if we have a value for a particular option.
 
static char * expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg, char *orig, unsigned int depth)
 Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR" where either in the "PATHS" section or the environment "FOO" is set to "DIRECTORY".
 
char * GNUNET_CONFIGURATION_expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg, char *orig)
 Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR" where either in the "PATHS" section or the environment "FOO" is set to "DIRECTORY".
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
 Get a configuration value that should be the name of a file or directory.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
 Get a configuration value that should be in a set of "YES" or "NO".
 
int GNUNET_CONFIGURATION_iterate_value_filenames (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, GNUNET_FileNameCallback cb, void *cb_cls)
 Iterate over the set of filenames stored in a configuration value.
 
static char * escape_name (const char *value)
 FIXME.
 
static enum GNUNET_GenericReturnValue test_match (void *cls, const char *fn)
 FIXME.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_append_value_filename (struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *value)
 Append a filename to a configuration value that represents a list of filenames.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_remove_value_filename (struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *value)
 Remove a filename from a configuration value that represents a list of filenames.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_load_from (struct GNUNET_CONFIGURATION_Handle *cfg, const char *defaults_d)
 Load default configuration.
 
char * GNUNET_CONFIGURATION_default_filename (const struct GNUNET_OS_ProjectData *pd)
 Return the filename of the default configuration filename that is used when no explicit configuration entry point has been specified.
 
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
 Load configuration.
 
static void print_filename_option (void *cls, const char *section, const char *option, const char *value)
 Print each option in a given section as a filename.
 
static void print_option (void *cls, const char *section, const char *option, const char *value)
 Print each option in a given section.
 
static void print_section_name (void *cls, const char *section)
 Print out given section name.
 
void GNUNET_CONFIGURATION_config_tool_run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
 Main task to run to perform operations typical for gnunet-config as per the configuration settings given in cls.
 
void GNUNET_CONFIGURATION_config_settings_free (struct GNUNET_CONFIGURATION_ConfigSettings *cs)
 Free resources associated with cs.
 
const struct GNUNET_OS_ProjectDataGNUNET_CONFIGURATION_get_project_data (const struct GNUNET_CONFIGURATION_Handle *cfg)
 Return the project data associated with this configuration.
 

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "util", __VA_ARGS__)

Definition at line 30 of file configuration.c.

◆ LOG_STRERROR_FILE

#define LOG_STRERROR_FILE (   kind,
  syscall,
  filename 
)     GNUNET_log_from_strerror_file (kind, "util", syscall, filename)

Definition at line 32 of file configuration.c.

38{
42 struct ConfigEntry *next;
43
47 char *key;
48
52 char *val;
53
57 char *hint_filename;
58
62 unsigned int hint_lineno;
63};
64
65
69struct ConfigSection
70{
74 struct ConfigSection *next;
75
79 struct ConfigEntry *entries;
80
84 char *name;
85
92 bool inaccessible;
93
98
102 char *hint_secret_stat;
103
108
112 unsigned int hint_inlined_from_line;
113};
114
115struct ConfigFile
116{
120 char *source_filename;
121
125 unsigned int level;
126
127 struct ConfigFile *prev;
128
129 struct ConfigFile *next;
130
136
141};
142
143
148{
152 struct ConfigSection *sections;
153
158
163
167 const struct GNUNET_OS_ProjectData *pd;
168
172 unsigned int current_nest_level;
173
177 bool diagnostics;
178
185
189 bool load_called;
190
194 char *main_filename;
195
201 const char *restrict_section;
202};
203
204
209struct DiffHandle
210{
212
214};
215
216
217void
220{
221 cfg->diagnostics = true;
222}
223
224
227{
229 char *p;
230
232 cfg->pd = pd;
233 /* make certain values from the project data available
234 as PATHS */
237 if (NULL != p)
238 {
240 "PATHS",
241 "DATADIR",
242 p);
243 GNUNET_free (p);
244 }
247 if (NULL != p)
248 {
250 "PATHS",
251 "LIBDIR",
252 p);
253 GNUNET_free (p);
254 }
257 if (NULL != p)
258 {
260 "PATHS",
261 "BINDIR",
262 p);
263 GNUNET_free (p);
264 }
267 if (NULL != p)
268 {
270 "PATHS",
271 "PREFIX",
272 p);
273 GNUNET_free (p);
274 }
277 if (NULL != p)
278 {
280 "PATHS",
281 "LOCALEDIR",
282 p);
283 GNUNET_free (p);
284 }
287 if (NULL != p)
288 {
290 "PATHS",
291 "ICONDIR",
292 p);
293 GNUNET_free (p);
294 }
297 if (NULL != p)
298 {
300 "PATHS",
301 "DOCDIR",
302 p);
303 GNUNET_free (p);
304 }
307 if (NULL != p)
308 {
310 "PATHS",
311 "LIBEXECDIR",
312 p);
313 GNUNET_free (p);
314 }
315 return cfg;
316}
317
318
319void
321{
322 struct ConfigSection *sec;
323 struct ConfigFile *cf;
324
325 while (NULL != (sec = cfg->sections))
327 while (NULL != (cf = cfg->loaded_files_head))
328 {
333 cf);
334 GNUNET_free (cf);
335 }
338}
339
340
343 const char *filename,
345 void *cb_cls)
346{
349
351 if (GNUNET_OK !=
353 filename))
354 {
355 GNUNET_break (0);
357 return GNUNET_SYSERR;
358 }
359 ret = cb (cb_cls,
360 cfg);
362 return ret;
363}
364
365
370{
374 char **files;
375
379 unsigned int files_length;
380};
381
382
393collect_files_cb (void *cls,
394 const char *filename)
395{
396 struct CollectFilesContext *igc = cls;
397
399 igc->files_length,
401 return GNUNET_OK;
402}
403
404
412static struct ConfigSection *
414 const char *section)
415{
416 struct ConfigSection *pos;
417
418 if (NULL == cfg)
419 return NULL;
420 pos = cfg->sections;
421 while ( (NULL != pos) &&
422 (0 != strcasecmp (section,
423 pos->name)) )
424 pos = pos->next;
425 return pos;
426}
427
428
429static int
430pstrcmp (const void *a,
431 const void *b)
432{
433 return strcmp (*((const char **) a),
434 *((const char **) b));
435}
436
437
445 const char *path_or_glob,
446 bool path_is_glob,
447 const char *restrict_section,
448 const char *source_filename,
449 unsigned int source_lineno)
450{
451 char *inline_path = NULL;
452 struct GNUNET_CONFIGURATION_Handle *other_cfg = NULL;
453 struct CollectFilesContext igc = {
454 .files = NULL,
455 .files_length = 0,
456 };
457 enum GNUNET_GenericReturnValue fun_ret;
458 unsigned int old_nest_level = cfg->current_nest_level++;
459
460 /* We support the section restriction only for non-globs */
461 GNUNET_assert (! (path_is_glob && (NULL != restrict_section)));
462
463 if (NULL == source_filename)
464 {
466 "Refusing to parse inline configurations, "
467 "not allowed without source filename!\n");
468 fun_ret = GNUNET_SYSERR;
469 goto cleanup;
470 }
471
472 if ('/' == *path_or_glob)
473 inline_path = GNUNET_strdup (path_or_glob);
474 else
475 {
476 /* We compute the canonical, absolute path first,
477 so that relative imports resolve properly with symlinked
478 config files. */
479 char *source_realpath;
480 char *endsep;
481
482 source_realpath = realpath (source_filename,
483 NULL);
484 if (NULL == source_realpath)
485 {
486 /* Couldn't even resolve path of base dir. */
487 GNUNET_break (0);
488 /* failed to parse included config */
489 fun_ret = GNUNET_SYSERR;
490 goto cleanup;
491 }
492 endsep = strrchr (source_realpath, '/');
493 GNUNET_assert (NULL != endsep);
494 *endsep = '\0';
495 GNUNET_asprintf (&inline_path,
496 "%s/%s",
497 source_realpath,
498 path_or_glob);
499 free (source_realpath);
500 }
501
502 if (path_is_glob)
503 {
504 int nret;
505
507 "processing config glob '%s'\n",
508 inline_path);
509
510 nret = GNUNET_DISK_glob (inline_path,
512 &igc);
513 if (-1 == nret)
514 {
515 fun_ret = GNUNET_SYSERR;
516 goto cleanup;
517 }
518 GNUNET_assert (nret == igc.files_length);
519 qsort (igc.files,
520 igc.files_length,
521 sizeof (char *),
522 &pstrcmp);
523 for (int i = 0; i < nret; i++)
524 {
525 if (GNUNET_OK !=
527 igc.files[i]))
528 {
529 fun_ret = GNUNET_SYSERR;
530 goto cleanup;
531 }
532 }
533 fun_ret = GNUNET_OK;
534 }
535 else if (NULL != restrict_section)
536 {
537 enum GNUNET_GenericReturnValue inner_ret;
538 struct ConfigSection *cs;
539 struct ConfigFile *cf = GNUNET_new (struct ConfigFile);
540
541 inner_ret = GNUNET_DISK_file_test_read (inline_path);
542
543 cs = find_section (cfg, restrict_section);
544
545 if (NULL == cs)
546 {
547 cs = GNUNET_new (struct ConfigSection);
548 cs->name = GNUNET_strdup (restrict_section);
549 cs->next = cfg->sections;
550 cfg->sections = cs;
551 cs->entries = NULL;
552 }
553 if (cfg->diagnostics)
554 {
555 const char *pwname;
556 const char *grname;
557 char *sfn = GNUNET_STRINGS_filename_expand (inline_path);
558 struct stat istat;
559
560 cs->hint_secret_filename = sfn;
561 if (0 == stat (sfn, &istat))
562 {
563 struct passwd *pw = getpwuid (istat.st_uid);
564 struct group *gr = getgrgid (istat.st_gid);
565 pwname = (NULL == pw) ? "<unknown>" : pw->pw_name;
566 grname = (NULL == gr) ? "<unknown>" : gr->gr_name;
567
569 "%s:%s %o",
570 pwname,
571 grname,
572 istat.st_mode);
573 }
574 else
575 {
576 cs->hint_secret_stat = GNUNET_strdup ("<can't stat file>");
577 }
578 if (source_filename)
579 {
580 /* Possible that this secret section has been inlined before */
582 cs->hint_inlined_from_filename = GNUNET_strdup (source_filename);
583 cs->hint_inlined_from_line = source_lineno;
584 }
585 }
586
587 /* Put file in the load list for diagnostics, even if we can't access it. */
588 {
590 cf->source_filename = GNUNET_strdup (inline_path);
591 cf->hint_restrict_section = GNUNET_strdup (restrict_section);
594 cf);
595 }
596
597 if (GNUNET_OK != inner_ret)
598 {
599 cs->inaccessible = true;
600 cf->hint_inaccessible = true;
601 /* File can't be accessed, but that's okay. */
602 fun_ret = GNUNET_OK;
603 goto cleanup;
604 }
605
606 other_cfg = GNUNET_CONFIGURATION_create (cfg->pd);
607 other_cfg->restrict_section = restrict_section;
608 inner_ret = GNUNET_CONFIGURATION_parse (other_cfg,
609 inline_path);
610 if (GNUNET_OK != inner_ret)
611 {
612 cf->hint_inaccessible = true;
613 fun_ret = inner_ret;
614 goto cleanup;
615 }
616
617 cs = find_section (other_cfg,
618 restrict_section);
619 if (NULL == cs)
620 {
622 "Configuration file '%s' loaded with @inline-secret@ "
623 "does not contain section '%s'.\n",
624 inline_path,
625 restrict_section);
626 /* Inlined configuration is accessible but doesn't contain any values.
627 We treat this as if the inlined section was empty, and do not
628 consider it an error. */
629 fun_ret = GNUNET_OK;
630 goto cleanup;
631 }
632 for (struct ConfigEntry *ce = cs->entries;
633 NULL != ce;
634 ce = ce->next)
636 restrict_section,
637 ce->key,
638 ce->val);
639 fun_ret = GNUNET_OK;
640 }
641 else if (GNUNET_OK !=
643 inline_path))
644 {
645 fun_ret = GNUNET_SYSERR;
646 goto cleanup;
647 }
648 else
649 {
650 fun_ret = GNUNET_OK;
651 }
652cleanup:
653 cfg->current_nest_level = old_nest_level;
654 if (NULL != other_cfg)
656 GNUNET_free (inline_path);
657 if (igc.files_length > 0)
658 {
659 for (size_t i = 0; i < igc.files_length; i++)
660 GNUNET_free (igc.files[i]);
662 }
663 return fun_ret;
664}
665
666
675static struct ConfigEntry *
677 const char *section,
678 const char *key)
679{
680 struct ConfigSection *sec;
681 struct ConfigEntry *pos;
682
683 if (NULL == (sec = find_section (cfg, section)))
684 return NULL;
685 if (sec->inaccessible)
686 {
688 "Section '%s' is marked as inaccessible, because the configuration "
689 "file that contains the section can't be read. Attempts to use "
690 "option '%s' will fail.\n",
691 section,
692 key);
693 return NULL;
694 }
695 pos = sec->entries;
696 while ((pos != NULL) && (0 != strcasecmp (key, pos->key)))
697 pos = pos->next;
698 return pos;
699}
700
701
711static void
713 const char *section,
714 const char *option,
715 const char *hint_filename,
716 unsigned int hint_line)
717{
718 struct ConfigEntry *e = find_entry (cfg, section, option);
719 if (! cfg->diagnostics)
720 return;
721 if (! e)
722 return;
724 e->hint_lineno = hint_line;
725}
726
727
730 const char *mem,
731 size_t size,
732 const char *source_filename)
733{
734 size_t line_size;
735 unsigned int nr;
736 size_t r_bytes;
737 size_t to_read;
739 char *section;
740 char *eq;
741 char *tag;
742 char *value;
743 char *line_orig = NULL;
744
745 ret = GNUNET_OK;
746 section = NULL;
747 nr = 0;
748 r_bytes = 0;
749 while (r_bytes < size)
750 {
751 char *pos;
752 char *line;
753 bool emptyline;
754
755 GNUNET_free (line_orig);
756 /* fgets-like behaviour on buffer */
757 to_read = size - r_bytes;
758 pos = memchr (&mem[r_bytes], '\n', to_read);
759 if (NULL == pos)
760 {
761 line_orig = GNUNET_strndup (&mem[r_bytes],
762 line_size = to_read);
763 r_bytes += line_size;
764 }
765 else
766 {
767 line_orig = GNUNET_strndup (&mem[r_bytes],
768 line_size = (pos - &mem[r_bytes]));
769 r_bytes += line_size + 1;
770 }
771 line = line_orig;
772 /* increment line number */
773 nr++;
774 /* tabs and '\r' are whitespace */
775 emptyline = GNUNET_YES;
776 for (size_t i = 0; i < line_size; i++)
777 {
778 if (line[i] == '\t')
779 line[i] = ' ';
780 if (line[i] == '\r')
781 line[i] = ' ';
782 if (' ' != line[i])
783 emptyline = GNUNET_NO;
784 }
785 /* ignore empty lines */
786 if (GNUNET_YES == emptyline)
787 continue;
788
789 /* remove tailing whitespace */
790 for (size_t i = line_size - 1;
791 (i >= 1) && (isspace ((unsigned char) line[i]));
792 i--)
793 line[i] = '\0';
794
795 /* remove leading whitespace */
796 for (; line[0] != '\0' && (isspace ((unsigned char) line[0])); line++)
797 ;
798
799 /* ignore comments */
800 if ( ('#' == line[0]) ||
801 ('%' == line[0]) )
802 continue;
803
804 /* Handle special directives. */
805 if ('@' == line[0])
806 {
807 char *end = strchr (line + 1, '@');
808 char *directive;
809 enum GNUNET_GenericReturnValue directive_ret;
810
811 if (NULL != cfg->restrict_section)
812 {
814 "Illegal directive in line %u (parsing restricted section %s)\n",
815 nr,
818 break;
819 }
820
821 if (NULL == end)
822 {
824 "Bad directive in line %u\n",
825 nr);
827 break;
828 }
829 *end = '\0';
830 directive = line + 1;
831
832 if (0 == strcasecmp (directive,
833 "INLINE"))
834 {
835 const char *path = end + 1;
836
837 /* Skip space before path */
838 for (; isspace (*path); path++)
839 ;
840
841 directive_ret = handle_inline (cfg,
842 path,
843 false,
844 NULL,
845 source_filename,
846 nr);
847 }
848 else if (0 == strcasecmp (directive,
849 "INLINE-MATCHING"))
850 {
851 const char *path = end + 1;
852
853 /* Skip space before path */
854 for (; isspace (*path); path++)
855 ;
856
857 directive_ret = handle_inline (cfg,
858 path,
859 true,
860 NULL,
861 source_filename,
862 nr);
863 }
864 else if (0 == strcasecmp (directive,
865 "INLINE-SECRET"))
866 {
867 char *secname = end + 1;
868 char *secname_end;
869 const char *path;
870
871 /* Skip space before secname */
872 for (; isspace (*secname); secname++)
873 ;
874
875 secname_end = strchr (secname, ' ');
876
877 if (NULL == secname_end)
878 {
880 "Bad inline-secret directive in line %u\n",
881 nr);
883 break;
884 }
885 *secname_end = '\0';
886 path = secname_end + 1;
887
888 /* Skip space before path */
889 for (; isspace (*path); path++)
890 ;
891
892 directive_ret = handle_inline (cfg,
893 path,
894 false,
895 secname,
896 source_filename,
897 nr);
898 }
899 else
900 {
902 "Unknown or malformed directive '%s' in line %u\n",
903 directive,
904 nr);
906 break;
907 }
908 if (GNUNET_OK != directive_ret)
909 {
910 ret = directive_ret;
911 break;
912 }
913 continue;
914 }
915 if ( ('[' == line[0]) &&
916 (']' == line[line_size - 1]) )
917 {
918 /* [value] */
919 line[line_size - 1] = '\0';
920 value = &line[1];
921 GNUNET_free (section);
922 section = GNUNET_strdup (value);
923 continue;
924 }
925 if (NULL != (eq = strchr (line, '=')))
926 {
927
928 if (NULL == section)
929 {
931 "Syntax error while deserializing in line %u (option without section)\n",
932 nr);
934 break;
935 }
936
937 /* tag = value */
938 tag = GNUNET_strndup (line, eq - line);
939 /* remove tailing whitespace */
940 for (int i = strlen (tag) - 1;
941 (i >= 1) && (isspace ((unsigned char) tag[i]));
942 i--)
943 tag[i] = '\0';
944
945 /* Strip whitespace */
946 value = eq + 1;
947 while (isspace ((unsigned char) value[0]))
948 value++;
949 for (int i = strlen (value) - 1;
950 (i >= 1) && (isspace ((unsigned char) value[i]));
951 i--)
952 value[i] = '\0';
953
954 /* remove quotes */
955 if ( ('"' == value[0]) &&
956 ('"' == value[strlen (value) - 1]) )
957 {
958 value[strlen (value) - 1] = '\0';
959 value++;
960 }
962 section,
963 tag,
964 value);
965 if (cfg->diagnostics)
966 {
968 section,
969 tag,
970 source_filename
971 ? source_filename
972 : "<input>",
973 nr);
974 }
975 GNUNET_free (tag);
976 continue;
977 }
978 /* parse error */
980 "Syntax error while deserializing in line %u\n",
981 nr);
983 break;
984 }
985 GNUNET_free (line_orig);
986 GNUNET_free (section);
987 GNUNET_assert ( (GNUNET_OK != ret) ||
988 (r_bytes == size) );
989 return ret;
990}
991
992
995 const char *filename)
996{
997 uint64_t fs64;
998 size_t fs;
999 char *fn;
1000 char *mem;
1001 int dirty;
1003 ssize_t sret;
1004
1007 "Asked to parse config file `%s'\n",
1008 fn);
1009 if (NULL == fn)
1010 return GNUNET_SYSERR;
1011
1012
1013 /* Check for cycles */
1014 {
1015 unsigned int lvl = cfg->current_nest_level;
1016 struct ConfigFile *cf = cfg->loaded_files_tail;
1017 struct ConfigFile *parent = NULL;
1018
1019
1020 for (; NULL != cf; parent = cf, cf = cf->prev)
1021 {
1022 /* Check parents based on level, skipping children of siblings. */
1023 if (cf->level >= lvl)
1024 continue;
1025 lvl = cf->level;
1026 if ( (NULL == cf->source_filename) ||
1027 (NULL == filename) )
1028 continue;
1029 if (0 == strcmp (cf->source_filename,
1030 filename))
1031 {
1032 if (NULL == parent)
1033 {
1035 "Forbidden direct cyclic configuration import (%s -> %s)\n",
1036 cf->source_filename,
1037 filename);
1038 }
1039 else
1041 "Forbidden indirect cyclic configuration import (%s -> ... -> %s -> %s)\n",
1042 cf->source_filename,
1043 parent->source_filename,
1044 filename);
1045 GNUNET_free (fn);
1046 return GNUNET_SYSERR;
1047 }
1048 }
1049
1050 }
1051
1052 /* Keep track of loaded files.*/
1053 {
1054 struct ConfigFile *cf = GNUNET_new (struct ConfigFile);
1055
1057 cf->source_filename = GNUNET_strdup (filename ? filename : "<input>");
1060 cf);
1061 }
1062
1063 dirty = cfg->dirty; /* back up value! */
1064 if (GNUNET_SYSERR ==
1066 &fs64,
1067 GNUNET_NO,
1068 GNUNET_YES))
1069 {
1071 "Error while determining the file size of `%s'\n",
1072 fn);
1073 GNUNET_free (fn);
1074 return GNUNET_SYSERR;
1075 }
1076 if (fs64 > SIZE_MAX)
1077 {
1078 GNUNET_break (0); /* File size is more than the heap size */
1079 GNUNET_free (fn);
1080 return GNUNET_SYSERR;
1081 }
1082 fs = fs64;
1083 mem = GNUNET_malloc (fs);
1084 sret = GNUNET_DISK_fn_read (fn,
1085 mem,
1086 fs);
1087 if ((sret < 0) || (fs != (size_t) sret))
1088 {
1090 "Error while reading file `%s'\n",
1091 fn);
1092 GNUNET_free (fn);
1093 GNUNET_free (mem);
1094 return GNUNET_SYSERR;
1095 }
1097 "Deserializing contents of file `%s'\n",
1098 fn);
1100 mem,
1101 fs,
1102 fn);
1103 if (GNUNET_SYSERR == ret)
1104 {
1106 _ ("Failed to parse configuration file `%s'\n"),
1107 fn);
1108 }
1109 GNUNET_free (fn);
1110 GNUNET_free (mem);
1111 /* restore dirty flag - anything we set in the meantime
1112 * came from disk */
1113 cfg->dirty = dirty;
1114 return ret;
1115}
1116
1117
1120{
1121 return cfg->dirty;
1122}
1123
1124
1132static bool
1133do_skip (const char *sec,
1134 const char *key)
1135{
1136 if (0 != strcasecmp ("PATHS",
1137 sec))
1138 return false;
1139 return ( (0 == strcasecmp ("DATADIR",
1140 key)) ||
1141 (0 == strcasecmp ("LIBDIR",
1142 key)) ||
1143 (0 == strcasecmp ("BINDIR",
1144 key)) ||
1145 (0 == strcasecmp ("PREFIX",
1146 key)) ||
1147 (0 == strcasecmp ("LOCALEDIR",
1148 key)) ||
1149 (0 == strcasecmp ("ICONDIR",
1150 key)) ||
1151 (0 == strcasecmp ("DOCDIR",
1152 key)) ||
1153 (0 == strcasecmp ("DEFAULTCONFIG",
1154 key)) ||
1155 (0 == strcasecmp ("LIBEXECDIR",
1156 key)) );
1157}
1158
1159
1160char *
1162 size_t *size)
1163{
1164 char *mem;
1165 char *cbuf;
1166 char *val;
1167 char *pos;
1168 size_t m_size;
1169 size_t c_size;
1170
1171 /* Pass1 : calculate the buffer size required */
1172 m_size = 0;
1173 for (struct ConfigSection *sec = cfg->sections;
1174 NULL != sec;
1175 sec = sec->next)
1176 {
1177 if (sec->inaccessible)
1178 continue;
1179 /* For each section we need to add 3 characters: {'[',']','\n'} */
1180 m_size += strlen (sec->name) + 3;
1181 for (struct ConfigEntry *ent = sec->entries;
1182 NULL != ent;
1183 ent = ent->next)
1184 {
1185 if (do_skip (sec->name,
1186 ent->key))
1187 continue;
1188 if (NULL != ent->val)
1189 {
1190 /* if val has any '\n' then they occupy +1 character as '\n'->'\\','n' */
1191 pos = ent->val;
1192 while (NULL != (pos = strstr (pos, "\n")))
1193 {
1194 m_size++;
1195 pos++;
1196 }
1197 /* For each key = value pair we need to add 4 characters (2
1198 spaces and 1 equal-to character and 1 new line) */
1199 m_size += strlen (ent->key) + strlen (ent->val) + 4;
1200 }
1201 }
1202 /* A new line after section end */
1203 m_size++;
1204 }
1205
1206 /* Pass2: Allocate memory and write the configuration to it */
1207 mem = GNUNET_malloc (m_size);
1208 c_size = 0;
1209 *size = c_size;
1210 for (struct ConfigSection *sec = cfg->sections;
1211 NULL != sec;
1212 sec = sec->next)
1213 {
1214 int len;
1215
1216 len = GNUNET_asprintf (&cbuf,
1217 "[%s]\n",
1218 sec->name);
1219 GNUNET_assert (0 < len);
1220 GNUNET_memcpy (mem + c_size,
1221 cbuf,
1222 len);
1223 c_size += len;
1224 GNUNET_free (cbuf);
1225 for (struct ConfigEntry *ent = sec->entries;
1226 NULL != ent;
1227 ent = ent->next)
1228 {
1229 if (do_skip (sec->name,
1230 ent->key))
1231 continue;
1232 if (NULL != ent->val)
1233 {
1234 val = GNUNET_malloc (strlen (ent->val) * 2 + 1);
1235 strcpy (val, ent->val);
1236 while (NULL != (pos = strstr (val, "\n")))
1237 {
1238 memmove (&pos[2], &pos[1], strlen (&pos[1]));
1239 pos[0] = '\\';
1240 pos[1] = 'n';
1241 }
1242 len = GNUNET_asprintf (&cbuf, "%s = %s\n", ent->key, val);
1243 GNUNET_free (val);
1244 GNUNET_memcpy (mem + c_size, cbuf, len);
1245 c_size += len;
1246 GNUNET_free (cbuf);
1247 }
1248 }
1249 GNUNET_memcpy (mem + c_size, "\n", 1);
1250 c_size++;
1251 }
1252 GNUNET_assert (c_size == m_size);
1253 *size = c_size;
1254 return mem;
1255}
1256
1257
1266static void
1268 const struct GNUNET_CONFIGURATION_Handle *cfg,
1269 struct GNUNET_Buffer *buf,
1271{
1273 ipk);
1274 const char *ipkname;
1275 switch (ipk)
1276 {
1278 ipkname = "IPK_DATADIR";
1279 break;
1281 ipkname = "IPK_BINDIR";
1282 break;
1284 ipkname = "IPK_LIBDIR";
1285 break;
1287 ipkname = "IPK_PREFIX";
1289 ipkname = "IPK_LOCALEDIR";
1290 break;
1292 ipkname = "IPK_ICONDIR";
1294 ipkname = "IPK_DOCDIR";
1295 break;
1297 ipkname = "IPK_LIBEXECDIR";
1298 break;
1300 ipkname = "IPK_SELF_PREFIX";
1301 break;
1302 default:
1303 ipkname = "??";
1304 break;
1305 }
1307 "# %s = %s\n",
1308 ipkname,
1309 v);
1310 GNUNET_free (v);
1311}
1312
1313
1314char *
1316 const struct GNUNET_CONFIGURATION_Handle *cfg)
1317{
1318 struct GNUNET_Buffer buf = { 0 };
1319
1321 "#\n# Configuration file diagnostics\n#\n");
1323 "# Entry point: %s\n",
1325 "<none>");
1327 "#\n# Files Loaded:\n");
1328
1329 for (struct ConfigFile *cfil = cfg->loaded_files_head;
1330 NULL != cfil;
1331 cfil = cfil->next)
1332 {
1334 "# ");
1335 for (unsigned int i = 0; i < cfil->level; i++)
1337 "+");
1338 if (0 != cfil->level)
1340 " ");
1341
1343 "%s",
1344 cfil->source_filename);
1345
1346 if (NULL != cfil->hint_restrict_section)
1348 " (%s secret section %s)",
1349 cfil->hint_inaccessible
1350 ? "inaccessible"
1351 : "loaded",
1352 cfil->hint_restrict_section);
1353
1355 "\n");
1356 }
1357
1359 "#\n# Installation paths:\n");
1360
1370
1371
1373 "#\n\n");
1374
1375 for (struct ConfigSection *sec = cfg->sections;
1376 NULL != sec;
1377 sec = sec->next)
1378 {
1379 if (sec->hint_secret_filename)
1381 "# secret section from %s\n# secret file stat %s\n",
1382 sec->hint_secret_filename,
1383 sec->hint_secret_stat);
1384 if (sec->hint_inlined_from_filename)
1385 {
1387 "# inlined from %s:%u\n",
1388 sec->hint_inlined_from_filename,
1389 sec->hint_inlined_from_line);
1390 }
1392 "[%s]\n\n",
1393 sec->name);
1394 if (sec->inaccessible)
1395 {
1397 "# <section contents inaccessible>\n\n\n");
1398 continue;
1399 }
1400 for (struct ConfigEntry *ent = sec->entries;
1401 NULL != ent;
1402 ent = ent->next)
1403 {
1404 if (do_skip (sec->name,
1405 ent->key))
1406 continue;
1407 if (NULL != ent->val)
1408 {
1409 char *pos;
1410 char *val = GNUNET_malloc (strlen (ent->val) * 2 + 1);
1411 strcpy (val, ent->val);
1412 while (NULL != (pos = strstr (val, "\n")))
1413 {
1414 memmove (&pos[2], &pos[1], strlen (&pos[1]));
1415 pos[0] = '\\';
1416 pos[1] = 'n';
1417 }
1418 if (NULL != ent->hint_filename)
1419 {
1421 "# %s:%u\n",
1422 ent->hint_filename,
1423 ent->hint_lineno);
1424 }
1426 "%s = %s\n",
1427 ent->key,
1428 val);
1429 GNUNET_free (val);
1430 }
1431 GNUNET_buffer_write_str (&buf, "\n");
1432 }
1433 GNUNET_buffer_write_str (&buf, "\n");
1434 }
1435 return GNUNET_buffer_reap_str (&buf);
1436}
1437
1438
1442 const char *filename)
1443{
1444 char *fn;
1445 char *cfg_buf;
1446 size_t size;
1447
1449 if (fn == NULL)
1450 return GNUNET_SYSERR;
1452 {
1453 GNUNET_free (fn);
1454 return GNUNET_SYSERR;
1455 }
1457 &size);
1458 {
1459 struct GNUNET_DISK_FileHandle *h;
1460
1469 if (NULL == h)
1470 {
1471 GNUNET_free (fn);
1472 GNUNET_free (cfg_buf);
1473 return GNUNET_SYSERR;
1474 }
1475 if (((ssize_t) size) !=
1477 cfg_buf,
1478 size))
1479 {
1481 "write",
1482 fn);
1484 (void) GNUNET_DISK_directory_remove (fn);
1485 GNUNET_free (fn);
1486 GNUNET_free (cfg_buf);
1487 cfg->dirty = GNUNET_SYSERR; /* last write failed */
1488 return GNUNET_SYSERR;
1489 }
1492 }
1493 GNUNET_free (fn);
1494 GNUNET_free (cfg_buf);
1495 cfg->dirty = GNUNET_NO; /* last write succeeded */
1496 return GNUNET_OK;
1497}
1498
1499
1500void
1502 const struct GNUNET_CONFIGURATION_Handle *cfg,
1504 void *iter_cls)
1505{
1506 for (struct ConfigSection *spos = cfg->sections;
1507 NULL != spos;
1508 spos = spos->next)
1509 for (struct ConfigEntry *epos = spos->entries;
1510 NULL != epos;
1511 epos = epos->next)
1512 if (NULL != epos->val)
1513 iter (iter_cls,
1514 spos->name,
1515 epos->key,
1516 epos->val);
1517}
1518
1519
1520void
1522 const struct GNUNET_CONFIGURATION_Handle *cfg,
1523 const char *section,
1525 void *iter_cls)
1526{
1527 struct ConfigSection *spos;
1528
1529 spos = cfg->sections;
1530 while ((spos != NULL) && (0 != strcasecmp (spos->name, section)))
1531 spos = spos->next;
1532 if (NULL == spos)
1533 return;
1534 if (spos->inaccessible)
1535 {
1537 "Section '%s' is marked as inaccessible, because the configuration "
1538 "file that contains the section can't be read.\n",
1539 section);
1540 return;
1541 }
1542 for (struct ConfigEntry *epos = spos->entries;
1543 NULL != epos;
1544 epos = epos->next)
1545 if (NULL != epos->val)
1546 iter (iter_cls,
1547 spos->name,
1548 epos->key,
1549 epos->val);
1550}
1551
1552
1553void
1555 const struct GNUNET_CONFIGURATION_Handle *cfg,
1557 void *iter_cls)
1558{
1559 struct ConfigSection *spos;
1560 struct ConfigSection *next;
1561
1562 next = cfg->sections;
1563 while (next != NULL)
1564 {
1565 spos = next;
1566 next = spos->next;
1567 if (! spos->inaccessible)
1568 iter (iter_cls,
1569 spos->name);
1570 }
1571}
1572
1573
1574void
1576 const char *section)
1577{
1578 struct ConfigSection *spos;
1579 struct ConfigSection *prev;
1580 struct ConfigEntry *ent;
1581
1582 prev = NULL;
1583 spos = cfg->sections;
1584 while (NULL != spos)
1585 {
1586 if (0 == strcasecmp (section,
1587 spos->name))
1588 {
1589 if (NULL == prev)
1590 cfg->sections = spos->next;
1591 else
1592 prev->next = spos->next;
1593 while (NULL != (ent = spos->entries))
1594 {
1595 spos->entries = ent->next;
1596 GNUNET_free (ent->key);
1597 GNUNET_free (ent->val);
1599 GNUNET_free (ent);
1600 cfg->dirty = GNUNET_YES;
1601 }
1602 GNUNET_free (spos->name);
1606 GNUNET_free (spos);
1607 return;
1608 }
1609 prev = spos;
1610 spos = spos->next;
1611 }
1612}
1613
1614
1624static void
1625copy_entry (void *cls,
1626 const char *section,
1627 const char *option,
1628 const char *value)
1629{
1630 struct GNUNET_CONFIGURATION_Handle *dst = cls;
1631
1633 section,
1634 option,
1635 value);
1636}
1637
1638
1641 const struct GNUNET_CONFIGURATION_Handle *cfg)
1642{
1644
1647 &copy_entry,
1648 ret);
1649 return ret;
1650}
1651
1652
1663static void
1664compare_entries (void *cls,
1665 const char *section,
1666 const char *option,
1667 const char *value)
1668{
1669 struct DiffHandle *dh = cls;
1670 struct ConfigEntry *entNew;
1671
1672 entNew = find_entry (dh->cfg_default, section, option);
1673 if ((NULL != entNew) && (NULL != entNew->val) &&
1674 (0 == strcmp (entNew->val, value)))
1675 return;
1677 section,
1678 option,
1679 value);
1680}
1681
1682
1685 const struct GNUNET_CONFIGURATION_Handle *cfg_default,
1686 const struct GNUNET_CONFIGURATION_Handle *cfg_new)
1687{
1688 struct DiffHandle diffHandle;
1689
1690 GNUNET_break (cfg_default->pd == cfg_new->pd);
1691 diffHandle.cfgDiff = GNUNET_CONFIGURATION_create (cfg_new->pd);
1692 diffHandle.cfg_default = cfg_default;
1695 &diffHandle);
1696 return diffHandle.cfgDiff;
1697}
1698
1699
1703 const struct GNUNET_CONFIGURATION_Handle *cfg_new,
1704 const char *filename)
1705{
1706 int ret;
1707 struct GNUNET_CONFIGURATION_Handle *diff;
1708
1709 diff = GNUNET_CONFIGURATION_get_diff (cfg_default, cfg_new);
1712 return ret;
1713}
1714
1715
1716void
1719 const char *section,
1720 const char *option,
1721 const char *value)
1722{
1723 struct ConfigSection *sec;
1724 struct ConfigEntry *e;
1725 char *nv;
1726
1727 e = find_entry (cfg, section, option);
1728 if (NULL != e)
1729 {
1730 if (NULL == value)
1731 {
1732 GNUNET_free (e->val);
1733 e->val = NULL;
1734 }
1735 else
1736 {
1737 nv = GNUNET_strdup (value);
1738 GNUNET_free (e->val);
1739 e->val = nv;
1740 }
1741 return;
1742 }
1743 sec = find_section (cfg, section);
1744 if (sec == NULL)
1745 {
1746 sec = GNUNET_new (struct ConfigSection);
1747 sec->name = GNUNET_strdup (section);
1748 sec->next = cfg->sections;
1749 cfg->sections = sec;
1750 }
1751 e = GNUNET_new (struct ConfigEntry);
1752 e->key = GNUNET_strdup (option);
1753 e->val = GNUNET_strdup (value);
1754 e->next = sec->entries;
1755 sec->entries = e;
1756}
1757
1758
1759void
1761 const char *section,
1762 const char *option,
1763 unsigned long long number)
1764{
1765 char s[64];
1766
1767 GNUNET_snprintf (s,
1768 64,
1769 "%llu",
1770 number);
1772 section,
1773 option,
1774 s);
1775}
1776
1777
1780 const struct GNUNET_CONFIGURATION_Handle *cfg,
1781 const char *section,
1782 const char *option,
1783 unsigned long long *number)
1784{
1785 struct ConfigEntry *e;
1786 char dummy[2];
1787
1788 if (NULL == (e = find_entry (cfg,
1789 section,
1790 option)))
1791 return GNUNET_NO;
1792 if (NULL == e->val)
1793 return GNUNET_NO;
1794 if (1 != sscanf (e->val,
1795 "%llu%1s",
1796 number,
1797 dummy))
1798 return GNUNET_SYSERR;
1799 return GNUNET_OK;
1800}
1801
1802
1803void
1805 const char *section,
1806 const char *option,
1807 float number)
1808{
1809 char s[64];
1810
1811 /* See: #9369 */
1812 const locale_t cl = newlocale (LC_NUMERIC_MASK,
1813 "C",
1814 (locale_t) 0);
1815 locale_t old_locale = uselocale (cl);
1816 GNUNET_snprintf (s,
1817 64,
1818 "%f",
1819 (double) number);
1820 uselocale (old_locale);
1822 section,
1823 option,
1824 s);
1825}
1826
1827
1830 const struct GNUNET_CONFIGURATION_Handle *cfg,
1831 const char *section,
1832 const char *option,
1833 float *number)
1834{
1835 struct ConfigEntry *e;
1836 char dummy[2];
1837
1838 if (NULL == (e = find_entry (cfg,
1839 section,
1840 option)))
1841 return GNUNET_NO;
1842 if (NULL == e->val)
1843 return GNUNET_NO;
1844 /* See #9369 */
1845 {
1846 const locale_t cl = newlocale (LC_NUMERIC_MASK,
1847 "C",
1848 (locale_t) 0);
1849 locale_t old_locale = uselocale (cl);
1850
1851 if (1 != sscanf (e->val,
1852 "%f%1s",
1853 number,
1854 dummy))
1855 return GNUNET_SYSERR;
1856 uselocale (old_locale);
1857 }
1858 return GNUNET_OK;
1859}
1860
1861
1864 const struct GNUNET_CONFIGURATION_Handle *cfg,
1865 const char *section,
1866 const char *option,
1867 struct GNUNET_TIME_Relative *time)
1868{
1869 struct ConfigEntry *e;
1870 int ret;
1871
1872 if (NULL == (e = find_entry (cfg,
1873 section,
1874 option)))
1875 return GNUNET_NO;
1876 if (NULL == e->val)
1877 return GNUNET_NO;
1879 time);
1880 if (GNUNET_OK != ret)
1882 section,
1883 option,
1884 _ ("Not a valid relative time specification"));
1885 return ret;
1886}
1887
1888
1891 const struct GNUNET_CONFIGURATION_Handle *cfg,
1892 const char *section,
1893 const char *option,
1894 unsigned long long *size)
1895{
1896 struct ConfigEntry *e;
1897
1898 if (NULL == (e = find_entry (cfg,
1899 section,
1900 option)))
1901 return GNUNET_NO;
1902 if (NULL == e->val)
1903 return GNUNET_NO;
1905 size);
1906}
1907
1908
1921 const struct GNUNET_CONFIGURATION_Handle *cfg,
1922 const char *section,
1923 const char *option,
1924 char **value)
1925{
1926 struct ConfigEntry *e;
1927
1928 if ( (NULL == (e = find_entry (cfg,
1929 section,
1930 option))) ||
1931 (NULL == e->val) )
1932 {
1933 *value = NULL;
1934 return GNUNET_NO;
1935 }
1936 *value = GNUNET_strdup (e->val);
1937 return GNUNET_OK;
1938}
1939
1940
1943 const struct GNUNET_CONFIGURATION_Handle *cfg,
1944 const char *section,
1945 const char *option,
1946 const char *const *choices,
1947 const char **value)
1948{
1949 struct ConfigEntry *e;
1950 unsigned int i;
1951
1952 if (NULL == (e = find_entry (cfg,
1953 section,
1954 option)))
1955 return GNUNET_NO;
1956 for (i = 0; NULL != choices[i]; i++)
1957 if (0 == strcasecmp (choices[i], e->val))
1958 break;
1959 if (NULL == choices[i])
1960 {
1962 _ ("Configuration value '%s' for '%s'"
1963 " in section '%s' is not in set of legal choices\n"),
1964 e->val,
1965 option,
1966 section);
1967 return GNUNET_SYSERR;
1968 }
1969 *value = choices[i];
1970 return GNUNET_OK;
1971}
1972
1973
1976 const char *section,
1977 const char *option,
1978 void *buf,
1979 size_t buf_size)
1980{
1981 char *enc;
1982 int res;
1983 size_t data_size;
1984
1985 if (GNUNET_OK !=
1986 (res =
1988 section,
1989 option,
1990 &enc)))
1991 return res;
1992 data_size = (strlen (enc) * 5) / 8;
1993 if (data_size != buf_size)
1994 {
1995 GNUNET_free (enc);
1996 return GNUNET_SYSERR;
1997 }
1998 if (GNUNET_OK !=
2000 strlen (enc),
2001 buf,
2002 buf_size))
2003 {
2004 GNUNET_free (enc);
2005 return GNUNET_SYSERR;
2006 }
2007 GNUNET_free (enc);
2008 return GNUNET_OK;
2009}
2010
2011
2014 const char *section,
2015 const char *option)
2016{
2017 struct ConfigEntry *e;
2018
2019 if ( (NULL == (e = find_entry (cfg,
2020 section,
2021 option))) ||
2022 (NULL == e->val) )
2023 return GNUNET_NO;
2024 return GNUNET_YES;
2025}
2026
2027
2043static char *
2045 char *orig,
2046 unsigned int depth)
2047{
2048 char *prefix;
2049 char *result;
2050 char *start;
2051 const char *post;
2052 const char *env;
2053 char *def;
2054 char *end;
2055 unsigned int lopen;
2056 char erased_char;
2057 char *erased_pos;
2058 size_t len;
2059
2060 if (NULL == orig)
2061 return NULL;
2062 if (depth > 128)
2063 {
2065 "Recursive expansion suspected, aborting $-expansion for term `%s'\n",
2066 orig);
2067 return orig;
2068 }
2070 "Asked to $-expand %s\n",
2071 orig);
2072 if ('$' != orig[0])
2073 {
2075 "Doesn't start with $ - not expanding\n");
2076 return orig;
2077 }
2078 erased_char = 0;
2079 erased_pos = NULL;
2080 if ('{' == orig[1])
2081 {
2082 start = &orig[2];
2083 lopen = 1;
2084 end = &orig[1];
2085 while (lopen > 0)
2086 {
2087 end++;
2088 switch (*end)
2089 {
2090 case '}':
2091 lopen--;
2092 break;
2093
2094 case '{':
2095 lopen++;
2096 break;
2097
2098 case '\0':
2100 "Missing closing `}' in option `%s'\n",
2101 orig);
2102 return orig;
2103
2104 default:
2105 break;
2106 }
2107 }
2108 erased_char = *end;
2109 erased_pos = end;
2110 *end = '\0';
2111 post = end + 1;
2112 def = strchr (orig, ':');
2113 if (NULL != def)
2114 {
2115 *def = '\0';
2116 def++;
2117 if (('-' == *def) || ('=' == *def))
2118 def++;
2119 def = GNUNET_strdup (def);
2120 }
2121 }
2122 else
2123 {
2124 int i;
2125
2126 start = &orig[1];
2127 def = NULL;
2128 i = 0;
2129 while ( (orig[i] != '/') &&
2130 (orig[i] != '\\') &&
2131 (orig[i] != '\0') &&
2132 (orig[i] != ' ') )
2133 i++;
2134 if (orig[i] == '\0')
2135 {
2136 post = "";
2137 }
2138 else
2139 {
2140 erased_char = orig[i];
2141 erased_pos = &orig[i];
2142 orig[i] = '\0';
2143 post = &orig[i + 1];
2144 }
2145 }
2147 "Split into `%s' and `%s' with default %s\n",
2148 start,
2149 post,
2150 def);
2151 if (GNUNET_OK !=
2153 "PATHS",
2154 start,
2155 &prefix))
2156 {
2157 if (NULL == (env = getenv (start)))
2158 {
2159 /* try default */
2160 def = expand_dollar (cfg,
2161 def,
2162 depth + 1);
2163 env = def;
2164 }
2165 if (NULL == env)
2166 {
2168 if (erased_pos)
2169 *erased_pos = erased_char;
2171 "Failed to expand `%s' in `%s' as it is neither found in [PATHS] nor defined as an environmental variable\n",
2172 start,
2173 orig);
2175 return orig;
2176 }
2178 }
2180 prefix);
2181 if ((erased_pos) && ('}' != erased_char))
2182 {
2183 len = strlen (prefix) + 1;
2184 prefix = GNUNET_realloc (prefix, len + 1);
2185 prefix[len - 1] = erased_char;
2186 prefix[len] = '\0';
2187 }
2188 result = GNUNET_malloc (strlen (prefix) + strlen (post) + 1);
2189 strcpy (result, prefix);
2190 strcat (result, post);
2191 GNUNET_free (def);
2193 GNUNET_free (orig);
2194 return result;
2195}
2196
2197
2198char *
2200 const struct GNUNET_CONFIGURATION_Handle *cfg,
2201 char *orig)
2202{
2203 char *dup;
2204 size_t i;
2205 size_t len;
2206
2207 for (i = 0; '\0' != orig[i]; i++)
2208 {
2209 if ('$' != orig[i])
2210 continue;
2211 dup = GNUNET_strdup (orig + i);
2212 dup = expand_dollar (cfg, dup, 0);
2213 GNUNET_assert (NULL != dup); /* make compiler happy */
2214 len = strlen (dup) + 1;
2215 orig = GNUNET_realloc (orig, i + len);
2216 GNUNET_memcpy (orig + i, dup, len);
2217 GNUNET_free (dup);
2218 }
2219 return orig;
2220}
2221
2222
2225 const struct GNUNET_CONFIGURATION_Handle *cfg,
2226 const char *section,
2227 const char *option,
2228 char **value)
2229{
2230 char *tmp;
2232
2234 section,
2235 option,
2236 &tmp);
2237 if (GNUNET_OK != ret)
2238 {
2240 "Failed to retrieve filename\n");
2241 *value = NULL;
2242 return ret;
2243 }
2245 tmp);
2247 GNUNET_free (tmp);
2248 if (*value == NULL)
2249 return GNUNET_SYSERR;
2250 return GNUNET_OK;
2251}
2252
2253
2256 const struct GNUNET_CONFIGURATION_Handle *cfg,
2257 const char *section,
2258 const char *option)
2259{
2260 static const char *yesno[] = {
2261 "YES",
2262 "NO",
2263 NULL
2264 };
2265 const char *val;
2267
2268 ret =
2270 section,
2271 option,
2272 yesno,
2273 &val);
2274 if (GNUNET_OK != ret)
2275 return ret;
2276 if (val == yesno[0])
2277 return GNUNET_YES;
2278 return GNUNET_NO;
2279}
2280
2281
2282int
2284 const struct GNUNET_CONFIGURATION_Handle *cfg,
2285 const char *section,
2286 const char *option,
2288 void *cb_cls)
2289{
2290 char *list;
2291 char *pos;
2292 char *end;
2293 char old;
2294 int ret;
2295
2296 if (GNUNET_OK !=
2298 section,
2299 option,
2300 &list))
2301 return 0;
2302 GNUNET_assert (list != NULL);
2303 ret = 0;
2304 pos = list;
2305 while (1)
2306 {
2307 while (pos[0] == ' ')
2308 pos++;
2309 if (strlen (pos) == 0)
2310 break;
2311 end = pos + 1;
2312 while ((end[0] != ' ') && (end[0] != '\0'))
2313 {
2314 if (end[0] == '\\')
2315 {
2316 switch (end[1])
2317 {
2318 case '\\':
2319 case ' ':
2320 memmove (end, &end[1], strlen (&end[1]) + 1);
2321
2322 case '\0':
2323 /* illegal, but just keep it */
2324 break;
2325
2326 default:
2327 /* illegal, but just ignore that there was a '/' */
2328 break;
2329 }
2330 }
2331 end++;
2332 }
2333 old = end[0];
2334 end[0] = '\0';
2335 if (strlen (pos) > 0)
2336 {
2337 ret++;
2338 if ( (NULL != cb) &&
2339 (GNUNET_OK != cb (cb_cls,
2340 pos)))
2341 {
2343 break;
2344 }
2345 }
2346 if (old == '\0')
2347 break;
2348 pos = end + 1;
2349 }
2350 GNUNET_free (list);
2351 return ret;
2352}
2353
2354
2361static char *
2362escape_name (const char *value)
2363{
2364 char *escaped;
2365 const char *rpos;
2366 char *wpos;
2367
2368 escaped = GNUNET_malloc (strlen (value) * 2 + 1);
2369 memset (escaped, 0, strlen (value) * 2 + 1);
2370 rpos = value;
2371 wpos = escaped;
2372 while (rpos[0] != '\0')
2373 {
2374 switch (rpos[0])
2375 {
2376 case '\\':
2377 case ' ':
2378 wpos[0] = '\\';
2379 wpos[1] = rpos[0];
2380 wpos += 2;
2381 break;
2382
2383 default:
2384 wpos[0] = rpos[0];
2385 wpos++;
2386 }
2387 rpos++;
2388 }
2389 return escaped;
2390}
2391
2392
2400static enum GNUNET_GenericReturnValue
2401test_match (void *cls,
2402 const char *fn)
2403{
2404 const char *of = cls;
2405
2406 return (0 == strcmp (of, fn))
2408 : GNUNET_OK;
2409}
2410
2411
2415 const char *section,
2416 const char *option,
2417 const char *value)
2418{
2419 char *escaped;
2420 char *old;
2421 char *nw;
2422
2423 if (GNUNET_SYSERR ==
2425 section,
2426 option,
2427 &test_match,
2428 (void *) value))
2429 return GNUNET_NO; /* already exists */
2430 if (GNUNET_OK !=
2431 GNUNET_CONFIGURATION_get_value_string (cfg, section, option, &old))
2432 old = GNUNET_strdup ("");
2433 escaped = escape_name (value);
2434 nw = GNUNET_malloc (strlen (old) + strlen (escaped) + 2);
2435 strcpy (nw, old);
2436 if (strlen (old) > 0)
2437 strcat (nw, " ");
2438 strcat (nw, escaped);
2440 section,
2441 option,
2442 nw);
2443 GNUNET_free (old);
2444 GNUNET_free (nw);
2445 GNUNET_free (escaped);
2446 return GNUNET_OK;
2447}
2448
2449
2453 const char *section,
2454 const char *option,
2455 const char *value)
2456{
2457 char *list;
2458 char *pos;
2459 char *end;
2460 char *match;
2461 char old;
2462
2463 if (GNUNET_OK !=
2465 section,
2466 option,
2467 &list))
2468 return GNUNET_NO;
2469 match = escape_name (value);
2470 pos = list;
2471 while (1)
2472 {
2473 while (pos[0] == ' ')
2474 pos++;
2475 if (strlen (pos) == 0)
2476 break;
2477 end = pos + 1;
2478 while ((end[0] != ' ') && (end[0] != '\0'))
2479 {
2480 if (end[0] == '\\')
2481 {
2482 switch (end[1])
2483 {
2484 case '\\':
2485 case ' ':
2486 end++;
2487 break;
2488
2489 case '\0':
2490 /* illegal, but just keep it */
2491 break;
2492
2493 default:
2494 /* illegal, but just ignore that there was a '/' */
2495 break;
2496 }
2497 }
2498 end++;
2499 }
2500 old = end[0];
2501 end[0] = '\0';
2502 if (0 == strcmp (pos, match))
2503 {
2504 if (old != '\0')
2505 memmove (pos,
2506 &end[1],
2507 strlen (&end[1]) + 1);
2508 else
2509 {
2510 if (pos != list)
2511 pos[-1] = '\0';
2512 else
2513 pos[0] = '\0';
2514 }
2516 section,
2517 option,
2518 list);
2519 GNUNET_free (list);
2520 GNUNET_free (match);
2521 return GNUNET_OK;
2522 }
2523 if (old == '\0')
2524 break;
2525 end[0] = old;
2526 pos = end + 1;
2527 }
2528 GNUNET_free (list);
2529 GNUNET_free (match);
2530 return GNUNET_NO;
2531}
2532
2533
2537 const char *defaults_d)
2538{
2539 struct CollectFilesContext files_context = {
2540 .files = NULL,
2541 .files_length = 0,
2542 };
2543 enum GNUNET_GenericReturnValue fun_ret;
2544
2545 if (GNUNET_SYSERR ==
2546 GNUNET_DISK_directory_scan (defaults_d,
2548 &files_context))
2549 return GNUNET_SYSERR; /* no configuration at all found */
2550 qsort (files_context.files,
2551 files_context.files_length,
2552 sizeof (char *),
2553 &pstrcmp);
2554 for (unsigned int i = 0; i < files_context.files_length; i++)
2555 {
2556 char *ext;
2557 const char *filename = files_context.files[i];
2558
2559 /* Examine file extension */
2560 ext = strrchr (filename, '.');
2561 if ( (NULL == ext) ||
2562 (0 != strcmp (ext,
2563 ".conf")) )
2564 {
2566 "Skipping file `%s'\n",
2567 filename);
2568 fun_ret = GNUNET_OK;
2569 continue;
2570 }
2572 filename);
2573 if (fun_ret != GNUNET_OK)
2574 break;
2575 }
2576 if (files_context.files_length > 0)
2577 {
2578 for (size_t i = 0; i < files_context.files_length; i++)
2579 GNUNET_free (files_context.files[i]);
2580 GNUNET_array_grow (files_context.files,
2581 files_context.files_length,
2582 0);
2583 }
2584 return fun_ret;
2585}
2586
2587
2588char *
2590 const struct GNUNET_OS_ProjectData *pd)
2591{
2592 char *cfg_fn;
2593 const char *xdg = getenv ("XDG_CONFIG_HOME");
2594
2595 if (NULL != xdg)
2596 GNUNET_asprintf (&cfg_fn,
2597 "%s%s%s",
2598 xdg,
2600 pd->config_file);
2601 else
2602 cfg_fn = GNUNET_strdup (pd->user_config_file);
2603
2604 if (GNUNET_OK == GNUNET_DISK_file_test_read (cfg_fn))
2605 return cfg_fn;
2606 GNUNET_free (cfg_fn);
2607
2608 /* Fall back to /etc/ for the default configuration.
2609 Should be okay to use forward slashes here. */
2610
2611 GNUNET_asprintf (&cfg_fn,
2612 "/etc/%s",
2613 pd->config_file);
2614 if (GNUNET_OK ==
2616 return cfg_fn;
2617 GNUNET_free (cfg_fn);
2618
2619 GNUNET_asprintf (&cfg_fn,
2620 "/etc/%s/%s",
2621 pd->project_dirname,
2622 pd->config_file);
2623 if (GNUNET_OK ==
2625 return cfg_fn;
2626
2627 GNUNET_free (cfg_fn);
2628 return NULL;
2629}
2630
2631
2635 const char *filename)
2636{
2637 char *baseconfig;
2638 const char *base_config_varname;
2639
2640 if (cfg->load_called)
2641 {
2642 /* FIXME: Make this a GNUNET_assert later */
2643 GNUNET_break (0);
2645 }
2646 cfg->load_called = true;
2647 if (NULL != filename)
2648 {
2651 }
2652
2653 base_config_varname = cfg->pd->base_config_varname;
2654
2655 if ((NULL != base_config_varname)
2656 && (NULL != (baseconfig = getenv (base_config_varname))))
2657 {
2658 baseconfig = GNUNET_strdup (baseconfig);
2659 }
2660 else
2661 {
2662 char *ipath;
2663
2666 if (NULL == ipath)
2667 {
2668 GNUNET_break (0);
2669 return GNUNET_SYSERR;
2670 }
2671 GNUNET_asprintf (&baseconfig,
2672 "%s%s",
2673 ipath,
2674 "config.d");
2675 GNUNET_free (ipath);
2676 }
2677
2678 {
2679 char *dname = GNUNET_STRINGS_filename_expand (baseconfig);
2680
2681 GNUNET_free (baseconfig);
2682
2683 if ((GNUNET_YES ==
2685 GNUNET_YES)) &&
2686 (GNUNET_SYSERR ==
2688 dname)))
2689 {
2691 "Failed to load base configuration from '%s'\n",
2692 filename);
2693 GNUNET_free (dname);
2694 return GNUNET_SYSERR; /* no configuration at all found */
2695 }
2696 GNUNET_free (dname);
2697 }
2698 if ((NULL != filename) &&
2699 (GNUNET_OK !=
2701 filename)))
2702 {
2703 /* specified configuration not found */
2705 "Failed to load configuration from file '%s'\n",
2706 filename);
2707 return GNUNET_SYSERR;
2708 }
2709 if (((GNUNET_YES !=
2711 "PATHS",
2712 "DEFAULTCONFIG"))) &&
2713 (filename != NULL))
2715 "PATHS",
2716 "DEFAULTCONFIG",
2717 filename);
2718 return GNUNET_OK;
2719}
2720
2721
2730static void
2731print_filename_option (void *cls,
2732 const char *section,
2733 const char *option,
2734 const char *value)
2735{
2736 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
2737
2738 char *value_fn;
2739 char *fn;
2740
2743 section,
2744 option,
2745 &value_fn));
2746 fn = GNUNET_STRINGS_filename_expand (value_fn);
2747 if (NULL == fn)
2748 fn = value_fn;
2749 else
2750 GNUNET_free (value_fn);
2751 fprintf (stdout,
2752 "%s = %s\n",
2753 option,
2754 fn);
2755 GNUNET_free (fn);
2756}
2757
2758
2767static void
2768print_option (void *cls,
2769 const char *section,
2770 const char *option,
2771 const char *value)
2772{
2773 (void) cls;
2774 (void) section;
2775
2776 fprintf (stdout,
2777 "%s = %s\n",
2778 option,
2779 value);
2780}
2781
2782
2789static void
2790print_section_name (void *cls,
2791 const char *section)
2792{
2793 (void) cls;
2794 fprintf (stdout,
2795 "%s\n",
2796 section);
2797}
2798
2799
2800void
2802 void *cls,
2803 char *const *args,
2804 const char *cfgfile,
2805 const struct GNUNET_CONFIGURATION_Handle *cfg)
2806{
2807 struct GNUNET_CONFIGURATION_ConfigSettings *cs = cls;
2808 struct GNUNET_CONFIGURATION_Handle *out = NULL;
2809 struct GNUNET_CONFIGURATION_Handle *ncfg = NULL;
2810
2811 (void) args;
2812 if (cs->diagnostics)
2813 {
2814 /* Re-parse the configuration with diagnostics enabled. */
2817 if (GNUNET_OK !=
2819 cfgfile))
2820 {
2821 fprintf (stderr,
2822 _ ("Failed to load config file `%s'"),
2823 cfgfile);
2824 return;
2825 }
2826 cfg = ncfg;
2827 }
2828
2829 if (cs->full)
2830 cs->rewrite = GNUNET_YES;
2831 if (cs->list_sections)
2832 {
2833 fprintf (stderr,
2834 _ ("The following sections are available:\n"));
2837 NULL);
2838 return;
2839 }
2840 if ( (! cs->rewrite) &&
2841 (NULL == cs->section) )
2842 {
2843 char *serialization;
2844
2845 if (! cs->diagnostics)
2846 {
2847 fprintf (stderr,
2848 _ ("%s, %s or %s argument is required\n"),
2849 "--section",
2850 "--list-sections",
2851 "--diagnostics");
2853 return;
2854 }
2856 fprintf (stdout,
2857 "%s",
2858 serialization);
2859 GNUNET_free (serialization);
2860 }
2861 else if ( (NULL != cs->section) &&
2862 (NULL == cs->value) )
2863 {
2864 if (NULL == cs->option)
2865 {
2867 cfg,
2868 cs->section,
2869 cs->is_filename
2871 : &print_option,
2872 (void *) cfg);
2873 }
2874 else
2875 {
2876 char *value;
2877
2878 if (cs->is_filename)
2879 {
2880 if (GNUNET_OK !=
2882 cs->section,
2883 cs->option,
2884 &value))
2885 {
2887 cs->section,
2888 cs->option);
2890 return;
2891 }
2892 }
2893 else
2894 {
2895 if (GNUNET_OK !=
2897 cs->section,
2898 cs->option,
2899 &value))
2900 {
2902 cs->section,
2903 cs->option);
2905 return;
2906 }
2907 }
2908 fprintf (stdout,
2909 "%s\n",
2910 value);
2912 }
2913 }
2914 else if (NULL != cs->section)
2915 {
2916 if (NULL == cs->option)
2917 {
2918 fprintf (stderr,
2919 _ ("--option argument required to set value\n"));
2921 return;
2922 }
2925 cs->section,
2926 cs->option,
2927 cs->value);
2928 cs->rewrite = GNUNET_YES;
2929 }
2930 if (cs->rewrite)
2931 {
2932 char *cfg_fn = NULL;
2933
2934 if (NULL == out)
2936
2937 if (NULL == cfgfile)
2938 {
2939 const char *xdg = getenv ("XDG_CONFIG_HOME");
2940
2941 if (NULL != xdg)
2942 GNUNET_asprintf (&cfg_fn,
2943 "%s%s%s",
2944 xdg,
2946 cfg->pd->config_file);
2947 else
2948 cfg_fn = GNUNET_strdup (cfg->pd->user_config_file);
2949 cfgfile = cfg_fn;
2950 }
2951
2952 if (! cs->full)
2953 {
2954 struct GNUNET_CONFIGURATION_Handle *def;
2955
2957 if (GNUNET_OK !=
2959 NULL))
2960 {
2961 fprintf (stderr,
2962 _ ("failed to load configuration defaults"));
2963 cs->global_ret = 1;
2966 GNUNET_free (cfg_fn);
2967 return;
2968 }
2969 if (GNUNET_OK !=
2971 out,
2972 cfgfile))
2973 cs->global_ret = 2;
2975 }
2976 else
2977 {
2978 if (GNUNET_OK !=
2980 cfgfile))
2981 cs->global_ret = 2;
2982 }
2983 GNUNET_free (cfg_fn);
2984 }
2985 if (NULL != out)
2987 if (NULL != ncfg)
2989}
2990
2991
2992void
2995{
2996 GNUNET_free (cs->option);
2997 GNUNET_free (cs->section);
2998 GNUNET_free (cs->value);
2999}
3000
3001
3002const struct GNUNET_OS_ProjectData *
3004 const struct GNUNET_CONFIGURATION_Handle *cfg)
3005{
3006 return cfg->pd;
3007}
3008
3009
3010/* end of configuration.c */
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
static bool do_skip(const char *sec, const char *key)
Should we skip this configuration entry when serializing?
static void print_filename_option(void *cls, const char *section, const char *option, const char *value)
Print each option in a given section as a filename.
static struct ConfigEntry * find_entry(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *key)
Find an entry from a configuration.
static enum GNUNET_GenericReturnValue handle_inline(struct GNUNET_CONFIGURATION_Handle *cfg, const char *path_or_glob, bool path_is_glob, const char *restrict_section, const char *source_filename, unsigned int source_lineno)
Handle an inline directive.
static void print_section_name(void *cls, const char *section)
Print out given section name.
static char * escape_name(const char *value)
FIXME.
static void compare_entries(void *cls, const char *section, const char *option, const char *value)
A callback function, compares entries from two configurations (default against a new configuration) a...
static enum GNUNET_GenericReturnValue test_match(void *cls, const char *fn)
FIXME.
static struct ConfigSection * find_section(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section)
Find a section entry from a configuration.
static int pstrcmp(const void *a, const void *b)
static char * expand_dollar(const struct GNUNET_CONFIGURATION_Handle *cfg, char *orig, unsigned int depth)
Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR" where either in the "PATHS" section or...
static enum GNUNET_GenericReturnValue collect_files_cb(void *cls, const char *filename)
Function called with a filename.
#define LOG(kind,...)
static void copy_entry(void *cls, const char *section, const char *option, const char *value)
Copy a configuration value to the given target configuration.
static void print_option(void *cls, const char *section, const char *option, const char *value)
Print each option in a given section.
static void dump_os_ipk(const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_Buffer *buf, enum GNUNET_OS_InstallationPathKind ipk)
Dump an os installation path to a buffer.
static void set_entry_hint(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *hint_filename, unsigned int hint_line)
Set a configuration hint.
char * getenv()
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition gnunet-arm.c:98
static int start
Set if we are to start default services (including ARM).
Definition gnunet-arm.c:38
static int list
Set if we should print a list of currently running services.
Definition gnunet-arm.c:68
static int ret
Final status code.
Definition gnunet-arm.c:93
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition gnunet-arm.c:108
static int end
Set if we are to shutdown all services (including ARM).
Definition gnunet-arm.c:33
static int prefix
If printing the value of PREFIX has been requested.
static char * line
Desired phone line (string to be converted to a hash).
struct GNUNET_HashCode key
The key used in the DHT.
static char * filename
static struct GNUNET_FS_Handle * fs
Handle to FS service.
Definition gnunet-fs.c:35
static OpusEncoder * enc
OPUS encoder.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
static char * res
Currently read line or NULL on EOF.
static char * value
Value of the record to add/remove.
static size_t data_size
Number of bytes in data.
static int result
Global testing status.
static void cleanup()
Cleanup task.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition gnunet-uri.c:38
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_data(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, void *buf, size_t buf_size)
Get Crockford32-encoded fixed-size binary data from a configuration.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_create(const struct GNUNET_OS_ProjectData *pd)
Create a new configuration object.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_is_dirty(const struct GNUNET_CONFIGURATION_Handle *cfg)
Test if there are configuration options that were changed since the last save.
void GNUNET_CONFIGURATION_set_value_string(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *value)
Set a configuration value that should be a string.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_append_value_filename(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *value)
Append a filename to a configuration value that represents a list of filenames.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
void GNUNET_CONFIGURATION_remove_section(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section)
Remove the given section and all options in it.
enum GNUNET_GenericReturnValue(* GNUNET_CONFIGURATION_Callback)(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
Signature of a function to be run with a configuration.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_dup(const struct GNUNET_CONFIGURATION_Handle *cfg)
Duplicate an existing configuration object.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
void GNUNET_CONFIGURATION_iterate_sections(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CONFIGURATION_SectionIterator iter, void *iter_cls)
Iterate over all sections in the configuration.
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
void GNUNET_CONFIGURATION_config_settings_free(struct GNUNET_CONFIGURATION_ConfigSettings *cs)
Free resources associated with cs.
void GNUNET_CONFIGURATION_iterate(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CONFIGURATION_Iterator iter, void *iter_cls)
Iterate over all options in the configuration.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_remove_value_filename(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *value)
Remove a filename from a configuration value that represents a list of filenames.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_parse_and_run(const struct GNUNET_OS_ProjectData *pd, const char *filename, GNUNET_CONFIGURATION_Callback cb, void *cb_cls)
Parse a configuration file filename and run the function cb with the resulting configuration object.
void GNUNET_CONFIGURATION_config_tool_run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Main task to run to perform operations typical for gnunet-config as per the configuration settings gi...
void(* GNUNET_CONFIGURATION_SectionIterator)(void *cls, const char *section)
Function to iterate over section.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_deserialize(struct GNUNET_CONFIGURATION_Handle *cfg, const char *mem, size_t size, const char *source_filename)
De-serializes configuration.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_size(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *size)
Get a configuration value that should be a size in bytes.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
char * GNUNET_CONFIGURATION_serialize(const struct GNUNET_CONFIGURATION_Handle *cfg, size_t *size)
Serializes the given configuration.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
void GNUNET_CONFIGURATION_set_value_number(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long number)
Set a configuration value that should be a number.
char * GNUNET_CONFIGURATION_default_filename(const struct GNUNET_OS_ProjectData *pd)
Return the filename of the default configuration filename that is used when no explicit configuration...
char * GNUNET_CONFIGURATION_expand_dollar(const struct GNUNET_CONFIGURATION_Handle *cfg, char *orig)
Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR" where either in the "PATHS" section or...
void GNUNET_CONFIGURATION_set_value_float(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, float number)
Set a configuration value that should be a float.
const struct GNUNET_OS_ProjectData * GNUNET_CONFIGURATION_get_project_data(const struct GNUNET_CONFIGURATION_Handle *cfg)
Return the project data associated with this configuration.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_load(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Load configuration.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_get_diff(const struct GNUNET_CONFIGURATION_Handle *cfg_default, const struct GNUNET_CONFIGURATION_Handle *cfg_new)
Compute configuration with only entries that have been changed.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_parse(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Parse a configuration file, add all of the options in the file to the configuration environment.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_float(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, float *number)
Get a configuration value that should be a floating point number.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_load_from(struct GNUNET_CONFIGURATION_Handle *cfg, const char *defaults_d)
Load default configuration.
int GNUNET_CONFIGURATION_iterate_value_filenames(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, GNUNET_FileNameCallback cb, void *cb_cls)
Iterate over the set of filenames stored in a configuration value.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_have_value(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Test if we have a value for a particular option.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_choice(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *const *choices, const char **value)
Get a configuration value that should be in a set of predefined strings.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_write(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Write configuration file.
void(* GNUNET_CONFIGURATION_Iterator)(void *cls, const char *section, const char *option, const char *value)
Function to iterate over options.
void GNUNET_CONFIGURATION_iterate_section_values(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, GNUNET_CONFIGURATION_Iterator iter, void *iter_cls)
Iterate over values of a section in the configuration.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_write_diffs(const struct GNUNET_CONFIGURATION_Handle *cfg_default, const struct GNUNET_CONFIGURATION_Handle *cfg_new, const char *filename)
Write only configuration entries that have been changed to configuration file.
char * GNUNET_CONFIGURATION_serialize_diagnostics(const struct GNUNET_CONFIGURATION_Handle *cfg)
Serializes the given configuration with diagnostics information.
void GNUNET_CONFIGURATION_enable_diagnostics(struct GNUNET_CONFIGURATION_Handle *cfg)
Enable extra diagnostics.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition disk.c:1258
int GNUNET_DISK_glob(const char *glob_pattern, GNUNET_FileNameCallback callback, void *callback_cls)
Find all files matching a glob pattern.
Definition disk.c:1021
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition disk.c:710
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test_read(const char *fil)
Check that fil corresponds to a filename and the file has read permissions.
Definition disk.c:540
enum GNUNET_GenericReturnValue GNUNET_DISK_file_size(const char *filename, uint64_t *size, int include_symbolic_links, int single_file_mode)
Get the size of the file (or directory) of the given file (in bytes).
Definition disk.c:235
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
Definition disk.c:1098
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition disk.c:454
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition disk.c:1332
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition disk.c:633
ssize_t GNUNET_DISK_fn_read(const char *fn, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition disk.c:687
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition disk.c:839
@ GNUNET_DISK_OPEN_WRITE
Open the file for writing.
@ GNUNET_DISK_OPEN_TRUNCATE
Truncate file if it exists.
@ GNUNET_DISK_OPEN_CREATE
Create file if it doesn't exist.
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
@ GNUNET_DISK_PERM_GROUP_READ
Group can read.
@ GNUNET_DISK_PERM_GROUP_WRITE
Group can write.
@ GNUNET_DISK_PERM_USER_WRITE
Owner can write.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
enum GNUNET_GenericReturnValue(* GNUNET_FileNameCallback)(void *cls, const char *filename)
Function called with a filename.
#define GNUNET_log(kind,...)
char * GNUNET_buffer_reap_str(struct GNUNET_Buffer *buf)
Clear the buffer and return the string it contained.
Definition buffer.c:123
void GNUNET_buffer_write_fstr(struct GNUNET_Buffer *buf, const char *fmt,...) __attribute__((format(printf
Write a 0-terminated formatted string to a buffer, excluding the 0-terminator.
void GNUNET_buffer_write_str(struct GNUNET_Buffer *buf, const char *str)
Write a 0-terminated string to a buffer, excluding the 0-terminator.
Definition buffer.c:103
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
void GNUNET_log_config_invalid(enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
Log error message about invalid configuration option value.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_realloc(ptr, size)
Wrapper around realloc.
#define GNUNET_array_append(arr, len, element)
Append an element to an array (growing the array by one).
#define GNUNET_free(ptr)
Wrapper around free.
char * GNUNET_OS_installation_get_path(const struct GNUNET_OS_ProjectData *pd, enum GNUNET_OS_InstallationPathKind dirkind)
Get the path to a specific GNUnet installation directory or, with GNUNET_OS_IPK_SELF_PREFIX,...
GNUNET_OS_InstallationPathKind
Possible installation paths to request.
@ GNUNET_OS_IPK_SELF_PREFIX
Return the installation directory of this application, not the one of the overall GNUnet installation...
@ GNUNET_OS_IPK_ICONDIR
Return the prefix of the path with application icons (share/icons/).
@ GNUNET_OS_IPK_DATADIR
Return the directory where data is installed (share/gnunet/)
@ GNUNET_OS_IPK_DOCDIR
Return the prefix of the path with documentation files, including the license (share/doc/gnunet/).
@ GNUNET_OS_IPK_LOCALEDIR
Return the directory where translations are installed (share/locale/)
@ GNUNET_OS_IPK_LIBDIR
Return the directory where libraries are installed.
@ GNUNET_OS_IPK_PREFIX
Return the "PREFIX" directory given to configure.
@ GNUNET_OS_IPK_BINDIR
Return the directory where the program binaries are installed.
@ GNUNET_OS_IPK_LIBEXECDIR
Return the directory where helper binaries are installed (lib/gnunet/libexec/)
char * GNUNET_STRINGS_filename_expand(const char *fil)
Complete filename (a la shell) from abbrevition.
Definition strings.c:520
enum GNUNET_GenericReturnValue GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition strings.c:832
enum GNUNET_GenericReturnValue GNUNET_STRINGS_fancy_time_to_relative(const char *fancy_time, struct GNUNET_TIME_Relative *rtime)
Convert a given fancy human-readable time to our internal representation.
Definition strings.c:259
enum GNUNET_GenericReturnValue GNUNET_STRINGS_fancy_size_to_bytes(const char *fancy_size, unsigned long long *size)
Convert a given fancy human-readable size to bytes.
Definition strings.c:235
static unsigned int size
Size of the "table".
Definition peer.c:68
#define DIR_SEPARATOR_STR
Definition platform.h:167
#define _(String)
GNU gettext support macro.
Definition platform.h:179
#define SIZE_MAX
Definition platform.h:209
#define EXIT_INVALIDARGUMENT
Definition platform.h:254
#define EXIT_NOTCONFIGURED
Definition platform.h:270
uint32_t number
Closure to collect_files_cb.
char ** files
Collected files from globbing.
unsigned int files_length
Size of the files array.
configuration entry
char * hint_filename
Diagnostics information for the filename.
struct ConfigEntry * next
This is a linked list.
char * key
key for this entry
unsigned int hint_lineno
Diagnostics information for the line number.
char * val
current, committed value
char * hint_restrict_section
Was this configuration file parsed via @inline-secret@?
struct ConfigFile * next
char * source_filename
Source filename.
bool hint_inaccessible
Was this configuration file inaccessible?
struct ConfigFile * prev
unsigned int level
Level in the tree of loaded config files.
configuration section
char * name
name of the section
char * hint_inlined_from_filename
For secret sections: Where was this inlined from?
struct ConfigEntry * entries
entries in the section
bool inaccessible
Is the configuration section marked as inaccessible?
struct ConfigSection * next
This is a linked list.
char * hint_secret_filename
Diagnostics hint for the secret file.
unsigned int hint_inlined_from_line
For secret sections: Where was this inlined from?
char * hint_secret_stat
Extra information regarding permissions of the secret file.
Used for diffing a configuration object against the default one.
const struct GNUNET_CONFIGURATION_Handle * cfg_default
struct GNUNET_CONFIGURATION_Handle * cfgDiff
Dynamically growing buffer.
Closure for GNUNET_CONFIGURATION_config_tool_run() with settings for what should be done with the con...
int full
Should the generated configuration file contain the whole configuration?
int global_ret
Return value from the operation, to be returned from 'main'.
int diagnostics
Should we give extra diagnostics?
int list_sections
Whether to show the sections.
int rewrite
Should we write out the configuration file, even if no value was changed?
int is_filename
Treat option as a filename.
struct ConfigFile * loaded_files_tail
Linked list of loaded files.
bool load_called
Was the configuration ever loaded via GNUNET_CONFIGURATION_load?
unsigned int current_nest_level
Current nesting level of file loading.
const struct GNUNET_OS_ProjectData * pd
Project data for this configuration object.
struct ConfigSection * sections
Configuration sections.
struct ConfigFile * loaded_files_head
Linked list of loaded files.
char * main_filename
Name of the entry point configuration file.
enum GNUNET_GenericReturnValue dirty
Modification indication since last save GNUNET_NO if clean, GNUNET_YES if dirty, GNUNET_SYSERR on err...
bool diagnostics
Enable diagnostics.
const char * restrict_section
When parsing into this configuration, and this value is non-NULL, only parse sections of the same nam...
Handle used to access files (and pipes).
Project-specific data used to help the OS subsystem find installation paths.
const char * base_config_varname
Name of an environment variable that can be used to override the location from which default configur...
const char * project_dirname
Name of the project that is used in the "libexec" prefix, For example, "gnunet".
const char * user_config_file
Configuration file name to use (if $XDG_CONFIG_HOME is not set).
const char * config_file
Configuration file name (in $XDG_CONFIG_HOME) to use.
Time for relative time used by GNUnet, in microseconds.

Function Documentation

◆ collect_files_cb()

static enum GNUNET_GenericReturnValue collect_files_cb ( void *  cls,
const char *  filename 
)
static

Function called with a filename.

Parameters
clsclosure
filenamecomplete filename (absolute path)
Returns
GNUNET_OK to continue to iterate, GNUNET_NO to stop iteration with no error, GNUNET_SYSERR to abort iteration with error!

Definition at line 394 of file configuration.c.

396{
397 struct CollectFilesContext *igc = cls;
398
400 igc->files_length,
402 return GNUNET_OK;
403}

References filename, CollectFilesContext::files, CollectFilesContext::files_length, GNUNET_array_append, GNUNET_OK, and GNUNET_strdup.

Referenced by GNUNET_CONFIGURATION_load_from(), and handle_inline().

Here is the caller graph for this function:

◆ find_section()

static struct ConfigSection * find_section ( const struct GNUNET_CONFIGURATION_Handle cfg,
const char *  section 
)
static

Find a section entry from a configuration.

Parameters
cfgconfiguration to search in
sectionname of the section to look for
Returns
matching entry, NULL if not found

Definition at line 414 of file configuration.c.

416{
417 struct ConfigSection *pos;
418
419 if (NULL == cfg)
420 return NULL;
421 pos = cfg->sections;
422 while ( (NULL != pos) &&
423 (0 != strcasecmp (section,
424 pos->name)) )
425 pos = pos->next;
426 return pos;
427}

References cfg, ConfigSection::name, ConfigSection::next, and GNUNET_CONFIGURATION_Handle::sections.

Referenced by find_entry(), GNUNET_CONFIGURATION_set_value_string(), and handle_inline().

Here is the caller graph for this function:

◆ pstrcmp()

static int pstrcmp ( const void *  a,
const void *  b 
)
static

Definition at line 431 of file configuration.c.

433{
434 return strcmp (*((const char **) a),
435 *((const char **) b));
436}

Referenced by GNUNET_CONFIGURATION_load_from(), and handle_inline().

Here is the caller graph for this function:

◆ handle_inline()

static enum GNUNET_GenericReturnValue handle_inline ( struct GNUNET_CONFIGURATION_Handle cfg,
const char *  path_or_glob,
bool  path_is_glob,
const char *  restrict_section,
const char *  source_filename,
unsigned int  source_lineno 
)
static

Handle an inline directive.

Returns
GNUNET_SYSERR on error, GNUNET_OK otherwise

Definition at line 445 of file configuration.c.

451{
452 char *inline_path = NULL;
453 struct GNUNET_CONFIGURATION_Handle *other_cfg = NULL;
454 struct CollectFilesContext igc = {
455 .files = NULL,
456 .files_length = 0,
457 };
458 enum GNUNET_GenericReturnValue fun_ret;
459 unsigned int old_nest_level = cfg->current_nest_level++;
460
461 /* We support the section restriction only for non-globs */
462 GNUNET_assert (! (path_is_glob && (NULL != restrict_section)));
463
464 if (NULL == source_filename)
465 {
467 "Refusing to parse inline configurations, "
468 "not allowed without source filename!\n");
469 fun_ret = GNUNET_SYSERR;
470 goto cleanup;
471 }
472
473 if ('/' == *path_or_glob)
474 inline_path = GNUNET_strdup (path_or_glob);
475 else
476 {
477 /* We compute the canonical, absolute path first,
478 so that relative imports resolve properly with symlinked
479 config files. */
480 char *source_realpath;
481 char *endsep;
482
483 source_realpath = realpath (source_filename,
484 NULL);
485 if (NULL == source_realpath)
486 {
487 /* Couldn't even resolve path of base dir. */
488 GNUNET_break (0);
489 /* failed to parse included config */
490 fun_ret = GNUNET_SYSERR;
491 goto cleanup;
492 }
493 endsep = strrchr (source_realpath, '/');
494 GNUNET_assert (NULL != endsep);
495 *endsep = '\0';
496 GNUNET_asprintf (&inline_path,
497 "%s/%s",
498 source_realpath,
499 path_or_glob);
500 free (source_realpath);
501 }
502
503 if (path_is_glob)
504 {
505 int nret;
506
508 "processing config glob '%s'\n",
509 inline_path);
510
511 nret = GNUNET_DISK_glob (inline_path,
513 &igc);
514 if (-1 == nret)
515 {
516 fun_ret = GNUNET_SYSERR;
517 goto cleanup;
518 }
519 GNUNET_assert (nret == igc.files_length);
520 qsort (igc.files,
521 igc.files_length,
522 sizeof (char *),
523 &pstrcmp);
524 for (int i = 0; i < nret; i++)
525 {
526 if (GNUNET_OK !=
528 igc.files[i]))
529 {
530 fun_ret = GNUNET_SYSERR;
531 goto cleanup;
532 }
533 }
534 fun_ret = GNUNET_OK;
535 }
536 else if (NULL != restrict_section)
537 {
538 enum GNUNET_GenericReturnValue inner_ret;
539 struct ConfigSection *cs;
540 struct ConfigFile *cf = GNUNET_new (struct ConfigFile);
541
542 inner_ret = GNUNET_DISK_file_test_read (inline_path);
543
544 cs = find_section (cfg, restrict_section);
545
546 if (NULL == cs)
547 {
548 cs = GNUNET_new (struct ConfigSection);
549 cs->name = GNUNET_strdup (restrict_section);
550 cs->next = cfg->sections;
551 cfg->sections = cs;
552 cs->entries = NULL;
553 }
554 if (cfg->diagnostics)
555 {
556 const char *pwname;
557 const char *grname;
558 char *sfn = GNUNET_STRINGS_filename_expand (inline_path);
559 struct stat istat;
560
561 cs->hint_secret_filename = sfn;
562 if (0 == stat (sfn, &istat))
563 {
564 struct passwd *pw = getpwuid (istat.st_uid);
565 struct group *gr = getgrgid (istat.st_gid);
566 pwname = (NULL == pw) ? "<unknown>" : pw->pw_name;
567 grname = (NULL == gr) ? "<unknown>" : gr->gr_name;
568
570 "%s:%s %o",
571 pwname,
572 grname,
573 istat.st_mode);
574 }
575 else
576 {
577 cs->hint_secret_stat = GNUNET_strdup ("<can't stat file>");
578 }
579 if (source_filename)
580 {
581 /* Possible that this secret section has been inlined before */
583 cs->hint_inlined_from_filename = GNUNET_strdup (source_filename);
584 cs->hint_inlined_from_line = source_lineno;
585 }
586 }
587
588 /* Put file in the load list for diagnostics, even if we can't access it. */
589 {
591 cf->source_filename = GNUNET_strdup (inline_path);
592 cf->hint_restrict_section = GNUNET_strdup (restrict_section);
595 cf);
596 }
597
598 if (GNUNET_OK != inner_ret)
599 {
600 cs->inaccessible = true;
601 cf->hint_inaccessible = true;
602 /* File can't be accessed, but that's okay. */
603 fun_ret = GNUNET_OK;
604 goto cleanup;
605 }
606
607 other_cfg = GNUNET_CONFIGURATION_create (cfg->pd);
608 other_cfg->restrict_section = restrict_section;
609 inner_ret = GNUNET_CONFIGURATION_parse (other_cfg,
610 inline_path);
611 if (GNUNET_OK != inner_ret)
612 {
613 cf->hint_inaccessible = true;
614 fun_ret = inner_ret;
615 goto cleanup;
616 }
617
618 cs = find_section (other_cfg,
619 restrict_section);
620 if (NULL == cs)
621 {
623 "Configuration file '%s' loaded with @inline-secret@ "
624 "does not contain section '%s'.\n",
625 inline_path,
626 restrict_section);
627 /* Inlined configuration is accessible but doesn't contain any values.
628 We treat this as if the inlined section was empty, and do not
629 consider it an error. */
630 fun_ret = GNUNET_OK;
631 goto cleanup;
632 }
633 for (struct ConfigEntry *ce = cs->entries;
634 NULL != ce;
635 ce = ce->next)
637 restrict_section,
638 ce->key,
639 ce->val);
640 fun_ret = GNUNET_OK;
641 }
642 else if (GNUNET_OK !=
644 inline_path))
645 {
646 fun_ret = GNUNET_SYSERR;
647 goto cleanup;
648 }
649 else
650 {
651 fun_ret = GNUNET_OK;
652 }
653cleanup:
654 cfg->current_nest_level = old_nest_level;
655 if (NULL != other_cfg)
657 GNUNET_free (inline_path);
658 if (igc.files_length > 0)
659 {
660 for (size_t i = 0; i < igc.files_length; i++)
661 GNUNET_free (igc.files[i]);
663 }
664 return fun_ret;
665}

References cfg, cleanup(), collect_files_cb(), GNUNET_CONFIGURATION_Handle::current_nest_level, GNUNET_CONFIGURATION_Handle::diagnostics, ConfigSection::entries, CollectFilesContext::files, CollectFilesContext::files_length, find_section(), GNUNET_array_grow, GNUNET_asprintf(), GNUNET_assert, GNUNET_break, GNUNET_CONFIGURATION_create(), GNUNET_CONFIGURATION_destroy(), GNUNET_CONFIGURATION_parse(), GNUNET_CONFIGURATION_set_value_string(), GNUNET_CONTAINER_DLL_insert_tail, GNUNET_DISK_file_test_read(), GNUNET_DISK_glob(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_new, GNUNET_OK, GNUNET_strdup, GNUNET_STRINGS_filename_expand(), GNUNET_SYSERR, ConfigFile::hint_inaccessible, ConfigSection::hint_inlined_from_filename, ConfigSection::hint_inlined_from_line, ConfigFile::hint_restrict_section, ConfigSection::hint_secret_filename, ConfigSection::hint_secret_stat, ConfigSection::inaccessible, ConfigFile::level, GNUNET_CONFIGURATION_Handle::loaded_files_head, GNUNET_CONFIGURATION_Handle::loaded_files_tail, LOG, ConfigSection::name, ConfigSection::next, GNUNET_CONFIGURATION_Handle::pd, pstrcmp(), GNUNET_CONFIGURATION_Handle::restrict_section, GNUNET_CONFIGURATION_Handle::sections, and ConfigFile::source_filename.

Referenced by GNUNET_CONFIGURATION_deserialize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_entry()

static struct ConfigEntry * find_entry ( const struct GNUNET_CONFIGURATION_Handle cfg,
const char *  section,
const char *  key 
)
static

Find an entry from a configuration.

Parameters
cfghandle to the configuration
sectionsection the option is in
keythe option
Returns
matching entry, NULL if not found

Definition at line 677 of file configuration.c.

680{
681 struct ConfigSection *sec;
682 struct ConfigEntry *pos;
683
684 if (NULL == (sec = find_section (cfg, section)))
685 return NULL;
686 if (sec->inaccessible)
687 {
689 "Section '%s' is marked as inaccessible, because the configuration "
690 "file that contains the section can't be read. Attempts to use "
691 "option '%s' will fail.\n",
692 section,
693 key);
694 return NULL;
695 }
696 pos = sec->entries;
697 while ((pos != NULL) && (0 != strcasecmp (key, pos->key)))
698 pos = pos->next;
699 return pos;
700}

References cfg, ConfigSection::entries, find_section(), GNUNET_ERROR_TYPE_WARNING, ConfigSection::inaccessible, key, ConfigEntry::key, LOG, and ConfigEntry::next.

Referenced by compare_entries(), GNUNET_CONFIGURATION_get_value_choice(), GNUNET_CONFIGURATION_get_value_float(), GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_size(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_get_value_time(), GNUNET_CONFIGURATION_have_value(), GNUNET_CONFIGURATION_set_value_string(), and set_entry_hint().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_entry_hint()

static void set_entry_hint ( struct GNUNET_CONFIGURATION_Handle cfg,
const char *  section,
const char *  option,
const char *  hint_filename,
unsigned int  hint_line 
)
static

Set a configuration hint.

Parameters
cfgconfiguration handle
sectionsection
optionconfig option
hint_filename
hint_line

Definition at line 713 of file configuration.c.

718{
719 struct ConfigEntry *e = find_entry (cfg, section, option);
720 if (! cfg->diagnostics)
721 return;
722 if (! e)
723 return;
725 e->hint_lineno = hint_line;
726}

References cfg, GNUNET_CONFIGURATION_Handle::diagnostics, find_entry(), GNUNET_strdup, ConfigEntry::hint_filename, and ConfigEntry::hint_lineno.

Referenced by GNUNET_CONFIGURATION_deserialize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_skip()

static bool do_skip ( const char *  sec,
const char *  key 
)
static

Should we skip this configuration entry when serializing?

Parameters
secsection name
keykey
Returns
true if we should skip it

Definition at line 1134 of file configuration.c.

1136{
1137 if (0 != strcasecmp ("PATHS",
1138 sec))
1139 return false;
1140 return ( (0 == strcasecmp ("DATADIR",
1141 key)) ||
1142 (0 == strcasecmp ("LIBDIR",
1143 key)) ||
1144 (0 == strcasecmp ("BINDIR",
1145 key)) ||
1146 (0 == strcasecmp ("PREFIX",
1147 key)) ||
1148 (0 == strcasecmp ("LOCALEDIR",
1149 key)) ||
1150 (0 == strcasecmp ("ICONDIR",
1151 key)) ||
1152 (0 == strcasecmp ("DOCDIR",
1153 key)) ||
1154 (0 == strcasecmp ("DEFAULTCONFIG",
1155 key)) ||
1156 (0 == strcasecmp ("LIBEXECDIR",
1157 key)) );
1158}

References key.

Referenced by GNUNET_CONFIGURATION_serialize(), and GNUNET_CONFIGURATION_serialize_diagnostics().

Here is the caller graph for this function:

◆ dump_os_ipk()

static void dump_os_ipk ( const struct GNUNET_CONFIGURATION_Handle cfg,
struct GNUNET_Buffer buf,
enum GNUNET_OS_InstallationPathKind  ipk 
)
static

Dump an os installation path to a buffer.

Parameters
cfgconfiguration
bufbuffer to write to
ipkwhich path to print

Definition at line 1268 of file configuration.c.

1272{
1274 ipk);
1275 const char *ipkname;
1276 switch (ipk)
1277 {
1279 ipkname = "IPK_DATADIR";
1280 break;
1282 ipkname = "IPK_BINDIR";
1283 break;
1285 ipkname = "IPK_LIBDIR";
1286 break;
1288 ipkname = "IPK_PREFIX";
1290 ipkname = "IPK_LOCALEDIR";
1291 break;
1293 ipkname = "IPK_ICONDIR";
1295 ipkname = "IPK_DOCDIR";
1296 break;
1298 ipkname = "IPK_LIBEXECDIR";
1299 break;
1301 ipkname = "IPK_SELF_PREFIX";
1302 break;
1303 default:
1304 ipkname = "??";
1305 break;
1306 }
1308 "# %s = %s\n",
1309 ipkname,
1310 v);
1311 GNUNET_free (v);
1312}

References cfg, GNUNET_buffer_write_fstr(), GNUNET_free, GNUNET_OS_installation_get_path(), GNUNET_OS_IPK_BINDIR, GNUNET_OS_IPK_DATADIR, GNUNET_OS_IPK_DOCDIR, GNUNET_OS_IPK_ICONDIR, GNUNET_OS_IPK_LIBDIR, GNUNET_OS_IPK_LIBEXECDIR, GNUNET_OS_IPK_LOCALEDIR, GNUNET_OS_IPK_PREFIX, GNUNET_OS_IPK_SELF_PREFIX, and GNUNET_CONFIGURATION_Handle::pd.

Referenced by GNUNET_CONFIGURATION_serialize_diagnostics().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ copy_entry()

static void copy_entry ( void *  cls,
const char *  section,
const char *  option,
const char *  value 
)
static

Copy a configuration value to the given target configuration.

Overwrites existing entries.

Parameters
clsthe destination configuration (struct GNUNET_CONFIGURATION_Handle *)
sectionsection for the value
optionoption name of the value
valuevalue to copy

Definition at line 1626 of file configuration.c.

1630{
1631 struct GNUNET_CONFIGURATION_Handle *dst = cls;
1632
1634 section,
1635 option,
1636 value);
1637}

References GNUNET_CONFIGURATION_set_value_string(), and value.

Referenced by GNUNET_CONFIGURATION_dup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ compare_entries()

static void compare_entries ( void *  cls,
const char *  section,
const char *  option,
const char *  value 
)
static

A callback function, compares entries from two configurations (default against a new configuration) and write the diffs in a diff-configuration object (the callback object).

Parameters
clsthe diff configuration (struct DiffHandle *)
sectionsection for the value (of the default conf.)
optionoption name of the value (of the default conf.)
valuevalue to copy (of the default conf.)

Definition at line 1665 of file configuration.c.

1669{
1670 struct DiffHandle *dh = cls;
1671 struct ConfigEntry *entNew;
1672
1673 entNew = find_entry (dh->cfg_default, section, option);
1674 if ((NULL != entNew) && (NULL != entNew->val) &&
1675 (0 == strcmp (entNew->val, value)))
1676 return;
1678 section,
1679 option,
1680 value);
1681}

References DiffHandle::cfg_default, DiffHandle::cfgDiff, find_entry(), GNUNET_CONFIGURATION_set_value_string(), ConfigEntry::val, and value.

Referenced by GNUNET_CONFIGURATION_get_diff().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ expand_dollar()

static char * expand_dollar ( const struct GNUNET_CONFIGURATION_Handle cfg,
char *  orig,
unsigned int  depth 
)
static

Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR" where either in the "PATHS" section or the environment "FOO" is set to "DIRECTORY".

We also support default expansion, i.e. ${VARIABLE:-default} will expand to $VARIABLE if VARIABLE is set in PATHS or the environment, and otherwise to "default". Note that "default" itself can also be a $-expression, thus "${VAR1:-{$VAR2}}" will expand to VAR1 and if that is not defined to VAR2.

Parameters
cfgconfiguration to use for path expansion
origstring to $-expand (will be freed!)
depthrecursion depth, used to detect recursive expansions
Returns
$-expanded string, never NULL unless orig was NULL

Definition at line 2045 of file configuration.c.

2048{
2049 char *prefix;
2050 char *result;
2051 char *start;
2052 const char *post;
2053 const char *env;
2054 char *def;
2055 char *end;
2056 unsigned int lopen;
2057 char erased_char;
2058 char *erased_pos;
2059 size_t len;
2060
2061 if (NULL == orig)
2062 return NULL;
2063 if (depth > 128)
2064 {
2066 "Recursive expansion suspected, aborting $-expansion for term `%s'\n",
2067 orig);
2068 return orig;
2069 }
2071 "Asked to $-expand %s\n",
2072 orig);
2073 if ('$' != orig[0])
2074 {
2076 "Doesn't start with $ - not expanding\n");
2077 return orig;
2078 }
2079 erased_char = 0;
2080 erased_pos = NULL;
2081 if ('{' == orig[1])
2082 {
2083 start = &orig[2];
2084 lopen = 1;
2085 end = &orig[1];
2086 while (lopen > 0)
2087 {
2088 end++;
2089 switch (*end)
2090 {
2091 case '}':
2092 lopen--;
2093 break;
2094
2095 case '{':
2096 lopen++;
2097 break;
2098
2099 case '\0':
2101 "Missing closing `}' in option `%s'\n",
2102 orig);
2103 return orig;
2104
2105 default:
2106 break;
2107 }
2108 }
2109 erased_char = *end;
2110 erased_pos = end;
2111 *end = '\0';
2112 post = end + 1;
2113 def = strchr (orig, ':');
2114 if (NULL != def)
2115 {
2116 *def = '\0';
2117 def++;
2118 if (('-' == *def) || ('=' == *def))
2119 def++;
2120 def = GNUNET_strdup (def);
2121 }
2122 }
2123 else
2124 {
2125 int i;
2126
2127 start = &orig[1];
2128 def = NULL;
2129 i = 0;
2130 while ( (orig[i] != '/') &&
2131 (orig[i] != '\\') &&
2132 (orig[i] != '\0') &&
2133 (orig[i] != ' ') )
2134 i++;
2135 if (orig[i] == '\0')
2136 {
2137 post = "";
2138 }
2139 else
2140 {
2141 erased_char = orig[i];
2142 erased_pos = &orig[i];
2143 orig[i] = '\0';
2144 post = &orig[i + 1];
2145 }
2146 }
2148 "Split into `%s' and `%s' with default %s\n",
2149 start,
2150 post,
2151 def);
2152 if (GNUNET_OK !=
2154 "PATHS",
2155 start,
2156 &prefix))
2157 {
2158 if (NULL == (env = getenv (start)))
2159 {
2160 /* try default */
2161 def = expand_dollar (cfg,
2162 def,
2163 depth + 1);
2164 env = def;
2165 }
2166 if (NULL == env)
2167 {
2169 if (erased_pos)
2170 *erased_pos = erased_char;
2172 "Failed to expand `%s' in `%s' as it is neither found in [PATHS] nor defined as an environmental variable\n",
2173 start,
2174 orig);
2176 return orig;
2177 }
2179 }
2181 prefix);
2182 if ((erased_pos) && ('}' != erased_char))
2183 {
2184 len = strlen (prefix) + 1;
2185 prefix = GNUNET_realloc (prefix, len + 1);
2186 prefix[len - 1] = erased_char;
2187 prefix[len] = '\0';
2188 }
2189 result = GNUNET_malloc (strlen (prefix) + strlen (post) + 1);
2190 strcpy (result, prefix);
2191 strcat (result, post);
2192 GNUNET_free (def);
2194 GNUNET_free (orig);
2195 return result;
2196}

References cfg, end, env, expand_dollar(), getenv(), GNUNET_CONFIGURATION_expand_dollar(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_malloc, GNUNET_OK, GNUNET_realloc, GNUNET_strdup, LOG, prefix, result, and start.

Referenced by expand_dollar(), and GNUNET_CONFIGURATION_expand_dollar().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ escape_name()

static char * escape_name ( const char *  value)
static

FIXME.

Parameters
valueFIXME
Returns
FIXME

Definition at line 2363 of file configuration.c.

2364{
2365 char *escaped;
2366 const char *rpos;
2367 char *wpos;
2368
2369 escaped = GNUNET_malloc (strlen (value) * 2 + 1);
2370 memset (escaped, 0, strlen (value) * 2 + 1);
2371 rpos = value;
2372 wpos = escaped;
2373 while (rpos[0] != '\0')
2374 {
2375 switch (rpos[0])
2376 {
2377 case '\\':
2378 case ' ':
2379 wpos[0] = '\\';
2380 wpos[1] = rpos[0];
2381 wpos += 2;
2382 break;
2383
2384 default:
2385 wpos[0] = rpos[0];
2386 wpos++;
2387 }
2388 rpos++;
2389 }
2390 return escaped;
2391}

References GNUNET_malloc, and value.

Referenced by GNUNET_CONFIGURATION_append_value_filename(), and GNUNET_CONFIGURATION_remove_value_filename().

Here is the caller graph for this function:

◆ test_match()

static enum GNUNET_GenericReturnValue test_match ( void *  cls,
const char *  fn 
)
static

FIXME.

Parameters
clsstring we compare with (const char*)
fnfilename we are currently looking at
Returns
GNUNET_OK if the names do not match, GNUNET_SYSERR if they do

Definition at line 2402 of file configuration.c.

2404{
2405 const char *of = cls;
2406
2407 return (0 == strcmp (of, fn))
2409 : GNUNET_OK;
2410}

References GNUNET_OK, and GNUNET_SYSERR.

Referenced by GNUNET_CONFIGURATION_append_value_filename().

Here is the caller graph for this function:

◆ print_filename_option()

static void print_filename_option ( void *  cls,
const char *  section,
const char *  option,
const char *  value 
)
static

Print each option in a given section as a filename.

Parameters
clsclosure
sectionname of the section
optionname of the option
valuevalue of the option

Definition at line 2732 of file configuration.c.

2736{
2737 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
2738
2739 char *value_fn;
2740 char *fn;
2741
2744 section,
2745 option,
2746 &value_fn));
2747 fn = GNUNET_STRINGS_filename_expand (value_fn);
2748 if (NULL == fn)
2749 fn = value_fn;
2750 else
2751 GNUNET_free (value_fn);
2752 fprintf (stdout,
2753 "%s = %s\n",
2754 option,
2755 fn);
2756 GNUNET_free (fn);
2757}

References cfg, GNUNET_assert, GNUNET_CONFIGURATION_get_value_filename(), GNUNET_free, GNUNET_OK, and GNUNET_STRINGS_filename_expand().

Referenced by GNUNET_CONFIGURATION_config_tool_run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ print_option()

static void print_option ( void *  cls,
const char *  section,
const char *  option,
const char *  value 
)
static

Print each option in a given section.

Parameters
clsclosure
sectionname of the section
optionname of the option
valuevalue of the option

Definition at line 2769 of file configuration.c.

2773{
2774 (void) cls;
2775 (void) section;
2776
2777 fprintf (stdout,
2778 "%s = %s\n",
2779 option,
2780 value);
2781}

References value.

Referenced by GNUNET_CONFIGURATION_config_tool_run().

Here is the caller graph for this function:

◆ print_section_name()

static void print_section_name ( void *  cls,
const char *  section 
)
static

Print out given section name.

Parameters
clsunused
sectiona section in the configuration file

Definition at line 2791 of file configuration.c.

2793{
2794 (void) cls;
2795 fprintf (stdout,
2796 "%s\n",
2797 section);
2798}

Referenced by GNUNET_CONFIGURATION_config_tool_run().

Here is the caller graph for this function: