diff options
author | Florian Dold <florian@dold.me> | 2021-07-28 18:59:07 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2021-07-28 18:59:07 +0200 |
commit | 1af9f6c1c6adcbb5e5d7af154cb0134e51613a03 (patch) | |
tree | 5653f49db7675f11ef0a260a487db60f0642a9f9 /src/util/configuration.c | |
parent | 7a0caef7a7b1a3fe2949b6a0462125471905540b (diff) | |
download | gnunet-1af9f6c1c6adcbb5e5d7af154cb0134e51613a03.tar.gz gnunet-1af9f6c1c6adcbb5e5d7af154cb0134e51613a03.zip |
config: sort globbed files
Diffstat (limited to 'src/util/configuration.c')
-rw-r--r-- | src/util/configuration.c | 97 |
1 files changed, 68 insertions, 29 deletions
diff --git a/src/util/configuration.c b/src/util/configuration.c index 6178ab68e..fffe08788 100644 --- a/src/util/configuration.c +++ b/src/util/configuration.c | |||
@@ -284,9 +284,14 @@ GNUNET_CONFIGURATION_parse_and_run (const char *filename, | |||
284 | struct InlineGlobClosure | 284 | struct InlineGlobClosure |
285 | { | 285 | { |
286 | /** | 286 | /** |
287 | * Configuration to read inlined configuration into. | 287 | * Collected files from globbing. |
288 | */ | 288 | */ |
289 | struct GNUNET_CONFIGURATION_Handle *cfg; | 289 | char **files; |
290 | |||
291 | /** | ||
292 | * Size of the files array. | ||
293 | */ | ||
294 | unsigned int files_length; | ||
290 | }; | 295 | }; |
291 | 296 | ||
292 | 297 | ||
@@ -306,15 +311,12 @@ inline_glob_cb (void *cls, | |||
306 | struct InlineGlobClosure *igc = cls; | 311 | struct InlineGlobClosure *igc = cls; |
307 | 312 | ||
308 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 313 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
309 | "Reading globbed config file '%s'\n", | 314 | "Found globbed config file '%s'\n", |
310 | filename); | 315 | filename); |
311 | 316 | ||
312 | if (GNUNET_OK != | 317 | GNUNET_array_append (igc->files, |
313 | GNUNET_CONFIGURATION_parse (igc->cfg, | 318 | igc->files_length, |
314 | filename)) | 319 | GNUNET_strdup (filename)); |
315 | { | ||
316 | return GNUNET_SYSERR; | ||
317 | } | ||
318 | return GNUNET_OK; | 320 | return GNUNET_OK; |
319 | } | 321 | } |
320 | 322 | ||
@@ -339,6 +341,13 @@ find_section (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
339 | } | 341 | } |
340 | 342 | ||
341 | 343 | ||
344 | static int | ||
345 | pstrcmp (const void *a, const void *b) | ||
346 | { | ||
347 | return strcmp (*((const char **) a), *((const char **) b)); | ||
348 | } | ||
349 | |||
350 | |||
342 | /** | 351 | /** |
343 | * Handle an inline directive. | 352 | * Handle an inline directive. |
344 | * | 353 | * |
@@ -353,6 +362,12 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
353 | unsigned int source_lineno) | 362 | unsigned int source_lineno) |
354 | { | 363 | { |
355 | char *inline_path; | 364 | char *inline_path; |
365 | struct GNUNET_CONFIGURATION_Handle *other_cfg = NULL; | ||
366 | struct InlineGlobClosure igc = { | ||
367 | .files = NULL, | ||
368 | .files_length = 0, | ||
369 | }; | ||
370 | enum GNUNET_GenericReturnValue fun_ret; | ||
356 | 371 | ||
357 | /* We support the section restriction only for non-globs */ | 372 | /* We support the section restriction only for non-globs */ |
358 | GNUNET_assert (! (path_is_glob && (NULL != restrict_section))); | 373 | GNUNET_assert (! (path_is_glob && (NULL != restrict_section))); |
@@ -362,8 +377,10 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
362 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 377 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
363 | "Refusing to parse inline configurations, " | 378 | "Refusing to parse inline configurations, " |
364 | "not allowed without source filename!\n"); | 379 | "not allowed without source filename!\n"); |
365 | return GNUNET_SYSERR; | 380 | fun_ret = GNUNET_SYSERR; |
381 | goto cleanup; | ||
366 | } | 382 | } |
383 | |||
367 | if ('/' == *path_or_glob) | 384 | if ('/' == *path_or_glob) |
368 | inline_path = GNUNET_strdup (path_or_glob); | 385 | inline_path = GNUNET_strdup (path_or_glob); |
369 | else | 386 | else |
@@ -381,7 +398,8 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
381 | /* Couldn't even resolve path of base dir. */ | 398 | /* Couldn't even resolve path of base dir. */ |
382 | GNUNET_break (0); | 399 | GNUNET_break (0); |
383 | /* failed to parse included config */ | 400 | /* failed to parse included config */ |
384 | return GNUNET_SYSERR; | 401 | fun_ret = GNUNET_SYSERR; |
402 | goto cleanup; | ||
385 | } | 403 | } |
386 | endsep = strrchr (source_realpath, '/'); | 404 | endsep = strrchr (source_realpath, '/'); |
387 | GNUNET_assert (NULL != endsep); | 405 | GNUNET_assert (NULL != endsep); |
@@ -392,12 +410,10 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
392 | path_or_glob); | 410 | path_or_glob); |
393 | free (source_realpath); | 411 | free (source_realpath); |
394 | } | 412 | } |
413 | |||
395 | if (path_is_glob) | 414 | if (path_is_glob) |
396 | { | 415 | { |
397 | int nret; | 416 | int nret; |
398 | struct InlineGlobClosure igc = { | ||
399 | .cfg = cfg, | ||
400 | }; | ||
401 | 417 | ||
402 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 418 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
403 | "processing config glob '%s'\n", | 419 | "processing config glob '%s'\n", |
@@ -406,13 +422,25 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
406 | nret = GNUNET_DISK_glob (inline_path, inline_glob_cb, &igc); | 422 | nret = GNUNET_DISK_glob (inline_path, inline_glob_cb, &igc); |
407 | if (-1 == nret) | 423 | if (-1 == nret) |
408 | { | 424 | { |
409 | GNUNET_free (inline_path); | 425 | fun_ret = GNUNET_SYSERR; |
410 | return GNUNET_SYSERR; | 426 | goto cleanup; |
427 | } | ||
428 | GNUNET_assert (nret == igc.files_length); | ||
429 | qsort (igc.files, igc.files_length, sizeof (char *), pstrcmp); | ||
430 | for (int i = 0; i < nret; i++) | ||
431 | { | ||
432 | if (GNUNET_OK != | ||
433 | GNUNET_CONFIGURATION_parse (cfg, | ||
434 | igc.files[i])) | ||
435 | { | ||
436 | fun_ret = GNUNET_SYSERR; | ||
437 | goto cleanup; | ||
438 | } | ||
411 | } | 439 | } |
440 | fun_ret = GNUNET_OK; | ||
412 | } | 441 | } |
413 | else if (NULL != restrict_section) | 442 | else if (NULL != restrict_section) |
414 | { | 443 | { |
415 | struct GNUNET_CONFIGURATION_Handle *other_cfg; | ||
416 | enum GNUNET_GenericReturnValue fret; | 444 | enum GNUNET_GenericReturnValue fret; |
417 | struct ConfigSection *cs; | 445 | struct ConfigSection *cs; |
418 | 446 | ||
@@ -442,17 +470,16 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
442 | if (GNUNET_OK != fret) | 470 | if (GNUNET_OK != fret) |
443 | { | 471 | { |
444 | cs->inaccessible = true; | 472 | cs->inaccessible = true; |
445 | GNUNET_free (inline_path); | 473 | fun_ret = GNUNET_OK; |
446 | return GNUNET_OK; | 474 | goto cleanup; |
447 | } | 475 | } |
448 | 476 | ||
449 | other_cfg = GNUNET_CONFIGURATION_create (); | 477 | other_cfg = GNUNET_CONFIGURATION_create (); |
450 | if (GNUNET_OK != GNUNET_CONFIGURATION_parse (other_cfg, | 478 | if (GNUNET_OK != GNUNET_CONFIGURATION_parse (other_cfg, |
451 | inline_path)) | 479 | inline_path)) |
452 | { | 480 | { |
453 | GNUNET_free (inline_path); | 481 | fun_ret = GNUNET_SYSERR; |
454 | GNUNET_CONFIGURATION_destroy (other_cfg); | 482 | goto cleanup; |
455 | return GNUNET_SYSERR; | ||
456 | } | 483 | } |
457 | 484 | ||
458 | cs = find_section (other_cfg, restrict_section); | 485 | cs = find_section (other_cfg, restrict_section); |
@@ -462,9 +489,8 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
462 | "inlined configuration '%s' does not contain section '%s'\n", | 489 | "inlined configuration '%s' does not contain section '%s'\n", |
463 | inline_path, | 490 | inline_path, |
464 | restrict_section); | 491 | restrict_section); |
465 | GNUNET_free (inline_path); | 492 | fun_ret = GNUNET_SYSERR; |
466 | GNUNET_free (other_cfg); | 493 | goto cleanup; |
467 | return GNUNET_SYSERR; | ||
468 | } | 494 | } |
469 | for (struct ConfigEntry *ce = cs->entries; | 495 | for (struct ConfigEntry *ce = cs->entries; |
470 | NULL != ce; | 496 | NULL != ce; |
@@ -473,17 +499,30 @@ handle_inline (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
473 | restrict_section, | 499 | restrict_section, |
474 | ce->key, | 500 | ce->key, |
475 | ce->val); | 501 | ce->val); |
476 | GNUNET_CONFIGURATION_destroy (other_cfg); | 502 | fun_ret = GNUNET_OK; |
477 | } | 503 | } |
478 | else if (GNUNET_OK != | 504 | else if (GNUNET_OK != |
479 | GNUNET_CONFIGURATION_parse (cfg, | 505 | GNUNET_CONFIGURATION_parse (cfg, |
480 | inline_path)) | 506 | inline_path)) |
481 | { | 507 | { |
482 | GNUNET_free (inline_path); | 508 | fun_ret = GNUNET_SYSERR; |
483 | return GNUNET_SYSERR; | 509 | goto cleanup; |
510 | } | ||
511 | else | ||
512 | { | ||
513 | fun_ret = GNUNET_OK; | ||
484 | } | 514 | } |
515 | cleanup: | ||
516 | if (NULL != other_cfg) | ||
517 | GNUNET_CONFIGURATION_destroy (other_cfg); | ||
485 | GNUNET_free (inline_path); | 518 | GNUNET_free (inline_path); |
486 | return GNUNET_OK; | 519 | if (igc.files_length > 0) |
520 | { | ||
521 | for (size_t i = 0; i < igc.files_length; i++) | ||
522 | GNUNET_free (igc.files[i]); | ||
523 | GNUNET_array_grow (igc.files, igc.files_length, 0); | ||
524 | } | ||
525 | return fun_ret; | ||
487 | } | 526 | } |
488 | 527 | ||
489 | 528 | ||