chiark / gitweb /
8ec8252a7bf8f3c8b8e55d6f1e09e18e532b176c
[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         int flags;
498         int fd = -1;
499         struct stat st;
500         int r = 0;
501
502         assert(i);
503         assert(path);
504
505         flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND :
506                 i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC : 0;
507
508         RUN_WITH_UMASK(0) {
509                 label_context_set(path, S_IFREG);
510                 fd = open(path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY|O_NOFOLLOW, i->mode);
511                 label_context_clear();
512         }
513
514         if (fd < 0) {
515                 if (i->type == WRITE_FILE && errno == ENOENT)
516                         return 0;
517
518                 log_error("Failed to create file %s: %m", path);
519                 return -errno;
520         }
521
522         if (i->argument) {
523                 _cleanup_free_ char *unescaped;
524                 ssize_t n;
525                 size_t l;
526
527                 unescaped = cunescape(i->argument);
528                 if (unescaped == NULL) {
529                         safe_close(fd);
530                         return log_oom();
531                 }
532
533                 l = strlen(unescaped);
534                 n = write(fd, unescaped, l);
535
536                 if (n < 0 || (size_t) n < l) {
537                         log_error("Failed to write file %s: %s", path, n < 0 ? strerror(-n) : "Short write");
538                         safe_close(fd);
539                         return n < 0 ? n : -EIO;
540                 }
541         }
542
543         safe_close(fd);
544
545         if (stat(path, &st) < 0) {
546                 log_error("stat(%s) failed: %m", path);
547                 return -errno;
548         }
549
550         if (!S_ISREG(st.st_mode)) {
551                 log_error("%s is not a file.", path);
552                 return -EEXIST;
553         }
554
555         r = item_set_perms(i, path);
556         if (r < 0)
557                 return r;
558
559         return 0;
560 }
561
562 static int item_set_perms_children(Item *i, const char *path) {
563         _cleanup_closedir_ DIR *d;
564         int r = 0;
565
566         assert(i);
567         assert(path);
568
569         /* This returns the first error we run into, but nevertheless
570          * tries to go on */
571
572         d = opendir(path);
573         if (!d)
574                 return errno == ENOENT || errno == ENOTDIR ? 0 : -errno;
575
576         for (;;) {
577                 _cleanup_free_ char *p = NULL;
578                 struct dirent *de;
579                 int q;
580
581                 errno = 0;
582                 de = readdir(d);
583                 if (!de) {
584                         if (errno != 0 && r == 0)
585                                 r = -errno;
586
587                         break;
588                 }
589
590                 if (streq(de->d_name, ".") || streq(de->d_name, ".."))
591                         continue;
592
593                 p = strjoin(path, "/", de->d_name, NULL);
594                 if (!p)
595                         return -ENOMEM;
596
597                 q = item_set_perms(i, p);
598                 if (q < 0 && q != -ENOENT && r == 0)
599                         r = q;
600
601                 if (IN_SET(de->d_type, DT_UNKNOWN, DT_DIR)) {
602                         q = item_set_perms_children(i, p);
603                         if (q < 0 && r == 0)
604                                 r = q;
605                 }
606         }
607
608         return r;
609 }
610
611 static int item_set_perms_recursive(Item *i, const char *path) {
612         int r, q;
613
614         assert(i);
615         assert(path);
616
617         r = item_set_perms(i, path);
618         if (r < 0)
619                 return r;
620
621         q = item_set_perms_children(i, path);
622         if (q < 0 && r == 0)
623                 r = q;
624
625         return r;
626 }
627
628 static int glob_item(Item *i, int (*action)(Item *, const char *)) {
629         _cleanup_globfree_ glob_t g = {};
630         int r = 0, k;
631         char **fn;
632
633         errno = 0;
634         k = glob(i->path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
635         if (k != 0 && k != GLOB_NOMATCH) {
636                 if (errno == 0)
637                         errno = EIO;
638
639                 log_error("glob(%s) failed: %m", i->path);
640                 return -errno;
641         }
642
643         STRV_FOREACH(fn, g.gl_pathv) {
644                 k = action(i, *fn);
645                 if (k < 0 && r == 0)
646                         r = k;
647         }
648
649         return r;
650 }
651
652 static int create_item(Item *i) {
653         struct stat st;
654         int r = 0;
655
656         assert(i);
657
658         switch (i->type) {
659
660         case IGNORE_PATH:
661         case IGNORE_DIRECTORY_PATH:
662         case REMOVE_PATH:
663         case RECURSIVE_REMOVE_PATH:
664                 return 0;
665
666         case CREATE_FILE:
667         case TRUNCATE_FILE:
668                 r = write_one_file(i, i->path);
669                 if (r < 0)
670                         return r;
671                 break;
672
673         case COPY_FILES:
674                 r = copy_tree(i->argument, i->path);
675                 if (r < 0) {
676                         log_error("Failed to copy files: %s", strerror(-r));
677                         return r;
678                 }
679
680                 r = item_set_perms(i, i->path);
681                 if (r < 0)
682                         return r;
683
684                 break;
685
686         case WRITE_FILE:
687                 r = glob_item(i, write_one_file);
688                 if (r < 0)
689                         return r;
690
691                 break;
692
693         case TRUNCATE_DIRECTORY:
694         case CREATE_DIRECTORY:
695
696                 RUN_WITH_UMASK(0000) {
697                         mkdir_parents_label(i->path, 0755);
698                         r = mkdir(i->path, i->mode);
699                 }
700
701                 if (r < 0 && errno != EEXIST) {
702                         log_error("Failed to create directory %s: %m", i->path);
703                         return -errno;
704                 }
705
706                 if (stat(i->path, &st) < 0) {
707                         log_error("stat(%s) failed: %m", i->path);
708                         return -errno;
709                 }
710
711                 if (!S_ISDIR(st.st_mode)) {
712                         log_error("%s is not a directory.", i->path);
713                         return -EEXIST;
714                 }
715
716                 r = item_set_perms(i, i->path);
717                 if (r < 0)
718                         return r;
719
720                 break;
721
722         case CREATE_FIFO:
723
724                 RUN_WITH_UMASK(0000) {
725                         label_context_set(i->path, S_IFIFO);
726                         r = mkfifo(i->path, i->mode);
727                         label_context_clear();
728                 }
729
730                 if (r < 0) {
731                         if (errno != EEXIST) {
732                                 log_error("Failed to create fifo %s: %m", i->path);
733                                 return -errno;
734                         }
735
736                         if (stat(i->path, &st) < 0) {
737                                 log_error("stat(%s) failed: %m", i->path);
738                                 return -errno;
739                         }
740
741                         if (!S_ISFIFO(st.st_mode)) {
742
743                                 if (i->force) {
744
745                                         RUN_WITH_UMASK(0000) {
746                                                 label_context_set(i->path, S_IFIFO);
747                                                 r = mkfifo_atomic(i->path, i->mode);
748                                                 label_context_clear();
749                                         }
750
751                                         if (r < 0) {
752                                                 log_error("Failed to create fifo %s: %s", i->path, strerror(-r));
753                                                 return r;
754                                         }
755                                 } else {
756                                         log_debug("%s is not a fifo.", i->path);
757                                         return 0;
758                                 }
759                         }
760                 }
761
762                 r = item_set_perms(i, i->path);
763                 if (r < 0)
764                         return r;
765
766                 break;
767
768         case CREATE_SYMLINK:
769
770                 label_context_set(i->path, S_IFLNK);
771                 r = symlink(i->argument, i->path);
772                 label_context_clear();
773
774                 if (r < 0) {
775                         _cleanup_free_ char *x = NULL;
776
777                         if (errno != EEXIST) {
778                                 log_error("symlink(%s, %s) failed: %m", i->argument, i->path);
779                                 return -errno;
780                         }
781
782                         r = readlink_malloc(i->path, &x);
783                         if (r < 0 || !streq(i->argument, x)) {
784
785                                 if (i->force) {
786                                         label_context_set(i->path, S_IFLNK);
787                                         r = symlink_atomic(i->argument, i->path);
788                                         label_context_clear();
789
790                                         if (r < 0) {
791                                                 log_error("symlink(%s, %s) failed: %s", i->argument, i->path, strerror(-r));
792                                                 return r;
793                                         }
794                                 } else {
795                                         log_debug("%s is not a symlink or does not point to the correct path.", i->path);
796                                         return 0;
797                                 }
798                         }
799                 }
800
801                 break;
802
803         case CREATE_BLOCK_DEVICE:
804         case CREATE_CHAR_DEVICE: {
805                 mode_t file_type;
806
807                 if (have_effective_cap(CAP_MKNOD) == 0) {
808                         /* In a container we lack CAP_MKNOD. We
809                         shouldn't attempt to create the device node in
810                         that case to avoid noise, and we don't support
811                         virtualized devices in containers anyway. */
812
813                         log_debug("We lack CAP_MKNOD, skipping creation of device node %s.", i->path);
814                         return 0;
815                 }
816
817                 file_type = i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR;
818
819                 RUN_WITH_UMASK(0000) {
820                         label_context_set(i->path, file_type);
821                         r = mknod(i->path, i->mode | file_type, i->major_minor);
822                         label_context_clear();
823                 }
824
825                 if (r < 0) {
826                         if (errno == EPERM) {
827                                 log_debug("We lack permissions, possibly because of cgroup configuration; "
828                                           "skipping creation of device node %s.", i->path);
829                                 return 0;
830                         }
831
832                         if (errno != EEXIST) {
833                                 log_error("Failed to create device node %s: %m", i->path);
834                                 return -errno;
835                         }
836
837                         if (stat(i->path, &st) < 0) {
838                                 log_error("stat(%s) failed: %m", i->path);
839                                 return -errno;
840                         }
841
842                         if ((st.st_mode & S_IFMT) != file_type) {
843
844                                 if (i->force) {
845
846                                         RUN_WITH_UMASK(0000) {
847                                                 label_context_set(i->path, file_type);
848                                                 r = mknod_atomic(i->path, i->mode | file_type, i->major_minor);
849                                                 label_context_clear();
850                                         }
851
852                                         if (r < 0) {
853                                                 log_error("Failed to create device node %s: %s", i->path, strerror(-r));
854                                                 return r;
855                                         }
856                                 } else {
857                                         log_debug("%s is not a device node.", i->path);
858                                         return 0;
859                                 }
860                         }
861                 }
862
863                 r = item_set_perms(i, i->path);
864                 if (r < 0)
865                         return r;
866
867                 break;
868         }
869
870         case ADJUST_MODE:
871         case RELABEL_PATH:
872
873                 r = glob_item(i, item_set_perms);
874                 if (r < 0)
875                         return r;
876                 break;
877
878         case RECURSIVE_RELABEL_PATH:
879
880                 r = glob_item(i, item_set_perms_recursive);
881                 if (r < 0)
882                         return r;
883
884                 break;
885         }
886
887         log_debug("%s created successfully.", i->path);
888
889         return 0;
890 }
891
892 static int remove_item_instance(Item *i, const char *instance) {
893         int r;
894
895         assert(i);
896
897         switch (i->type) {
898
899         case CREATE_FILE:
900         case TRUNCATE_FILE:
901         case CREATE_DIRECTORY:
902         case CREATE_FIFO:
903         case CREATE_SYMLINK:
904         case CREATE_BLOCK_DEVICE:
905         case CREATE_CHAR_DEVICE:
906         case IGNORE_PATH:
907         case IGNORE_DIRECTORY_PATH:
908         case ADJUST_MODE:
909         case RELABEL_PATH:
910         case RECURSIVE_RELABEL_PATH:
911         case WRITE_FILE:
912         case COPY_FILES:
913                 break;
914
915         case REMOVE_PATH:
916                 if (remove(instance) < 0 && errno != ENOENT) {
917                         log_error("remove(%s): %m", instance);
918                         return -errno;
919                 }
920
921                 break;
922
923         case TRUNCATE_DIRECTORY:
924         case RECURSIVE_REMOVE_PATH:
925                 /* FIXME: we probably should use dir_cleanup() here
926                  * instead of rm_rf() so that 'x' is honoured. */
927                 r = rm_rf_dangerous(instance, false, i->type == RECURSIVE_REMOVE_PATH, false);
928                 if (r < 0 && r != -ENOENT) {
929                         log_error("rm_rf(%s): %s", instance, strerror(-r));
930                         return r;
931                 }
932
933                 break;
934         }
935
936         return 0;
937 }
938
939 static int remove_item(Item *i) {
940         int r = 0;
941
942         assert(i);
943
944         switch (i->type) {
945
946         case CREATE_FILE:
947         case TRUNCATE_FILE:
948         case CREATE_DIRECTORY:
949         case CREATE_FIFO:
950         case CREATE_SYMLINK:
951         case CREATE_CHAR_DEVICE:
952         case CREATE_BLOCK_DEVICE:
953         case IGNORE_PATH:
954         case IGNORE_DIRECTORY_PATH:
955         case ADJUST_MODE:
956         case RELABEL_PATH:
957         case RECURSIVE_RELABEL_PATH:
958         case WRITE_FILE:
959         case COPY_FILES:
960                 break;
961
962         case REMOVE_PATH:
963         case TRUNCATE_DIRECTORY:
964         case RECURSIVE_REMOVE_PATH:
965                 r = glob_item(i, remove_item_instance);
966                 break;
967         }
968
969         return r;
970 }
971
972 static int clean_item_instance(Item *i, const char* instance) {
973         _cleanup_closedir_ DIR *d = NULL;
974         struct stat s, ps;
975         bool mountpoint;
976         int r;
977         usec_t cutoff, n;
978
979         assert(i);
980
981         if (!i->age_set)
982                 return 0;
983
984         n = now(CLOCK_REALTIME);
985         if (n < i->age)
986                 return 0;
987
988         cutoff = n - i->age;
989
990         d = opendir(instance);
991         if (!d) {
992                 if (errno == ENOENT || errno == ENOTDIR)
993                         return 0;
994
995                 log_error("Failed to open directory %s: %m", i->path);
996                 return -errno;
997         }
998
999         if (fstat(dirfd(d), &s) < 0) {
1000                 log_error("stat(%s) failed: %m", i->path);
1001                 return -errno;
1002         }
1003
1004         if (!S_ISDIR(s.st_mode)) {
1005                 log_error("%s is not a directory.", i->path);
1006                 return -ENOTDIR;
1007         }
1008
1009         if (fstatat(dirfd(d), "..", &ps, AT_SYMLINK_NOFOLLOW) != 0) {
1010                 log_error("stat(%s/..) failed: %m", i->path);
1011                 return -errno;
1012         }
1013
1014         mountpoint = s.st_dev != ps.st_dev ||
1015                      (s.st_dev == ps.st_dev && s.st_ino == ps.st_ino);
1016
1017         r = dir_cleanup(i, instance, d, &s, cutoff, s.st_dev, mountpoint,
1018                         MAX_DEPTH, i->keep_first_level);
1019         return r;
1020 }
1021
1022 static int clean_item(Item *i) {
1023         int r = 0;
1024
1025         assert(i);
1026
1027         switch (i->type) {
1028         case CREATE_DIRECTORY:
1029         case TRUNCATE_DIRECTORY:
1030         case IGNORE_PATH:
1031         case COPY_FILES:
1032                 clean_item_instance(i, i->path);
1033                 break;
1034         case IGNORE_DIRECTORY_PATH:
1035                 r = glob_item(i, clean_item_instance);
1036                 break;
1037         default:
1038                 break;
1039         }
1040
1041         return r;
1042 }
1043
1044 static int process_item(Item *i) {
1045         int r, q, p;
1046         char prefix[PATH_MAX];
1047
1048         assert(i);
1049
1050         if (i->done)
1051                 return 0;
1052
1053         i->done = true;
1054
1055         PATH_FOREACH_PREFIX(prefix, i->path) {
1056                 Item *j;
1057
1058                 j = hashmap_get(items, prefix);
1059                 if (j)
1060                         process_item(j);
1061         }
1062
1063         r = arg_create ? create_item(i) : 0;
1064         q = arg_remove ? remove_item(i) : 0;
1065         p = arg_clean ? clean_item(i) : 0;
1066
1067         if (r < 0)
1068                 return r;
1069
1070         if (q < 0)
1071                 return q;
1072
1073         return p;
1074 }
1075
1076 static void item_free(Item *i) {
1077
1078         if (!i)
1079                 return;
1080
1081         free(i->path);
1082         free(i->argument);
1083         free(i);
1084 }
1085
1086 DEFINE_TRIVIAL_CLEANUP_FUNC(Item*, item_free);
1087
1088 static bool item_equal(Item *a, Item *b) {
1089         assert(a);
1090         assert(b);
1091
1092         if (!streq_ptr(a->path, b->path))
1093                 return false;
1094
1095         if (a->type != b->type)
1096                 return false;
1097
1098         if (a->uid_set != b->uid_set ||
1099             (a->uid_set && a->uid != b->uid))
1100             return false;
1101
1102         if (a->gid_set != b->gid_set ||
1103             (a->gid_set && a->gid != b->gid))
1104             return false;
1105
1106         if (a->mode_set != b->mode_set ||
1107             (a->mode_set && a->mode != b->mode))
1108             return false;
1109
1110         if (a->age_set != b->age_set ||
1111             (a->age_set && a->age != b->age))
1112             return false;
1113
1114         if ((a->type == CREATE_FILE ||
1115              a->type == TRUNCATE_FILE ||
1116              a->type == WRITE_FILE ||
1117              a->type == CREATE_SYMLINK ||
1118              a->type == COPY_FILES) &&
1119             !streq_ptr(a->argument, b->argument))
1120                 return false;
1121
1122         if ((a->type == CREATE_CHAR_DEVICE ||
1123              a->type == CREATE_BLOCK_DEVICE) &&
1124             a->major_minor != b->major_minor)
1125                 return false;
1126
1127         return true;
1128 }
1129
1130 static bool should_include_path(const char *path) {
1131         char **prefix;
1132
1133         STRV_FOREACH(prefix, arg_exclude_prefixes)
1134                 if (path_startswith(path, *prefix))
1135                         return false;
1136
1137         STRV_FOREACH(prefix, arg_include_prefixes)
1138                 if (path_startswith(path, *prefix))
1139                         return true;
1140
1141         /* no matches, so we should include this path only if we
1142          * have no whitelist at all */
1143         return strv_length(arg_include_prefixes) == 0;
1144 }
1145
1146 static int parse_line(const char *fname, unsigned line, const char *buffer) {
1147
1148         static const Specifier specifier_table[] = {
1149                 { 'm', specifier_machine_id, NULL },
1150                 { 'b', specifier_boot_id, NULL },
1151                 { 'H', specifier_host_name, NULL },
1152                 { 'v', specifier_kernel_release, NULL },
1153                 {}
1154         };
1155
1156         _cleanup_free_ char *action = NULL, *mode = NULL, *user = NULL, *group = NULL, *age = NULL, *path = NULL;
1157         _cleanup_(item_freep) Item *i = NULL;
1158         Item *existing;
1159         char type;
1160         Hashmap *h;
1161         int r, n = -1;
1162
1163         assert(fname);
1164         assert(line >= 1);
1165         assert(buffer);
1166
1167         r = sscanf(buffer,
1168                    "%ms %ms %ms %ms %ms %ms %n",
1169                    &action,
1170                    &path,
1171                    &mode,
1172                    &user,
1173                    &group,
1174                    &age,
1175                    &n);
1176         if (r < 2) {
1177                 log_error("[%s:%u] Syntax error.", fname, line);
1178                 return -EIO;
1179         }
1180
1181         if (isempty(action)) {
1182                 log_error("[%s:%u] Command too short '%s'.", fname, line, action);
1183                 return -EINVAL;
1184         }
1185
1186         if (strlen(action) > 1 && !in_charset(action+1, "!+")) {
1187                 log_error("[%s:%u] Unknown modifiers in command '%s'", fname, line, action);
1188                 return -EINVAL;
1189         }
1190
1191         if (strchr(action+1, '!') && !arg_boot)
1192                 return 0;
1193
1194         type = action[0];
1195
1196         i = new0(Item, 1);
1197         if (!i)
1198                 return log_oom();
1199
1200         i->force = !!strchr(action+1, '+');
1201
1202         r = specifier_printf(path, specifier_table, NULL, &i->path);
1203         if (r < 0) {
1204                 log_error("[%s:%u] Failed to replace specifiers: %s", fname, line, path);
1205                 return r;
1206         }
1207
1208         if (n >= 0)  {
1209                 n += strspn(buffer+n, WHITESPACE);
1210                 if (buffer[n] != 0 && (buffer[n] != '-' || buffer[n+1] != 0)) {
1211                         i->argument = unquote(buffer+n, "\"");
1212                         if (!i->argument)
1213                                 return log_oom();
1214                 }
1215         }
1216
1217         switch (type) {
1218
1219         case CREATE_FILE:
1220         case TRUNCATE_FILE:
1221         case CREATE_DIRECTORY:
1222         case TRUNCATE_DIRECTORY:
1223         case CREATE_FIFO:
1224         case IGNORE_PATH:
1225         case IGNORE_DIRECTORY_PATH:
1226         case REMOVE_PATH:
1227         case RECURSIVE_REMOVE_PATH:
1228         case ADJUST_MODE:
1229         case RELABEL_PATH:
1230         case RECURSIVE_RELABEL_PATH:
1231                 break;
1232
1233         case CREATE_SYMLINK:
1234                 if (!i->argument) {
1235                         log_error("[%s:%u] Symlink file requires argument.", fname, line);
1236                         return -EBADMSG;
1237                 }
1238
1239                 break;
1240
1241         case WRITE_FILE:
1242                 if (!i->argument) {
1243                         log_error("[%s:%u] Write file requires argument.", fname, line);
1244                         return -EBADMSG;
1245                 }
1246                 break;
1247
1248         case COPY_FILES:
1249                 if (!i->argument) {
1250                         log_error("[%s:%u] Copy files requires argument.", fname, line);
1251                         return -EBADMSG;
1252                 }
1253
1254                 if (!path_is_absolute(i->argument)) {
1255                         log_error("[%s:%u] Source path is not absolute.", fname, line);
1256                         return -EBADMSG;
1257                 }
1258
1259                 path_kill_slashes(i->argument);
1260                 break;
1261
1262         case CREATE_CHAR_DEVICE:
1263         case CREATE_BLOCK_DEVICE: {
1264                 unsigned major, minor;
1265
1266                 if (!i->argument) {
1267                         log_error("[%s:%u] Device file requires argument.", fname, line);
1268                         return -EBADMSG;
1269                 }
1270
1271                 if (sscanf(i->argument, "%u:%u", &major, &minor) != 2) {
1272                         log_error("[%s:%u] Can't parse device file major/minor '%s'.", fname, line, i->argument);
1273                         return -EBADMSG;
1274                 }
1275
1276                 i->major_minor = makedev(major, minor);
1277                 break;
1278         }
1279
1280         default:
1281                 log_error("[%s:%u] Unknown command type '%c'.", fname, line, type);
1282                 return -EBADMSG;
1283         }
1284
1285         i->type = type;
1286
1287         if (!path_is_absolute(i->path)) {
1288                 log_error("[%s:%u] Path '%s' not absolute.", fname, line, i->path);
1289                 return -EBADMSG;
1290         }
1291
1292         path_kill_slashes(i->path);
1293
1294         if (!should_include_path(i->path))
1295                 return 0;
1296
1297         if (arg_root) {
1298                 char *p;
1299
1300                 p = strappend(arg_root, i->path);
1301                 if (!p)
1302                         return log_oom();
1303
1304                 free(i->path);
1305                 i->path = p;
1306         }
1307
1308         if (user && !streq(user, "-")) {
1309                 const char *u = user;
1310
1311                 r = get_user_creds(&u, &i->uid, NULL, NULL, NULL);
1312                 if (r < 0) {
1313                         log_error("[%s:%u] Unknown user '%s'.", fname, line, user);
1314                         return r;
1315                 }
1316
1317                 i->uid_set = true;
1318         }
1319
1320         if (group && !streq(group, "-")) {
1321                 const char *g = group;
1322
1323                 r = get_group_creds(&g, &i->gid);
1324                 if (r < 0) {
1325                         log_error("[%s:%u] Unknown group '%s'.", fname, line, group);
1326                         return r;
1327                 }
1328
1329                 i->gid_set = true;
1330         }
1331
1332         if (mode && !streq(mode, "-")) {
1333                 const char *mm = mode;
1334                 unsigned m;
1335
1336                 if (*mm == '~') {
1337                         i->mask_perms = true;
1338                         mm++;
1339                 }
1340
1341                 if (sscanf(mm, "%o", &m) != 1) {
1342                         log_error("[%s:%u] Invalid mode '%s'.", fname, line, mode);
1343                         return -ENOENT;
1344                 }
1345
1346                 i->mode = m;
1347                 i->mode_set = true;
1348         } else
1349                 i->mode =
1350                         i->type == CREATE_DIRECTORY ||
1351                         i->type == TRUNCATE_DIRECTORY ? 0755 : 0644;
1352
1353         if (age && !streq(age, "-")) {
1354                 const char *a = age;
1355
1356                 if (*a == '~') {
1357                         i->keep_first_level = true;
1358                         a++;
1359                 }
1360
1361                 if (parse_sec(a, &i->age) < 0) {
1362                         log_error("[%s:%u] Invalid age '%s'.", fname, line, age);
1363                         return -EBADMSG;
1364                 }
1365
1366                 i->age_set = true;
1367         }
1368
1369         h = needs_glob(i->type) ? globs : items;
1370
1371         existing = hashmap_get(h, i->path);
1372         if (existing) {
1373
1374                 /* Two identical items are fine */
1375                 if (!item_equal(existing, i))
1376                         log_warning("Two or more conflicting lines for %s configured, ignoring.", i->path);
1377
1378                 return 0;
1379         }
1380
1381         r = hashmap_put(h, i->path, i);
1382         if (r < 0) {
1383                 log_error("Failed to insert item %s: %s", i->path, strerror(-r));
1384                 return r;
1385         }
1386
1387         i = NULL; /* avoid cleanup */
1388
1389         return 0;
1390 }
1391
1392 static int help(void) {
1393
1394         printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
1395                "Creates, deletes and cleans up volatile and temporary files and directories.\n\n"
1396                "  -h --help                 Show this help\n"
1397                "     --version              Show package version\n"
1398                "     --create               Create marked files/directories\n"
1399                "     --clean                Clean up marked directories\n"
1400                "     --remove               Remove marked files/directories\n"
1401                "     --boot                 Execute actions only safe at boot\n"
1402                "     --prefix=PATH          Only apply rules that apply to paths with the specified prefix\n"
1403                "     --exclude-prefix=PATH  Ignore rules that apply to paths with the specified prefix\n"
1404                "     --root=PATH            Operate on an alternate filesystem root\n",
1405                program_invocation_short_name);
1406
1407         return 0;
1408 }
1409
1410 static int parse_argv(int argc, char *argv[]) {
1411
1412         enum {
1413                 ARG_VERSION = 0x100,
1414                 ARG_CREATE,
1415                 ARG_CLEAN,
1416                 ARG_REMOVE,
1417                 ARG_BOOT,
1418                 ARG_PREFIX,
1419                 ARG_EXCLUDE_PREFIX,
1420                 ARG_ROOT,
1421         };
1422
1423         static const struct option options[] = {
1424                 { "help",           no_argument,         NULL, 'h'                },
1425                 { "version",        no_argument,         NULL, ARG_VERSION        },
1426                 { "create",         no_argument,         NULL, ARG_CREATE         },
1427                 { "clean",          no_argument,         NULL, ARG_CLEAN          },
1428                 { "remove",         no_argument,         NULL, ARG_REMOVE         },
1429                 { "boot",           no_argument,         NULL, ARG_BOOT           },
1430                 { "prefix",         required_argument,   NULL, ARG_PREFIX         },
1431                 { "exclude-prefix", required_argument,   NULL, ARG_EXCLUDE_PREFIX },
1432                 { "root",           required_argument,   NULL, ARG_ROOT           },
1433                 {}
1434         };
1435
1436         int c;
1437
1438         assert(argc >= 0);
1439         assert(argv);
1440
1441         while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
1442
1443                 switch (c) {
1444
1445                 case 'h':
1446                         return help();
1447
1448                 case ARG_VERSION:
1449                         puts(PACKAGE_STRING);
1450                         puts(SYSTEMD_FEATURES);
1451                         return 0;
1452
1453                 case ARG_CREATE:
1454                         arg_create = true;
1455                         break;
1456
1457                 case ARG_CLEAN:
1458                         arg_clean = true;
1459                         break;
1460
1461                 case ARG_REMOVE:
1462                         arg_remove = true;
1463                         break;
1464
1465                 case ARG_BOOT:
1466                         arg_boot = true;
1467                         break;
1468
1469                 case ARG_PREFIX:
1470                         if (strv_push(&arg_include_prefixes, optarg) < 0)
1471                                 return log_oom();
1472                         break;
1473
1474                 case ARG_EXCLUDE_PREFIX:
1475                         if (strv_push(&arg_exclude_prefixes, optarg) < 0)
1476                                 return log_oom();
1477                         break;
1478
1479                 case ARG_ROOT:
1480                         free(arg_root);
1481                         arg_root = path_make_absolute_cwd(optarg);
1482                         if (!arg_root)
1483                                 return log_oom();
1484
1485                         path_kill_slashes(arg_root);
1486                         break;
1487
1488                 case '?':
1489                         return -EINVAL;
1490
1491                 default:
1492                         assert_not_reached("Unhandled option");
1493                 }
1494         }
1495
1496         if (!arg_clean && !arg_create && !arg_remove) {
1497                 log_error("You need to specify at least one of --clean, --create or --remove.");
1498                 return -EINVAL;
1499         }
1500
1501         return 1;
1502 }
1503
1504 static int read_config_file(const char *fn, bool ignore_enoent) {
1505         _cleanup_fclose_ FILE *f = NULL;
1506         char line[LINE_MAX];
1507         Iterator iterator;
1508         unsigned v = 0;
1509         Item *i;
1510         int r;
1511
1512         assert(fn);
1513
1514         r = search_and_fopen_nulstr(fn, "re", arg_root, conf_file_dirs, &f);
1515         if (r < 0) {
1516                 if (ignore_enoent && r == -ENOENT)
1517                         return 0;
1518
1519                 log_error("Failed to open '%s', ignoring: %s", fn, strerror(-r));
1520                 return r;
1521         }
1522
1523         FOREACH_LINE(line, f, break) {
1524                 char *l;
1525                 int k;
1526
1527                 v++;
1528
1529                 l = strstrip(line);
1530                 if (*l == '#' || *l == 0)
1531                         continue;
1532
1533                 k = parse_line(fn, v, l);
1534                 if (k < 0 && r == 0)
1535                         r = k;
1536         }
1537
1538         /* we have to determine age parameter for each entry of type X */
1539         HASHMAP_FOREACH(i, globs, iterator) {
1540                 Iterator iter;
1541                 Item *j, *candidate_item = NULL;
1542
1543                 if (i->type != IGNORE_DIRECTORY_PATH)
1544                         continue;
1545
1546                 HASHMAP_FOREACH(j, items, iter) {
1547                         if (j->type != CREATE_DIRECTORY && j->type != TRUNCATE_DIRECTORY)
1548                                 continue;
1549
1550                         if (path_equal(j->path, i->path)) {
1551                                 candidate_item = j;
1552                                 break;
1553                         }
1554
1555                         if ((!candidate_item && path_startswith(i->path, j->path)) ||
1556                             (candidate_item && path_startswith(j->path, candidate_item->path) && (fnmatch(i->path, j->path, FNM_PATHNAME | FNM_PERIOD) == 0)))
1557                                 candidate_item = j;
1558                 }
1559
1560                 if (candidate_item) {
1561                         i->age = candidate_item->age;
1562                         i->age_set = true;
1563                 }
1564         }
1565
1566         if (ferror(f)) {
1567                 log_error("Failed to read from file %s: %m", fn);
1568                 if (r == 0)
1569                         r = -EIO;
1570         }
1571
1572         return r;
1573 }
1574
1575 int main(int argc, char *argv[]) {
1576         int r, k;
1577         Item *i;
1578         Iterator iterator;
1579
1580         r = parse_argv(argc, argv);
1581         if (r <= 0)
1582                 goto finish;
1583
1584         log_set_target(LOG_TARGET_AUTO);
1585         log_parse_environment();
1586         log_open();
1587
1588         umask(0022);
1589
1590         label_init(NULL);
1591
1592         items = hashmap_new(string_hash_func, string_compare_func);
1593         globs = hashmap_new(string_hash_func, string_compare_func);
1594
1595         if (!items || !globs) {
1596                 r = log_oom();
1597                 goto finish;
1598         }
1599
1600         r = 0;
1601
1602         if (optind < argc) {
1603                 int j;
1604
1605                 for (j = optind; j < argc; j++) {
1606                         k = read_config_file(argv[j], false);
1607                         if (k < 0 && r == 0)
1608                                 r = k;
1609                 }
1610
1611         } else {
1612                 _cleanup_strv_free_ char **files = NULL;
1613                 char **f;
1614
1615                 r = conf_files_list_nulstr(&files, ".conf", arg_root, conf_file_dirs);
1616                 if (r < 0) {
1617                         log_error("Failed to enumerate tmpfiles.d files: %s", strerror(-r));
1618                         goto finish;
1619                 }
1620
1621                 STRV_FOREACH(f, files) {
1622                         k = read_config_file(*f, true);
1623                         if (k < 0 && r == 0)
1624                                 r = k;
1625                 }
1626         }
1627
1628         HASHMAP_FOREACH(i, globs, iterator)
1629                 process_item(i);
1630
1631         HASHMAP_FOREACH(i, items, iterator)
1632                 process_item(i);
1633
1634 finish:
1635         while ((i = hashmap_steal_first(items)))
1636                 item_free(i);
1637
1638         while ((i = hashmap_steal_first(globs)))
1639                 item_free(i);
1640
1641         hashmap_free(items);
1642         hashmap_free(globs);
1643
1644         free(arg_include_prefixes);
1645         free(arg_exclude_prefixes);
1646         free(arg_root);
1647
1648         set_free_free(unix_sockets);
1649
1650         label_finish();
1651
1652         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1653 }