]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Update args parser framework
authordhfelix <daniel.hdz.felix@hotmail.com>
Thu, 14 Feb 2019 21:57:03 +0000 (15:57 -0600)
committerdhfelix <daniel.hdz.felix@hotmail.com>
Thu, 14 Feb 2019 21:57:03 +0000 (15:57 -0600)
src/config.c
src/config.h
src/main.c
src/rsync/rsync.c
src/rsync/rsync.h
src/toml_handler.c
src/toml_handler.h
test/Makefile.am

index 6b25b719a00106f38142a5840bc8f18530a24cc1..92f31e2c7ead0f0b5b0716c5edd9f5a53a4f684d 100644 (file)
@@ -1,31 +1,44 @@
 #include "config.h"
 
 #include <stdio.h>
-#include <strings.h>
+#include <string.h>
 #include <errno.h>
 #include <getopt.h>
 
 #include "common.h"
 #include "log.h"
+#include "toml_handler.h"
 
 #define OPT_FIELD_ARRAY_LEN(array) ARRAY_LEN(array) - 1
 
-struct args_flag {
-       struct option_field *field;
-       bool is_set;
+struct rpki_config {
+       /* tal file path*/
+       char *tal;
+       /* Local repository path */
+       char *local_repository;
+       /* Enable rsync downloads */
+       bool enable_rsync;
+       /* Shuffle uris in tal */
+       bool shuffle_uris;
+       /*
+        * rfc6487#section-7.2, last paragraph.
+        * Prevents arbitrarily long paths and loops.
+        */
+       unsigned int maximum_certificate_depth;
 };
 
 static int parse_bool(struct option_field *, char *, void *);
 static int parse_u_int(struct option_field *, char *, void *);
+static void _free_rpki_config(struct rpki_config *);
 
-static struct rpki_config config;
+static struct rpki_config rpki_config;
 
 static struct global_type gt_bool = {
        .id = GTI_BOOL,
        .name = "Boolean",
        .size = sizeof(bool),
        .parse = parse_bool,
-       .candidates = "true false",
+       .candidates = "true|false",
 };
 
 static struct global_type gt_string = {
@@ -38,9 +51,19 @@ static struct global_type gt_u_int = {
        .name = "Unsigned Int",
        .size = sizeof(unsigned int),
        .parse = parse_u_int,
-       .candidates = "Unsigned Int",
+       .candidates = "NUM",
+};
+
+static struct option manual_long_opts[] = {
+       {
+               .name = "configuration-file",
+               .has_arg = required_argument,
+               .flag = NULL,
+               .val = 'f',
+       },
 };
 
+
 static struct option_field global_fields[] = {
        {
                .name = "local-repository",
@@ -91,8 +114,8 @@ static struct option_field tal_fields[] = {
                .short_opt = 0,
                .min = 1,
                /**
-                * It cannot be UINT_MAX, because then the actual number will overflow
-                * and will never be bigger than this.
+                * It cannot be UINT_MAX, because then the actual number will
+                * overflow and will never be bigger than this.
                 */
                .max =  UINT_MAX - 1,
                .required = false,
@@ -100,6 +123,22 @@ static struct option_field tal_fields[] = {
        { NULL },
 };
 
+
+
+static struct group_fields fields[] = {
+       {
+               .group_name = "root",
+               .options = global_fields,
+               .options_len = OPT_FIELD_ARRAY_LEN(global_fields),
+       },
+       {
+               .group_name = "tal",
+               .options = tal_fields,
+               .options_len = OPT_FIELD_ARRAY_LEN(tal_fields),
+       },
+       { NULL },
+};
+
 static int
 str_to_bool(const char *str, bool *bool_out)
 {
@@ -129,26 +168,17 @@ parse_bool(struct option_field *field, char *str, void *result)
                *value = true;
                return 0;
                break;
-       case required_argument:
        case optional_argument:
-               if (field->has_arg == optional_argument && str == NULL) {
+               if (str == NULL) {
                        *value = true;
-                       return 0;
+                       break;
                }
-               /**
-                * XXX: (fine) GETOPT should had ensure that the code did
-                * not reach here for this particular case.
-                * */
+               /* FALLTHROUGH */
+       case required_argument:
                return str_to_bool(str, result);
-               break;
-       }
-
-       if (str == NULL) {
-               *value = true;
-               return 0;
        }
 
-       return str_to_bool(str, result);
+       return 0;
 }
 
 static int str_to_ull(const char *str, char **endptr,
@@ -199,46 +229,59 @@ static int
 construct_options(struct args_flag **flags, struct option **long_options,
     int *flags_len)
 {
+       struct option_field *tmp;
+       struct group_fields *tmp_all_fields;
        struct args_flag *result_flags;
-       struct option_field *global, *tal;
        struct option *result_options;
-       unsigned int global_len, tal_len, total_len, i, result_idx;
-
-       get_global_fields(&global, &global_len);
-       get_tal_fields(&tal, &tal_len);
-
-       total_len = global_len + tal_len;
+       unsigned int total_len, i, result_idx,
+           extra_long_options;
+
+       tmp_all_fields = fields;
+       total_len = 0;
+       while (tmp_all_fields->group_name != NULL) {
+               total_len += tmp_all_fields->options_len;
+               tmp_all_fields += 1;
+       }
 
-       result_flags = calloc(total_len, sizeof(struct args_flag));
+       /* +1 NULL end, means end of array. */
+       result_flags = calloc(total_len + 1, sizeof(struct args_flag));
        if (result_flags == NULL)
                return pr_enomem();
 
-       /* Long options must end with zeros (+1) */
-       result_options = calloc(total_len + 1, sizeof(struct option));
+       extra_long_options = ARRAY_LEN(manual_long_opts);
+
+       result_options = calloc(total_len
+           + extra_long_options /* extra options handled manually. */
+           + 1, /* long options must end with zeros */
+           sizeof(struct option));
        if (result_options == NULL) {
                free(result_flags);
                return pr_enomem();
        }
 
        result_idx = 0;
-       for(i = 0; i < global_len; i++) {
-               result_flags[result_idx].field = &(global[i]);
-
-               result_options[result_idx].name = global[i].name;
-               result_options[result_idx].has_arg = global[i].has_arg;
-               result_options[result_idx].val = global[i].short_opt;
-               result_options[result_idx].flag = NULL;
-
-               result_idx++;
+       tmp_all_fields = fields;
+       while (tmp_all_fields->group_name != NULL) {
+               tmp = tmp_all_fields->options;
+               while(tmp->name != NULL) {
+                       result_flags[result_idx].field = tmp;
+
+                       result_options[result_idx].name = tmp->name;
+                       result_options[result_idx].has_arg = tmp->has_arg;
+                       result_options[result_idx].val = tmp->short_opt;
+                       result_options[result_idx].flag = NULL;
+
+                       result_idx++;
+                       tmp += 1;
+               }
+               tmp_all_fields += 1;
        }
 
-       for(i = 0; i < tal_len; i++) {
-               result_flags[result_idx].field = &(tal[i]);
-
-               result_options[result_idx].name = tal[i].name;
-               result_options[result_idx].has_arg = tal[i].has_arg;
-               result_options[result_idx].val = tal[i].short_opt;
-               result_options[result_idx].flag = NULL;
+       for (i = 0; i < extra_long_options; i++) {
+               result_options[result_idx].name = manual_long_opts[i].name;
+               result_options[result_idx].has_arg = manual_long_opts[i].has_arg;
+               result_options[result_idx].val = manual_long_opts[i].val;
+               result_options[result_idx].flag = manual_long_opts[i].flag;
 
                result_idx++;
        }
@@ -250,10 +293,21 @@ construct_options(struct args_flag **flags, struct option **long_options,
        return 0;
 }
 
-static void
+static int
 set_string(void **field, char *str)
 {
-       *field = str;
+       char *result;
+
+       /* malloc the string, because if the string comes from TOML_HANDLER,
+        * the string is freed later in that function. */
+       result = malloc(strlen(str) + 1);
+       if (result == NULL)
+               return pr_enomem();
+
+       strcpy(result, str);
+       *field = result;
+
+       return 0;
 }
 
 static void
@@ -280,7 +334,9 @@ handle_option(struct rpki_config *config, struct option_field *field, char *str)
        config_param += field->offset;
 
        if (field->type == &gt_string) {
-               set_string(config_param, str);
+               error = set_string(config_param, str);
+               if (error)
+                       return error;
                set_config_param_for_string(config_param, &config_param);
        } else if (field->type->parse != NULL){
                error = field->type->parse(field, str, config_param);
@@ -307,7 +363,7 @@ check_missing_flags(struct args_flag *flag)
        if (!flag->field->required)
                return 0;
 
-       printf("Missing flag --%s", flag->field->name);
+       printf("Missing param: %s", flag->field->name);
        switch (flag->field->has_arg) {
        case no_argument:
                break;
@@ -352,44 +408,151 @@ print_config(struct rpki_config *config)
        pr_debug_rm("}");
 }
 
+static void
+set_default_values(struct rpki_config *config)
+{
+       config->enable_rsync = true;
+       config->local_repository = NULL;
+       config->maximum_certificate_depth = 32;
+       config->shuffle_uris = false;
+       config->tal = NULL;
+}
+
+static void _print_usage(bool only_required)
+{
+       struct option_field *tmp;
+       struct group_fields *tmp_all_fields;
+       char *candidates;
+       bool required;
+
+       get_group_fields(&tmp_all_fields);
+
+       while (tmp_all_fields->group_name != NULL) {
+               tmp = tmp_all_fields->options;
+               while(tmp->name != NULL) {
+                       required = tmp->required;
+
+                       if (only_required != required) {
+                               tmp += 1;
+                               continue;
+                       }
+
+                       fprintf(stderr, " ");
+
+                       if (!required)
+                               fprintf(stderr, "[");
+                       fprintf(stderr, "--%s", tmp->name);
+
+                       if (tmp->candidates != NULL)
+                               candidates = tmp->candidates;
+                       else if (tmp->type->candidates != NULL)
+                               candidates = tmp->type->candidates;
+                       else
+                               candidates = NULL;
+
+                       switch (tmp->has_arg) {
+                       case no_argument:
+                               break;
+                       case optional_argument:
+                               if(candidates == NULL)
+                                       break;
+                               fprintf(stderr, "=<%s>", candidates);
+                               break;
+                       case required_argument:
+                               if(candidates == NULL)
+                                       break;
+                               fprintf(stderr, " <%s>", candidates);
+                               break;
+                       default:
+                               break;
+                       }
+                       if (!required)
+                               fprintf(stderr, "]");
+                       tmp += 1;
+               }
+               tmp_all_fields += 1;
+       }
+
+}
+
+
+void
+print_usage(char *progname)
+{
+       /*
+        * TODO openbsd styleguide said use "getprogname" to set the progam
+        * name.
+        */
+       fprintf(stderr, "usage: %s", progname);
+
+       fprintf(stderr, " [-f <config_file>] "
+           "[--configuration-file <config_file>]");
+
+       _print_usage(true);
+       _print_usage(false);
+
+       fprintf(stderr, "\n");
+       exit(1);
+}
+
 int
-handle_flags_config(int argc, char **argv, struct rpki_config *config)
+handle_flags_config(int argc, char **argv)
 {
        struct args_flag *flags;
        struct option *long_options;
-       int opt, indexptr, flags_len, error = 0;
+       struct rpki_config config;
+       int opt, indexptr, flags_len, error;
+
+       set_default_values(&config);
 
-       flags = NULL;
        long_options = NULL;
+       flags = NULL;
+       flags_len = 0;
 
        error = construct_options(&flags, &long_options, &flags_len);
        if (error)
                return error; /* Error msg already printed. */
 
-       while ((opt = getopt_long(argc, argv, "", long_options, &indexptr))
-           != -1) {
+       while ((opt = getopt_long(argc, argv, "f:", long_options, &indexptr))
+           != -1)
                switch (opt) {
                case 0:
                        flags[indexptr].is_set = true;
-                       error = handle_option(config, flags[indexptr].field,
+                       error = handle_option(&config, flags[indexptr].field,
                            optarg);
+                       if (error) {
+                               print_usage(argv[0]);
+                               goto end;
+                       }
                        break;
-               default:
-                       error = pr_err("some usage hints.");/* TODO */
+               case 'f':
+                       error = set_config_from_file(optarg, &config, flags);
+                       if (error) {
+                               print_usage(argv[0]);
+                               goto end;
+                       }
                        break;
-               }
-
-               if (error)
+               default:
+                       print_usage(argv[0]);
+                       error = -EINVAL;
                        goto end;
-       }
+               }
 
-       for (indexptr = 0; indexptr < flags_len; indexptr++) {
+       for (indexptr = 0; indexptr < flags_len; indexptr++)
                error |= check_missing_flags(&flags[indexptr]);
+
+       if (error) {
+               print_usage(argv[0]);
+               goto end;
        }
 
-       print_config(config);
+       print_config(&config);
+       config_set(&config);
 
 end:
+       if (error)
+               _free_rpki_config(&config);
+
        free(flags);
        free(long_options);
        return error;
@@ -397,55 +560,60 @@ end:
 }
 
 void
-get_global_fields(struct option_field **fields, unsigned int *len)
-{
-       if (fields)
-               *fields = global_fields;
-       if (len)
-               *len = OPT_FIELD_ARRAY_LEN(global_fields);
-}
-
-void
-get_tal_fields(struct option_field **fields, unsigned int *len)
+get_group_fields(struct group_fields **group_fields)
 {
-       if (fields)
-               *fields = tal_fields;
-       if (len)
-               *len = OPT_FIELD_ARRAY_LEN(tal_fields);
+       if (group_fields)
+               *group_fields = fields;
 }
 
 void
 config_set(struct rpki_config *new)
 {
-       config = *new;
+       rpki_config = *new;
 }
 
 char const *
 config_get_tal(void)
 {
-       return config.tal;
+       return rpki_config.tal;
 }
 
 char const *
 config_get_local_repository(void)
 {
-       return config.local_repository;
+       return rpki_config.local_repository;
 }
 
 bool
 config_get_enable_rsync(void)
 {
-       return config.enable_rsync;
+       return rpki_config.enable_rsync;
 }
 
 bool
 config_get_shuffle_uris(void)
 {
-       return config.shuffle_uris;
+       return rpki_config.shuffle_uris;
 }
 
 unsigned int
 config_get_max_cert_depth(void)
 {
-       return config.maximum_certificate_depth;
+       return rpki_config.maximum_certificate_depth;
+}
+
+static void
+_free_rpki_config(struct rpki_config *config)
+{
+       if (config->local_repository != NULL)
+               free(config->local_repository);
+
+       if (config->tal != NULL)
+               free(config->tal);
+}
+
+void
+free_rpki_config(void)
+{
+       _free_rpki_config(&rpki_config);
 }
index 54a64e5a1b7f6eab09e5219f028aa84508dcb320..14fac274c761e5cc2b06f8d83e723fca0c878b87 100644 (file)
@@ -4,21 +4,9 @@
 #include <stdbool.h>
 #include <stddef.h>
 
-struct rpki_config {
-       /* tal file path*/
-       char *tal;
-       /* Local repository path */
-       char *local_repository;
-       /* Enable rsync downloads */
-       bool enable_rsync;
-       /* Shuffle uris in tal */
-       bool shuffle_uris;
-       /*
-        * rfc6487#section-7.2, last paragraph.
-        * Prevents arbitrarily long paths and loops.
-        */
-       unsigned int maximum_certificate_depth;
-};
+struct rpki_config;
+
+struct option_field;
 
 typedef enum global_type_id {
        GTI_BOOL,
@@ -26,13 +14,16 @@ typedef enum global_type_id {
        GTI_U_INT,
 } global_type_id;
 
-struct option_field;
-
 typedef void (*print_function)(void *, bool);
 typedef int (*parse_function)(struct option_field *, char *, void *);
 /* This function does not need to validate type->size. */
 typedef int (*validate_function)(struct option_field *, void *);
 
+struct args_flag {
+       struct option_field *field;
+       bool is_set;
+};
+
 struct global_type {
        global_type_id id;
        const char *name;
@@ -58,12 +49,17 @@ struct option_field {
        bool required;
 };
 
-int handle_option(struct rpki_config *, struct option_field *, char *);
-int handle_flags_config(int , char **, struct rpki_config *);
+struct group_fields {
+       char *group_name;
+       struct option_field *options;
+       unsigned int options_len;
+};
 
-void get_global_fields(struct option_field **, unsigned int *);
+void print_usage(char *progname);
+int handle_option(struct rpki_config *, struct option_field *, char *);
+int handle_flags_config(int , char **);
 
-void get_tal_fields(struct option_field **, unsigned int *);
+void get_group_fields(struct group_fields **);
 
 void config_set(struct rpki_config *);
 
@@ -72,5 +68,6 @@ char const *config_get_local_repository(void);
 bool config_get_enable_rsync(void);
 bool config_get_shuffle_uris(void);
 unsigned int config_get_max_cert_depth(void);
+void free_rpki_config(void);
 
 #endif /* SRC_CONFIG_H_ */
index ae826fbd87a7174da65d50fabc2783ea758ea772..4b15ffb5a274b07fcb1be319e4c3ee9e03189408 100644 (file)
@@ -9,7 +9,6 @@
 #include "log.h"
 #include "rpp.h"
 #include "thread_var.h"
-#include "toml_handler.h"
 #include "object/certificate.h"
 #include "object/manifest.h"
 #include "object/tal.h"
@@ -112,62 +111,21 @@ end:
        return error;
 }
 
-static int
-handle_file_config(char *config_file, struct rpki_config *config)
-{
-       return set_config_from_file(config_file, config);
-}
-
-static int
-handle_args(int argc, char **argv)
-{
-       struct rpki_config config;
-       char *config_file;
-       int error;
-
-       config.enable_rsync = true;
-       config.local_repository = NULL;
-       config.maximum_certificate_depth = 32;
-       config.shuffle_uris = false;
-       config.tal = NULL;
-
-       if (argc == 1) {
-               return pr_err("Show usage"); /*TODO*/
-       }
-       if (strcasecmp(argv[1], "--configuration_file") == 0) {
-               if (argc == 2) {
-                       return pr_err("--configuration_file requires a string "
-                           "as argument.");
-               }
-               config_file = argv[2];
-               argc -= 2;
-               argv += 2;
-               error = handle_file_config(config_file, &config);
-       } else {
-               error = handle_flags_config(argc, argv, &config);
-       }
-
-       if (!error)
-               config_set(&config);
-
-       return error;
-}
-
-
 int
 main(int argc, char **argv)
 {
        struct tal *tal;
        int error;
 
-       error = handle_args(argc, argv);
+       error = handle_flags_config(argc, argv);
        if (error)
                return error;
+
        print_stack_trace_on_segfault();
 
-       error = rsync_init();
+       error = rsync_init(config_get_enable_rsync());
        if (error)
-               return error;
+               goto end;
 
        add_rpki_oids();
        thvar_init();
@@ -184,5 +142,7 @@ main(int argc, char **argv)
        }
 
        rsync_destroy();
+end:
+       free_rpki_config();
        return error;
 }
index 2072d4e97af93c2cff8f70ca97d31d85574893bf..7c435d40718302c2bba0cc1c2aba32b8122de0bd 100644 (file)
@@ -23,14 +23,16 @@ SLIST_HEAD(uri_list, uri);
 
 static struct uri_list *rsync_uris;
 static char const *const RSYNC_PREFIX = "rsync://";
+static bool rsync_enabled;
 
 //static const char *rsync_command[] = {"rsync", "--recursive", "--delete", "--times", NULL};
 
 int
-rsync_init(void)
+rsync_init(bool is_rsync_enable)
 {
        /* Disabling rsync will forever be a useful debugging feature. */
-       if (!config_get_enable_rsync())
+       rsync_enabled = is_rsync_enable;
+       if (!rsync_enabled)
                return 0;
 
        rsync_uris = malloc(sizeof(struct uri_list));
@@ -46,7 +48,7 @@ rsync_destroy(void)
 {
        struct uri *uri;
 
-       if (!config_get_enable_rsync())
+       if (!rsync_enabled)
                return;
 
        while (!SLIST_EMPTY(rsync_uris)) {
@@ -378,7 +380,7 @@ download_files(struct rpki_uri const *uri)
 
        prefix_len = strlen(RSYNC_PREFIX);
 
-       if (!config_get_enable_rsync())
+       if (!rsync_enabled)
                return 0;
 
        if (uri->global_len < prefix_len ||
index f4114df66b53516865787a9414fc5b9d97184756..688c1df6b49b9ea05d1d050e5b4b5dd0938c43c3 100644 (file)
@@ -5,7 +5,7 @@
 #include "uri.h"
 
 int download_files(struct rpki_uri const *);
-int rsync_init(void);
+int rsync_init(bool);
 void rsync_destroy(void);
 
 
index 58bd754ea645bd3047a20410e00cb3490a6d96fd..1f793104b3b02882ee0e82b8805fa58453158f54 100644 (file)
 #include "thread_var.h"
 #include "uri.h"
 
-
-static void
-print_config(struct rpki_config *config)
+static int
+find_flag(struct args_flag *flags_handled, char *flag_to_find,
+    struct args_flag **result)
 {
-       pr_debug("Program configuration");
-       pr_debug_add("{");
-       pr_debug("%s: %s", "local_repository", config->local_repository);
-       pr_debug("%s: %s", "tal.file", config->tal);
-       pr_debug("%s: %s", "enable_rsync",
-           config->enable_rsync ? "true" : "false");
-       pr_debug("%s: %s", "tal.shuffle_uris",
-           config->shuffle_uris ? "true" : "false");
-       pr_debug("%s: %u", "tal.maximum-certificate-depth",
-                   config->maximum_certificate_depth);
-       pr_debug_rm("}");
+       int cmp;
+       *result = NULL;
+
+       while(flags_handled->field != NULL) {
+               cmp = strcmp(flags_handled->field->name, flag_to_find);
+               if (cmp == 0) {
+                       *result = flags_handled;
+                       break;
+               }
+               flags_handled = flags_handled + 1;
+       }
+
+       if (*result == NULL)
+               return pr_crit("Missing parameter %s.", flag_to_find);
+
+       return 0;
 }
 
 static int
 iterate_fields(struct toml_table_t *table, struct rpki_config *config,
-    struct option_field *fields, unsigned int field_len)
+    struct option_field *fields, struct args_flag *flags_handled)
 {
-       struct option_field *field;
+       struct option_field *tmp_field;
+       struct args_flag *tmp_arg;
        const char *result;
        char *str;
-       int i, error, missing_param;
+       int error;
 
-       missing_param = 0;
+       tmp_field = fields;
+       while (tmp_field->name != NULL) {
+               error = find_flag(flags_handled, tmp_field->name, &tmp_arg);
+               if (error)
+                       return error; /* Error msg already printed. */
+               if (tmp_arg->is_set) {
+                       tmp_field += 1;
+                       continue;
+               }
 
-       for (i = 0; i < field_len; i++) {
-               field = &(fields[i]);
-               result = toml_raw_in(table, field->name);
+               result = toml_raw_in(table, tmp_field->name);
                if (result == 0) {
-                       if (field->required) {
-                               printf("Required parameter is missing '%s'\n",
-                                   field->name);
-                               missing_param |= -ENOENT;
-                       }
+                       tmp_field += 1;
                        continue;
                }
 
                str = (char *) result;
-               if (field->type->id == GTI_STRING) {
+               if (tmp_field->type->id == GTI_STRING) {
                        error = toml_rtos(result, &str);
                        if (error)
                                return pr_err("Bad value in '%s'",
-                                   field->name);
+                                   tmp_field->name);
                }
 
-               error = handle_option(config, field, str);
+               error = handle_option(config, tmp_field, str);
                if (error)
                        return error;
 
+               /* Free returned string from toml */
+               if (tmp_field->type->id == GTI_STRING)
+                       free(str);
+
+               tmp_arg->is_set = true;
+               tmp_field += 1;
        }
 
-       if (missing_param)
-               return missing_param;
        return error;
 }
 
 static int
-handle_tal_table(struct toml_table_t *tal, struct rpki_config *config)
+toml_to_config(struct toml_table_t *root, struct rpki_config *config,
+    struct args_flag *flags_handled)
 {
-       struct option_field *tal_fields;
-       unsigned int tal_len;
-
-       get_tal_fields(&tal_fields, &tal_len);
-
-       return iterate_fields(tal, config, tal_fields, tal_len);
-}
-
-static int
-toml_to_config(struct toml_table_t *root, struct rpki_config *config)
-{
-       struct option_field *globals;
-       struct toml_table_t *tal;
+       struct toml_table_t *toml_table;
+       struct group_fields *group_fields;
        int error;
-       unsigned int global_len;
 
+       get_group_fields(&group_fields);
+       if (group_fields == NULL)
+               return 0;
 
-       get_global_fields(&globals, &global_len);
-       error = iterate_fields(root, config, globals, global_len);
+       error = iterate_fields(root, config, group_fields->options,
+           flags_handled);
        if (error)
                return error;
+       group_fields += 1;
 
-       tal = toml_table_in(root, "tal");
-       if (tal != 0)
-               error = handle_tal_table(tal, config);
-       else
-               return pr_err("Required table '%s' is missing.", "tal");
+       while (group_fields->group_name != NULL) {
+               toml_table = toml_table_in(root, group_fields->group_name);
+               if (toml_table == 0) {
+                       group_fields += 1;
+                       continue;
+               }
+               error = iterate_fields(toml_table, config,
+                   group_fields->options, flags_handled);
+               if (error)
+                       return error;
+               group_fields += 1;
+       }
 
        return error;
 }
 
 int
-set_config_from_file(char *config_file, struct rpki_config *config)
+set_config_from_file(char *config_file, struct rpki_config *config,
+    struct args_flag *flags_handled)
 {
-       struct file_contents fc;
+       FILE *file;
+       struct stat stat;
        struct toml_table_t *root;
        struct rpki_uri uri;
        char errbuf[200];
@@ -130,12 +144,12 @@ set_config_from_file(char *config_file, struct rpki_config *config)
                goto end;
        }
 
-       error = file_load(&uri, &fc);
+       error = file_open(&uri, &file, &stat);
        if (error)
                goto end; /* Error msg already printed. */
 
-       root = toml_parse((char *) fc.buffer, errbuf, sizeof(errbuf));
-       file_free(&fc);
+       root = toml_parse_file(file, errbuf, sizeof(errbuf));
+       file_close(file);
 
        if (root == NULL) {
                error = pr_err("Error while parsing configuration file: %s",
@@ -143,12 +157,10 @@ set_config_from_file(char *config_file, struct rpki_config *config)
                goto end;
        }
 
-       error = toml_to_config(root, config);
+       error = toml_to_config(root, config, flags_handled);
 
        toml_free(root);
 
-       print_config(config);
-
 end:
        return error;
 }
index b75f20f81347bf6831eaa3ee54502ba93296577c..ae04120a484127a62617fc3d6c6bac47ea85f464 100644 (file)
@@ -3,6 +3,6 @@
 
 #include "config.h"
 
-int set_config_from_file(char *, struct rpki_config *);
+int set_config_from_file(char *, struct rpki_config *, struct args_flag *);
 
 #endif /* SRC_TOML_HANDLER_H_ */
index d3199efd573fa4f3a028b5fceab235810f50bb08..b4c72bff297554f06ef2c73227c16551334834d1 100644 (file)
@@ -23,6 +23,8 @@ line_file_test_SOURCES += line_file_test.c ../src/line_file.c ../src/line_file.h
 line_file_test_LDADD = ${MY_LDADD}
 
 tal_test_SOURCES = ../src/file.c ../src/file.h ../src/log.c ../src/log.h
+tal_test_SOURCES += ../src/config.c ../src/config.h
+tal_test_SOURCES += ../src/toml_handler.c ../src/toml_handler.h
 tal_test_SOURCES += ../src/common.c ../src/common.h
 tal_test_SOURCES += ../src/crypto/base64.c ../src/crypto/base64.h
 tal_test_SOURCES += ../src/random.c ../src/random.h
@@ -32,6 +34,8 @@ tal_test_CFLAGS = ${AM_CFLAGS} ${GLIB_CFLAGS}
 tal_test_LDADD = ${MY_LDADD} ${GLIB_LIBS}
 
 rsync_test_SOURCES = ../src/file.c ../src/file.h ../src/log.c ../src/log.h
+rsync_test_SOURCES += ../src/config.c ../src/config.h
+rsync_test_SOURCES += ../src/toml_handler.c ../src/toml_handler.h
 rsync_test_SOURCES += ../src/uri.c ../src/uri.h
 rsync_test_SOURCES += ../src/common.c ../src/common.h
 rsync_test_SOURCES += rsync_test.c