chiark / gitweb /
tmpfiles: when processing lines, always process prefixes before suffixes
[elogind.git] / src / tmpfiles / tmpfiles.c
index 89f6c6bd15696037e3004d2f2a6a886a93b45002..c6121bccf3641fb25a43dc9fd79b4194fe00bcd5 100644 (file)
@@ -101,18 +101,17 @@ typedef struct Item {
         bool age_set:1;
 
         bool keep_first_level:1;
-} Item;
 
-static Hashmap *items = NULL, *globs = NULL;
-static Set *unix_sockets = NULL;
+        bool done:1;
+} Item;
 
 static bool arg_create = false;
 static bool arg_clean = false;
 static bool arg_remove = false;
 static bool arg_boot = false;
 
-static char **include_prefixes = NULL;
-static char **exclude_prefixes = NULL;
+static char **arg_include_prefixes = NULL;
+static char **arg_exclude_prefixes = NULL;
 static char *arg_root = NULL;
 
 static const char conf_file_dirs[] =
@@ -127,6 +126,9 @@ static const char conf_file_dirs[] =
 
 #define MAX_DEPTH 256
 
+static Hashmap *items = NULL, *globs = NULL;
+static Set *unix_sockets = NULL;
+
 static bool needs_glob(ItemType t) {
         return IN_SET(t,
                       WRITE_FILE,
@@ -750,7 +752,7 @@ static int create_item(Item *i) {
                 }
 
                 if (!streq(i->argument, x)) {
-                        log_error("%s is not the right symlinks.", i->path);
+                        log_error("%s is not the right symlink.", i->path);
                         return -EEXIST;
                 }
 
@@ -977,9 +979,23 @@ static int clean_item(Item *i) {
 
 static int process_item(Item *i) {
         int r, q, p;
+        char prefix[PATH_MAX];
 
         assert(i);
 
+        if (i->done)
+                return 0;
+
+        i->done = true;
+
+        PATH_FOREACH_PREFIX(prefix, i->path) {
+                Item *j;
+
+                j = hashmap_get(items, prefix);
+                if (j)
+                        process_item(j);
+        }
+
         r = arg_create ? create_item(i) : 0;
         q = arg_remove ? remove_item(i) : 0;
         p = arg_clean ? clean_item(i) : 0;
@@ -1048,19 +1064,19 @@ static bool item_equal(Item *a, Item *b) {
 static bool should_include_path(const char *path) {
         char **prefix;
 
-        STRV_FOREACH(prefix, exclude_prefixes) {
+        STRV_FOREACH(prefix, arg_exclude_prefixes) {
                 if (path_startswith(path, *prefix))
                         return false;
         }
 
-        STRV_FOREACH(prefix, include_prefixes) {
+        STRV_FOREACH(prefix, arg_include_prefixes) {
                 if (path_startswith(path, *prefix))
                         return true;
         }
 
         /* no matches, so we should include this path only if we
          * have no whitelist at all */
-        return strv_length(include_prefixes) == 0;
+        return strv_length(arg_include_prefixes) == 0;
 }
 
 static int parse_line(const char *fname, unsigned line, const char *buffer) {
@@ -1372,12 +1388,12 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_PREFIX:
-                        if (strv_push(&include_prefixes, optarg) < 0)
+                        if (strv_push(&arg_include_prefixes, optarg) < 0)
                                 return log_oom();
                         break;
 
                 case ARG_EXCLUDE_PREFIX:
-                        if (strv_push(&exclude_prefixes, optarg) < 0)
+                        if (strv_push(&arg_exclude_prefixes, optarg) < 0)
                                 return log_oom();
                         break;
 
@@ -1544,8 +1560,8 @@ finish:
         hashmap_free(items);
         hashmap_free(globs);
 
-        free(include_prefixes);
-        free(exclude_prefixes);
+        free(arg_include_prefixes);
+        free(arg_exclude_prefixes);
         free(arg_root);
 
         set_free_free(unix_sockets);