File systemd-add-user-keep.patch of Package systemd.578

diff -Naur systemd-210/man/tmpfiles.d.xml systemd-210.mod/man/tmpfiles.d.xml
--- systemd-210/man/tmpfiles.d.xml	2014-12-18 09:40:29.403629407 +0100
+++ systemd-210.mod/man/tmpfiles.d.xml	2014-12-18 10:34:06.274130934 +0100
@@ -435,8 +435,12 @@
                         <varname>f</varname>, <varname>F</varname>,
                         and <varname>w</varname> may be used to
                         specify a short string that is written to the
-                        file, suffixed by a newline. Ignored for all
-                        other lines.</para>
+                        file, suffixed by a newline. 
+                        For <varname>x</varname>, <varname>X</varname>
+                        a comma separated list of usernames. If given, 
+                        only paths belonging to these users will be 
+                        excluded during directory cleanup.
+                        Ignored for all other lines.</para>
                 </refsect2>
 
         </refsect1>
diff -Naur systemd-210/src/tmpfiles/tmpfiles.c systemd-210.mod/src/tmpfiles/tmpfiles.c
--- systemd-210/src/tmpfiles/tmpfiles.c	2014-12-18 09:40:29.342629177 +0100
+++ systemd-210.mod/src/tmpfiles/tmpfiles.c	2014-12-18 11:58:16.686576974 +0100
@@ -263,6 +263,7 @@
         struct timespec times[2];
         bool deleted = false;
         int r = 0;
+        Item *found = NULL;
 
         while ((dent = readdir(d))) {
                 struct stat s;
@@ -306,11 +307,43 @@
                 }
 
                 /* Is there an item configured for this path? */
-                if (hashmap_get(items, sub_path))
-                        continue;
-
-                if (find_glob(globs, sub_path))
-                        continue;
+                found = hashmap_get(items, sub_path);
+         
+                if (!found)
+                        found = find_glob(globs, sub_path);
+
+                if (found) {
+                        /* evaluate username arguments in ignore statements */
+                        if (found->type == IGNORE_PATH || found->type == IGNORE_DIRECTORY_PATH) {
+                                if (!found->argument)
+                                        continue; 
+                                else {
+                                        struct passwd *pw;
+                                        char *userfound = NULL, *args = strdup(found->argument);
+                                        bool match = false;
+                                        int uid = -1;
+
+                                        while ((userfound = strsep(&args, ","))) {
+                                                pw = getpwnam(userfound);
+
+                                                if (!pw)
+                                                        log_error("Unknown user '%s' in ignore statement.", userfound);
+                                                else {
+                                                        uid = pw->pw_uid;
+                                                        if (s.st_uid == uid) { 
+                                                                match = true;
+                                                                break;
+                                                        }
+                                                }
+                                        }
+                                        if (match) {
+                                                found = NULL;
+                                                continue;  
+                                        }
+                                }
+                        } else 
+                                 continue; 
+                }
 
                 if (S_ISDIR(s.st_mode)) {
 
openSUSE Build Service is sponsored by