Wraps up #4 properly.
struct {
char *program;
- struct string_array args;
+ struct {
+ struct string_array flat;
+ struct string_array recursive;
+ } args;
} rsync;
struct {
.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 },
"$LOCAL",
};
- size_t i;
+ int error;
/*
* Values that might need to be freed WILL be freed, so use heap
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;
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
}
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
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 *);
#include "config/string_array.h"
+#include <errno.h>
#include <getopt.h>
#include <stdlib.h>
+#include <string.h>
#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;
}
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;
}
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;
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 = "<sequence of strings>",
};
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_ */
}
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()) {
}
static void
-handle_child_thread(struct rpki_uri *uri)
+handle_child_thread(struct rpki_uri *uri, bool is_ta)
{
/* THIS FUNCTION MUST NEVER RETURN!!! */
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
* 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;
/* 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. */
}
/**
- * @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:
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);