chiark / gitweb /
tmpfiles: create directories already with the right label, instead of creating them...
[elogind.git] / src / tmpfiles / tmpfiles.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering, Kay Sievers
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <unistd.h>
23 #include <fcntl.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <sys/stat.h>
27 #include <limits.h>
28 #include <dirent.h>
29 #include <grp.h>
30 #include <pwd.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <stddef.h>
34 #include <getopt.h>
35 #include <stdbool.h>
36 #include <time.h>
37 #include <sys/types.h>
38 #include <sys/param.h>
39 #include <glob.h>
40 #include <fnmatch.h>
41 #include <sys/capability.h>
42
43 #include "log.h"
44 #include "util.h"
45 #include "macro.h"
46 #include "missing.h"
47 #include "mkdir.h"
48 #include "path-util.h"
49 #include "strv.h"
50 #include "label.h"
51 #include "set.h"
52 #include "conf-files.h"
53 #include "capability.h"
54 #include "specifier.h"
55 #include "build.h"
56 #include "copy.h"
57
58 /* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates
59  * them in the file system. This is intended to be used to create
60  * properly owned directories beneath /tmp, /var/tmp, /run, which are
61  * volatile and hence need to be recreated on bootup. */
62
63 typedef enum ItemType {
64         /* These ones take file names */
65         CREATE_FILE = 'f',
66         TRUNCATE_FILE = 'F',
67         CREATE_DIRECTORY = 'd',
68         TRUNCATE_DIRECTORY = 'D',
69         CREATE_FIFO = 'p',
70         CREATE_SYMLINK = 'L',
71         CREATE_CHAR_DEVICE = 'c',
72         CREATE_BLOCK_DEVICE = 'b',
73         COPY_FILES = 'C',
74
75         /* These ones take globs */
76         WRITE_FILE = 'w',
77         IGNORE_PATH = 'x',
78         IGNORE_DIRECTORY_PATH = 'X',
79         REMOVE_PATH = 'r',
80         RECURSIVE_REMOVE_PATH = 'R',
81         ADJUST_MODE = 'm', /* legacy, 'z' is identical to this */
82         RELABEL_PATH = 'z',
83         RECURSIVE_RELABEL_PATH = 'Z',
84 } ItemType;
85
86 typedef struct Item {
87         ItemType type;
88
89         char *path;
90         char *argument;
91         uid_t uid;
92         gid_t gid;
93         mode_t mode;
94         usec_t age;
95
96         dev_t major_minor;
97
98         bool uid_set:1;
99         bool gid_set:1;
100         bool mode_set:1;
101         bool age_set:1;
102         bool mask_perms:1;
103
104         bool keep_first_level:1;
105
106         bool force:1;
107
108         bool done:1;
109 } Item;
110
111 static bool arg_create = false;
112 static bool arg_clean = false;
113 static bool arg_remove = false;
114 static bool arg_boot = false;
115
116 static char **arg_include_prefixes = NULL;
117 static char **arg_exclude_prefixes = NULL;
118 static char *arg_root = NULL;
119
120 static const char conf_file_dirs[] =
121         "/etc/tmpfiles.d\0"
122         "/run/tmpfiles.d\0"
123         "/usr/local/lib/tmpfiles.d\0"
124         "/usr/lib/tmpfiles.d\0"
125 #ifdef HAVE_SPLIT_USR
126         "/lib/tmpfiles.d\0"
127 #endif
128         ;
129
130 #define MAX_DEPTH 256
131
132 static Hashmap *items = NULL, *globs = NULL;
133 static Set *unix_sockets = NULL;
134
135 static bool needs_glob(ItemType t) {
136         return IN_SET(t,
137                       WRITE_FILE,
138                       IGNORE_PATH,
139                       IGNORE_DIRECTORY_PATH,
140                       REMOVE_PATH,
141                       RECURSIVE_REMOVE_PATH,
142                       ADJUST_MODE,
143                       RELABEL_PATH,
144                       RECURSIVE_RELABEL_PATH);
145 }
146
147 static struct Item* find_glob(Hashmap *h, const char *match) {
148         Item *j;
149         Iterator i;
150
151         HASHMAP_FOREACH(j, h, i)
152                 if (fnmatch(j->path, match, FNM_PATHNAME|FNM_PERIOD) == 0)
153                         return j;
154
155         return NULL;
156 }
157
158 static void load_unix_sockets(void) {
159         _cleanup_fclose_ FILE *f = NULL;
160         char line[LINE_MAX];
161
162         if (unix_sockets)
163                 return;
164
165         /* We maintain a cache of the sockets we found in
166          * /proc/net/unix to speed things up a little. */
167
168         unix_sockets = set_new(string_hash_func, string_compare_func);
169         if (!unix_sockets)
170                 return;
171
172         f = fopen("/proc/net/unix", "re");
173         if (!f)
174                 return;
175
176         /* Skip header */
177         if (!fgets(line, sizeof(line), f))
178                 goto fail;
179
180         for (;;) {
181                 char *p, *s;
182                 int k;
183
184                 if (!fgets(line, sizeof(line), f))
185                         break;
186
187                 truncate_nl(line);
188
189                 p = strchr(line, ':');
190                 if (!p)
191                         continue;
192
193                 if (strlen(p) < 37)
194                         continue;
195
196                 p += 37;
197                 p += strspn(p, WHITESPACE);
198                 p += strcspn(p, WHITESPACE); /* skip one more word */
199                 p += strspn(p, WHITESPACE);
200
201                 if (*p != '/')
202                         continue;
203
204                 s = strdup(p);
205                 if (!s)
206                         goto fail;
207
208                 path_kill_slashes(s);
209
210                 k = set_consume(unix_sockets, s);
211                 if (k < 0 && k != -EEXIST)
212                         goto fail;
213         }
214
215         return;
216
217 fail:
218         set_free_free(unix_sockets);
219         unix_sockets = NULL;
220 }
221
222 static bool unix_socket_alive(const char *fn) {
223         assert(fn);
224
225         load_unix_sockets();
226
227         if (unix_sockets)
228                 return !!set_get(unix_sockets, (char*) fn);
229
230         /* We don't know, so assume yes */
231         return true;
232 }
233
234 static int dir_is_mount_point(DIR *d, const char *subdir) {
235
236         union file_handle_union h = {
237                 .handle.handle_bytes = MAX_HANDLE_SZ
238         };
239
240         int mount_id_parent, mount_id;
241         int r_p, r;
242
243         r_p = name_to_handle_at(dirfd(d), ".", &h.handle, &mount_id_parent, 0);
244         if (r_p < 0)
245                 r_p = -errno;
246
247         h.handle.handle_bytes = MAX_HANDLE_SZ;
248         r = name_to_handle_at(dirfd(d), subdir, &h.handle, &mount_id, 0);
249         if (r < 0)
250                 r = -errno;
251
252         /* got no handle; make no assumptions, return error */
253         if (r_p < 0 && r < 0)
254                 return r_p;
255
256         /* got both handles; if they differ, it is a mount point */
257         if (r_p >= 0 && r >= 0)
258                 return mount_id_parent != mount_id;
259
260         /* got only one handle; assume different mount points if one
261          * of both queries was not supported by the filesystem */
262         if (r_p == -ENOSYS || r_p == -ENOTSUP || r == -ENOSYS || r == -ENOTSUP)
263                 return true;
264
265         /* return error */
266         if (r_p < 0)
267                 return r_p;
268         return r;
269 }
270
271 static int dir_cleanup(
272                 Item *i,
273                 const char *p,
274                 DIR *d,
275                 const struct stat *ds,
276                 usec_t cutoff,
277                 dev_t rootdev,
278                 bool mountpoint,
279                 int maxdepth,
280                 bool keep_this_level) {
281
282         struct dirent *dent;
283         struct timespec times[2];
284         bool deleted = false;
285         int r = 0;
286
287         while ((dent = readdir(d))) {
288                 struct stat s;
289                 usec_t age;
290                 _cleanup_free_ char *sub_path = NULL;
291
292                 if (streq(dent->d_name, ".") ||
293                     streq(dent->d_name, ".."))
294                         continue;
295
296                 if (fstatat(dirfd(d), dent->d_name, &s, AT_SYMLINK_NOFOLLOW) < 0) {
297                         if (errno == ENOENT)
298                                 continue;
299
300                         /* FUSE, NFS mounts, SELinux might return EACCES */
301                         if (errno == EACCES)
302                                 log_debug("stat(%s/%s) failed: %m", p, dent->d_name);
303                         else
304                                 log_error("stat(%s/%s) failed: %m", p, dent->d_name);
305                         r = -errno;
306                         continue;
307                 }
308
309                 /* Stay on the same filesystem */
310                 if (s.st_dev != rootdev)
311                         continue;
312
313                 /* Try to detect bind mounts of the same filesystem instance; they
314                  * do not differ in device major/minors. This type of query is not
315                  * supported on all kernels or filesystem types though. */
316                 if (S_ISDIR(s.st_mode) && dir_is_mount_point(d, dent->d_name) > 0)
317                         continue;
318
319                 /* Do not delete read-only files owned by root */
320                 if (s.st_uid == 0 && !(s.st_mode & S_IWUSR))
321                         continue;
322
323                 sub_path = strjoin(p, "/", dent->d_name, NULL);
324                 if (!sub_path) {
325                         r = log_oom();
326                         goto finish;
327                 }
328
329                 /* Is there an item configured for this path? */
330                 if (hashmap_get(items, sub_path))
331                         continue;
332
333                 if (find_glob(globs, sub_path))
334                         continue;
335
336                 if (S_ISDIR(s.st_mode)) {
337
338                         if (mountpoint &&
339                             streq(dent->d_name, "lost+found") &&
340                             s.st_uid == 0)
341                                 continue;
342
343                         if (maxdepth <= 0)
344                                 log_warning("Reached max depth on %s.", sub_path);
345                         else {
346                                 _cleanup_closedir_ DIR *sub_dir;
347                                 int q;
348
349                                 sub_dir = xopendirat(dirfd(d), dent->d_name, O_NOFOLLOW|O_NOATIME);
350                                 if (!sub_dir) {
351                                         if (errno != ENOENT) {
352                                                 log_error("opendir(%s/%s) failed: %m", p, dent->d_name);
353                                                 r = -errno;
354                                         }
355
356                                         continue;
357                                 }
358
359                                 q = dir_cleanup(i, sub_path, sub_dir, &s, cutoff, rootdev, false, maxdepth-1, false);
360                                 if (q < 0)
361                                         r = q;
362                         }
363
364                         /* Note: if you are wondering why we don't
365                          * support the sticky bit for excluding
366                          * directories from cleaning like we do it for
367                          * other file system objects: well, the sticky
368                          * bit already has a meaning for directories,
369                          * so we don't want to overload that. */
370
371                         if (keep_this_level)
372                                 continue;
373
374                         /* Ignore ctime, we change it when deleting */
375                         age = MAX(timespec_load(&s.st_mtim),
376                                   timespec_load(&s.st_atim));
377                         if (age >= cutoff)
378                                 continue;
379
380                         if (i->type != IGNORE_DIRECTORY_PATH || !streq(dent->d_name, p)) {
381                                 log_debug("rmdir '%s'", sub_path);
382
383                                 if (unlinkat(dirfd(d), dent->d_name, AT_REMOVEDIR) < 0) {
384                                         if (errno != ENOENT && errno != ENOTEMPTY) {
385                                                 log_error("rmdir(%s): %m", sub_path);
386                                                 r = -errno;
387                                         }
388                                 }
389                         }
390
391                 } else {
392                         /* Skip files for which the sticky bit is
393                          * set. These are semantics we define, and are
394                          * unknown elsewhere. See XDG_RUNTIME_DIR
395                          * specification for details. */
396                         if (s.st_mode & S_ISVTX)
397                                 continue;
398
399                         if (mountpoint && S_ISREG(s.st_mode)) {
400                                 if (streq(dent->d_name, ".journal") &&
401                                     s.st_uid == 0)
402                                         continue;
403
404                                 if (streq(dent->d_name, "aquota.user") ||
405                                     streq(dent->d_name, "aquota.group"))
406                                         continue;
407                         }
408
409                         /* Ignore sockets that are listed in /proc/net/unix */
410                         if (S_ISSOCK(s.st_mode) && unix_socket_alive(sub_path))
411                                 continue;
412
413                         /* Ignore device nodes */
414                         if (S_ISCHR(s.st_mode) || S_ISBLK(s.st_mode))
415                                 continue;
416
417                         /* Keep files on this level around if this is
418                          * requested */
419                         if (keep_this_level)
420                                 continue;
421
422                         age = MAX3(timespec_load(&s.st_mtim),
423                                    timespec_load(&s.st_atim),
424                                    timespec_load(&s.st_ctim));
425
426                         if (age >= cutoff)
427                                 continue;
428
429                         log_debug("unlink '%s'", sub_path);
430
431                         if (unlinkat(dirfd(d), dent->d_name, 0) < 0) {
432                                 if (errno != ENOENT) {
433                                         log_error("unlink(%s): %m", sub_path);
434                                         r = -errno;
435                                 }
436                         }
437
438                         deleted = true;
439                 }
440         }
441
442 finish:
443         if (deleted) {
444                 /* Restore original directory timestamps */
445                 times[0] = ds->st_atim;
446                 times[1] = ds->st_mtim;
447
448                 if (futimens(dirfd(d), times) < 0)
449                         log_error("utimensat(%s): %m", p);
450         }
451
452         return r;
453 }
454
455 static int item_set_perms(Item *i, const char *path) {
456         assert(i);
457         assert(path);
458
459         /* not using i->path directly because it may be a glob */
460         if (i->mode_set) {
461                 mode_t m = i->mode;
462
463                 if (i->mask_perms) {
464                         struct stat st;
465
466                         if (stat(path, &st) >= 0) {
467                                 if (!(st.st_mode & 0111))
468                                         m &= ~0111;
469                                 if (!(st.st_mode & 0222))
470                                         m &= ~0222;
471                                 if (!(st.st_mode & 0444))
472                                         m &= ~0444;
473                                 if (!S_ISDIR(st.st_mode))
474                                         m &= ~07000; /* remove sticky/sgid/suid bit, unless directory */
475                         }
476                 }
477
478                 if (chmod(path, m) < 0) {
479                         log_error("chmod(%s) failed: %m", path);
480                         return -errno;
481                 }
482         }
483
484         if (i->uid_set || i->gid_set)
485                 if (chown(path,
486                           i->uid_set ? i->uid : (uid_t) -1,
487                           i->gid_set ? i->gid : (gid_t) -1) < 0) {
488
489                         log_error("chown(%s) failed: %m", path);
490                         return -errno;
491                 }
492
493         return label_fix(path, false, false);
494 }
495
496 static int write_one_file(Item *i, const char *path) {
497         _cleanup_close_ int fd = -1;
498         int flags, r = 0;
499         struct stat st;
500
501         assert(i);
502         assert(path);
503
504         flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND|O_NOFOLLOW :
505                 i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC|O_NOFOLLOW : 0;
506
507         RUN_WITH_UMASK(0000) {
508                 label_context_set(path, S_IFREG);
509                 fd = open(path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY, i->mode);
510                 label_context_clear();
511         }
512
513         if (fd < 0) {
514                 if (i->type == WRITE_FILE && errno == ENOENT)
515                         return 0;
516
517                 log_error("Failed to create file %s: %m", path);
518                 return -errno;
519         }
520
521         if (i->argument) {
522                 _cleanup_free_ char *unescaped;
523                 ssize_t n;
524                 size_t l;
525
526                 unescaped = cunescape(i->argument);
527                 if (!unescaped)
528                         return log_oom();
529
530                 l = strlen(unescaped);
531                 n = write(fd, unescaped, l);
532
533                 if (n < 0 || (size_t) n < l) {
534                         log_error("Failed to write file %s: %s", path, n < 0 ? strerror(-n) : "Short write");
535                         return n < 0 ? n : -EIO;
536                 }
537         }
538
539         fd = safe_close(fd);
540
541         if (stat(path, &st) < 0) {
542                 log_error("stat(%s) failed: %m", path);
543                 return -errno;
544         }
545
546         if (!S_ISREG(st.st_mode)) {
547                 log_error("%s is not a file.", path);
548                 return -EEXIST;
549         }
550
551         r = item_set_perms(i, path);
552         if (r < 0)
553                 return r;
554
555         return 0;
556 }
557
558 static int item_set_perms_children(Item *i, const char *path) {
559         _cleanup_closedir_ DIR *d;
560         int r = 0;
561
562         assert(i);
563         assert(path);
564
565         /* This returns the first error we run into, but nevertheless
566          * tries to go on */
567
568         d = opendir(path);
569         if (!d)
570                 return errno == ENOENT || errno == ENOTDIR ? 0 : -errno;
571
572         for (;;) {
573                 _cleanup_free_ char *p = NULL;
574                 struct dirent *de;
575                 int q;
576
577                 errno = 0;
578                 de = readdir(d);
579                 if (!de) {
580                         if (errno != 0 && r == 0)
581                                 r = -errno;
582
583                         break;
584                 }
585
586                 if (streq(de->d_name, ".") || streq(de->d_name, ".."))
587                         continue;
588
589                 p = strjoin(path, "/", de->d_name, NULL);
590                 if (!p)
591                         return -ENOMEM;
592
593                 q = item_set_perms(i, p);
594                 if (q < 0 && q != -ENOENT && r == 0)
595                         r = q;
596
597                 if (IN_SET(de->d_type, DT_UNKNOWN, DT_DIR)) {
598                         q = item_set_perms_children(i, p);
599                         if (q < 0 && r == 0)
600                                 r = q;
601                 }
602         }
603
604         return r;
605 }
606
607 static int item_set_perms_recursive(Item *i, const char *path) {
608         int r, q;
609
610         assert(i);
611         assert(path);
612
613         r = item_set_perms(i, path);
614         if (r < 0)
615                 return r;
616
617         q = item_set_perms_children(i, path);
618         if (q < 0 && r == 0)
619                 r = q;
620
621         return r;
622 }
623
624 static int glob_item(Item *i, int (*action)(Item *, const char *)) {
625         _cleanup_globfree_ glob_t g = {};
626         int r = 0, k;
627         char **fn;
628
629         errno = 0;
630         k = glob(i->path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
631         if (k != 0 && k != GLOB_NOMATCH) {
632                 if (errno == 0)
633                         errno = EIO;
634
635                 log_error("glob(%s) failed: %m", i->path);
636                 return -errno;
637         }
638
639         STRV_FOREACH(fn, g.gl_pathv) {
640                 k = action(i, *fn);
641                 if (k < 0 && r == 0)
642                         r = k;
643         }
644
645         return r;
646 }
647
648 static int create_item(Item *i) {
649         struct stat st;
650         int r = 0;
651
652         assert(i);
653
654         switch (i->type) {
655
656         case IGNORE_PATH:
657         case IGNORE_DIRECTORY_PATH:
658         case REMOVE_PATH:
659         case RECURSIVE_REMOVE_PATH:
660                 return 0;
661
662         case CREATE_FILE:
663         case TRUNCATE_FILE:
664                 r = write_one_file(i, i->path);
665                 if (r < 0)
666                         return r;
667                 break;
668
669         case COPY_FILES:
670                 r = copy_tree(i->argument, i->path);
671                 if (r < 0) {
672                         log_error("Failed to copy files: %s", strerror(-r));
673                         return r;
674                 }
675
676                 r = item_set_perms(i, i->path);
677                 if (r < 0)
678                         return r;
679
680                 break;
681
682         case WRITE_FILE:
683                 r = glob_item(i, write_one_file);
684                 if (r < 0)
685                         return r;
686
687                 break;
688
689         case TRUNCATE_DIRECTORY:
690         case CREATE_DIRECTORY:
691
692                 RUN_WITH_UMASK(0000) {
693                         mkdir_parents_label(i->path, 0755);
694                         r = mkdir_label(i->path, i->mode);
695                 }
696
697                 if (r < 0 && r != -EEXIST) {
698                         log_error("Failed to create directory %s: %s", i->path, strerror(-r));
699                         return r;
700                 }
701
702                 if (stat(i->path, &st) < 0) {
703                         log_error("stat(%s) failed: %m", i->path);
704                         return -errno;
705                 }
706
707                 if (!S_ISDIR(st.st_mode)) {
708                         log_error("%s is not a directory.", i->path);
709                         return -EEXIST;
710                 }
711
712                 r = item_set_perms(i, i->path);
713                 if (r < 0)
714                         return r;
715
716                 break;
717
718         case CREATE_FIFO:
719
720                 RUN_WITH_UMASK(0000) {
721                         label_context_set(i->path, S_IFIFO);
722                         r = mkfifo(i->path, i->mode);
723                         label_context_clear();
724                 }
725
726                 if (r < 0) {
727                         if (errno != EEXIST) {
728                                 log_error("Failed to create fifo %s: %m", i->path);
729                                 return -errno;
730                         }
731
732                         if (stat(i->path, &st) < 0) {
733                                 log_error("stat(%s) failed: %m", i->path);
734                                 return -errno;
735                         }
736
737                         if (!S_ISFIFO(st.st_mode)) {
738
739                                 if (i->force) {
740
741                                         RUN_WITH_UMASK(0000) {
742                                                 label_context_set(i->path, S_IFIFO);
743                                                 r = mkfifo_atomic(i->path, i->mode);
744                                                 label_context_clear();
745                                         }
746
747                                         if (r < 0) {
748                                                 log_error("Failed to create fifo %s: %s", i->path, strerror(-r));
749                                                 return r;
750                                         }
751                                 } else {
752                                         log_debug("%s is not a fifo.", i->path);
753                                         return 0;
754                                 }
755                         }
756                 }
757
758                 r = item_set_perms(i, i->path);
759                 if (r < 0)
760                         return r;
761
762                 break;
763
764         case CREATE_SYMLINK:
765
766                 label_context_set(i->path, S_IFLNK);
767                 r = symlink(i->argument, i->path);
768                 label_context_clear();
769
770                 if (r < 0) {
771                         _cleanup_free_ char *x = NULL;
772
773                         if (errno != EEXIST) {
774                                 log_error("symlink(%s, %s) failed: %m", i->argument, i->path);
775                                 return -errno;
776                         }
777
778                         r = readlink_malloc(i->path, &x);
779                         if (r < 0 || !streq(i->argument, x)) {
780
781                                 if (i->force) {
782                                         label_context_set(i->path, S_IFLNK);
783                                         r = symlink_atomic(i->argument, i->path);
784                                         label_context_clear();
785
786                                         if (r < 0) {
787                                                 log_error("symlink(%s, %s) failed: %s", i->argument, i->path, strerror(-r));
788                                                 return r;
789                                         }
790                                 } else {
791                                         log_debug("%s is not a symlink or does not point to the correct path.", i->path);
792                                         return 0;
793                                 }
794                         }
795                 }
796
797                 break;
798
799         case CREATE_BLOCK_DEVICE:
800         case CREATE_CHAR_DEVICE: {
801                 mode_t file_type;
802
803                 if (have_effective_cap(CAP_MKNOD) == 0) {
804                         /* In a container we lack CAP_MKNOD. We
805                         shouldn't attempt to create the device node in
806                         that case to avoid noise, and we don't support
807                         virtualized devices in containers anyway. */
808
809                         log_debug("We lack CAP_MKNOD, skipping creation of device node %s.", i->path);
810                         return 0;
811                 }
812
813                 file_type = i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR;
814
815                 RUN_WITH_UMASK(0000) {
816                         label_context_set(i->path, file_type);
817                         r = mknod(i->path, i->mode | file_type, i->major_minor);
818                         label_context_clear();
819                 }
820
821                 if (r < 0) {
822                         if (errno == EPERM) {
823                                 log_debug("We lack permissions, possibly because of cgroup configuration; "
824                                           "skipping creation of device node %s.", i->path);
825                                 return 0;
826                         }
827
828                         if (errno != EEXIST) {
829                                 log_error("Failed to create device node %s: %m", i->path);
830                                 return -errno;
831                         }
832
833                         if (stat(i->path, &st) < 0) {
834                                 log_error("stat(%s) failed: %m", i->path);
835                                 return -errno;
836                         }
837
838                         if ((st.st_mode & S_IFMT) != file_type) {
839
840                                 if (i->force) {
841
842                                         RUN_WITH_UMASK(0000) {
843                                                 label_context_set(i->path, file_type);
844                                                 r = mknod_atomic(i->path, i->mode | file_type, i->major_minor);
845                                                 label_context_clear();
846                                         }
847
848                                         if (r < 0) {
849                                                 log_error("Failed to create device node %s: %s", i->path, strerror(-r));
850                                                 return r;
851                                         }
852                                 } else {
853                                         log_debug("%s is not a device node.", i->path);
854                                         return 0;
855                                 }
856                         }
857                 }
858
859                 r = item_set_perms(i, i->path);
860                 if (r < 0)
861                         return r;
862
863                 break;
864         }
865
866         case ADJUST_MODE:
867         case RELABEL_PATH:
868
869                 r = glob_item(i, item_set_perms);
870                 if (r < 0)
871                         return r;
872                 break;
873
874         case RECURSIVE_RELABEL_PATH:
875
876                 r = glob_item(i, item_set_perms_recursive);
877                 if (r < 0)
878                         return r;
879
880                 break;
881         }
882
883         log_debug("%s created successfully.", i->path);
884
885         return 0;
886 }
887
888 static int remove_item_instance(Item *i, const char *instance) {
889         int r;
890
891         assert(i);
892
893         switch (i->type) {
894
895         case CREATE_FILE:
896         case TRUNCATE_FILE:
897         case CREATE_DIRECTORY:
898         case CREATE_FIFO:
899         case CREATE_SYMLINK:
900         case CREATE_BLOCK_DEVICE:
901         case CREATE_CHAR_DEVICE:
902         case IGNORE_PATH:
903         case IGNORE_DIRECTORY_PATH:
904         case ADJUST_MODE:
905         case RELABEL_PATH:
906         case RECURSIVE_RELABEL_PATH:
907         case WRITE_FILE:
908         case COPY_FILES:
909                 break;
910
911         case REMOVE_PATH:
912                 if (remove(instance) < 0 && errno != ENOENT) {
913                         log_error("remove(%s): %m", instance);
914                         return -errno;
915                 }
916
917                 break;
918
919         case TRUNCATE_DIRECTORY:
920         case RECURSIVE_REMOVE_PATH:
921                 /* FIXME: we probably should use dir_cleanup() here
922                  * instead of rm_rf() so that 'x' is honoured. */
923                 r = rm_rf_dangerous(instance, false, i->type == RECURSIVE_REMOVE_PATH, false);
924                 if (r < 0 && r != -ENOENT) {
925                         log_error("rm_rf(%s): %s", instance, strerror(-r));
926                         return r;
927                 }
928
929                 break;
930         }
931
932         return 0;
933 }
934
935 static int remove_item(Item *i) {
936         int r = 0;
937
938         assert(i);
939
940         switch (i->type) {
941
942         case CREATE_FILE:
943         case TRUNCATE_FILE:
944         case CREATE_DIRECTORY:
945         case CREATE_FIFO:
946         case CREATE_SYMLINK:
947         case CREATE_CHAR_DEVICE:
948         case CREATE_BLOCK_DEVICE:
949         case IGNORE_PATH:
950         case IGNORE_DIRECTORY_PATH:
951         case ADJUST_MODE:
952         case RELABEL_PATH:
953         case RECURSIVE_RELABEL_PATH:
954         case WRITE_FILE:
955         case COPY_FILES:
956                 break;
957
958         case REMOVE_PATH:
959         case TRUNCATE_DIRECTORY:
960         case RECURSIVE_REMOVE_PATH:
961                 r = glob_item(i, remove_item_instance);
962                 break;
963         }
964
965         return r;
966 }
967
968 static int clean_item_instance(Item *i, const char* instance) {
969         _cleanup_closedir_ DIR *d = NULL;
970         struct stat s, ps;
971         bool mountpoint;
972         int r;
973         usec_t cutoff, n;
974
975         assert(i);
976
977         if (!i->age_set)
978                 return 0;
979
980         n = now(CLOCK_REALTIME);
981         if (n < i->age)
982                 return 0;
983
984         cutoff = n - i->age;
985
986         d = opendir(instance);
987         if (!d) {
988                 if (errno == ENOENT || errno == ENOTDIR)
989                         return 0;
990
991                 log_error("Failed to open directory %s: %m", i->path);
992                 return -errno;
993         }
994
995         if (fstat(dirfd(d), &s) < 0) {
996                 log_error("stat(%s) failed: %m", i->path);
997                 return -errno;
998         }
999
1000         if (!S_ISDIR(s.st_mode)) {
1001                 log_error("%s is not a directory.", i->path);
1002                 return -ENOTDIR;
1003         }
1004
1005         if (fstatat(dirfd(d), "..", &ps, AT_SYMLINK_NOFOLLOW) != 0) {
1006                 log_error("stat(%s/..) failed: %m", i->path);
1007                 return -errno;
1008         }
1009
1010         mountpoint = s.st_dev != ps.st_dev ||
1011                      (s.st_dev == ps.st_dev && s.st_ino == ps.st_ino);
1012
1013         r = dir_cleanup(i, instance, d, &s, cutoff, s.st_dev, mountpoint,
1014                         MAX_DEPTH, i->keep_first_level);
1015         return r;
1016 }
1017
1018 static int clean_item(Item *i) {
1019         int r = 0;
1020
1021         assert(i);
1022
1023         switch (i->type) {
1024         case CREATE_DIRECTORY:
1025         case TRUNCATE_DIRECTORY:
1026         case IGNORE_PATH:
1027         case COPY_FILES:
1028                 clean_item_instance(i, i->path);
1029                 break;
1030         case IGNORE_DIRECTORY_PATH:
1031                 r = glob_item(i, clean_item_instance);
1032                 break;
1033         default:
1034                 break;
1035         }
1036
1037         return r;
1038 }
1039
1040 static int process_item(Item *i) {
1041         int r, q, p;
1042         char prefix[PATH_MAX];
1043
1044         assert(i);
1045
1046         if (i->done)
1047                 return 0;
1048
1049         i->done = true;
1050
1051         PATH_FOREACH_PREFIX(prefix, i->path) {
1052                 Item *j;
1053
1054                 j = hashmap_get(items, prefix);
1055                 if (j)
1056                         process_item(j);
1057         }
1058
1059         r = arg_create ? create_item(i) : 0;
1060         q = arg_remove ? remove_item(i) : 0;
1061         p = arg_clean ? clean_item(i) : 0;
1062
1063         if (r < 0)
1064                 return r;
1065
1066         if (q < 0)
1067                 return q;
1068
1069         return p;
1070 }
1071
1072 static void item_free(Item *i) {
1073
1074         if (!i)
1075                 return;
1076
1077         free(i->path);
1078         free(i->argument);
1079         free(i);
1080 }
1081
1082 DEFINE_TRIVIAL_CLEANUP_FUNC(Item*, item_free);
1083
1084 static bool item_equal(Item *a, Item *b) {
1085         assert(a);
1086         assert(b);
1087
1088         if (!streq_ptr(a->path, b->path))
1089                 return false;
1090
1091         if (a->type != b->type)
1092                 return false;
1093
1094         if (a->uid_set != b->uid_set ||
1095             (a->uid_set && a->uid != b->uid))
1096             return false;
1097
1098         if (a->gid_set != b->gid_set ||
1099             (a->gid_set && a->gid != b->gid))
1100             return false;
1101
1102         if (a->mode_set != b->mode_set ||
1103             (a->mode_set && a->mode != b->mode))
1104             return false;
1105
1106         if (a->age_set != b->age_set ||
1107             (a->age_set && a->age != b->age))
1108             return false;
1109
1110         if ((a->type == CREATE_FILE ||
1111              a->type == TRUNCATE_FILE ||
1112              a->type == WRITE_FILE ||
1113              a->type == CREATE_SYMLINK ||
1114              a->type == COPY_FILES) &&
1115             !streq_ptr(a->argument, b->argument))
1116                 return false;
1117
1118         if ((a->type == CREATE_CHAR_DEVICE ||
1119              a->type == CREATE_BLOCK_DEVICE) &&
1120             a->major_minor != b->major_minor)
1121                 return false;
1122
1123         return true;
1124 }
1125
1126 static bool should_include_path(const char *path) {
1127         char **prefix;
1128
1129         STRV_FOREACH(prefix, arg_exclude_prefixes)
1130                 if (path_startswith(path, *prefix))
1131                         return false;
1132
1133         STRV_FOREACH(prefix, arg_include_prefixes)
1134                 if (path_startswith(path, *prefix))
1135                         return true;
1136
1137         /* no matches, so we should include this path only if we
1138          * have no whitelist at all */
1139         return strv_length(arg_include_prefixes) == 0;
1140 }
1141
1142 static int parse_line(const char *fname, unsigned line, const char *buffer) {
1143
1144         static const Specifier specifier_table[] = {
1145                 { 'm', specifier_machine_id, NULL },
1146                 { 'b', specifier_boot_id, NULL },
1147                 { 'H', specifier_host_name, NULL },
1148                 { 'v', specifier_kernel_release, NULL },
1149                 {}
1150         };
1151
1152         _cleanup_free_ char *action = NULL, *mode = NULL, *user = NULL, *group = NULL, *age = NULL, *path = NULL;
1153         _cleanup_(item_freep) Item *i = NULL;
1154         Item *existing;
1155         char type;
1156         Hashmap *h;
1157         int r, n = -1;
1158
1159         assert(fname);
1160         assert(line >= 1);
1161         assert(buffer);
1162
1163         r = sscanf(buffer,
1164                    "%ms %ms %ms %ms %ms %ms %n",
1165                    &action,
1166                    &path,
1167                    &mode,
1168                    &user,
1169                    &group,
1170                    &age,
1171                    &n);
1172         if (r < 2) {
1173                 log_error("[%s:%u] Syntax error.", fname, line);
1174                 return -EIO;
1175         }
1176
1177         if (isempty(action)) {
1178                 log_error("[%s:%u] Command too short '%s'.", fname, line, action);
1179                 return -EINVAL;
1180         }
1181
1182         if (strlen(action) > 1 && !in_charset(action+1, "!+")) {
1183                 log_error("[%s:%u] Unknown modifiers in command '%s'", fname, line, action);
1184                 return -EINVAL;
1185         }
1186
1187         if (strchr(action+1, '!') && !arg_boot)
1188                 return 0;
1189
1190         type = action[0];
1191
1192         i = new0(Item, 1);
1193         if (!i)
1194                 return log_oom();
1195
1196         i->force = !!strchr(action+1, '+');
1197
1198         r = specifier_printf(path, specifier_table, NULL, &i->path);
1199         if (r < 0) {
1200                 log_error("[%s:%u] Failed to replace specifiers: %s", fname, line, path);
1201                 return r;
1202         }
1203
1204         if (n >= 0)  {
1205                 n += strspn(buffer+n, WHITESPACE);
1206                 if (buffer[n] != 0 && (buffer[n] != '-' || buffer[n+1] != 0)) {
1207                         i->argument = unquote(buffer+n, "\"");
1208                         if (!i->argument)
1209                                 return log_oom();
1210                 }
1211         }
1212
1213         switch (type) {
1214
1215         case CREATE_FILE:
1216         case TRUNCATE_FILE:
1217         case CREATE_DIRECTORY:
1218         case TRUNCATE_DIRECTORY:
1219         case CREATE_FIFO:
1220         case IGNORE_PATH:
1221         case IGNORE_DIRECTORY_PATH:
1222         case REMOVE_PATH:
1223         case RECURSIVE_REMOVE_PATH:
1224         case ADJUST_MODE:
1225         case RELABEL_PATH:
1226         case RECURSIVE_RELABEL_PATH:
1227                 break;
1228
1229         case CREATE_SYMLINK:
1230                 if (!i->argument) {
1231                         log_error("[%s:%u] Symlink file requires argument.", fname, line);
1232                         return -EBADMSG;
1233                 }
1234
1235                 break;
1236
1237         case WRITE_FILE:
1238                 if (!i->argument) {
1239                         log_error("[%s:%u] Write file requires argument.", fname, line);
1240                         return -EBADMSG;
1241                 }
1242                 break;
1243
1244         case COPY_FILES:
1245                 if (!i->argument) {
1246                         log_error("[%s:%u] Copy files requires argument.", fname, line);
1247                         return -EBADMSG;
1248                 }
1249
1250                 if (!path_is_absolute(i->argument)) {
1251                         log_error("[%s:%u] Source path is not absolute.", fname, line);
1252                         return -EBADMSG;
1253                 }
1254
1255                 path_kill_slashes(i->argument);
1256                 break;
1257
1258         case CREATE_CHAR_DEVICE:
1259         case CREATE_BLOCK_DEVICE: {
1260                 unsigned major, minor;
1261
1262                 if (!i->argument) {
1263                         log_error("[%s:%u] Device file requires argument.", fname, line);
1264                         return -EBADMSG;
1265                 }
1266
1267                 if (sscanf(i->argument, "%u:%u", &major, &minor) != 2) {
1268                         log_error("[%s:%u] Can't parse device file major/minor '%s'.", fname, line, i->argument);
1269                         return -EBADMSG;
1270                 }
1271
1272                 i->major_minor = makedev(major, minor);
1273                 break;
1274         }
1275
1276         default:
1277                 log_error("[%s:%u] Unknown command type '%c'.", fname, line, type);
1278                 return -EBADMSG;
1279         }
1280
1281         i->type = type;
1282
1283         if (!path_is_absolute(i->path)) {
1284                 log_error("[%s:%u] Path '%s' not absolute.", fname, line, i->path);
1285                 return -EBADMSG;
1286         }
1287
1288         path_kill_slashes(i->path);
1289
1290         if (!should_include_path(i->path))
1291                 return 0;
1292
1293         if (arg_root) {
1294                 char *p;
1295
1296                 p = strappend(arg_root, i->path);
1297                 if (!p)
1298                         return log_oom();
1299
1300                 free(i->path);
1301                 i->path = p;
1302         }
1303
1304         if (user && !streq(user, "-")) {
1305                 const char *u = user;
1306
1307                 r = get_user_creds(&u, &i->uid, NULL, NULL, NULL);
1308                 if (r < 0) {
1309                         log_error("[%s:%u] Unknown user '%s'.", fname, line, user);
1310                         return r;
1311                 }
1312
1313                 i->uid_set = true;
1314         }
1315
1316         if (group && !streq(group, "-")) {
1317                 const char *g = group;
1318
1319                 r = get_group_creds(&g, &i->gid);
1320                 if (r < 0) {
1321                         log_error("[%s:%u] Unknown group '%s'.", fname, line, group);
1322                         return r;
1323                 }
1324
1325                 i->gid_set = true;
1326         }
1327
1328         if (mode && !streq(mode, "-")) {
1329                 const char *mm = mode;
1330                 unsigned m;
1331
1332                 if (*mm == '~') {
1333                         i->mask_perms = true;
1334                         mm++;
1335                 }
1336
1337                 if (sscanf(mm, "%o", &m) != 1) {
1338                         log_error("[%s:%u] Invalid mode '%s'.", fname, line, mode);
1339                         return -ENOENT;
1340                 }
1341
1342                 i->mode = m;
1343                 i->mode_set = true;
1344         } else
1345                 i->mode =
1346                         i->type == CREATE_DIRECTORY ||
1347                         i->type == TRUNCATE_DIRECTORY ? 0755 : 0644;
1348
1349         if (age && !streq(age, "-")) {
1350                 const char *a = age;
1351
1352                 if (*a == '~') {
1353                         i->keep_first_level = true;
1354                         a++;
1355                 }
1356
1357                 if (parse_sec(a, &i->age) < 0) {
1358                         log_error("[%s:%u] Invalid age '%s'.", fname, line, age);
1359                         return -EBADMSG;
1360                 }
1361
1362                 i->age_set = true;
1363         }
1364
1365         h = needs_glob(i->type) ? globs : items;
1366
1367         existing = hashmap_get(h, i->path);
1368         if (existing) {
1369
1370                 /* Two identical items are fine */
1371                 if (!item_equal(existing, i))
1372                         log_warning("Two or more conflicting lines for %s configured, ignoring.", i->path);
1373
1374                 return 0;
1375         }
1376
1377         r = hashmap_put(h, i->path, i);
1378         if (r < 0) {
1379                 log_error("Failed to insert item %s: %s", i->path, strerror(-r));
1380                 return r;
1381         }
1382
1383         i = NULL; /* avoid cleanup */
1384
1385         return 0;
1386 }
1387
1388 static int help(void) {
1389
1390         printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
1391                "Creates, deletes and cleans up volatile and temporary files and directories.\n\n"
1392                "  -h --help                 Show this help\n"
1393                "     --version              Show package version\n"
1394                "     --create               Create marked files/directories\n"
1395                "     --clean                Clean up marked directories\n"
1396                "     --remove               Remove marked files/directories\n"
1397                "     --boot                 Execute actions only safe at boot\n"
1398                "     --prefix=PATH          Only apply rules that apply to paths with the specified prefix\n"
1399                "     --exclude-prefix=PATH  Ignore rules that apply to paths with the specified prefix\n"
1400                "     --root=PATH            Operate on an alternate filesystem root\n",
1401                program_invocation_short_name);
1402
1403         return 0;
1404 }
1405
1406 static int parse_argv(int argc, char *argv[]) {
1407
1408         enum {
1409                 ARG_VERSION = 0x100,
1410                 ARG_CREATE,
1411                 ARG_CLEAN,
1412                 ARG_REMOVE,
1413                 ARG_BOOT,
1414                 ARG_PREFIX,
1415                 ARG_EXCLUDE_PREFIX,
1416                 ARG_ROOT,
1417         };
1418
1419         static const struct option options[] = {
1420                 { "help",           no_argument,         NULL, 'h'                },
1421                 { "version",        no_argument,         NULL, ARG_VERSION        },
1422                 { "create",         no_argument,         NULL, ARG_CREATE         },
1423                 { "clean",          no_argument,         NULL, ARG_CLEAN          },
1424                 { "remove",         no_argument,         NULL, ARG_REMOVE         },
1425                 { "boot",           no_argument,         NULL, ARG_BOOT           },
1426                 { "prefix",         required_argument,   NULL, ARG_PREFIX         },
1427                 { "exclude-prefix", required_argument,   NULL, ARG_EXCLUDE_PREFIX },
1428                 { "root",           required_argument,   NULL, ARG_ROOT           },
1429                 {}
1430         };
1431
1432         int c;
1433
1434         assert(argc >= 0);
1435         assert(argv);
1436
1437         while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
1438
1439                 switch (c) {
1440
1441                 case 'h':
1442                         return help();
1443
1444                 case ARG_VERSION:
1445                         puts(PACKAGE_STRING);
1446                         puts(SYSTEMD_FEATURES);
1447                         return 0;
1448
1449                 case ARG_CREATE:
1450                         arg_create = true;
1451                         break;
1452
1453                 case ARG_CLEAN:
1454                         arg_clean = true;
1455                         break;
1456
1457                 case ARG_REMOVE:
1458                         arg_remove = true;
1459                         break;
1460
1461                 case ARG_BOOT:
1462                         arg_boot = true;
1463                         break;
1464
1465                 case ARG_PREFIX:
1466                         if (strv_push(&arg_include_prefixes, optarg) < 0)
1467                                 return log_oom();
1468                         break;
1469
1470                 case ARG_EXCLUDE_PREFIX:
1471                         if (strv_push(&arg_exclude_prefixes, optarg) < 0)
1472                                 return log_oom();
1473                         break;
1474
1475                 case ARG_ROOT:
1476                         free(arg_root);
1477                         arg_root = path_make_absolute_cwd(optarg);
1478                         if (!arg_root)
1479                                 return log_oom();
1480
1481                         path_kill_slashes(arg_root);
1482                         break;
1483
1484                 case '?':
1485                         return -EINVAL;
1486
1487                 default:
1488                         assert_not_reached("Unhandled option");
1489                 }
1490         }
1491
1492         if (!arg_clean && !arg_create && !arg_remove) {
1493                 log_error("You need to specify at least one of --clean, --create or --remove.");
1494                 return -EINVAL;
1495         }
1496
1497         return 1;
1498 }
1499
1500 static int read_config_file(const char *fn, bool ignore_enoent) {
1501         _cleanup_fclose_ FILE *f = NULL;
1502         char line[LINE_MAX];
1503         Iterator iterator;
1504         unsigned v = 0;
1505         Item *i;
1506         int r;
1507
1508         assert(fn);
1509
1510         r = search_and_fopen_nulstr(fn, "re", arg_root, conf_file_dirs, &f);
1511         if (r < 0) {
1512                 if (ignore_enoent && r == -ENOENT)
1513                         return 0;
1514
1515                 log_error("Failed to open '%s', ignoring: %s", fn, strerror(-r));
1516                 return r;
1517         }
1518
1519         FOREACH_LINE(line, f, break) {
1520                 char *l;
1521                 int k;
1522
1523                 v++;
1524
1525                 l = strstrip(line);
1526                 if (*l == '#' || *l == 0)
1527                         continue;
1528
1529                 k = parse_line(fn, v, l);
1530                 if (k < 0 && r == 0)
1531                         r = k;
1532         }
1533
1534         /* we have to determine age parameter for each entry of type X */
1535         HASHMAP_FOREACH(i, globs, iterator) {
1536                 Iterator iter;
1537                 Item *j, *candidate_item = NULL;
1538
1539                 if (i->type != IGNORE_DIRECTORY_PATH)
1540                         continue;
1541
1542                 HASHMAP_FOREACH(j, items, iter) {
1543                         if (j->type != CREATE_DIRECTORY && j->type != TRUNCATE_DIRECTORY)
1544                                 continue;
1545
1546                         if (path_equal(j->path, i->path)) {
1547                                 candidate_item = j;
1548                                 break;
1549                         }
1550
1551                         if ((!candidate_item && path_startswith(i->path, j->path)) ||
1552                             (candidate_item && path_startswith(j->path, candidate_item->path) && (fnmatch(i->path, j->path, FNM_PATHNAME | FNM_PERIOD) == 0)))
1553                                 candidate_item = j;
1554                 }
1555
1556                 if (candidate_item) {
1557                         i->age = candidate_item->age;
1558                         i->age_set = true;
1559                 }
1560         }
1561
1562         if (ferror(f)) {
1563                 log_error("Failed to read from file %s: %m", fn);
1564                 if (r == 0)
1565                         r = -EIO;
1566         }
1567
1568         return r;
1569 }
1570
1571 int main(int argc, char *argv[]) {
1572         int r, k;
1573         Item *i;
1574         Iterator iterator;
1575
1576         r = parse_argv(argc, argv);
1577         if (r <= 0)
1578                 goto finish;
1579
1580         log_set_target(LOG_TARGET_AUTO);
1581         log_parse_environment();
1582         log_open();
1583
1584         umask(0022);
1585
1586         label_init(NULL);
1587
1588         items = hashmap_new(string_hash_func, string_compare_func);
1589         globs = hashmap_new(string_hash_func, string_compare_func);
1590
1591         if (!items || !globs) {
1592                 r = log_oom();
1593                 goto finish;
1594         }
1595
1596         r = 0;
1597
1598         if (optind < argc) {
1599                 int j;
1600
1601                 for (j = optind; j < argc; j++) {
1602                         k = read_config_file(argv[j], false);
1603                         if (k < 0 && r == 0)
1604                                 r = k;
1605                 }
1606
1607         } else {
1608                 _cleanup_strv_free_ char **files = NULL;
1609                 char **f;
1610
1611                 r = conf_files_list_nulstr(&files, ".conf", arg_root, conf_file_dirs);
1612                 if (r < 0) {
1613                         log_error("Failed to enumerate tmpfiles.d files: %s", strerror(-r));
1614                         goto finish;
1615                 }
1616
1617                 STRV_FOREACH(f, files) {
1618                         k = read_config_file(*f, true);
1619                         if (k < 0 && r == 0)
1620                                 r = k;
1621                 }
1622         }
1623
1624         HASHMAP_FOREACH(i, globs, iterator)
1625                 process_item(i);
1626
1627         HASHMAP_FOREACH(i, items, iterator)
1628                 process_item(i);
1629
1630 finish:
1631         while ((i = hashmap_steal_first(items)))
1632                 item_free(i);
1633
1634         while ((i = hashmap_steal_first(globs)))
1635                 item_free(i);
1636
1637         hashmap_free(items);
1638         hashmap_free(globs);
1639
1640         free(arg_include_prefixes);
1641         free(arg_exclude_prefixes);
1642         free(arg_root);
1643
1644         set_free_free(unix_sockets);
1645
1646         label_finish();
1647
1648         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1649 }