aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2021-07-28 20:19:38 +0200
committerFlorian Dold <florian@dold.me>2021-07-28 20:19:38 +0200
commit346706b1857dd9ec129cf40897468133f3c6bdd3 (patch)
tree0e0a90e306d80b59cdb5678a0770674d742bd676 /src/util
parent1af9f6c1c6adcbb5e5d7af154cb0134e51613a03 (diff)
downloadgnunet-346706b1857dd9ec129cf40897468133f3c6bdd3.tar.gz
gnunet-346706b1857dd9ec129cf40897468133f3c6bdd3.zip
config: extended diagnostics, import cycle detection, deterministic load order
Diffstat (limited to 'src/util')
-rw-r--r--src/util/Makefile.am1
-rw-r--r--src/util/configuration.c297
-rw-r--r--src/util/configuration_loader.c91
-rw-r--r--src/util/disk.c13
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
115struct 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
250GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg) 288GNUNET_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 */
284struct InlineGlobClosure 327struct 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 */
307static int 350static int
308inline_glob_cb (void *cls, 351collect_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 */
2071static enum GNUNET_GenericReturnValue
2072parse_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
2089enum GNUNET_GenericReturnValue 2179enum GNUNET_GenericReturnValue
2090GNUNET_CONFIGURATION_load_from (struct GNUNET_CONFIGURATION_Handle *cfg, 2180GNUNET_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 */
2296int
2297GNUNET_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 */
41int
42GNUNET_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 {