diff options
author | t3sserakt <t3ss@posteo.de> | 2021-07-30 14:54:23 +0200 |
---|---|---|
committer | t3sserakt <t3ss@posteo.de> | 2021-07-30 14:54:23 +0200 |
commit | 6d4120e96a52cbd38fb761b03485303b5000215a (patch) | |
tree | f87edf470ec9778076233245361f3434f3d08f14 /src | |
parent | 4748af6e8e04347ceaeec09ccdfc04d740fa65f0 (diff) | |
parent | e84ea6f9f1718298486a088832c87479bd6e9572 (diff) | |
download | gnunet-6d4120e96a52cbd38fb761b03485303b5000215a.tar.gz gnunet-6d4120e96a52cbd38fb761b03485303b5000215a.zip |
:Merge branch 'master' of ssh://gnunet.org/gnunet
Diffstat (limited to 'src')
-rw-r--r-- | src/ats-tests/Makefile.am | 1 | ||||
-rw-r--r-- | src/consensus/Makefile.am | 1 | ||||
-rw-r--r-- | src/dht/Makefile.am | 1 | ||||
-rw-r--r-- | src/fs/Makefile.am | 1 | ||||
-rw-r--r-- | src/include/gnunet_configuration_lib.h | 35 | ||||
-rw-r--r-- | src/json/Makefile.am | 7 | ||||
-rw-r--r-- | src/json/json_pack.c | 6 | ||||
-rw-r--r-- | src/nse/Makefile.am | 1 | ||||
-rw-r--r-- | src/regex/Makefile.am | 1 | ||||
-rw-r--r-- | src/secretsharing/Makefile.am | 1 | ||||
-rw-r--r-- | src/testbed/Makefile.am | 2 | ||||
-rw-r--r-- | src/transport/Makefile.am | 28 | ||||
-rw-r--r-- | src/util/Makefile.am | 7 | ||||
-rw-r--r-- | src/util/configuration.c | 804 | ||||
-rw-r--r-- | src/util/configuration_loader.c | 91 | ||||
-rw-r--r-- | src/util/disk.c | 34 | ||||
-rw-r--r-- | src/util/gnunet-config.c | 51 | ||||
-rw-r--r-- | src/util/plugin.c | 6 | ||||
-rw-r--r-- | src/util/program.c | 31 | ||||
-rw-r--r-- | src/util/test_plugin.c | 52 | ||||
-rw-r--r-- | src/util/test_plugin_plug.c | 5 |
21 files changed, 864 insertions, 302 deletions
diff --git a/src/ats-tests/Makefile.am b/src/ats-tests/Makefile.am index 543fed287..d515d3e17 100644 --- a/src/ats-tests/Makefile.am +++ b/src/ats-tests/Makefile.am | |||
@@ -61,6 +61,7 @@ gnunet_ats_sim_SOURCES = \ | |||
61 | gnunet_ats_sim_LDADD = \ | 61 | gnunet_ats_sim_LDADD = \ |
62 | $(top_builddir)/src/util/libgnunetutil.la \ | 62 | $(top_builddir)/src/util/libgnunetutil.la \ |
63 | $(top_builddir)/src/ats-tests/libgnunetatstesting.la \ | 63 | $(top_builddir)/src/ats-tests/libgnunetatstesting.la \ |
64 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
64 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | 65 | $(top_builddir)/src/testbed/libgnunettestbed.la \ |
65 | $(top_builddir)/src/ats/libgnunetats.la \ | 66 | $(top_builddir)/src/ats/libgnunetats.la \ |
66 | $(top_builddir)/src/core/libgnunetcore.la \ | 67 | $(top_builddir)/src/core/libgnunetcore.la \ |
diff --git a/src/consensus/Makefile.am b/src/consensus/Makefile.am index 24e685fb9..cf1d32e74 100644 --- a/src/consensus/Makefile.am +++ b/src/consensus/Makefile.am | |||
@@ -40,6 +40,7 @@ gnunet_consensus_profiler_SOURCES = \ | |||
40 | gnunet_consensus_profiler_LDADD = \ | 40 | gnunet_consensus_profiler_LDADD = \ |
41 | $(top_builddir)/src/util/libgnunetutil.la \ | 41 | $(top_builddir)/src/util/libgnunetutil.la \ |
42 | libgnunetconsensus.la \ | 42 | libgnunetconsensus.la \ |
43 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
43 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | 44 | $(top_builddir)/src/testbed/libgnunettestbed.la \ |
44 | $(GN_LIBINTL) | 45 | $(GN_LIBINTL) |
45 | 46 | ||
diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am index 2182d1c7f..919eca438 100644 --- a/src/dht/Makefile.am +++ b/src/dht/Makefile.am | |||
@@ -112,6 +112,7 @@ gnunet_dht_profiler_LDADD = \ | |||
112 | libgnunetdht.la \ | 112 | libgnunetdht.la \ |
113 | $(top_builddir)/src/core/libgnunetcore.la \ | 113 | $(top_builddir)/src/core/libgnunetcore.la \ |
114 | $(top_builddir)/src/util/libgnunetutil.la \ | 114 | $(top_builddir)/src/util/libgnunetutil.la \ |
115 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
115 | $(top_builddir)/src/testbed/libgnunettestbed.la | 116 | $(top_builddir)/src/testbed/libgnunettestbed.la |
116 | gnunet_dht_profiler_LDFLAGS = \ | 117 | gnunet_dht_profiler_LDFLAGS = \ |
117 | $(GN_LIBINTL) | 118 | $(GN_LIBINTL) |
diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am index 25590c6f7..2400d412e 100644 --- a/src/fs/Makefile.am +++ b/src/fs/Makefile.am | |||
@@ -105,6 +105,7 @@ endif | |||
105 | gnunet_fs_profiler_SOURCES = \ | 105 | gnunet_fs_profiler_SOURCES = \ |
106 | gnunet-fs-profiler.c | 106 | gnunet-fs-profiler.c |
107 | gnunet_fs_profiler_LDADD = \ | 107 | gnunet_fs_profiler_LDADD = \ |
108 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
108 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | 109 | $(top_builddir)/src/testbed/libgnunettestbed.la \ |
109 | $(top_builddir)/src/util/libgnunetutil.la \ | 110 | $(top_builddir)/src/util/libgnunetutil.la \ |
110 | $(GN_LIBINTL) | 111 | $(GN_LIBINTL) |
diff --git a/src/include/gnunet_configuration_lib.h b/src/include/gnunet_configuration_lib.h index 68ed570a3..02e656196 100644 --- a/src/include/gnunet_configuration_lib.h +++ b/src/include/gnunet_configuration_lib.h | |||
@@ -113,6 +113,18 @@ GNUNET_CONFIGURATION_default (void); | |||
113 | 113 | ||
114 | 114 | ||
115 | /** | 115 | /** |
116 | * Return the filename of the default configuration filename | ||
117 | * that is used when no explicit configuration entry point | ||
118 | * has been specified. | ||
119 | * | ||
120 | * @returns NULL if no default configuration file can be located, | ||
121 | * a newly allocated string otherwise | ||
122 | */ | ||
123 | char * | ||
124 | GNUNET_CONFIGURATION_default_filename (void); | ||
125 | |||
126 | |||
127 | /** | ||
116 | * Parse a configuration file, add all of the options in the | 128 | * Parse a configuration file, add all of the options in the |
117 | * file to the configuration environment. | 129 | * file to the configuration environment. |
118 | * | 130 | * |
@@ -139,6 +151,19 @@ GNUNET_CONFIGURATION_serialize (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
139 | 151 | ||
140 | 152 | ||
141 | /** | 153 | /** |
154 | * Serializes the given configuration with diagnostics information. | ||
155 | * Diagnostics information will only be available if diagnostics | ||
156 | * have been enabled before parsing. | ||
157 | * | ||
158 | * @param cfg configuration to serialize | ||
159 | * @return the memory block where the serialized configuration is | ||
160 | * present. This memory should be freed by the caller | ||
161 | */ | ||
162 | char * | ||
163 | GNUNET_CONFIGURATION_serialize_diagnostics (const struct | ||
164 | GNUNET_CONFIGURATION_Handle *cfg); | ||
165 | |||
166 | /** | ||
142 | * De-serializes configuration | 167 | * De-serializes configuration |
143 | * | 168 | * |
144 | * @param cfg configuration to update | 169 | * @param cfg configuration to update |
@@ -234,6 +259,16 @@ GNUNET_CONFIGURATION_parse_and_run (const char *filename, | |||
234 | GNUNET_CONFIGURATION_Callback cb, | 259 | GNUNET_CONFIGURATION_Callback cb, |
235 | void *cb_cls); | 260 | void *cb_cls); |
236 | 261 | ||
262 | /** | ||
263 | * Enable extra diagnostics. Will produce more log output | ||
264 | * and allocate more memory. | ||
265 | * | ||
266 | * @param cfg configuration handle | ||
267 | */ | ||
268 | void | ||
269 | GNUNET_CONFIGURATION_enable_diagnostics (struct | ||
270 | GNUNET_CONFIGURATION_Handle *cfg); | ||
271 | |||
237 | 272 | ||
238 | /** | 273 | /** |
239 | * Function to iterate over options. | 274 | * Function to iterate over options. |
diff --git a/src/json/Makefile.am b/src/json/Makefile.am index 3c19f96bf..2e97cecb9 100644 --- a/src/json/Makefile.am +++ b/src/json/Makefile.am | |||
@@ -13,7 +13,9 @@ libgnunetjson_la_LDFLAGS = \ | |||
13 | $(GN_LIBINTL) \ | 13 | $(GN_LIBINTL) \ |
14 | -version-info 0:0:0 \ | 14 | -version-info 0:0:0 \ |
15 | -no-undefined | 15 | -no-undefined |
16 | libgnunetjson_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS) | 16 | libgnunetjson_la_CFLAGS = \ |
17 | $(MHD_CFLAGS) \ | ||
18 | $(AM_CFLAGS) | ||
17 | libgnunetjson_la_SOURCES = \ | 19 | libgnunetjson_la_SOURCES = \ |
18 | json.c \ | 20 | json.c \ |
19 | json_generator.c \ | 21 | json_generator.c \ |
@@ -26,9 +28,6 @@ libgnunetjson_la_LIBADD = \ | |||
26 | $(MHD_LIBS) \ | 28 | $(MHD_LIBS) \ |
27 | $(XLIB) \ | 29 | $(XLIB) \ |
28 | $(Z_LIBS) | 30 | $(Z_LIBS) |
29 | libgnunetjson_la_DEPENDENCIES = \ | ||
30 | $(top_builddir)/src/util/libgnunetutil.la | ||
31 | |||
32 | 31 | ||
33 | check_PROGRAMS = \ | 32 | check_PROGRAMS = \ |
34 | test_json \ | 33 | test_json \ |
diff --git a/src/json/json_pack.c b/src/json/json_pack.c index 20db47cd4..d86baff41 100644 --- a/src/json/json_pack.c +++ b/src/json/json_pack.c | |||
@@ -109,7 +109,7 @@ GNUNET_JSON_pack_uint64 (const char *name, | |||
109 | }; | 109 | }; |
110 | 110 | ||
111 | #if JSON_INTEGER_IS_LONG_LONG | 111 | #if JSON_INTEGER_IS_LONG_LONG |
112 | GNUNET_assert (num <= LONG_LONG_MAX); | 112 | GNUNET_assert (num <= LLONG_MAX); |
113 | #else | 113 | #else |
114 | GNUNET_assert (num <= LONG_MAX); | 114 | GNUNET_assert (num <= LONG_MAX); |
115 | #endif | 115 | #endif |
@@ -127,8 +127,8 @@ GNUNET_JSON_pack_int64 (const char *name, | |||
127 | }; | 127 | }; |
128 | 128 | ||
129 | #if JSON_INTEGER_IS_LONG_LONG | 129 | #if JSON_INTEGER_IS_LONG_LONG |
130 | GNUNET_assert (num <= LONG_LONG_MAX); | 130 | GNUNET_assert (num <= LLONG_MAX); |
131 | GNUNET_assert (num >= LONG_LONG_MIN); | 131 | GNUNET_assert (num >= LLONG_MIN); |
132 | #else | 132 | #else |
133 | GNUNET_assert (num <= LONG_MAX); | 133 | GNUNET_assert (num <= LONG_MAX); |
134 | GNUNET_assert (num >= LONG_MIN); | 134 | GNUNET_assert (num >= LONG_MIN); |
diff --git a/src/nse/Makefile.am b/src/nse/Makefile.am index 85ae4d3be..824aa10d4 100644 --- a/src/nse/Makefile.am +++ b/src/nse/Makefile.am | |||
@@ -47,6 +47,7 @@ gnunet_nse_profiler_LDADD = -lm \ | |||
47 | libgnunetnse.la \ | 47 | libgnunetnse.la \ |
48 | $(top_builddir)/src/util/libgnunetutil.la \ | 48 | $(top_builddir)/src/util/libgnunetutil.la \ |
49 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 49 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
50 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
50 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | 51 | $(top_builddir)/src/testbed/libgnunettestbed.la \ |
51 | $(GN_LIBINTL) | 52 | $(GN_LIBINTL) |
52 | 53 | ||
diff --git a/src/regex/Makefile.am b/src/regex/Makefile.am index 13413f242..0b55d134f 100644 --- a/src/regex/Makefile.am +++ b/src/regex/Makefile.am | |||
@@ -126,6 +126,7 @@ gnunet_regex_profiler_SOURCES = \ | |||
126 | gnunet-regex-profiler.c | 126 | gnunet-regex-profiler.c |
127 | gnunet_regex_profiler_LDADD = -lm \ | 127 | gnunet_regex_profiler_LDADD = -lm \ |
128 | $(top_builddir)/src/arm/libgnunetarm.la \ | 128 | $(top_builddir)/src/arm/libgnunetarm.la \ |
129 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
129 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | 130 | $(top_builddir)/src/testbed/libgnunettestbed.la \ |
130 | libgnunetregex_internal.a \ | 131 | libgnunetregex_internal.a \ |
131 | $(top_builddir)/src/dht/libgnunetdht.la \ | 132 | $(top_builddir)/src/dht/libgnunetdht.la \ |
diff --git a/src/secretsharing/Makefile.am b/src/secretsharing/Makefile.am index 787cfa0c1..9ae6e7892 100644 --- a/src/secretsharing/Makefile.am +++ b/src/secretsharing/Makefile.am | |||
@@ -24,6 +24,7 @@ gnunet_secretsharing_profiler_SOURCES = \ | |||
24 | gnunet-secretsharing-profiler.c | 24 | gnunet-secretsharing-profiler.c |
25 | gnunet_secretsharing_profiler_LDADD = \ | 25 | gnunet_secretsharing_profiler_LDADD = \ |
26 | libgnunetsecretsharing.la \ | 26 | libgnunetsecretsharing.la \ |
27 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
27 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | 28 | $(top_builddir)/src/testbed/libgnunettestbed.la \ |
28 | $(top_builddir)/src/util/libgnunetutil.la \ | 29 | $(top_builddir)/src/util/libgnunetutil.la \ |
29 | $(GN_LIBINTL) | 30 | $(GN_LIBINTL) |
diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am index 347d16007..b4b2cff97 100644 --- a/src/testbed/Makefile.am +++ b/src/testbed/Makefile.am | |||
@@ -76,6 +76,7 @@ gnunet_service_testbed_LDADD = $(XLIB) \ | |||
76 | gnunet_testbed_profiler_SOURCES = \ | 76 | gnunet_testbed_profiler_SOURCES = \ |
77 | gnunet-testbed-profiler.c | 77 | gnunet-testbed-profiler.c |
78 | gnunet_testbed_profiler_LDADD = $(XLIB) \ | 78 | gnunet_testbed_profiler_LDADD = $(XLIB) \ |
79 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
79 | $(top_builddir)/src/util/libgnunetutil.la \ | 80 | $(top_builddir)/src/util/libgnunetutil.la \ |
80 | libgnunettestbed.la | 81 | libgnunettestbed.la |
81 | gnunet_testbed_profiler_LDFLAGS = \ | 82 | gnunet_testbed_profiler_LDFLAGS = \ |
@@ -169,6 +170,7 @@ libgnunettestbed_la_LDFLAGS = \ | |||
169 | 170 | ||
170 | generate_underlay_topology_SOURCES = generate-underlay-topology.c | 171 | generate_underlay_topology_SOURCES = generate-underlay-topology.c |
171 | generate_underlay_topology_LDADD = $(XLIB) \ | 172 | generate_underlay_topology_LDADD = $(XLIB) \ |
173 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
172 | $(top_builddir)/src/util/libgnunetutil.la \ | 174 | $(top_builddir)/src/util/libgnunetutil.la \ |
173 | libgnunettestbed.la \ | 175 | libgnunettestbed.la \ |
174 | $(LTLIBINTL) -lsqlite3 | 176 | $(LTLIBINTL) -lsqlite3 |
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index e19ebd8e9..55a338729 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am | |||
@@ -398,20 +398,20 @@ plugin_LTLIBRARIES = \ | |||
398 | $(HTTP_SERVER_PLUGIN_LA) \ | 398 | $(HTTP_SERVER_PLUGIN_LA) \ |
399 | $(HTTPS_SERVER_PLUGIN_LA) \ | 399 | $(HTTPS_SERVER_PLUGIN_LA) \ |
400 | $(WLAN_PLUGIN_LA) \ | 400 | $(WLAN_PLUGIN_LA) \ |
401 | $(BT_PLUGIN_LA) \ | 401 | $(BT_PLUGIN_LA) |
402 | libgnunet_plugin_cmd_simple_send.la | 402 | # libgnunet_plugin_cmd_simple_send.la |
403 | 403 | ||
404 | libgnunet_plugin_cmd_simple_send_la_SOURCES = \ | 404 | #libgnunet_plugin_cmd_simple_send_la_SOURCES = \ |
405 | plugin_cmd_simple_send.c | 405 | # plugin_cmd_simple_send.c |
406 | libgnunet_plugin_cmd_simple_send_la_LIBADD = \ | 406 | #libgnunet_plugin_cmd_simple_send_la_LIBADD = \ |
407 | $(top_builddir)/src/util/libgnunetutil.la \ | 407 | # $(top_builddir)/src/util/libgnunetutil.la \ |
408 | $(top_builddir)/src/testing/libgnunettesting.la \ | 408 | # $(top_builddir)/src/testing/libgnunettesting.la \ |
409 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 409 | # $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
410 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | 410 | # $(top_builddir)/src/testbed/libgnunettestbed.la \ |
411 | libgnunettransporttesting2.la \ | 411 | # libgnunettransporttesting2.la \ |
412 | $(LTLIBINTL) | 412 | # $(LTLIBINTL) |
413 | libgnunet_plugin_cmd_simple_send_la_LDFLAGS = \ | 413 | #libgnunet_plugin_cmd_simple_send_la_LDFLAGS = \ |
414 | $(GN_PLUGIN_LDFLAGS) | 414 | # $(GN_PLUGIN_LDFLAGS) |
415 | 415 | ||
416 | if HAVE_EXPERIMENTAL | 416 | if HAVE_EXPERIMENTAL |
417 | plugin_LTLIBRARIES += libgnunet_plugin_transport_udp.la | 417 | plugin_LTLIBRARIES += libgnunet_plugin_transport_udp.la |
diff --git a/src/util/Makefile.am b/src/util/Makefile.am index e720112be..89d040a0c 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 \ |
@@ -243,11 +242,11 @@ gnunet_qr_LDADD = \ | |||
243 | gnunet_qr_LDFLAGS= -lzbar | 242 | gnunet_qr_LDFLAGS= -lzbar |
244 | 243 | ||
245 | plugin_LTLIBRARIES = \ | 244 | plugin_LTLIBRARIES = \ |
246 | libgnunet_plugin_test.la | 245 | libgnunet_plugin_utiltest.la |
247 | 246 | ||
248 | libgnunet_plugin_test_la_SOURCES = \ | 247 | libgnunet_plugin_utiltest_la_SOURCES = \ |
249 | test_plugin_plug.c | 248 | test_plugin_plug.c |
250 | libgnunet_plugin_test_la_LDFLAGS = \ | 249 | libgnunet_plugin_utiltest_la_LDFLAGS = \ |
251 | $(GN_PLUGIN_LDFLAGS) | 250 | $(GN_PLUGIN_LDFLAGS) |
252 | 251 | ||
253 | if HAVE_BENCHMARKS | 252 | if HAVE_BENCHMARKS |
diff --git a/src/util/configuration.c b/src/util/configuration.c index 06938be67..e515c7c46 100644 --- a/src/util/configuration.c +++ b/src/util/configuration.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include "gnunet_os_lib.h" | 28 | #include "gnunet_os_lib.h" |
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" | ||
32 | #include "gnunet_container_lib.h" | ||
31 | 33 | ||
32 | #define LOG(kind, ...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 34 | #define LOG(kind, ...) GNUNET_log_from (kind, "util", __VA_ARGS__) |
33 | 35 | ||
@@ -53,6 +55,16 @@ struct ConfigEntry | |||
53 | * current, committed value | 55 | * current, committed value |
54 | */ | 56 | */ |
55 | char *val; | 57 | char *val; |
58 | |||
59 | /** | ||
60 | * Diagnostics information for the filename. | ||
61 | */ | ||
62 | char *hint_filename; | ||
63 | |||
64 | /** | ||
65 | * Diagnostics information for the line number. | ||
66 | */ | ||
67 | unsigned int hint_lineno; | ||
56 | }; | 68 | }; |
57 | 69 | ||
58 | 70 | ||
@@ -83,6 +95,54 @@ struct ConfigSection | |||
83 | * directive, but the referenced file can't be found or accessed. | 95 | * directive, but the referenced file can't be found or accessed. |
84 | */ | 96 | */ |
85 | bool inaccessible; | 97 | bool inaccessible; |
98 | |||
99 | /** | ||
100 | * Diagnostics hint for the secret file. | ||
101 | */ | ||
102 | char *hint_secret_filename; | ||
103 | |||
104 | /** | ||
105 | * Extra information regarding permissions of the secret file. | ||
106 | */ | ||
107 | char *hint_secret_stat; | ||
108 | |||
109 | /** | ||
110 | * For secret sections: Where was this inlined from? | ||
111 | */ | ||
112 | char *hint_inlined_from_filename; | ||
113 | |||
114 | /** | ||
115 | * For secret sections: Where was this inlined from? | ||
116 | */ | ||
117 | unsigned int hint_inlined_from_line; | ||
118 | }; | ||
119 | |||
120 | struct ConfigFile | ||
121 | { | ||
122 | /** | ||
123 | * Source filename. | ||
124 | */ | ||
125 | char *source_filename; | ||
126 | |||
127 | /** | ||
128 | * Level in the tree of loaded config files. | ||
129 | */ | ||
130 | unsigned int level; | ||
131 | |||
132 | struct ConfigFile *prev; | ||
133 | |||
134 | struct ConfigFile *next; | ||
135 | |||
136 | /** | ||
137 | * Was this configuration file parsed via | ||
138 | * @inline-secret@? | ||
139 | */ | ||
140 | char *hint_restrict_section; | ||
141 | |||
142 | /** | ||
143 | * Was this configuration file inaccessible? | ||
144 | */ | ||
145 | bool hint_inaccessible; | ||
86 | }; | 146 | }; |
87 | 147 | ||
88 | 148 | ||
@@ -97,6 +157,26 @@ struct GNUNET_CONFIGURATION_Handle | |||
97 | struct ConfigSection *sections; | 157 | struct ConfigSection *sections; |
98 | 158 | ||
99 | /** | 159 | /** |
160 | * Linked list of loaded files. | ||
161 | */ | ||
162 | struct ConfigFile *loaded_files_head; | ||
163 | |||
164 | /** | ||
165 | * Linked list of loaded files. | ||
166 | */ | ||
167 | struct ConfigFile *loaded_files_tail; | ||
168 | |||
169 | /** | ||
170 | * Current nesting level of file loading. | ||
171 | */ | ||
172 | unsigned int current_nest_level; | ||
173 | |||
174 | /** | ||
175 | * Enable diagnostics. | ||
176 | */ | ||
177 | bool diagnostics; | ||
178 | |||
179 | /** | ||
100 | * Modification indication since last save | 180 | * Modification indication since last save |
101 | * #GNUNET_NO if clean, #GNUNET_YES if dirty, | 181 | * #GNUNET_NO if clean, #GNUNET_YES if dirty, |
102 | * #GNUNET_SYSERR on error (i.e. last save failed) | 182 | * #GNUNET_SYSERR on error (i.e. last save failed) |
@@ -104,9 +184,21 @@ struct GNUNET_CONFIGURATION_Handle | |||
104 | enum GNUNET_GenericReturnValue dirty; | 184 | enum GNUNET_GenericReturnValue dirty; |
105 | 185 | ||
106 | /** | 186 | /** |
187 | * Was the configuration ever loaded via GNUNET_CONFIGURATION_load? | ||
188 | */ | ||
189 | bool load_called; | ||
190 | |||
191 | /** | ||
107 | * Name of the entry point configuration file. | 192 | * Name of the entry point configuration file. |
108 | */ | 193 | */ |
109 | char *main_filename; | 194 | char *main_filename; |
195 | |||
196 | /** | ||
197 | * When parsing into this configuration, and this value | ||
198 | * is non-NULL, only parse sections of the same name, | ||
199 | * and ban import statements. | ||
200 | */ | ||
201 | const char *restrict_section; | ||
110 | }; | 202 | }; |
111 | 203 | ||
112 | 204 | ||
@@ -122,6 +214,14 @@ struct DiffHandle | |||
122 | }; | 214 | }; |
123 | 215 | ||
124 | 216 | ||
217 | void | ||
218 | GNUNET_CONFIGURATION_enable_diagnostics (struct | ||
219 | GNUNET_CONFIGURATION_Handle *cfg) | ||
220 | { | ||
221 | cfg->diagnostics = true; | ||
222 | } | ||
223 | |||
224 | |||
125 | struct GNUNET_CONFIGURATION_Handle * | 225 | struct GNUNET_CONFIGURATION_Handle * |
126 | GNUNET_CONFIGURATION_create () | 226 | GNUNET_CONFIGURATION_create () |
127 | { | 227 | { |
@@ -211,9 +311,18 @@ void | |||
211 | GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg) | 311 | GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg) |
212 | { | 312 | { |
213 | struct ConfigSection *sec; | 313 | struct ConfigSection *sec; |
314 | struct ConfigFile *cf; | ||
214 | 315 | ||
215 | while (NULL != (sec = cfg->sections)) | 316 | while (NULL != (sec = cfg->sections)) |
216 | GNUNET_CONFIGURATION_remove_section (cfg, sec->name); | 317 | GNUNET_CONFIGURATION_remove_section (cfg, sec->name); |
318 | while (NULL != (cf = cfg->loaded_files_head)) | ||
319 | { | ||
320 | GNUNET_free (cf->hint_restrict_section); | ||
321 | GNUNET_free (cf->source_filename); | ||
322 | GNUNET_CONTAINER_DLL_remove (cfg->loaded_files_head, | ||
323 | cfg->loaded_files_tail, | ||
324 | cf); | ||
325 | } | ||
217 | GNUNET_free (cfg); | 326 | GNUNET_free (cfg); |
218 | } | 327 | } |
219 | 328 | ||
@@ -240,14 +349,19 @@ GNUNET_CONFIGURATION_parse_and_run (const char *filename, | |||
240 | 349 | ||
241 | 350 | ||
242 | /** | 351 | /** |
243 | * Closure to inline_glob_cb. | 352 | * Closure to collect_files_cb. |
244 | */ | 353 | */ |
245 | struct InlineGlobClosure | 354 | struct CollectFilesContext |
246 | { | 355 | { |
247 | /** | 356 | /** |
248 | * Configuration to read inlined configuration into. | 357 | * Collected files from globbing. |
249 | */ | 358 | */ |
250 | struct GNUNET_CONFIGURATION_Handle *cfg; | 359 | char **files; |
360 | |||
361 | /** | ||
362 | * Size of the files array. | ||
363 | */ | ||
364 | unsigned int files_length; | ||
251 | }; | 365 | }; |
252 | 366 | ||
253 | 367 | ||
@@ -261,21 +375,14 @@ struct InlineGlobClosure | |||
261 | * #GNUNET_SYSERR to abort iteration with error! | 375 | * #GNUNET_SYSERR to abort iteration with error! |
262 | */ | 376 | */ |
263 | static int | 377 | static int |
264 | inline_glob_cb (void *cls, | 378 | collect_files_cb (void *cls, |
265 | const char *filename) | 379 | const char *filename) |
266 | { | 380 | { |
267 | struct InlineGlobClosure *igc = cls; | 381 | struct CollectFilesContext *igc = cls; |
268 | 382 | ||
269 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 383 | GNUNET_array_append (igc->files, |
270 | "Reading globbed config file '%s'\n", | 384 | igc->files_length, |
271 | filename); | 385 | GNUNET_strdup (filename)); |
272 | |||
273 | if (GNUNET_OK != | ||
274 | GNUNET_CONFIGURATION_parse (igc->cfg, | ||
275 | filename)) | ||
276 | { | ||
277 | return GNUNET_SYSERR; | ||
278 | } | ||
279 | return GNUNET_OK; | 386 | return GNUNET_OK; |
280 | } | 387 | } |
281 | 388 | ||
@@ -300,24 +407,10 @@ find_section (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
300 | } | 407 | } |
301 | 408 | ||
302 | 409 | ||
303 | static void | 410 | static int |
304 | set_section_inaccessible (struct GNUNET_CONFIGURATION_Handle *cfg, | 411 | pstrcmp (const void *a, const void *b) |
305 | const char *section) | ||
306 | { | 412 | { |
307 | struct ConfigSection *sec; | 413 | return strcmp (*((const char **) a), *((const char **) b)); |
308 | |||
309 | sec = find_section (cfg, section); | ||
310 | |||
311 | if (NULL == sec) | ||
312 | { | ||
313 | sec = GNUNET_new (struct ConfigSection); | ||
314 | sec->name = GNUNET_strdup (section); | ||
315 | sec->next = cfg->sections; | ||
316 | cfg->sections = sec; | ||
317 | sec->entries = NULL; | ||
318 | } | ||
319 | |||
320 | sec->inaccessible = true; | ||
321 | } | 414 | } |
322 | 415 | ||
323 | 416 | ||
@@ -331,9 +424,17 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
331 | const char *path_or_glob, | 424 | const char *path_or_glob, |
332 | bool path_is_glob, | 425 | bool path_is_glob, |
333 | const char *restrict_section, | 426 | const char *restrict_section, |
334 | const char *source_filename) | 427 | const char *source_filename, |
428 | unsigned int source_lineno) | ||
335 | { | 429 | { |
336 | char *inline_path; | 430 | char *inline_path; |
431 | struct GNUNET_CONFIGURATION_Handle *other_cfg = NULL; | ||
432 | struct CollectFilesContext igc = { | ||
433 | .files = NULL, | ||
434 | .files_length = 0, | ||
435 | }; | ||
436 | enum GNUNET_GenericReturnValue fun_ret; | ||
437 | unsigned int old_nest_level = cfg->current_nest_level++; | ||
337 | 438 | ||
338 | /* We support the section restriction only for non-globs */ | 439 | /* We support the section restriction only for non-globs */ |
339 | GNUNET_assert (! (path_is_glob && (NULL != restrict_section))); | 440 | GNUNET_assert (! (path_is_glob && (NULL != restrict_section))); |
@@ -343,8 +444,10 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
343 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 444 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
344 | "Refusing to parse inline configurations, " | 445 | "Refusing to parse inline configurations, " |
345 | "not allowed without source filename!\n"); | 446 | "not allowed without source filename!\n"); |
346 | return GNUNET_SYSERR; | 447 | fun_ret = GNUNET_SYSERR; |
448 | goto cleanup; | ||
347 | } | 449 | } |
450 | |||
348 | if ('/' == *path_or_glob) | 451 | if ('/' == *path_or_glob) |
349 | inline_path = GNUNET_strdup (path_or_glob); | 452 | inline_path = GNUNET_strdup (path_or_glob); |
350 | else | 453 | else |
@@ -362,7 +465,8 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
362 | /* Couldn't even resolve path of base dir. */ | 465 | /* Couldn't even resolve path of base dir. */ |
363 | GNUNET_break (0); | 466 | GNUNET_break (0); |
364 | /* failed to parse included config */ | 467 | /* failed to parse included config */ |
365 | return GNUNET_SYSERR; | 468 | fun_ret = GNUNET_SYSERR; |
469 | goto cleanup; | ||
366 | } | 470 | } |
367 | endsep = strrchr (source_realpath, '/'); | 471 | endsep = strrchr (source_realpath, '/'); |
368 | GNUNET_assert (NULL != endsep); | 472 | GNUNET_assert (NULL != endsep); |
@@ -373,46 +477,113 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
373 | path_or_glob); | 477 | path_or_glob); |
374 | free (source_realpath); | 478 | free (source_realpath); |
375 | } | 479 | } |
480 | |||
376 | if (path_is_glob) | 481 | if (path_is_glob) |
377 | { | 482 | { |
378 | int nret; | 483 | int nret; |
379 | struct InlineGlobClosure igc = { | ||
380 | .cfg = cfg, | ||
381 | }; | ||
382 | 484 | ||
383 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 485 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
384 | "processing config glob '%s'\n", | 486 | "processing config glob '%s'\n", |
385 | inline_path); | 487 | inline_path); |
386 | 488 | ||
387 | nret = GNUNET_DISK_glob (inline_path, inline_glob_cb, &igc); | 489 | nret = GNUNET_DISK_glob (inline_path, collect_files_cb, &igc); |
388 | if (-1 == nret) | 490 | if (-1 == nret) |
389 | { | 491 | { |
390 | GNUNET_free (inline_path); | 492 | fun_ret = GNUNET_SYSERR; |
391 | return GNUNET_SYSERR; | 493 | goto cleanup; |
494 | } | ||
495 | GNUNET_assert (nret == igc.files_length); | ||
496 | qsort (igc.files, igc.files_length, sizeof (char *), pstrcmp); | ||
497 | for (int i = 0; i < nret; i++) | ||
498 | { | ||
499 | if (GNUNET_OK != | ||
500 | GNUNET_CONFIGURATION_parse (cfg, | ||
501 | igc.files[i])) | ||
502 | { | ||
503 | fun_ret = GNUNET_SYSERR; | ||
504 | goto cleanup; | ||
505 | } | ||
392 | } | 506 | } |
507 | fun_ret = GNUNET_OK; | ||
393 | } | 508 | } |
394 | else if (NULL != restrict_section) | 509 | else if (NULL != restrict_section) |
395 | { | 510 | { |
396 | struct GNUNET_CONFIGURATION_Handle *other_cfg; | 511 | enum GNUNET_GenericReturnValue inner_ret; |
397 | enum GNUNET_GenericReturnValue fret; | ||
398 | struct ConfigSection *cs; | 512 | struct ConfigSection *cs; |
513 | struct ConfigFile *cf = GNUNET_new (struct ConfigFile); | ||
399 | 514 | ||
400 | fret = GNUNET_DISK_file_test_read (inline_path); | 515 | inner_ret = GNUNET_DISK_file_test_read (inline_path); |
401 | 516 | ||
402 | if (GNUNET_OK != fret) | 517 | cs = find_section (cfg, restrict_section); |
518 | |||
519 | if (NULL == cs) | ||
403 | { | 520 | { |
404 | set_section_inaccessible (cfg, restrict_section); | 521 | cs = GNUNET_new (struct ConfigSection); |
405 | GNUNET_free (inline_path); | 522 | cs->name = GNUNET_strdup (restrict_section); |
406 | return GNUNET_OK; | 523 | cs->next = cfg->sections; |
524 | cfg->sections = cs; | ||
525 | cs->entries = NULL; | ||
526 | } | ||
527 | if (cfg->diagnostics) | ||
528 | { | ||
529 | char *sfn = GNUNET_STRINGS_filename_expand (inline_path); | ||
530 | struct stat istat; | ||
531 | |||
532 | cs->hint_secret_filename = sfn; | ||
533 | if (0 == stat (sfn, &istat)) | ||
534 | { | ||
535 | struct passwd *pw = getpwuid (istat.st_uid); | ||
536 | struct group *gr = getgrgid (istat.st_gid); | ||
537 | char *pwname = (NULL == pw) ? "<unknown>" : pw->pw_name; | ||
538 | char *grname = (NULL == gr) ? "<unknown>" : gr->gr_name; | ||
539 | |||
540 | GNUNET_asprintf (&cs->hint_secret_stat, | ||
541 | "%s:%s %o", | ||
542 | pwname, | ||
543 | grname, | ||
544 | istat.st_mode); | ||
545 | } | ||
546 | else | ||
547 | { | ||
548 | cs->hint_secret_stat = GNUNET_strdup ("<can't stat file>"); | ||
549 | } | ||
550 | if (source_filename) | ||
551 | { | ||
552 | /* Possible that this secret section has been inlined before */ | ||
553 | GNUNET_free (cs->hint_inlined_from_filename); | ||
554 | cs->hint_inlined_from_filename = GNUNET_strdup (source_filename); | ||
555 | cs->hint_inlined_from_line = source_lineno; | ||
556 | } | ||
557 | } | ||
558 | |||
559 | /* Put file in the load list for diagnostics, even if we can't access it. */ | ||
560 | { | ||
561 | cf->level = cfg->current_nest_level; | ||
562 | cf->source_filename = GNUNET_strdup (inline_path); | ||
563 | cf->hint_restrict_section = GNUNET_strdup (restrict_section); | ||
564 | GNUNET_CONTAINER_DLL_insert_tail (cfg->loaded_files_head, | ||
565 | cfg->loaded_files_tail, | ||
566 | cf); | ||
567 | } | ||
568 | |||
569 | if (GNUNET_OK != inner_ret) | ||
570 | { | ||
571 | cs->inaccessible = true; | ||
572 | cf->hint_inaccessible = true; | ||
573 | /* File can't be accessed, but that's okay. */ | ||
574 | fun_ret = GNUNET_OK; | ||
575 | goto cleanup; | ||
407 | } | 576 | } |
408 | 577 | ||
409 | other_cfg = GNUNET_CONFIGURATION_create (); | 578 | other_cfg = GNUNET_CONFIGURATION_create (); |
410 | if (GNUNET_OK != GNUNET_CONFIGURATION_parse (other_cfg, | 579 | other_cfg->restrict_section = restrict_section; |
411 | inline_path)) | 580 | inner_ret = GNUNET_CONFIGURATION_parse (other_cfg, |
581 | inline_path); | ||
582 | if (GNUNET_OK != inner_ret) | ||
412 | { | 583 | { |
413 | GNUNET_free (inline_path); | 584 | cf->hint_inaccessible = true; |
414 | GNUNET_CONFIGURATION_destroy (other_cfg); | 585 | fun_ret = inner_ret; |
415 | return GNUNET_SYSERR; | 586 | goto cleanup; |
416 | } | 587 | } |
417 | 588 | ||
418 | cs = find_section (other_cfg, restrict_section); | 589 | cs = find_section (other_cfg, restrict_section); |
@@ -422,9 +593,8 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
422 | "inlined configuration '%s' does not contain section '%s'\n", | 593 | "inlined configuration '%s' does not contain section '%s'\n", |
423 | inline_path, | 594 | inline_path, |
424 | restrict_section); | 595 | restrict_section); |
425 | GNUNET_free (inline_path); | 596 | fun_ret = GNUNET_SYSERR; |
426 | GNUNET_free (other_cfg); | 597 | goto cleanup; |
427 | return GNUNET_SYSERR; | ||
428 | } | 598 | } |
429 | for (struct ConfigEntry *ce = cs->entries; | 599 | for (struct ConfigEntry *ce = cs->entries; |
430 | NULL != ce; | 600 | NULL != ce; |
@@ -433,17 +603,92 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
433 | restrict_section, | 603 | restrict_section, |
434 | ce->key, | 604 | ce->key, |
435 | ce->val); | 605 | ce->val); |
436 | GNUNET_CONFIGURATION_destroy (other_cfg); | 606 | fun_ret = GNUNET_OK; |
437 | } | 607 | } |
438 | else if (GNUNET_OK != | 608 | else if (GNUNET_OK != |
439 | GNUNET_CONFIGURATION_parse (cfg, | 609 | GNUNET_CONFIGURATION_parse (cfg, |
440 | inline_path)) | 610 | inline_path)) |
441 | { | 611 | { |
442 | GNUNET_free (inline_path); | 612 | fun_ret = GNUNET_SYSERR; |
443 | return GNUNET_SYSERR; | 613 | goto cleanup; |
444 | } | 614 | } |
615 | else | ||
616 | { | ||
617 | fun_ret = GNUNET_OK; | ||
618 | } | ||
619 | cleanup: | ||
620 | cfg->current_nest_level = old_nest_level; | ||
621 | if (NULL != other_cfg) | ||
622 | GNUNET_CONFIGURATION_destroy (other_cfg); | ||
445 | GNUNET_free (inline_path); | 623 | GNUNET_free (inline_path); |
446 | return GNUNET_OK; | 624 | if (igc.files_length > 0) |
625 | { | ||
626 | for (size_t i = 0; i < igc.files_length; i++) | ||
627 | GNUNET_free (igc.files[i]); | ||
628 | GNUNET_array_grow (igc.files, igc.files_length, 0); | ||
629 | } | ||
630 | return fun_ret; | ||
631 | } | ||
632 | |||
633 | |||
634 | /** | ||
635 | * Find an entry from a configuration. | ||
636 | * | ||
637 | * @param cfg handle to the configuration | ||
638 | * @param section section the option is in | ||
639 | * @param key the option | ||
640 | * @return matching entry, NULL if not found | ||
641 | */ | ||
642 | static struct ConfigEntry * | ||
643 | find_entry (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
644 | const char *section, | ||
645 | const char *key) | ||
646 | { | ||
647 | struct ConfigSection *sec; | ||
648 | struct ConfigEntry *pos; | ||
649 | |||
650 | if (NULL == (sec = find_section (cfg, section))) | ||
651 | return NULL; | ||
652 | if (sec->inaccessible) | ||
653 | { | ||
654 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
655 | "Section '%s' is marked as inaccessible, because the configuration " | ||
656 | " file that contains the section can't be read. Attempts to use " | ||
657 | "option '%s' will fail.\n", | ||
658 | section, | ||
659 | key); | ||
660 | return NULL; | ||
661 | } | ||
662 | pos = sec->entries; | ||
663 | while ((pos != NULL) && (0 != strcasecmp (key, pos->key))) | ||
664 | pos = pos->next; | ||
665 | return pos; | ||
666 | } | ||
667 | |||
668 | |||
669 | /** | ||
670 | * Set a configuration hint. | ||
671 | * | ||
672 | * @param cfg configuration handle | ||
673 | * @param section section | ||
674 | * @param option config option | ||
675 | * @param hint_filename | ||
676 | * @param hint_line | ||
677 | */ | ||
678 | static void | ||
679 | set_entry_hint (struct GNUNET_CONFIGURATION_Handle *cfg, | ||
680 | const char *section, | ||
681 | const char *option, | ||
682 | const char *hint_filename, | ||
683 | unsigned int hint_line) | ||
684 | { | ||
685 | struct ConfigEntry *e = find_entry (cfg, section, option); | ||
686 | if (! cfg->diagnostics) | ||
687 | return; | ||
688 | if (! e) | ||
689 | return; | ||
690 | e->hint_filename = GNUNET_strdup (hint_filename); | ||
691 | e->hint_lineno = hint_line; | ||
447 | } | 692 | } |
448 | 693 | ||
449 | 694 | ||
@@ -530,6 +775,17 @@ GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
530 | char *directive; | 775 | char *directive; |
531 | enum GNUNET_GenericReturnValue directive_ret; | 776 | enum GNUNET_GenericReturnValue directive_ret; |
532 | 777 | ||
778 | if (NULL != cfg->restrict_section) | ||
779 | { | ||
780 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
781 | _ ( | ||
782 | "Illegal directive in line %u (parsing restricted section %s)\n"), | ||
783 | nr, | ||
784 | cfg->restrict_section); | ||
785 | ret = GNUNET_SYSERR; | ||
786 | break; | ||
787 | } | ||
788 | |||
533 | if (NULL == end) | 789 | if (NULL == end) |
534 | { | 790 | { |
535 | LOG (GNUNET_ERROR_TYPE_WARNING, | 791 | LOG (GNUNET_ERROR_TYPE_WARNING, |
@@ -553,7 +809,8 @@ GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
553 | path, | 809 | path, |
554 | false, | 810 | false, |
555 | NULL, | 811 | NULL, |
556 | source_filename); | 812 | source_filename, |
813 | nr); | ||
557 | } | 814 | } |
558 | else if (0 == strcasecmp (directive, "INLINE-MATCHING")) | 815 | else if (0 == strcasecmp (directive, "INLINE-MATCHING")) |
559 | { | 816 | { |
@@ -567,7 +824,8 @@ GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
567 | path, | 824 | path, |
568 | true, | 825 | true, |
569 | NULL, | 826 | NULL, |
570 | source_filename); | 827 | source_filename, |
828 | nr); | ||
571 | } | 829 | } |
572 | else if (0 == strcasecmp (directive, "INLINE-SECRET")) | 830 | else if (0 == strcasecmp (directive, "INLINE-SECRET")) |
573 | { | 831 | { |
@@ -600,7 +858,8 @@ GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
600 | path, | 858 | path, |
601 | false, | 859 | false, |
602 | secname, | 860 | secname, |
603 | source_filename); | 861 | source_filename, |
862 | nr); | ||
604 | } | 863 | } |
605 | else | 864 | else |
606 | { | 865 | { |
@@ -613,11 +872,7 @@ GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
613 | } | 872 | } |
614 | if (GNUNET_OK != directive_ret) | 873 | if (GNUNET_OK != directive_ret) |
615 | { | 874 | { |
616 | LOG (GNUNET_ERROR_TYPE_WARNING, | 875 | ret = directive_ret; |
617 | _ ("Bad directive '%s' in line %u\n"), | ||
618 | directive, | ||
619 | nr); | ||
620 | ret = GNUNET_SYSERR; | ||
621 | break; | 876 | break; |
622 | } | 877 | } |
623 | continue; | 878 | continue; |
@@ -660,6 +915,14 @@ GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
660 | value++; | 915 | value++; |
661 | } | 916 | } |
662 | GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, &value[i]); | 917 | GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, &value[i]); |
918 | if (cfg->diagnostics) | ||
919 | { | ||
920 | set_entry_hint (cfg, | ||
921 | section, | ||
922 | tag, | ||
923 | source_filename ? source_filename : "<input>", | ||
924 | nr); | ||
925 | } | ||
663 | GNUNET_free (tag); | 926 | GNUNET_free (tag); |
664 | continue; | 927 | continue; |
665 | } | 928 | } |
@@ -694,6 +957,55 @@ GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
694 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to parse config file `%s'\n", fn); | 957 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to parse config file `%s'\n", fn); |
695 | if (NULL == fn) | 958 | if (NULL == fn) |
696 | return GNUNET_SYSERR; | 959 | return GNUNET_SYSERR; |
960 | |||
961 | |||
962 | /* Check for cycles */ | ||
963 | { | ||
964 | unsigned int lvl = cfg->current_nest_level; | ||
965 | struct ConfigFile *cf = cfg->loaded_files_tail; | ||
966 | struct ConfigFile *parent = NULL; | ||
967 | |||
968 | |||
969 | for (; NULL != cf; parent = cf, cf = cf->prev) | ||
970 | { | ||
971 | /* Check parents based on level, skipping children of siblings. */ | ||
972 | if (cf->level >= lvl) | ||
973 | continue; | ||
974 | lvl = cf->level; | ||
975 | if ( (NULL == cf->source_filename) || (NULL == filename)) | ||
976 | continue; | ||
977 | if (0 == strcmp (cf->source_filename, filename)) | ||
978 | { | ||
979 | if (NULL == parent) | ||
980 | { | ||
981 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
982 | "Forbidden direct cyclic configuration import (%s -> %s)\n", | ||
983 | cf->source_filename, | ||
984 | filename); | ||
985 | } | ||
986 | else | ||
987 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
988 | "Forbidden indirect cyclic configuration import (%s -> ... -> %s -> %s)\n", | ||
989 | cf->source_filename, | ||
990 | parent->source_filename, | ||
991 | filename); | ||
992 | return GNUNET_SYSERR; | ||
993 | } | ||
994 | } | ||
995 | |||
996 | } | ||
997 | |||
998 | /* Keep track of loaded files.*/ | ||
999 | { | ||
1000 | struct ConfigFile *cf = GNUNET_new (struct ConfigFile); | ||
1001 | |||
1002 | cf->level = cfg->current_nest_level; | ||
1003 | cf->source_filename = GNUNET_strdup (filename ? filename : "<input>"); | ||
1004 | GNUNET_CONTAINER_DLL_insert_tail (cfg->loaded_files_head, | ||
1005 | cfg->loaded_files_tail, | ||
1006 | cf); | ||
1007 | } | ||
1008 | |||
697 | dirty = cfg->dirty; /* back up value! */ | 1009 | dirty = cfg->dirty; /* back up value! */ |
698 | if (GNUNET_SYSERR == | 1010 | if (GNUNET_SYSERR == |
699 | GNUNET_DISK_file_size (fn, &fs64, GNUNET_YES, GNUNET_YES)) | 1011 | GNUNET_DISK_file_size (fn, &fs64, GNUNET_YES, GNUNET_YES)) |
@@ -725,7 +1037,7 @@ GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
725 | mem, | 1037 | mem, |
726 | fs, | 1038 | fs, |
727 | fn); | 1039 | fn); |
728 | if (GNUNET_OK != ret) | 1040 | if (GNUNET_SYSERR == ret) |
729 | { | 1041 | { |
730 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1042 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
731 | _ ("Failed to parse configuration file `%s'\n"), | 1043 | _ ("Failed to parse configuration file `%s'\n"), |
@@ -799,6 +1111,8 @@ GNUNET_CONFIGURATION_serialize (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
799 | NULL != sec; | 1111 | NULL != sec; |
800 | sec = sec->next) | 1112 | sec = sec->next) |
801 | { | 1113 | { |
1114 | if (sec->inaccessible) | ||
1115 | continue; | ||
802 | /* For each section we need to add 3 characters: {'[',']','\n'} */ | 1116 | /* For each section we need to add 3 characters: {'[',']','\n'} */ |
803 | m_size += strlen (sec->name) + 3; | 1117 | m_size += strlen (sec->name) + 3; |
804 | for (struct ConfigEntry *ent = sec->entries; | 1118 | for (struct ConfigEntry *ent = sec->entries; |
@@ -878,6 +1192,117 @@ GNUNET_CONFIGURATION_serialize (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
878 | } | 1192 | } |
879 | 1193 | ||
880 | 1194 | ||
1195 | char * | ||
1196 | GNUNET_CONFIGURATION_serialize_diagnostics (const struct | ||
1197 | GNUNET_CONFIGURATION_Handle *cfg) | ||
1198 | { | ||
1199 | struct GNUNET_Buffer buf = { 0 }; | ||
1200 | |||
1201 | GNUNET_buffer_write_fstr (&buf, | ||
1202 | "#\n# Configuration file diagnostics\n#\n"); | ||
1203 | GNUNET_buffer_write_fstr (&buf, | ||
1204 | "# Entry point: %s\n", | ||
1205 | cfg->main_filename ? cfg->main_filename : | ||
1206 | "<none>"); | ||
1207 | GNUNET_buffer_write_fstr (&buf, | ||
1208 | "#\n# Files Loaded:\n"); | ||
1209 | |||
1210 | for (struct ConfigFile *cfil = cfg->loaded_files_head; | ||
1211 | NULL != cfil; | ||
1212 | cfil = cfil->next) | ||
1213 | { | ||
1214 | GNUNET_buffer_write_fstr (&buf, | ||
1215 | "# "); | ||
1216 | for (unsigned int i = 0; i < cfil->level; i++) | ||
1217 | GNUNET_buffer_write_fstr (&buf, | ||
1218 | "+"); | ||
1219 | if (0 != cfil->level) | ||
1220 | GNUNET_buffer_write_fstr (&buf, | ||
1221 | " "); | ||
1222 | |||
1223 | GNUNET_buffer_write_fstr (&buf, | ||
1224 | "%s", | ||
1225 | cfil->source_filename); | ||
1226 | |||
1227 | if (NULL != cfil->hint_restrict_section) | ||
1228 | GNUNET_buffer_write_fstr (&buf, | ||
1229 | " (%s secret section %s)", | ||
1230 | cfil->hint_inaccessible | ||
1231 | ? "inaccessible" | ||
1232 | : "loaded", | ||
1233 | cfil->hint_restrict_section); | ||
1234 | |||
1235 | GNUNET_buffer_write_str (&buf, | ||
1236 | "\n"); | ||
1237 | } | ||
1238 | |||
1239 | GNUNET_buffer_write_fstr (&buf, | ||
1240 | "#\n\n"); | ||
1241 | |||
1242 | for (struct ConfigSection *sec = cfg->sections; | ||
1243 | NULL != sec; | ||
1244 | sec = sec->next) | ||
1245 | { | ||
1246 | if (sec->hint_secret_filename) | ||
1247 | GNUNET_buffer_write_fstr (&buf, | ||
1248 | "# secret section from %s\n# secret file stat %s\n", | ||
1249 | sec->hint_secret_filename, | ||
1250 | sec->hint_secret_stat); | ||
1251 | if (sec->hint_inlined_from_filename) | ||
1252 | { | ||
1253 | GNUNET_buffer_write_fstr (&buf, | ||
1254 | "# inlined from %s:%u\n", | ||
1255 | sec->hint_inlined_from_filename, | ||
1256 | sec->hint_inlined_from_line); | ||
1257 | } | ||
1258 | GNUNET_buffer_write_fstr (&buf, | ||
1259 | "[%s]\n\n", | ||
1260 | sec->name); | ||
1261 | if (sec->inaccessible) | ||
1262 | { | ||
1263 | GNUNET_buffer_write_fstr (&buf, | ||
1264 | "# <section contents inaccessible>\n\n\n"); | ||
1265 | continue; | ||
1266 | } | ||
1267 | for (struct ConfigEntry *ent = sec->entries; | ||
1268 | NULL != ent; | ||
1269 | ent = ent->next) | ||
1270 | { | ||
1271 | if (do_skip (sec->name, | ||
1272 | ent->key)) | ||
1273 | continue; | ||
1274 | if (NULL != ent->val) | ||
1275 | { | ||
1276 | char *pos; | ||
1277 | char *val = GNUNET_malloc (strlen (ent->val) * 2 + 1); | ||
1278 | strcpy (val, ent->val); | ||
1279 | while (NULL != (pos = strstr (val, "\n"))) | ||
1280 | { | ||
1281 | memmove (&pos[2], &pos[1], strlen (&pos[1])); | ||
1282 | pos[0] = '\\'; | ||
1283 | pos[1] = 'n'; | ||
1284 | } | ||
1285 | if (NULL != ent->hint_filename) | ||
1286 | { | ||
1287 | GNUNET_buffer_write_fstr (&buf, | ||
1288 | "# %s:%u\n", | ||
1289 | ent->hint_filename, | ||
1290 | ent->hint_lineno); | ||
1291 | } | ||
1292 | GNUNET_buffer_write_fstr (&buf, | ||
1293 | "%s = %s\n", | ||
1294 | ent->key, | ||
1295 | val); | ||
1296 | GNUNET_free (val); | ||
1297 | } | ||
1298 | GNUNET_buffer_write_str (&buf, "\n"); | ||
1299 | } | ||
1300 | GNUNET_buffer_write_str (&buf, "\n"); | ||
1301 | } | ||
1302 | return GNUNET_buffer_reap_str (&buf); | ||
1303 | } | ||
1304 | |||
1305 | |||
881 | enum GNUNET_GenericReturnValue | 1306 | enum GNUNET_GenericReturnValue |
882 | GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg, | 1307 | GNUNET_CONFIGURATION_write (struct GNUNET_CONFIGURATION_Handle *cfg, |
883 | const char *filename) | 1308 | const char *filename) |
@@ -1028,10 +1453,14 @@ GNUNET_CONFIGURATION_remove_section (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
1028 | spos->entries = ent->next; | 1453 | spos->entries = ent->next; |
1029 | GNUNET_free (ent->key); | 1454 | GNUNET_free (ent->key); |
1030 | GNUNET_free (ent->val); | 1455 | GNUNET_free (ent->val); |
1456 | GNUNET_free (ent->hint_filename); | ||
1031 | GNUNET_free (ent); | 1457 | GNUNET_free (ent); |
1032 | cfg->dirty = GNUNET_YES; | 1458 | cfg->dirty = GNUNET_YES; |
1033 | } | 1459 | } |
1034 | GNUNET_free (spos->name); | 1460 | GNUNET_free (spos->name); |
1461 | GNUNET_free (spos->hint_secret_filename); | ||
1462 | GNUNET_free (spos->hint_secret_stat); | ||
1463 | GNUNET_free (spos->hint_inlined_from_filename); | ||
1035 | GNUNET_free (spos); | 1464 | GNUNET_free (spos); |
1036 | return; | 1465 | return; |
1037 | } | 1466 | } |
@@ -1074,41 +1503,6 @@ GNUNET_CONFIGURATION_dup (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
1074 | 1503 | ||
1075 | 1504 | ||
1076 | /** | 1505 | /** |
1077 | * Find an entry from a configuration. | ||
1078 | * | ||
1079 | * @param cfg handle to the configuration | ||
1080 | * @param section section the option is in | ||
1081 | * @param key the option | ||
1082 | * @return matching entry, NULL if not found | ||
1083 | */ | ||
1084 | static struct ConfigEntry * | ||
1085 | find_entry (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
1086 | const char *section, | ||
1087 | const char *key) | ||
1088 | { | ||
1089 | struct ConfigSection *sec; | ||
1090 | struct ConfigEntry *pos; | ||
1091 | |||
1092 | if (NULL == (sec = find_section (cfg, section))) | ||
1093 | return NULL; | ||
1094 | if (sec->inaccessible) | ||
1095 | { | ||
1096 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
1097 | "Section '%s' is marked as inaccessible, because the configuration " | ||
1098 | " file that contains the section can't be read. Attempts to use " | ||
1099 | "option '%s' will fail.\n", | ||
1100 | section, | ||
1101 | key); | ||
1102 | return NULL; | ||
1103 | } | ||
1104 | pos = sec->entries; | ||
1105 | while ((pos != NULL) && (0 != strcasecmp (key, pos->key))) | ||
1106 | pos = pos->next; | ||
1107 | return pos; | ||
1108 | } | ||
1109 | |||
1110 | |||
1111 | /** | ||
1112 | * A callback function, compares entries from two configurations | 1506 | * A callback function, compares entries from two configurations |
1113 | * (default against a new configuration) and write the diffs in a | 1507 | * (default against a new configuration) and write the diffs in a |
1114 | * diff-configuration object (the callback object). | 1508 | * diff-configuration object (the callback object). |
@@ -1871,41 +2265,104 @@ GNUNET_CONFIGURATION_remove_value_filename ( | |||
1871 | } | 2265 | } |
1872 | 2266 | ||
1873 | 2267 | ||
1874 | /** | 2268 | enum GNUNET_GenericReturnValue |
1875 | * Wrapper around #GNUNET_CONFIGURATION_parse. Called on each | 2269 | GNUNET_CONFIGURATION_load_from (struct GNUNET_CONFIGURATION_Handle *cfg, |
1876 | * file in a directory, we trigger parsing on those files that | 2270 | const char *defaults_d) |
1877 | * end with ".conf". | ||
1878 | * | ||
1879 | * @param cls the cfg | ||
1880 | * @param filename file to parse | ||
1881 | * @return #GNUNET_OK on success | ||
1882 | */ | ||
1883 | static enum GNUNET_GenericReturnValue | ||
1884 | parse_configuration_file (void *cls, const char *filename) | ||
1885 | { | 2271 | { |
1886 | struct GNUNET_CONFIGURATION_Handle *cfg = cls; | 2272 | struct CollectFilesContext files_context = { |
1887 | char *ext; | 2273 | .files = NULL, |
2274 | .files_length = 0, | ||
2275 | }; | ||
2276 | enum GNUNET_GenericReturnValue fun_ret; | ||
1888 | 2277 | ||
1889 | /* Examine file extension */ | 2278 | if (GNUNET_SYSERR == |
1890 | ext = strrchr (filename, '.'); | 2279 | GNUNET_DISK_directory_scan (defaults_d, &collect_files_cb, |
1891 | if ((NULL == ext) || (0 != strcmp (ext, ".conf"))) | 2280 | &files_context)) |
2281 | return GNUNET_SYSERR; /* no configuration at all found */ | ||
2282 | qsort (files_context.files, | ||
2283 | files_context.files_length, | ||
2284 | sizeof (char *), | ||
2285 | pstrcmp); | ||
2286 | for (unsigned int i = 0; i < files_context.files_length; i++) | ||
1892 | { | 2287 | { |
1893 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Skipping file `%s'\n", filename); | 2288 | char *ext; |
1894 | return GNUNET_OK; | 2289 | const char *filename = files_context.files[i]; |
1895 | } | ||
1896 | 2290 | ||
1897 | return GNUNET_CONFIGURATION_parse (cfg, filename); | 2291 | /* Examine file extension */ |
2292 | ext = strrchr (filename, '.'); | ||
2293 | if ((NULL == ext) || (0 != strcmp (ext, ".conf"))) | ||
2294 | { | ||
2295 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Skipping file `%s'\n", filename); | ||
2296 | fun_ret = GNUNET_OK; | ||
2297 | goto cleanup; | ||
2298 | } | ||
2299 | fun_ret = GNUNET_CONFIGURATION_parse (cfg, filename); | ||
2300 | if (fun_ret != GNUNET_OK) | ||
2301 | break; | ||
2302 | } | ||
2303 | cleanup: | ||
2304 | if (files_context.files_length > 0) | ||
2305 | { | ||
2306 | for (size_t i = 0; i < files_context.files_length; i++) | ||
2307 | GNUNET_free (files_context.files[i]); | ||
2308 | GNUNET_array_grow (files_context.files, | ||
2309 | files_context.files_length, | ||
2310 | 0); | ||
2311 | } | ||
2312 | return fun_ret; | ||
1898 | } | 2313 | } |
1899 | 2314 | ||
1900 | 2315 | ||
1901 | enum GNUNET_GenericReturnValue | 2316 | char * |
1902 | GNUNET_CONFIGURATION_load_from (struct GNUNET_CONFIGURATION_Handle *cfg, | 2317 | GNUNET_CONFIGURATION_default_filename (void) |
1903 | const char *defaults_d) | ||
1904 | { | 2318 | { |
1905 | if (GNUNET_SYSERR == | 2319 | char *cfg_fn; |
1906 | GNUNET_DISK_directory_scan (defaults_d, &parse_configuration_file, cfg)) | 2320 | const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get (); |
1907 | return GNUNET_SYSERR; /* no configuration at all found */ | 2321 | const char *xdg = getenv ("XDG_CONFIG_HOME"); |
1908 | return GNUNET_OK; | 2322 | |
2323 | if (NULL != xdg) | ||
2324 | GNUNET_asprintf (&cfg_fn, | ||
2325 | "%s%s%s", | ||
2326 | xdg, | ||
2327 | DIR_SEPARATOR_STR, | ||
2328 | pd->config_file); | ||
2329 | else | ||
2330 | cfg_fn = GNUNET_strdup (pd->user_config_file); | ||
2331 | |||
2332 | if (GNUNET_OK == GNUNET_DISK_file_test_read (cfg_fn)) | ||
2333 | return cfg_fn; | ||
2334 | |||
2335 | GNUNET_free (cfg_fn); | ||
2336 | |||
2337 | /* Fall back to /etc/ for the default configuration. | ||
2338 | Should be okay to use forward slashes here. */ | ||
2339 | |||
2340 | GNUNET_asprintf (&cfg_fn, | ||
2341 | "/etc/%s", | ||
2342 | pd->config_file); | ||
2343 | |||
2344 | if (GNUNET_OK == GNUNET_DISK_file_test_read (cfg_fn)) | ||
2345 | return cfg_fn; | ||
2346 | |||
2347 | GNUNET_free (cfg_fn); | ||
2348 | |||
2349 | GNUNET_asprintf (&cfg_fn, | ||
2350 | "/etc/%s", | ||
2351 | pd->config_file); | ||
2352 | |||
2353 | if (GNUNET_OK == GNUNET_DISK_file_test_read (cfg_fn)) | ||
2354 | return cfg_fn; | ||
2355 | |||
2356 | GNUNET_asprintf (&cfg_fn, | ||
2357 | "/etc/%s/%s", | ||
2358 | pd->project_dirname, | ||
2359 | pd->config_file); | ||
2360 | |||
2361 | if (GNUNET_OK == GNUNET_DISK_file_test_read (cfg_fn)) | ||
2362 | return cfg_fn; | ||
2363 | |||
2364 | GNUNET_free (cfg_fn); | ||
2365 | return NULL; | ||
1909 | } | 2366 | } |
1910 | 2367 | ||
1911 | 2368 | ||
@@ -1939,7 +2396,9 @@ GNUNET_CONFIGURATION_default (void) | |||
1939 | if (GNUNET_OK != GNUNET_DISK_file_test (cfgname)) | 2396 | if (GNUNET_OK != GNUNET_DISK_file_test (cfgname)) |
1940 | { | 2397 | { |
1941 | GNUNET_free (cfgname); | 2398 | GNUNET_free (cfgname); |
1942 | GNUNET_asprintf (&cfgname, "/etc/%s/%s", pd->project_dirname, | 2399 | GNUNET_asprintf (&cfgname, |
2400 | "/etc/%s/%s", | ||
2401 | pd->project_dirname, | ||
1943 | pd->config_file); | 2402 | pd->config_file); |
1944 | } | 2403 | } |
1945 | if (GNUNET_OK != GNUNET_DISK_file_test (cfgname)) | 2404 | if (GNUNET_OK != GNUNET_DISK_file_test (cfgname)) |
@@ -1971,4 +2430,81 @@ GNUNET_CONFIGURATION_default (void) | |||
1971 | } | 2430 | } |
1972 | 2431 | ||
1973 | 2432 | ||
2433 | /** | ||
2434 | * Load configuration (starts with defaults, then loads | ||
2435 | * system-specific configuration). | ||
2436 | * | ||
2437 | * @param cfg configuration to update | ||
2438 | * @param filename name of the configuration file, NULL to load defaults | ||
2439 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
2440 | */ | ||
2441 | int | ||
2442 | GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg, | ||
2443 | const char *filename) | ||
2444 | { | ||
2445 | char *baseconfig; | ||
2446 | const char *base_config_varname; | ||
2447 | |||
2448 | if (cfg->load_called) | ||
2449 | { | ||
2450 | /* FIXME: Make this a GNUNET_assert later */ | ||
2451 | GNUNET_break (0); | ||
2452 | GNUNET_free (cfg->main_filename); | ||
2453 | } | ||
2454 | cfg->load_called = true; | ||
2455 | if (NULL != filename) | ||
2456 | cfg->main_filename = GNUNET_strdup (filename); | ||
2457 | |||
2458 | base_config_varname = GNUNET_OS_project_data_get ()->base_config_varname; | ||
2459 | |||
2460 | if ((NULL != base_config_varname) | ||
2461 | && (NULL != (baseconfig = getenv (base_config_varname)))) | ||
2462 | { | ||
2463 | baseconfig = GNUNET_strdup (baseconfig); | ||
2464 | } | ||
2465 | else | ||
2466 | { | ||
2467 | char *ipath; | ||
2468 | |||
2469 | ipath = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); | ||
2470 | if (NULL == ipath) | ||
2471 | { | ||
2472 | GNUNET_break (0); | ||
2473 | return GNUNET_SYSERR; | ||
2474 | } | ||
2475 | GNUNET_asprintf (&baseconfig, "%s%s", ipath, "config.d"); | ||
2476 | GNUNET_free (ipath); | ||
2477 | } | ||
2478 | |||
2479 | char *dname = GNUNET_STRINGS_filename_expand (baseconfig); | ||
2480 | GNUNET_free (baseconfig); | ||
2481 | |||
2482 | if ((GNUNET_YES == GNUNET_DISK_directory_test (dname, GNUNET_YES)) && | ||
2483 | (GNUNET_SYSERR == GNUNET_CONFIGURATION_load_from (cfg, dname))) | ||
2484 | { | ||
2485 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
2486 | "Failed to load base configuration from '%s'\n", | ||
2487 | filename); | ||
2488 | GNUNET_free (dname); | ||
2489 | return GNUNET_SYSERR; /* no configuration at all found */ | ||
2490 | } | ||
2491 | GNUNET_free (dname); | ||
2492 | if ((NULL != filename) && | ||
2493 | (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, filename))) | ||
2494 | { | ||
2495 | /* specified configuration not found */ | ||
2496 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
2497 | "Failed to load configuration from file '%s'\n", | ||
2498 | filename); | ||
2499 | return GNUNET_SYSERR; | ||
2500 | } | ||
2501 | if (((GNUNET_YES != | ||
2502 | GNUNET_CONFIGURATION_have_value (cfg, "PATHS", "DEFAULTCONFIG"))) && | ||
2503 | (filename != NULL)) | ||
2504 | GNUNET_CONFIGURATION_set_value_string (cfg, "PATHS", "DEFAULTCONFIG", | ||
2505 | filename); | ||
2506 | return GNUNET_OK; | ||
2507 | } | ||
2508 | |||
2509 | |||
1974 | /* end of configuration.c */ | 2510 | /* 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..ada35249f 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 |
@@ -455,7 +455,7 @@ file_test_internal (const char *fil, int amode) | |||
455 | { | 455 | { |
456 | if (errno != ENOENT) | 456 | if (errno != ENOENT) |
457 | { | 457 | { |
458 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", rdir); | 458 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_DEBUG, "stat", rdir); |
459 | GNUNET_free (rdir); | 459 | GNUNET_free (rdir); |
460 | return GNUNET_SYSERR; | 460 | return GNUNET_SYSERR; |
461 | } | 461 | } |
@@ -469,7 +469,7 @@ file_test_internal (const char *fil, int amode) | |||
469 | } | 469 | } |
470 | if (access (rdir, amode) < 0) | 470 | if (access (rdir, amode) < 0) |
471 | { | 471 | { |
472 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "access", rdir); | 472 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_DEBUG, "access", rdir); |
473 | GNUNET_free (rdir); | 473 | GNUNET_free (rdir); |
474 | return GNUNET_SYSERR; | 474 | return GNUNET_SYSERR; |
475 | } | 475 | } |
@@ -956,6 +956,11 @@ struct GlobClosure | |||
956 | const char *glob; | 956 | const char *glob; |
957 | GNUNET_FileNameCallback cb; | 957 | GNUNET_FileNameCallback cb; |
958 | void *cls; | 958 | void *cls; |
959 | |||
960 | /** | ||
961 | * Number of files that actually matched the glob pattern. | ||
962 | */ | ||
963 | int nres; | ||
959 | }; | 964 | }; |
960 | 965 | ||
961 | /** | 966 | /** |
@@ -984,10 +989,15 @@ glob_cb (void *cls, | |||
984 | 989 | ||
985 | if (glob_match (gc->glob, fn)) | 990 | if (glob_match (gc->glob, fn)) |
986 | { | 991 | { |
992 | enum GNUNET_GenericReturnValue cbret; | ||
993 | |||
987 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 994 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
988 | "found glob match '%s'\n", | 995 | "found glob match '%s'\n", |
989 | filename); | 996 | filename); |
990 | gc->cb (gc->cls, filename); | 997 | gc->nres++; |
998 | cbret = gc->cb (gc->cls, filename); | ||
999 | if (GNUNET_OK != cbret) | ||
1000 | return cbret; | ||
991 | } | 1001 | } |
992 | return GNUNET_OK; | 1002 | return GNUNET_OK; |
993 | } | 1003 | } |
@@ -1002,6 +1012,17 @@ GNUNET_DISK_glob (const char *glob_pattern, | |||
1002 | char *sep; | 1012 | char *sep; |
1003 | int ret; | 1013 | int ret; |
1004 | 1014 | ||
1015 | if ( (NULL != strrchr (glob_pattern, '+')) || | ||
1016 | (NULL != strrchr (glob_pattern, '[')) || | ||
1017 | (NULL != strrchr (glob_pattern, '+')) || | ||
1018 | (NULL != strrchr (glob_pattern, '~')) ) | ||
1019 | { | ||
1020 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
1021 | "unsupported glob pattern: '%s'\n", | ||
1022 | glob_pattern); | ||
1023 | return -1; | ||
1024 | } | ||
1025 | |||
1005 | sep = strrchr (mypat, DIR_SEPARATOR); | 1026 | sep = strrchr (mypat, DIR_SEPARATOR); |
1006 | if (NULL == sep) | 1027 | if (NULL == sep) |
1007 | { | 1028 | { |
@@ -1025,6 +1046,7 @@ GNUNET_DISK_glob (const char *glob_pattern, | |||
1025 | .glob = sep + 1, | 1046 | .glob = sep + 1, |
1026 | .cb = callback, | 1047 | .cb = callback, |
1027 | .cls = callback_cls, | 1048 | .cls = callback_cls, |
1049 | .nres = 0, | ||
1028 | }; | 1050 | }; |
1029 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1051 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1030 | "scanning directory '%s' for glob matches on '%s'\n", | 1052 | "scanning directory '%s' for glob matches on '%s'\n", |
@@ -1034,9 +1056,9 @@ GNUNET_DISK_glob (const char *glob_pattern, | |||
1034 | glob_cb, | 1056 | glob_cb, |
1035 | &gc | 1057 | &gc |
1036 | ); | 1058 | ); |
1059 | GNUNET_free (mypat); | ||
1060 | return (ret < 0) ? ret : gc.nres; | ||
1037 | } | 1061 | } |
1038 | GNUNET_free (mypat); | ||
1039 | return ret; | ||
1040 | } | 1062 | } |
1041 | 1063 | ||
1042 | 1064 | ||
diff --git a/src/util/gnunet-config.c b/src/util/gnunet-config.c index 3932ff1bf..807df0d74 100644 --- a/src/util/gnunet-config.c +++ b/src/util/gnunet-config.c | |||
@@ -70,6 +70,12 @@ static int global_ret; | |||
70 | static int rewrite; | 70 | static int rewrite; |
71 | 71 | ||
72 | /** | 72 | /** |
73 | * Should we give extra diagnostics? | ||
74 | */ | ||
75 | static int diagnostics; | ||
76 | |||
77 | |||
78 | /** | ||
73 | * Should the generated configuration file contain the whole configuration? | 79 | * Should the generated configuration file contain the whole configuration? |
74 | */ | 80 | */ |
75 | static int full; | 81 | static int full; |
@@ -162,6 +168,17 @@ run (void *cls, | |||
162 | GNUNET_free (name); | 168 | GNUNET_free (name); |
163 | return; | 169 | return; |
164 | } | 170 | } |
171 | |||
172 | if (diagnostics) | ||
173 | { | ||
174 | struct GNUNET_CONFIGURATION_Handle *ncfg; | ||
175 | /* Re-parse the configuration with diagnostics enabled. */ | ||
176 | ncfg = GNUNET_CONFIGURATION_create (); | ||
177 | GNUNET_CONFIGURATION_enable_diagnostics (ncfg); | ||
178 | GNUNET_CONFIGURATION_load (ncfg, cfgfile); | ||
179 | cfg = ncfg; | ||
180 | } | ||
181 | |||
165 | if (full) | 182 | if (full) |
166 | rewrite = GNUNET_YES; | 183 | rewrite = GNUNET_YES; |
167 | if (list_sections) | 184 | if (list_sections) |
@@ -176,16 +193,26 @@ run (void *cls, | |||
176 | if ( (! rewrite) && | 193 | if ( (! rewrite) && |
177 | (NULL == section) ) | 194 | (NULL == section) ) |
178 | { | 195 | { |
179 | fprintf (stderr, | 196 | char *serialization; |
180 | _ ("%s or %s argument is required\n"), | ||
181 | "--section", | ||
182 | "--list-sections"); | ||
183 | global_ret = 1; | ||
184 | return; | ||
185 | } | ||
186 | 197 | ||
187 | if ( (NULL != section) && | 198 | if (! diagnostics) |
188 | (NULL == value) ) | 199 | { |
200 | fprintf (stderr, | ||
201 | _ ("%s, %s or %s argument is required\n"), | ||
202 | "--section", | ||
203 | "--list-sections", | ||
204 | "--diagnostics"); | ||
205 | global_ret = 1; | ||
206 | return; | ||
207 | } | ||
208 | serialization = GNUNET_CONFIGURATION_serialize_diagnostics (cfg); | ||
209 | fprintf (stdout, | ||
210 | "%s", | ||
211 | serialization); | ||
212 | GNUNET_free (serialization); | ||
213 | } | ||
214 | else if ( (NULL != section) && | ||
215 | (NULL == value) ) | ||
189 | { | 216 | { |
190 | if (NULL == option) | 217 | if (NULL == option) |
191 | { | 218 | { |
@@ -348,6 +375,12 @@ main (int argc, char *const *argv) | |||
348 | gettext_noop ( | 375 | gettext_noop ( |
349 | "rewrite the configuration file, even if nothing changed"), | 376 | "rewrite the configuration file, even if nothing changed"), |
350 | &rewrite), | 377 | &rewrite), |
378 | GNUNET_GETOPT_option_flag ( | ||
379 | 'd', | ||
380 | "diagnostics", | ||
381 | gettext_noop ( | ||
382 | "output extra diagnostics"), | ||
383 | &diagnostics), | ||
351 | GNUNET_GETOPT_option_flag ('S', | 384 | GNUNET_GETOPT_option_flag ('S', |
352 | "list-sections", | 385 | "list-sections", |
353 | gettext_noop ( | 386 | gettext_noop ( |
diff --git a/src/util/plugin.c b/src/util/plugin.c index feb661f24..39874a588 100644 --- a/src/util/plugin.c +++ b/src/util/plugin.c | |||
@@ -447,8 +447,12 @@ GNUNET_PLUGIN_load_all_in_context (const struct GNUNET_OS_ProjectData *ctx, | |||
447 | void *cb_cls) | 447 | void *cb_cls) |
448 | { | 448 | { |
449 | const struct GNUNET_OS_ProjectData *cpd = GNUNET_OS_project_data_get (); | 449 | const struct GNUNET_OS_ProjectData *cpd = GNUNET_OS_project_data_get (); |
450 | |||
450 | GNUNET_OS_init (ctx); | 451 | GNUNET_OS_init (ctx); |
451 | GNUNET_PLUGIN_load_all (basename, arg, cb, cb_cls); | 452 | GNUNET_PLUGIN_load_all (basename, |
453 | arg, | ||
454 | cb, | ||
455 | cb_cls); | ||
452 | GNUNET_OS_init (cpd); | 456 | GNUNET_OS_init (cpd); |
453 | } | 457 | } |
454 | 458 | ||
diff --git a/src/util/program.c b/src/util/program.c index e34b37370..a79e07d19 100644 --- a/src/util/program.c +++ b/src/util/program.c | |||
@@ -140,7 +140,6 @@ GNUNET_PROGRAM_run2 (int argc, | |||
140 | char *loglev; | 140 | char *loglev; |
141 | char *logfile; | 141 | char *logfile; |
142 | char *cfg_fn; | 142 | char *cfg_fn; |
143 | const char *xdg; | ||
144 | enum GNUNET_GenericReturnValue ret; | 143 | enum GNUNET_GenericReturnValue ret; |
145 | int iret; | 144 | int iret; |
146 | unsigned int cnt; | 145 | unsigned int cnt; |
@@ -149,12 +148,13 @@ GNUNET_PROGRAM_run2 (int argc, | |||
149 | long long clock_offset; | 148 | long long clock_offset; |
150 | struct GNUNET_CONFIGURATION_Handle *cfg; | 149 | struct GNUNET_CONFIGURATION_Handle *cfg; |
151 | const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get (); | 150 | const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get (); |
152 | struct GNUNET_GETOPT_CommandLineOption defoptions[] = | 151 | struct GNUNET_GETOPT_CommandLineOption defoptions[] = { |
153 | { GNUNET_GETOPT_option_cfgfile (&cc.cfgfile), | 152 | GNUNET_GETOPT_option_cfgfile (&cc.cfgfile), |
154 | GNUNET_GETOPT_option_help (binaryHelp), | 153 | GNUNET_GETOPT_option_help (binaryHelp), |
155 | GNUNET_GETOPT_option_loglevel (&loglev), | 154 | GNUNET_GETOPT_option_loglevel (&loglev), |
156 | GNUNET_GETOPT_option_logfile (&logfile), | 155 | GNUNET_GETOPT_option_logfile (&logfile), |
157 | GNUNET_GETOPT_option_version (pd->version) }; | 156 | GNUNET_GETOPT_option_version (pd->version) |
157 | }; | ||
158 | struct GNUNET_GETOPT_CommandLineOption *allopts; | 158 | struct GNUNET_GETOPT_CommandLineOption *allopts; |
159 | const char *gargs; | 159 | const char *gargs; |
160 | char *lpfx; | 160 | char *lpfx; |
@@ -219,17 +219,7 @@ GNUNET_PROGRAM_run2 (int argc, | |||
219 | &cmd_sorter); | 219 | &cmd_sorter); |
220 | loglev = NULL; | 220 | loglev = NULL; |
221 | if ((NULL != pd->config_file) && (NULL != pd->user_config_file)) | 221 | if ((NULL != pd->config_file) && (NULL != pd->user_config_file)) |
222 | { | 222 | cfg_fn = GNUNET_CONFIGURATION_default_filename (); |
223 | xdg = getenv ("XDG_CONFIG_HOME"); | ||
224 | if (NULL != xdg) | ||
225 | GNUNET_asprintf (&cfg_fn, | ||
226 | "%s%s%s", | ||
227 | xdg, | ||
228 | DIR_SEPARATOR_STR, | ||
229 | pd->config_file); | ||
230 | else | ||
231 | cfg_fn = GNUNET_strdup (pd->user_config_file); | ||
232 | } | ||
233 | else | 223 | else |
234 | cfg_fn = NULL; | 224 | cfg_fn = NULL; |
235 | lpfx = GNUNET_strdup (binaryName); | 225 | lpfx = GNUNET_strdup (binaryName); |
@@ -251,6 +241,9 @@ GNUNET_PROGRAM_run2 (int argc, | |||
251 | } | 241 | } |
252 | if (NULL != cc.cfgfile) | 242 | if (NULL != cc.cfgfile) |
253 | { | 243 | { |
244 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
245 | "Loading configuration from entry point specified as option (%s)\n", | ||
246 | cc.cfgfile); | ||
254 | if ((GNUNET_YES != GNUNET_DISK_file_test (cc.cfgfile)) || | 247 | if ((GNUNET_YES != GNUNET_DISK_file_test (cc.cfgfile)) || |
255 | (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cc.cfgfile))) | 248 | (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cc.cfgfile))) |
256 | { | 249 | { |
@@ -266,6 +259,9 @@ GNUNET_PROGRAM_run2 (int argc, | |||
266 | } | 259 | } |
267 | else | 260 | else |
268 | { | 261 | { |
262 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
263 | "Loading configuration default entry point (%s)\n", | ||
264 | cc.cfgfile); | ||
269 | if ((NULL != cfg_fn) && (GNUNET_YES == GNUNET_DISK_file_test (cfg_fn))) | 265 | if ((NULL != cfg_fn) && (GNUNET_YES == GNUNET_DISK_file_test (cfg_fn))) |
270 | { | 266 | { |
271 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cfg_fn)) | 267 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cfg_fn)) |
@@ -283,8 +279,9 @@ GNUNET_PROGRAM_run2 (int argc, | |||
283 | } | 279 | } |
284 | else if (NULL != cfg_fn) | 280 | else if (NULL != cfg_fn) |
285 | { | 281 | { |
282 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
283 | "Loading configuration without entry point\n"); | ||
286 | GNUNET_free (cfg_fn); | 284 | GNUNET_free (cfg_fn); |
287 | cfg_fn = NULL; | ||
288 | if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, NULL)) | 285 | if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, NULL)) |
289 | { | 286 | { |
290 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 287 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
@@ -349,7 +346,7 @@ GNUNET_PROGRAM_run2 (int argc, | |||
349 | cc.task (cc.task_cls, cc.args, cc.cfgfile, cc.cfg); | 346 | cc.task (cc.task_cls, cc.args, cc.cfgfile, cc.cfg); |
350 | } | 347 | } |
351 | ret = GNUNET_OK; | 348 | ret = GNUNET_OK; |
352 | cleanup: | 349 | cleanup: |
353 | GNUNET_CONFIGURATION_destroy (cfg); | 350 | GNUNET_CONFIGURATION_destroy (cfg); |
354 | GNUNET_free (cc.cfgfile); | 351 | GNUNET_free (cc.cfgfile); |
355 | GNUNET_free (cfg_fn); | 352 | GNUNET_free (cfg_fn); |
diff --git a/src/util/test_plugin.c b/src/util/test_plugin.c index c0eb717d6..e739d17c9 100644 --- a/src/util/test_plugin.c +++ b/src/util/test_plugin.c | |||
@@ -26,15 +26,22 @@ | |||
26 | 26 | ||
27 | 27 | ||
28 | static void | 28 | static void |
29 | test_cb (void *cls, const char *libname, void *lib_ret) | 29 | test_cb (void *cls, |
30 | const char *libname, | ||
31 | void *lib_ret) | ||
30 | { | 32 | { |
31 | void *ret; | 33 | const char *test_cls = cls; |
34 | char *ret; | ||
32 | 35 | ||
33 | GNUNET_assert (0 == strcmp (cls, "test")); | 36 | GNUNET_assert (0 == strcmp (test_cls, |
34 | GNUNET_assert (0 == strcmp (lib_ret, "Hello")); | 37 | "test-closure")); |
35 | ret = GNUNET_PLUGIN_unload (libname, "out"); | 38 | GNUNET_assert (0 == strcmp (lib_ret, |
39 | "Hello")); | ||
40 | ret = GNUNET_PLUGIN_unload (libname, | ||
41 | "out"); | ||
36 | GNUNET_assert (NULL != ret); | 42 | GNUNET_assert (NULL != ret); |
37 | GNUNET_assert (0 == strcmp (ret, "World")); | 43 | GNUNET_assert (0 == strcmp (ret, |
44 | "World")); | ||
38 | free (ret); | 45 | free (ret); |
39 | } | 46 | } |
40 | 47 | ||
@@ -44,24 +51,35 @@ main (int argc, char *argv[]) | |||
44 | { | 51 | { |
45 | void *ret; | 52 | void *ret; |
46 | 53 | ||
47 | GNUNET_log_setup ("test-plugin", "WARNING", NULL); | 54 | GNUNET_log_setup ("test-plugin", |
48 | GNUNET_log_skip (1, GNUNET_NO); | 55 | "WARNING", |
49 | ret = GNUNET_PLUGIN_load ("libgnunet_plugin_missing", NULL); | 56 | NULL); |
57 | GNUNET_log_skip (1, | ||
58 | GNUNET_NO); | ||
59 | ret = GNUNET_PLUGIN_load ("libgnunet_plugin_missing", | ||
60 | NULL); | ||
50 | GNUNET_log_skip (0, GNUNET_NO); | 61 | GNUNET_log_skip (0, GNUNET_NO); |
51 | if (ret != NULL) | 62 | if (NULL != ret) |
52 | return 1; | 63 | return 1; |
53 | ret = GNUNET_PLUGIN_load ("libgnunet_plugin_test", "in"); | 64 | ret = GNUNET_PLUGIN_load ("libgnunet_plugin_utiltest", |
54 | if (ret == NULL) | 65 | "in"); |
66 | if (NULL == ret) | ||
55 | return 1; | 67 | return 1; |
56 | if (0 != strcmp (ret, "Hello")) | 68 | if (0 != strcmp (ret, |
69 | "Hello")) | ||
57 | return 2; | 70 | return 2; |
58 | ret = GNUNET_PLUGIN_unload ("libgnunet_plugin_test", "out"); | 71 | ret = GNUNET_PLUGIN_unload ("libgnunet_plugin_utiltest", |
59 | if (ret == NULL) | 72 | "out"); |
73 | if (NULL == ret) | ||
60 | return 3; | 74 | return 3; |
61 | if (0 != strcmp (ret, "World")) | 75 | if (0 != strcmp (ret, |
76 | "World")) | ||
62 | return 4; | 77 | return 4; |
63 | free (ret); | 78 | free (ret); |
64 | GNUNET_PLUGIN_load_all ("libgnunet_plugin_tes", "in", &test_cb, "test"); | 79 | GNUNET_PLUGIN_load_all ("libgnunet_plugin_utiltes", |
80 | "in", | ||
81 | &test_cb, | ||
82 | "test-closure"); | ||
65 | return 0; | 83 | return 0; |
66 | } | 84 | } |
67 | 85 | ||
diff --git a/src/util/test_plugin_plug.c b/src/util/test_plugin_plug.c index 39c8774b1..bfaad52e8 100644 --- a/src/util/test_plugin_plug.c +++ b/src/util/test_plugin_plug.c | |||
@@ -23,8 +23,9 @@ | |||
23 | */ | 23 | */ |
24 | #include "platform.h" | 24 | #include "platform.h" |
25 | 25 | ||
26 | |||
26 | void * | 27 | void * |
27 | libgnunet_plugin_test_init (void *arg) | 28 | libgnunet_plugin_utiltest_init (void *arg) |
28 | { | 29 | { |
29 | if (0 == strcmp (arg, "in")) | 30 | if (0 == strcmp (arg, "in")) |
30 | return "Hello"; | 31 | return "Hello"; |
@@ -33,7 +34,7 @@ libgnunet_plugin_test_init (void *arg) | |||
33 | 34 | ||
34 | 35 | ||
35 | void * | 36 | void * |
36 | libgnunet_plugin_test_done (void *arg) | 37 | libgnunet_plugin_utiltest_done (void *arg) |
37 | { | 38 | { |
38 | if (0 == strcmp (arg, "out")) | 39 | if (0 == strcmp (arg, "out")) |
39 | return strdup ("World"); | 40 | return strdup ("World"); |