path-util: unify how we process paths specified on the command line
authorLennart Poettering <lennart@poettering.net>
Thu, 22 Oct 2015 17:54:29 +0000 (19:54 +0200)
committerLennart Poettering <lennart@poettering.net>
Sat, 24 Oct 2015 21:03:49 +0000 (23:03 +0200)
Let's introduce a common function that makes relative paths absolute and
warns about any errors while doing so.

src/basic/path-util.c
src/basic/path-util.h
src/firstboot/firstboot.c
src/journal/journalctl.c
src/machine-id-setup/machine-id-setup-main.c
src/nspawn/nspawn.c
src/systemctl/systemctl.c
src/sysusers/sysusers.c
src/tmpfiles/tmpfiles.c

index 96705cc..6b05b6e 100644 (file)
@@ -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;
+}
index c37c131..9d4522c 100644 (file)
@@ -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);
index cee05de..cc564d5 100644 (file)
@@ -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:
index 863c15b..1307bd5 100644 (file)
@@ -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;
 }
index a9c4e3f..f1165ea 100644 (file)
@@ -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;
 }
index 056b4ce..1a2e4b1 100644 (file)
@@ -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");
 
index b99c64a..dbf9f60 100644 (file)
@@ -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();
 
index e594053..238b108 100644 (file)
@@ -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 '?':
index 693a3da..1786e36 100644 (file)
@@ -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 '?':