chiark / gitweb /
tmpfiles: support passing --prefix multiple times
[elogind.git] / src / tmpfiles / tmpfiles.c
index 535381c470b13a4e221b105ce172ee3055561433..cb15133e5ed2a1639e5796d9273c7f182bf92864 100644 (file)
@@ -105,7 +105,7 @@ static bool arg_create = false;
 static bool arg_clean = false;
 static bool arg_remove = false;
 
-static const char *arg_prefix = NULL;
+static char **include_prefixes = NULL;
 
 static const char conf_file_dirs[] =
         "/etc/tmpfiles.d\0"
@@ -186,13 +186,9 @@ static void load_unix_sockets(void) {
 
                 path_kill_slashes(s);
 
-                k = set_put(unix_sockets, s);
-                if (k < 0) {
-                        free(s);
-
-                        if (k != -EEXIST)
-                                goto fail;
-                }
+                k = set_consume(unix_sockets, s);
+                if (k < 0 && k != -EEXIST)
+                        goto fail;
         }
 
         return;
@@ -787,7 +783,7 @@ static int create_item(Item *i) {
 
                 r = glob_item(i, item_set_perms);
                 if (r < 0)
-                        return 0;
+                        return r;
                 break;
 
         case RECURSIVE_RELABEL_PATH:
@@ -975,6 +971,12 @@ static void item_free(Item *i) {
         free(i);
 }
 
+static inline void item_freep(Item **i) {
+        if (*i)
+                item_free(*i);
+}
+#define _cleanup_item_free_ _cleanup_(item_freep)
+
 static bool item_equal(Item *a, Item *b) {
         assert(a);
         assert(b);
@@ -1016,8 +1018,23 @@ static bool item_equal(Item *a, Item *b) {
         return true;
 }
 
+static bool should_include_path(const char *path) {
+        char **prefix;
+
+        /* no explicit paths specified for inclusion, so everything is valid */
+        if (strv_length(include_prefixes) == 0)
+                return true;
+
+        STRV_FOREACH(prefix, include_prefixes) {
+                if (path_startswith(path, *prefix))
+                        return true;
+        }
+
+        return false;
+}
+
 static int parse_line(const char *fname, unsigned line, const char *buffer) {
-        _cleanup_free_ Item *i = NULL;
+        _cleanup_item_free_ Item *i = NULL;
         Item *existing;
         _cleanup_free_ char
                 *mode = NULL, *user = NULL, *group = NULL, *age = NULL;
@@ -1117,7 +1134,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
 
         path_kill_slashes(i->path);
 
-        if (arg_prefix && !path_startswith(i->path, arg_prefix))
+        if (!should_include_path(i->path))
                 return 0;
 
         if (user && !streq(user, "-")) {
@@ -1256,7 +1273,8 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_PREFIX:
-                        arg_prefix = optarg;
+                        if (strv_extend(&include_prefixes, optarg) < 0)
+                                return log_oom();
                         break;
 
                 case '?':
@@ -1421,6 +1439,8 @@ finish:
         hashmap_free(items);
         hashmap_free(globs);
 
+        strv_free(include_prefixes);
+
         set_free_free(unix_sockets);
 
         label_finish();