From: Alberto Leiva Popper Date: Fri, 22 Mar 2019 17:50:36 +0000 (-0600) Subject: Separate recursive from non-recursive RSYNCs X-Git-Tag: v0.0.2~61 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=af996ca1a7bf0433aa0bfa137a27aca1421d8b95;p=thirdparty%2FFORT-validator.git Separate recursive from non-recursive RSYNCs Wraps up #4 properly. --- diff --git a/src/config.c b/src/config.c index 73b1fc27..cc62fa8d 100644 --- a/src/config.c +++ b/src/config.c @@ -54,7 +54,10 @@ struct rpki_config { struct { char *program; - struct string_array args; + struct { + struct string_array flat; + struct string_array recursive; + } args; } rsync; struct { @@ -179,10 +182,17 @@ static const struct option_field rsync_fields[] = { .availability = AVAILABILITY_TOML, }, { .id = 3001, - .name = "arguments", + .name = "arguments-recursive", .type = >_string_array, - .offset = offsetof(struct rpki_config, rsync.args), - .doc = "Arguments to send to the RSYNC program call", + .offset = offsetof(struct rpki_config, rsync.args.recursive), + .doc = "RSYNC program arguments that will trigger a recursive RSYNC", + .availability = AVAILABILITY_TOML, + }, { + .id = 3002, + .name = "arguments-flat", + .type = >_string_array, + .offset = offsetof(struct rpki_config, rsync.args.flat), + .doc = "RSYNC program arguments that will trigger a non-recursive RSYNC", .availability = AVAILABILITY_TOML, }, { 0 }, @@ -368,7 +378,7 @@ set_default_values(void) "$LOCAL", }; - size_t i; + int error; /* * Values that might need to be freed WILL be freed, so use heap @@ -386,20 +396,20 @@ set_default_values(void) rpki_config.maximum_certificate_depth = 32; rpki_config.rsync.program = strdup("rsync"); - if (rpki_config.rsync.program == NULL) + if (rpki_config.rsync.program == NULL) { + error = pr_enomem(); goto revert_repository; + } - rpki_config.rsync.args.length = ARRAY_LEN(default_rsync_args); - rpki_config.rsync.args.array = calloc(rpki_config.rsync.args.length, - sizeof(char *)); - if (rpki_config.rsync.args.array == NULL) + error = string_array_init(&rpki_config.rsync.args.recursive, + default_rsync_args, ARRAY_LEN(default_rsync_args)); + if (error) goto revert_rsync_program; - - for (i = 0; i < ARRAY_LEN(default_rsync_args); i++) { - rpki_config.rsync.args.array[i] = strdup(default_rsync_args[i]); - if (rpki_config.rsync.args.array[i] == NULL) - goto revert_rsync_args; - } + /* Simply remove --recursive and --delete. */ + error = string_array_init(&rpki_config.rsync.args.flat, + default_rsync_args + 2, ARRAY_LEN(default_rsync_args) - 2); + if (error) + goto revert_recursive_array; rpki_config.output.color = false; rpki_config.output.filename_format = FNF_GLOBAL; @@ -408,15 +418,13 @@ set_default_values(void) return 0; -revert_rsync_args: - for (i = 0; i < ARRAY_LEN(default_rsync_args); i++) - free(rpki_config.rsync.args.array[i]); - free(rpki_config.rsync.args.array); +revert_recursive_array: + string_array_cleanup(&rpki_config.rsync.args.recursive); revert_rsync_program: free(rpki_config.rsync.program); revert_repository: free(rpki_config.local_repository); - return pr_enomem(); + return error; } static int @@ -597,9 +605,11 @@ config_get_rsync_program(void) } struct string_array const * -config_get_rsync_args(void) +config_get_rsync_args(bool is_ta) { - return &rpki_config.rsync.args; + return is_ta + ? &rpki_config.rsync.args.flat + : &rpki_config.rsync.args.recursive; } void diff --git a/src/config.h b/src/config.h index c2d755d1..341968c8 100644 --- a/src/config.h +++ b/src/config.h @@ -22,7 +22,7 @@ bool config_get_color_output(void); enum filename_format config_get_filename_format(void); FILE *config_get_roa_output(void); char *config_get_rsync_program(void); -struct string_array const *config_get_rsync_args(void); +struct string_array const *config_get_rsync_args(bool); /* Needed public by the TOML module */ void *get_rpki_config_field(struct option_field const *); diff --git a/src/config/string_array.c b/src/config/string_array.c index 0ee8dd32..91a327cc 100644 --- a/src/config/string_array.c +++ b/src/config/string_array.c @@ -1,11 +1,45 @@ #include "config/string_array.h" +#include #include #include +#include #include "log.h" +int +string_array_init(struct string_array *array, char const *const *values, + size_t len) +{ + size_t i; + + array->length = len; + + array->array = calloc(len, sizeof(char *)); + if (array->array == NULL) + return -ENOMEM; + + for (i = 0; i < len; i++) { + array->array[i] = strdup(values[i]); + if (array->array[i] == NULL) { + string_array_cleanup(array); + return -ENOMEM; + } + } + + return 0; +} + +void +string_array_cleanup(struct string_array *array) +{ + size_t i; + for (i = 0; i < array->length; i++) + free(array->array[i]); + free(array->array); +} + static void -print_string_array(struct group_fields const *group, +string_array_print(struct group_fields const *group, struct option_field const *field, void *_value) { struct string_array *value = _value; @@ -23,7 +57,7 @@ print_string_array(struct group_fields const *group, } static int -parse_toml_string_array(struct option_field const *opt, +string_array_parse_toml(struct option_field const *opt, struct toml_table_t *toml, void *_result) { toml_array_t *array; @@ -67,14 +101,11 @@ fail: } static void -free_string_array(void *_array) +string_array_free(void *_array) { struct string_array *array = _array; - size_t i; - for (i = 0; i < array->length; i++) - free(array->array[i]); - free(array->array); + string_array_cleanup(array); array->array = NULL; array->length = 0; @@ -83,8 +114,8 @@ free_string_array(void *_array) const struct global_type gt_string_array = { .has_arg = required_argument, .size = sizeof(char *const *), - .print = print_string_array, - .parse.toml = parse_toml_string_array, - .free = free_string_array, + .print = string_array_print, + .parse.toml = string_array_parse_toml, + .free = string_array_free, .arg_doc = "", }; diff --git a/src/config/string_array.h b/src/config/string_array.h index 02c73e29..74989eaa 100644 --- a/src/config/string_array.h +++ b/src/config/string_array.h @@ -11,4 +11,7 @@ struct string_array { extern const struct global_type gt_string_array; +int string_array_init(struct string_array *, char const *const *, size_t); +void string_array_cleanup(struct string_array *); + #endif /* SRC_CONFIG_STRING_ARRAY_H_ */ diff --git a/src/rsync/rsync.c b/src/rsync/rsync.c index 47e6206f..e8b93e96 100644 --- a/src/rsync/rsync.c +++ b/src/rsync/rsync.c @@ -130,10 +130,10 @@ handle_root_strategy(struct rpki_uri const *src, struct rpki_uri *dst) } static int -get_rsync_uri(struct rpki_uri const *requested_uri, bool force_strict, +get_rsync_uri(struct rpki_uri const *requested_uri, bool is_ta, struct rpki_uri *rsync_uri) { - if (force_strict) + if (is_ta) return handle_strict_strategy(requested_uri, rsync_uri); switch (config_get_sync_strategy()) { @@ -231,7 +231,7 @@ create_dir_recursive(char *localuri) } static void -handle_child_thread(struct rpki_uri *uri) +handle_child_thread(struct rpki_uri *uri, bool is_ta) { /* THIS FUNCTION MUST NEVER RETURN!!! */ @@ -240,7 +240,7 @@ handle_child_thread(struct rpki_uri *uri) unsigned int i; int error; - config_args = config_get_rsync_args(); + config_args = config_get_rsync_args(is_ta); /* * We need to work on a copy, because the config args are immutable, * and we need to add the program name (for some reason) and NULL @@ -285,7 +285,7 @@ handle_child_thread(struct rpki_uri *uri) * Downloads the @uri->global file into the @uri->local path. */ static int -do_rsync(struct rpki_uri *uri) +do_rsync(struct rpki_uri *uri, bool is_ta) { pid_t child_pid; int child_status; @@ -297,8 +297,10 @@ do_rsync(struct rpki_uri *uri) /* We need to fork because execvp() magics the thread away. */ child_pid = fork(); - if (child_pid == 0) - handle_child_thread(uri); /* This code is run by the child. */ + if (child_pid == 0) { + /* This code is run by the child. */ + handle_child_thread(uri, is_ta); + } /* This code is run by us. */ @@ -340,18 +342,14 @@ do_rsync(struct rpki_uri *uri) } /** - * @force_srict: - * true: - * SYNC_OFF -> SYNC_OFF - * SYNC_STRICT -> SYNC_STRICT - * SYNC_ROOT -> SYNC_STRICT - * false: - * SYNC_OFF -> SYNC_OFF - * SYNC_STRICT -> SYNC_STRICT - * SYNC_ROOT -> SYNC_ROOT + * @is_ta: Are we rsync'ing the TA? + * The TA rsync will not be recursive, and will force SYNC_STRICT + * (unless the strategy has been set to SYNC_OFF.) + * Why? Because we should probably not trust the repository until we've + * validated the TA's public key. */ int -download_files(struct rpki_uri const *requested_uri, bool force_strict) +download_files(struct rpki_uri const *requested_uri, bool is_ta) { /** * Note: @@ -370,14 +368,14 @@ download_files(struct rpki_uri const *requested_uri, bool force_strict) return 0; } - error = get_rsync_uri(requested_uri, force_strict, &rsync_uri); + error = get_rsync_uri(requested_uri, is_ta, &rsync_uri); if (error) return error; pr_debug("Going to RSYNC '%s' ('%s').", rsync_uri.global, rsync_uri.local); - error = do_rsync(&rsync_uri); + error = do_rsync(&rsync_uri, is_ta); if (!error) error = mark_as_downloaded(&rsync_uri);