From 0f03c2a4c093e3d44f4072144827e943c05c8904 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 22 Oct 2015 19:54:29 +0200 Subject: path-util: unify how we process paths specified on the command line Let's introduce a common function that makes relative paths absolute and warns about any errors while doing so. --- src/basic/path-util.c | 32 ++++++++++++++++++++++ src/basic/path-util.h | 2 ++ src/firstboot/firstboot.c | 7 ++--- src/journal/journalctl.c | 8 ++++-- src/machine-id-setup/machine-id-setup-main.c | 14 ++++++---- src/nspawn/nspawn.c | 41 ++++++---------------------- src/systemctl/systemctl.c | 9 ++++-- src/sysusers/sysusers.c | 7 ++--- src/tmpfiles/tmpfiles.c | 7 ++--- 9 files changed, 69 insertions(+), 58 deletions(-) diff --git a/src/basic/path-util.c b/src/basic/path-util.c index 96705cc9d8..6b05b6edb1 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -902,3 +902,35 @@ char *prefix_root(const char *root, const char *path) { strcpy(p, path); return n; } + +int parse_path_argument_and_warn(const char *path, bool suppress_root, char **arg) { + char *p; + int r; + + /* + * This function is intended to be used in command line + * parsers, to handle paths that are passed in. It makes the + * path absolute, and reduces it to NULL if omitted or + * root (the latter optionally). + * + * NOTE THAT THIS WILL FREE THE PREVIOUS ARGUMENT POINTER ON + * SUCCESS! Hence, do not pass in uninitialized pointers. + */ + + if (isempty(path)) { + *arg = mfree(*arg); + return 0; + } + + r = path_make_absolute_cwd(path, &p); + if (r < 0) + return log_error_errno(r, "Failed to parse path \"%s\" and make it absolute: %m", path); + + path_kill_slashes(p); + if (suppress_root && path_equal(p, "/")) + p = mfree(p); + + free(*arg); + *arg = p; + return 0; +} diff --git a/src/basic/path-util.h b/src/basic/path-util.h index c37c131bff..9d4522c8eb 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -101,3 +101,5 @@ char *prefix_root(const char *root, const char *path); } \ _ret; \ }) + +int parse_path_argument_and_warn(const char *path, bool suppress_root, char **arg); diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c index cee05de7a1..cc564d5cd8 100644 --- a/src/firstboot/firstboot.c +++ b/src/firstboot/firstboot.c @@ -690,12 +690,9 @@ static int parse_argv(int argc, char *argv[]) { return version(); case ARG_ROOT: - arg_root = mfree(arg_root); - r = path_make_absolute_cwd(optarg, &arg_root); + r = parse_path_argument_and_warn(optarg, true, &arg_root); if (r < 0) - return log_error_errno(r, "Failed to make root path absolute: %m"); - - path_kill_slashes(arg_root); + return r; break; case ARG_LOCALE: diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 863c15b738..1307bd5630 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -104,7 +104,7 @@ static const char *arg_field = NULL; static bool arg_catalog = false; static bool arg_reverse = false; static int arg_journal_type = 0; -static const char *arg_root = NULL; +static char *arg_root = NULL; static const char *arg_machine = NULL; static uint64_t arg_vacuum_size = 0; static uint64_t arg_vacuum_n_files = 0; @@ -505,7 +505,9 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_ROOT: - arg_root = optarg; + r = parse_path_argument_and_warn(optarg, true, &arg_root); + if (r < 0) + return r; break; case 'c': @@ -2247,5 +2249,7 @@ finish: strv_free(arg_system_units); strv_free(arg_user_units); + free(arg_root); + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/src/machine-id-setup/machine-id-setup-main.c b/src/machine-id-setup/machine-id-setup-main.c index a9c4e3fadf..f1165ea09c 100644 --- a/src/machine-id-setup/machine-id-setup-main.c +++ b/src/machine-id-setup/machine-id-setup-main.c @@ -27,8 +27,9 @@ #include "log.h" #include "machine-id-setup.h" #include "util.h" +#include "path-util.h" -static const char *arg_root = NULL; +static char *arg_root = NULL; static bool arg_commit = false; static void help(void) { @@ -57,7 +58,7 @@ static int parse_argv(int argc, char *argv[]) { {} }; - int c; + int c, r; assert(argc >= 0); assert(argv); @@ -74,7 +75,9 @@ static int parse_argv(int argc, char *argv[]) { return version(); case ARG_ROOT: - arg_root = optarg; + r = parse_path_argument_and_warn(optarg, true, &arg_root); + if (r < 0) + return r; break; case ARG_COMMIT: @@ -104,13 +107,14 @@ int main(int argc, char *argv[]) { r = parse_argv(argc, argv); if (r <= 0) - return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + goto finish; if (arg_commit) r = machine_id_commit(arg_root); else r = machine_id_setup(arg_root); - +finish: + free(arg_root); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 056b4ce5f3..1a2e4b184b 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -276,28 +276,6 @@ static int custom_mounts_prepare(void) { return 0; } -static int set_sanitized_path(char **b, const char *path) { - char *p; - int r; - - assert(b); - assert(path); - - p = canonicalize_file_name(path); - if (!p) { - if (errno != ENOENT) - return -errno; - - r = path_make_absolute_cwd(path, &p); - if (r < 0) - return r; - } - - free(*b); - *b = path_kill_slashes(p); - return 0; -} - static int detect_unified_cgroup_hierarchy(void) { const char *e; int r; @@ -417,24 +395,21 @@ static int parse_argv(int argc, char *argv[]) { return version(); case 'D': - r = set_sanitized_path(&arg_directory, optarg); + r = parse_path_argument_and_warn(optarg, false, &arg_directory); if (r < 0) - return log_error_errno(r, "Invalid root directory: %m"); - + return r; break; case ARG_TEMPLATE: - r = set_sanitized_path(&arg_template, optarg); + r = parse_path_argument_and_warn(optarg, false, &arg_template); if (r < 0) - return log_error_errno(r, "Invalid template directory: %m"); - + return r; break; case 'i': - r = set_sanitized_path(&arg_image, optarg); + r = parse_path_argument_and_warn(optarg, false, &arg_image); if (r < 0) - return log_error_errno(r, "Invalid image path: %m"); - + return r; break; case 'x': @@ -2323,9 +2298,9 @@ static int determine_names(void) { } if (i->type == IMAGE_RAW) - r = set_sanitized_path(&arg_image, i->path); + r = free_and_strdup(&arg_image, i->path); else - r = set_sanitized_path(&arg_directory, i->path); + r = free_and_strdup(&arg_directory, i->path); if (r < 0) return log_error_errno(r, "Invalid image directory: %m"); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index b99c64a75a..dbf9f600c0 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -107,7 +107,7 @@ static UnitFilePresetMode arg_preset_mode = UNIT_FILE_PRESET_FULL; static char **arg_wall = NULL; static const char *arg_kill_who = NULL; static int arg_signal = SIGTERM; -static const char *arg_root = NULL; +static char *arg_root = NULL; static usec_t arg_when = 0; static enum action { _ACTION_INVALID, @@ -6612,7 +6612,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { {} }; - int c; + int c, r; assert(argc >= 0); assert(argv); @@ -6769,7 +6769,9 @@ static int systemctl_parse_argv(int argc, char *argv[]) { break; case ARG_ROOT: - arg_root = optarg; + r = parse_path_argument_and_warn(optarg, true, &arg_root); + if (r < 0) + return r; break; case 'l': @@ -7778,6 +7780,7 @@ finish: strv_free(arg_properties); strv_free(arg_wall); + free(arg_root); release_busses(); diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index e594053ee8..238b1086b2 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -1779,12 +1779,9 @@ static int parse_argv(int argc, char *argv[]) { return version(); case ARG_ROOT: - arg_root = mfree(arg_root); - r = path_make_absolute_cwd(optarg, &arg_root); + r = parse_path_argument_and_warn(optarg, true, &arg_root); if (r < 0) - return log_error_errno(r, "Failed to make root path absolute: %m"); - - path_kill_slashes(arg_root); + return r; break; case '?': diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 693a3da2f4..1786e36674 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -2144,12 +2144,9 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_ROOT: - arg_root = mfree(arg_root); - r = path_make_absolute_cwd(optarg, &arg_root); + r = parse_path_argument_and_warn(optarg, true, &arg_root); if (r < 0) - return log_error_errno(r, "Failed to make root path absolute: %m"); - - path_kill_slashes(arg_root); + return r; break; case '?': -- cgit v1.2.3-54-g00ecf