diff options
author | Florian Dold <florian@dold.me> | 2021-07-28 20:19:38 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2021-07-28 20:19:38 +0200 |
commit | 346706b1857dd9ec129cf40897468133f3c6bdd3 (patch) | |
tree | 0e0a90e306d80b59cdb5678a0770674d742bd676 /src | |
parent | 1af9f6c1c6adcbb5e5d7af154cb0134e51613a03 (diff) | |
download | gnunet-346706b1857dd9ec129cf40897468133f3c6bdd3.tar.gz gnunet-346706b1857dd9ec129cf40897468133f3c6bdd3.zip |
config: extended diagnostics, import cycle detection, deterministic load order
Diffstat (limited to 'src')
-rw-r--r-- | src/util/Makefile.am | 1 | ||||
-rw-r--r-- | src/util/configuration.c | 297 | ||||
-rw-r--r-- | src/util/configuration_loader.c | 91 | ||||
-rw-r--r-- | src/util/disk.c | 13 |
4 files changed, 257 insertions, 145 deletions
diff --git a/src/util/Makefile.am b/src/util/Makefile.am index e720112be..37eb0508b 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am | |||
@@ -49,7 +49,6 @@ libgnunetutil_la_SOURCES = \ | |||
49 | common_endian.c \ | 49 | common_endian.c \ |
50 | common_logging.c \ | 50 | common_logging.c \ |
51 | configuration.c \ | 51 | configuration.c \ |
52 | configuration_loader.c \ | ||
53 | consttime_memcmp.c \ | 52 | consttime_memcmp.c \ |
54 | container_bloomfilter.c \ | 53 | container_bloomfilter.c \ |
55 | container_heap.c \ | 54 | container_heap.c \ |
diff --git a/src/util/configuration.c b/src/util/configuration.c index fffe08788..cc71a239d 100644 --- a/src/util/configuration.c +++ b/src/util/configuration.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "gnunet_configuration_lib.h" | 29 | #include "gnunet_configuration_lib.h" |
30 | #include "gnunet_disk_lib.h" | 30 | #include "gnunet_disk_lib.h" |
31 | #include "gnunet_buffer_lib.h" | 31 | #include "gnunet_buffer_lib.h" |
32 | #include "gnunet_container_lib.h" | ||
32 | 33 | ||
33 | #define LOG(kind, ...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 34 | #define LOG(kind, ...) GNUNET_log_from (kind, "util", __VA_ARGS__) |
34 | 35 | ||
@@ -111,6 +112,23 @@ struct ConfigSection | |||
111 | unsigned int hint_inlined_from_line; | 112 | unsigned int hint_inlined_from_line; |
112 | }; | 113 | }; |
113 | 114 | ||
115 | struct ConfigFile | ||
116 | { | ||
117 | /** | ||
118 | * Source filename. | ||
119 | */ | ||
120 | char *source_filename; | ||
121 | |||
122 | /** | ||
123 | * Level in the tree of loaded config files. | ||
124 | */ | ||
125 | unsigned int level; | ||
126 | |||
127 | struct ConfigFile *prev; | ||
128 | |||
129 | struct ConfigFile *next; | ||
130 | }; | ||
131 | |||
114 | 132 | ||
115 | /** | 133 | /** |
116 | * @brief configuration data | 134 | * @brief configuration data |
@@ -123,6 +141,21 @@ struct GNUNET_CONFIGURATION_Handle | |||
123 | struct ConfigSection *sections; | 141 | struct ConfigSection *sections; |
124 | 142 | ||
125 | /** | 143 | /** |
144 | * Linked list of loaded files. | ||
145 | */ | ||
146 | struct ConfigFile *loaded_files_head; | ||
147 | |||
148 | /** | ||
149 | * Linked list of loaded files. | ||
150 | */ | ||
151 | struct ConfigFile *loaded_files_tail; | ||
152 | |||
153 | /** | ||
154 | * Current nesting level of file loading. | ||
155 | */ | ||
156 | unsigned int current_nest_level; | ||
157 | |||
158 | /** | ||
126 | * Enable diagnostics. | 159 | * Enable diagnostics. |
127 | */ | 160 | */ |
128 | bool diagnostics; | 161 | bool diagnostics; |
@@ -135,6 +168,11 @@ struct GNUNET_CONFIGURATION_Handle | |||
135 | enum GNUNET_GenericReturnValue dirty; | 168 | enum GNUNET_GenericReturnValue dirty; |
136 | 169 | ||
137 | /** | 170 | /** |
171 | * Was the configuration ever loaded via GNUNET_CONFIGURATION_load? | ||
172 | */ | ||
173 | bool load_called; | ||
174 | |||
175 | /** | ||
138 | * Name of the entry point configuration file. | 176 | * Name of the entry point configuration file. |
139 | */ | 177 | */ |
140 | char *main_filename; | 178 | char *main_filename; |
@@ -250,9 +288,14 @@ void | |||
250 | GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg) | 288 | GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg) |
251 | { | 289 | { |
252 | struct ConfigSection *sec; | 290 | struct ConfigSection *sec; |
291 | struct ConfigFile *cf; | ||
253 | 292 | ||
254 | while (NULL != (sec = cfg->sections)) | 293 | while (NULL != (sec = cfg->sections)) |
255 | GNUNET_CONFIGURATION_remove_section (cfg, sec->name); | 294 | GNUNET_CONFIGURATION_remove_section (cfg, sec->name); |
295 | while (NULL != (cf = cfg->loaded_files_head)) | ||
296 | GNUNET_CONTAINER_DLL_remove (cfg->loaded_files_head, | ||
297 | cfg->loaded_files_tail, | ||
298 | cf); | ||
256 | GNUNET_free (cfg); | 299 | GNUNET_free (cfg); |
257 | } | 300 | } |
258 | 301 | ||
@@ -279,9 +322,9 @@ GNUNET_CONFIGURATION_parse_and_run (const char *filename, | |||
279 | 322 | ||
280 | 323 | ||
281 | /** | 324 | /** |
282 | * Closure to inline_glob_cb. | 325 | * Closure to collect_files_cb. |
283 | */ | 326 | */ |
284 | struct InlineGlobClosure | 327 | struct CollectFilesContext |
285 | { | 328 | { |
286 | /** | 329 | /** |
287 | * Collected files from globbing. | 330 | * Collected files from globbing. |
@@ -305,14 +348,10 @@ struct InlineGlobClosure | |||
305 | * #GNUNET_SYSERR to abort iteration with error! | 348 | * #GNUNET_SYSERR to abort iteration with error! |
306 | */ | 349 | */ |
307 | static int | 350 | static int |
308 | inline_glob_cb (void *cls, | 351 | collect_files_cb (void *cls, |
309 | const char *filename) | 352 | const char *filename) |
310 | { | 353 | { |
311 | struct InlineGlobClosure *igc = cls; | 354 | struct CollectFilesContext *igc = cls; |
312 | |||
313 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
314 | "Found globbed config file '%s'\n", | ||
315 | filename); | ||
316 | 355 | ||
317 | GNUNET_array_append (igc->files, | 356 | GNUNET_array_append (igc->files, |
318 | igc->files_length, | 357 | igc->files_length, |
@@ -363,11 +402,12 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
363 | { | 402 | { |
364 | char *inline_path; | 403 | char *inline_path; |
365 | struct GNUNET_CONFIGURATION_Handle *other_cfg = NULL; | 404 | struct GNUNET_CONFIGURATION_Handle *other_cfg = NULL; |
366 | struct InlineGlobClosure igc = { | 405 | struct CollectFilesContext igc = { |
367 | .files = NULL, | 406 | .files = NULL, |
368 | .files_length = 0, | 407 | .files_length = 0, |
369 | }; | 408 | }; |
370 | enum GNUNET_GenericReturnValue fun_ret; | 409 | enum GNUNET_GenericReturnValue fun_ret; |
410 | unsigned int old_nest_level = cfg->current_nest_level++; | ||
371 | 411 | ||
372 | /* We support the section restriction only for non-globs */ | 412 | /* We support the section restriction only for non-globs */ |
373 | GNUNET_assert (! (path_is_glob && (NULL != restrict_section))); | 413 | GNUNET_assert (! (path_is_glob && (NULL != restrict_section))); |
@@ -419,7 +459,7 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
419 | "processing config glob '%s'\n", | 459 | "processing config glob '%s'\n", |
420 | inline_path); | 460 | inline_path); |
421 | 461 | ||
422 | nret = GNUNET_DISK_glob (inline_path, inline_glob_cb, &igc); | 462 | nret = GNUNET_DISK_glob (inline_path, collect_files_cb, &igc); |
423 | if (-1 == nret) | 463 | if (-1 == nret) |
424 | { | 464 | { |
425 | fun_ret = GNUNET_SYSERR; | 465 | fun_ret = GNUNET_SYSERR; |
@@ -441,10 +481,10 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
441 | } | 481 | } |
442 | else if (NULL != restrict_section) | 482 | else if (NULL != restrict_section) |
443 | { | 483 | { |
444 | enum GNUNET_GenericReturnValue fret; | 484 | enum GNUNET_GenericReturnValue inner_ret; |
445 | struct ConfigSection *cs; | 485 | struct ConfigSection *cs; |
446 | 486 | ||
447 | fret = GNUNET_DISK_file_test_read (inline_path); | 487 | inner_ret = GNUNET_DISK_file_test_read (inline_path); |
448 | 488 | ||
449 | cs = find_section (cfg, restrict_section); | 489 | cs = find_section (cfg, restrict_section); |
450 | 490 | ||
@@ -467,7 +507,7 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
467 | } | 507 | } |
468 | } | 508 | } |
469 | 509 | ||
470 | if (GNUNET_OK != fret) | 510 | if (GNUNET_OK != inner_ret) |
471 | { | 511 | { |
472 | cs->inaccessible = true; | 512 | cs->inaccessible = true; |
473 | fun_ret = GNUNET_OK; | 513 | fun_ret = GNUNET_OK; |
@@ -475,10 +515,11 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
475 | } | 515 | } |
476 | 516 | ||
477 | other_cfg = GNUNET_CONFIGURATION_create (); | 517 | other_cfg = GNUNET_CONFIGURATION_create (); |
478 | if (GNUNET_OK != GNUNET_CONFIGURATION_parse (other_cfg, | 518 | inner_ret = GNUNET_CONFIGURATION_parse (other_cfg, |
479 | inline_path)) | 519 | inline_path); |
520 | if (GNUNET_OK != inner_ret) | ||
480 | { | 521 | { |
481 | fun_ret = GNUNET_SYSERR; | 522 | fun_ret = inner_ret; |
482 | goto cleanup; | 523 | goto cleanup; |
483 | } | 524 | } |
484 | 525 | ||
@@ -513,6 +554,7 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
513 | fun_ret = GNUNET_OK; | 554 | fun_ret = GNUNET_OK; |
514 | } | 555 | } |
515 | cleanup: | 556 | cleanup: |
557 | cfg->current_nest_level = old_nest_level; | ||
516 | if (NULL != other_cfg) | 558 | if (NULL != other_cfg) |
517 | GNUNET_CONFIGURATION_destroy (other_cfg); | 559 | GNUNET_CONFIGURATION_destroy (other_cfg); |
518 | GNUNET_free (inline_path); | 560 | GNUNET_free (inline_path); |
@@ -756,11 +798,7 @@ GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
756 | } | 798 | } |
757 | if (GNUNET_OK != directive_ret) | 799 | if (GNUNET_OK != directive_ret) |
758 | { | 800 | { |
759 | LOG (GNUNET_ERROR_TYPE_WARNING, | 801 | ret = directive_ret; |
760 | _ ("Bad directive '%s' in line %u\n"), | ||
761 | directive, | ||
762 | nr); | ||
763 | ret = GNUNET_SYSERR; | ||
764 | break; | 802 | break; |
765 | } | 803 | } |
766 | continue; | 804 | continue; |
@@ -845,6 +883,55 @@ GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
845 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to parse config file `%s'\n", fn); | 883 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to parse config file `%s'\n", fn); |
846 | if (NULL == fn) | 884 | if (NULL == fn) |
847 | return GNUNET_SYSERR; | 885 | return GNUNET_SYSERR; |
886 | |||
887 | |||
888 | /* Check for cycles */ | ||
889 | { | ||
890 | unsigned int lvl = cfg->current_nest_level; | ||
891 | struct ConfigFile *cf = cfg->loaded_files_tail; | ||
892 | struct ConfigFile *parent = NULL; | ||
893 | |||
894 | |||
895 | for (; NULL != cf; parent = cf, cf = cf->prev) | ||
896 | { | ||
897 | /* Check parents based on level, skipping children of siblings. */ | ||
898 | if (cf->level >= lvl) | ||
899 | continue; | ||
900 | lvl = cf->level; | ||
901 | if ( (NULL == cf->source_filename) || (NULL == filename)) | ||
902 | continue; | ||
903 | if (0 == strcmp (cf->source_filename, filename)) | ||
904 | { | ||
905 | if (NULL == parent) | ||
906 | { | ||
907 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
908 | "Forbidden direct cyclic configuration import (%s -> %s)\n", | ||
909 | cf->source_filename, | ||
910 | filename); | ||
911 | } | ||
912 | else | ||
913 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
914 | "Forbidden indirect cyclic configuration import (%s -> ... -> %s -> %s)\n", | ||
915 | cf->source_filename, | ||
916 | parent->source_filename, | ||
917 | filename); | ||
918 | return GNUNET_SYSERR; | ||
919 | } | ||
920 | } | ||
921 | |||
922 | } | ||
923 | |||
924 | /* Keep track of loaded files.*/ | ||
925 | { | ||
926 | struct ConfigFile *cf = GNUNET_new (struct ConfigFile); | ||
927 | |||
928 | cf->level = cfg->current_nest_level; | ||
929 | cf->source_filename = GNUNET_strdup (filename ? filename : "<input>"); | ||
930 | GNUNET_CONTAINER_DLL_insert_tail (cfg->loaded_files_head, | ||
931 | cfg->loaded_files_tail, | ||
932 | cf); | ||
933 | } | ||
934 | |||
848 | dirty = cfg->dirty; /* back up value! */ | 935 | dirty = cfg->dirty; /* back up value! */ |
849 | if (GNUNET_SYSERR == | 936 | if (GNUNET_SYSERR == |
850 | GNUNET_DISK_file_size (fn, &fs64, GNUNET_YES, GNUNET_YES)) | 937 | GNUNET_DISK_file_size (fn, &fs64, GNUNET_YES, GNUNET_YES)) |
@@ -876,7 +963,7 @@ GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
876 | mem, | 963 | mem, |
877 | fs, | 964 | fs, |
878 | fn); | 965 | fn); |
879 | if (GNUNET_OK != ret) | 966 | if (GNUNET_SYSERR == ret) |
880 | { | 967 | { |
881 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 968 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
882 | _ ("Failed to parse configuration file `%s'\n"), | 969 | _ ("Failed to parse configuration file `%s'\n"), |
@@ -1036,6 +1123,36 @@ GNUNET_CONFIGURATION_serialize_diagnostics (const struct | |||
1036 | { | 1123 | { |
1037 | struct GNUNET_Buffer buf = { 0 }; | 1124 | struct GNUNET_Buffer buf = { 0 }; |
1038 | 1125 | ||
1126 | GNUNET_buffer_write_fstr (&buf, | ||
1127 | "#\n# Configuration file diagnostics\n#\n"); | ||
1128 | GNUNET_buffer_write_fstr (&buf, | ||
1129 | "# Entry point: %s\n", | ||
1130 | cfg->main_filename ? cfg->main_filename : | ||
1131 | "<input>"); | ||
1132 | GNUNET_buffer_write_fstr (&buf, | ||
1133 | "#\n# Files Loaded:\n"); | ||
1134 | |||
1135 | for (struct ConfigFile *cfil = cfg->loaded_files_head; | ||
1136 | NULL != cfil; | ||
1137 | cfil = cfil->next) | ||
1138 | { | ||
1139 | GNUNET_buffer_write_fstr (&buf, | ||
1140 | "# "); | ||
1141 | for (unsigned int i = 0; i < cfil->level; i++) | ||
1142 | GNUNET_buffer_write_fstr (&buf, | ||
1143 | "+"); | ||
1144 | if (0 != cfil->level) | ||
1145 | GNUNET_buffer_write_fstr (&buf, | ||
1146 | " "); | ||
1147 | |||
1148 | GNUNET_buffer_write_fstr (&buf, | ||
1149 | "%s\n", | ||
1150 | cfil->source_filename); | ||
1151 | } | ||
1152 | |||
1153 | GNUNET_buffer_write_fstr (&buf, | ||
1154 | "#\n\n"); | ||
1155 | |||
1039 | for (struct ConfigSection *sec = cfg->sections; | 1156 | for (struct ConfigSection *sec = cfg->sections; |
1040 | NULL != sec; | 1157 | NULL != sec; |
1041 | sec = sec->next) | 1158 | sec = sec->next) |
@@ -2059,41 +2176,51 @@ GNUNET_CONFIGURATION_remove_value_filename ( | |||
2059 | } | 2176 | } |
2060 | 2177 | ||
2061 | 2178 | ||
2062 | /** | ||
2063 | * Wrapper around #GNUNET_CONFIGURATION_parse. Called on each | ||
2064 | * file in a directory, we trigger parsing on those files that | ||
2065 | * end with ".conf". | ||
2066 | * | ||
2067 | * @param cls the cfg | ||
2068 | * @param filename file to parse | ||
2069 | * @return #GNUNET_OK on success | ||
2070 | */ | ||
2071 | static enum GNUNET_GenericReturnValue | ||
2072 | parse_configuration_file (void *cls, const char *filename) | ||
2073 | { | ||
2074 | struct GNUNET_CONFIGURATION_Handle *cfg = cls; | ||
2075 | char *ext; | ||
2076 | |||
2077 | /* Examine file extension */ | ||
2078 | ext = strrchr (filename, '.'); | ||
2079 | if ((NULL == ext) || (0 != strcmp (ext, ".conf"))) | ||
2080 | { | ||
2081 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Skipping file `%s'\n", filename); | ||
2082 | return GNUNET_OK; | ||
2083 | } | ||
2084 | |||
2085 | return GNUNET_CONFIGURATION_parse (cfg, filename); | ||
2086 | } | ||
2087 | |||
2088 | |||
2089 | enum GNUNET_GenericReturnValue | 2179 | enum GNUNET_GenericReturnValue |
2090 | GNUNET_CONFIGURATION_load_from (struct GNUNET_CONFIGURATION_Handle *cfg, | 2180 | GNUNET_CONFIGURATION_load_from (struct GNUNET_CONFIGURATION_Handle *cfg, |
2091 | const char *defaults_d) | 2181 | const char *defaults_d) |
2092 | { | 2182 | { |
2183 | struct CollectFilesContext files_context = { | ||
2184 | .files = NULL, | ||
2185 | .files_length = 0, | ||
2186 | }; | ||
2187 | enum GNUNET_GenericReturnValue fun_ret; | ||
2188 | |||
2093 | if (GNUNET_SYSERR == | 2189 | if (GNUNET_SYSERR == |
2094 | GNUNET_DISK_directory_scan (defaults_d, &parse_configuration_file, cfg)) | 2190 | GNUNET_DISK_directory_scan (defaults_d, &collect_files_cb, |
2191 | &files_context)) | ||
2095 | return GNUNET_SYSERR; /* no configuration at all found */ | 2192 | return GNUNET_SYSERR; /* no configuration at all found */ |
2096 | return GNUNET_OK; | 2193 | qsort (files_context.files, |
2194 | files_context.files_length, | ||
2195 | sizeof (char *), | ||
2196 | pstrcmp); | ||
2197 | for (unsigned int i = 0; i < files_context.files_length; i++) | ||
2198 | { | ||
2199 | char *ext; | ||
2200 | const char *filename = files_context.files[i]; | ||
2201 | |||
2202 | /* Examine file extension */ | ||
2203 | ext = strrchr (filename, '.'); | ||
2204 | if ((NULL == ext) || (0 != strcmp (ext, ".conf"))) | ||
2205 | { | ||
2206 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Skipping file `%s'\n", filename); | ||
2207 | fun_ret = GNUNET_OK; | ||
2208 | goto cleanup; | ||
2209 | } | ||
2210 | fun_ret = GNUNET_CONFIGURATION_parse (cfg, filename); | ||
2211 | if (fun_ret != GNUNET_OK) | ||
2212 | break; | ||
2213 | } | ||
2214 | cleanup: | ||
2215 | if (files_context.files_length > 0) | ||
2216 | { | ||
2217 | for (size_t i = 0; i < files_context.files_length; i++) | ||
2218 | GNUNET_free (files_context.files[i]); | ||
2219 | GNUNET_array_grow (files_context.files, | ||
2220 | files_context.files_length, | ||
2221 | 0); | ||
2222 | } | ||
2223 | return fun_ret; | ||
2097 | } | 2224 | } |
2098 | 2225 | ||
2099 | 2226 | ||
@@ -2158,5 +2285,71 @@ GNUNET_CONFIGURATION_default (void) | |||
2158 | return cfg; | 2285 | return cfg; |
2159 | } | 2286 | } |
2160 | 2287 | ||
2288 | /** | ||
2289 | * Load configuration (starts with defaults, then loads | ||
2290 | * system-specific configuration). | ||
2291 | * | ||
2292 | * @param cfg configuration to update | ||
2293 | * @param filename name of the configuration file, NULL to load defaults | ||
2294 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
2295 | */ | ||
2296 | int | ||
2297 | GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg, | ||
2298 | const char *filename) | ||
2299 | { | ||
2300 | char *baseconfig; | ||
2301 | const char *base_config_varname; | ||
2302 | |||
2303 | if (cfg->load_called) | ||
2304 | { | ||
2305 | /* FIXME: Make this a GNUNET_assert later */ | ||
2306 | GNUNET_break (0); | ||
2307 | GNUNET_free (cfg->main_filename); | ||
2308 | } | ||
2309 | cfg->load_called = true; | ||
2310 | if (NULL != filename) | ||
2311 | cfg->main_filename = GNUNET_strdup (filename); | ||
2312 | |||
2313 | base_config_varname = GNUNET_OS_project_data_get ()->base_config_varname; | ||
2314 | |||
2315 | if ((NULL != base_config_varname) | ||
2316 | && (NULL != (baseconfig = getenv (base_config_varname)))) | ||
2317 | { | ||
2318 | baseconfig = GNUNET_strdup (baseconfig); | ||
2319 | } | ||
2320 | else | ||
2321 | { | ||
2322 | char *ipath; | ||
2323 | |||
2324 | ipath = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); | ||
2325 | if (NULL == ipath) | ||
2326 | return GNUNET_SYSERR; | ||
2327 | GNUNET_asprintf (&baseconfig, "%s%s", ipath, "config.d"); | ||
2328 | GNUNET_free (ipath); | ||
2329 | } | ||
2330 | |||
2331 | char *dname = GNUNET_STRINGS_filename_expand (baseconfig); | ||
2332 | GNUNET_free (baseconfig); | ||
2333 | |||
2334 | if ((GNUNET_YES == GNUNET_DISK_directory_test (dname, GNUNET_YES))&& | ||
2335 | (GNUNET_SYSERR == GNUNET_CONFIGURATION_load_from (cfg, dname))) | ||
2336 | { | ||
2337 | GNUNET_free (dname); | ||
2338 | return GNUNET_SYSERR; /* no configuration at all found */ | ||
2339 | } | ||
2340 | GNUNET_free (dname); | ||
2341 | if ((NULL != filename) && | ||
2342 | (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, filename))) | ||
2343 | { | ||
2344 | /* specified configuration not found */ | ||
2345 | return GNUNET_SYSERR; | ||
2346 | } | ||
2347 | if (((GNUNET_YES != | ||
2348 | GNUNET_CONFIGURATION_have_value (cfg, "PATHS", "DEFAULTCONFIG"))) && | ||
2349 | (filename != NULL)) | ||
2350 | GNUNET_CONFIGURATION_set_value_string (cfg, "PATHS", "DEFAULTCONFIG", | ||
2351 | filename); | ||
2352 | return GNUNET_OK; | ||
2353 | } | ||
2161 | 2354 | ||
2162 | /* end of configuration.c */ | 2355 | /* end of configuration.c */ |
diff --git a/src/util/configuration_loader.c b/src/util/configuration_loader.c deleted file mode 100644 index a59477b25..000000000 --- a/src/util/configuration_loader.c +++ /dev/null | |||
@@ -1,91 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2006, 2007, 2008, 2009, 2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file src/util/configuration_loader.c | ||
23 | * @brief configuration loading | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | |||
30 | #define LOG(kind, ...) GNUNET_log_from (kind, "util-configuration", __VA_ARGS__) | ||
31 | |||
32 | |||
33 | /** | ||
34 | * Load configuration (starts with defaults, then loads | ||
35 | * system-specific configuration). | ||
36 | * | ||
37 | * @param cfg configuration to update | ||
38 | * @param filename name of the configuration file, NULL to load defaults | ||
39 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
40 | */ | ||
41 | int | ||
42 | GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg, | ||
43 | const char *filename) | ||
44 | { | ||
45 | char *baseconfig; | ||
46 | const char *base_config_varname; | ||
47 | |||
48 | base_config_varname = GNUNET_OS_project_data_get ()->base_config_varname; | ||
49 | |||
50 | if (NULL != base_config_varname | ||
51 | && NULL != (baseconfig = getenv (base_config_varname))) | ||
52 | { | ||
53 | baseconfig = GNUNET_strdup (baseconfig); | ||
54 | } | ||
55 | else | ||
56 | { | ||
57 | char *ipath; | ||
58 | |||
59 | ipath = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); | ||
60 | if (NULL == ipath) | ||
61 | return GNUNET_SYSERR; | ||
62 | GNUNET_asprintf (&baseconfig, "%s%s", ipath, "config.d"); | ||
63 | GNUNET_free (ipath); | ||
64 | } | ||
65 | |||
66 | char *dname = GNUNET_STRINGS_filename_expand (baseconfig); | ||
67 | GNUNET_free (baseconfig); | ||
68 | |||
69 | if (GNUNET_YES == GNUNET_DISK_directory_test (dname, GNUNET_YES) && | ||
70 | GNUNET_SYSERR == GNUNET_CONFIGURATION_load_from (cfg, dname)) | ||
71 | { | ||
72 | GNUNET_free (dname); | ||
73 | return GNUNET_SYSERR; /* no configuration at all found */ | ||
74 | } | ||
75 | GNUNET_free (dname); | ||
76 | if ((NULL != filename) && | ||
77 | (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, filename))) | ||
78 | { | ||
79 | /* specified configuration not found */ | ||
80 | return GNUNET_SYSERR; | ||
81 | } | ||
82 | if (((GNUNET_YES != | ||
83 | GNUNET_CONFIGURATION_have_value (cfg, "PATHS", "DEFAULTCONFIG"))) && | ||
84 | (filename != NULL)) | ||
85 | GNUNET_CONFIGURATION_set_value_string (cfg, "PATHS", "DEFAULTCONFIG", | ||
86 | filename); | ||
87 | return GNUNET_OK; | ||
88 | } | ||
89 | |||
90 | |||
91 | /* end of configuration_loader.c */ | ||
diff --git a/src/util/disk.c b/src/util/disk.c index f68b32db5..1b6934082 100644 --- a/src/util/disk.c +++ b/src/util/disk.c | |||
@@ -434,7 +434,7 @@ GNUNET_DISK_directory_test (const char *fil, int is_readable) | |||
434 | 434 | ||
435 | /** | 435 | /** |
436 | * Check if fil can be accessed using amode. | 436 | * Check if fil can be accessed using amode. |
437 | * | 437 | * |
438 | * @param fil file to check for | 438 | * @param fil file to check for |
439 | * @param amode access mode | 439 | * @param amode access mode |
440 | * @returns GNUnet error code | 440 | * @returns GNUnet error code |
@@ -1002,6 +1002,17 @@ GNUNET_DISK_glob (const char *glob_pattern, | |||
1002 | char *sep; | 1002 | char *sep; |
1003 | int ret; | 1003 | int ret; |
1004 | 1004 | ||
1005 | if ( (NULL != strrchr (glob_pattern, '+')) || | ||
1006 | (NULL != strrchr (glob_pattern, '[')) || | ||
1007 | (NULL != strrchr (glob_pattern, '+')) || | ||
1008 | (NULL != strrchr (glob_pattern, '~')) ) | ||
1009 | { | ||
1010 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
1011 | "unsupported glob pattern: '%s'\n", | ||
1012 | glob_pattern); | ||
1013 | return -1; | ||
1014 | } | ||
1015 | |||
1005 | sep = strrchr (mypat, DIR_SEPARATOR); | 1016 | sep = strrchr (mypat, DIR_SEPARATOR); |
1006 | if (NULL == sep) | 1017 | if (NULL == sep) |
1007 | { | 1018 | { |