chiark / gitweb /
rescue: make 'systemctl default' fail if there is already something running when...
[elogind.git] / src / 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 General Public License as published by
10   the Free Software Foundation; either version 2 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   General Public License for more details.
17
18   You should have received a copy of the GNU 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
42 #include "log.h"
43 #include "util.h"
44 #include "strv.h"
45 #include "label.h"
46 #include "set.h"
47
48 /* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates
49  * them in the file system. This is intended to be used to create
50  * properly owned directories beneath /tmp, /var/tmp, /var/run and
51  * /var/lock which are volatile and hence need to be recreated on
52  * bootup. */
53
54 enum {
55         /* These ones take file names */
56         CREATE_FILE = 'f',
57         TRUNCATE_FILE = 'F',
58         CREATE_DIRECTORY = 'd',
59         TRUNCATE_DIRECTORY = 'D',
60
61         /* These ones take globs */
62         IGNORE_PATH = 'x',
63         REMOVE_PATH = 'r',
64         RECURSIVE_REMOVE_PATH = 'R'
65 };
66
67 typedef struct Item {
68         char type;
69
70         char *path;
71         uid_t uid;
72         gid_t gid;
73         mode_t mode;
74         usec_t age;
75
76         bool uid_set:1;
77         bool gid_set:1;
78         bool mode_set:1;
79         bool age_set:1;
80 } Item;
81
82 static Hashmap *items = NULL, *globs = NULL;
83 static Set *unix_sockets = NULL;
84
85 static bool arg_create = false;
86 static bool arg_clean = false;
87 static bool arg_remove = false;
88
89 static const char *arg_prefix = NULL;
90
91 #define MAX_DEPTH 256
92
93 static bool needs_glob(int t) {
94         return t == IGNORE_PATH || t == REMOVE_PATH || t == RECURSIVE_REMOVE_PATH;
95 }
96
97 static struct Item* find_glob(Hashmap *h, const char *match) {
98         Item *j;
99         Iterator i;
100
101         HASHMAP_FOREACH(j, h, i)
102                 if (fnmatch(j->path, match, FNM_PATHNAME|FNM_PERIOD) == 0)
103                         return j;
104
105         return NULL;
106 }
107
108 static void load_unix_sockets(void) {
109         FILE *f = NULL;
110         char line[LINE_MAX];
111
112         if (unix_sockets)
113                 return;
114
115         /* We maintain a cache of the sockets we found in
116          * /proc/net/unix to speed things up a little. */
117
118         if (!(unix_sockets = set_new(string_hash_func, string_compare_func)))
119                 return;
120
121         if (!(f = fopen("/proc/net/unix", "re")))
122                 return;
123
124         if (!(fgets(line, sizeof(line), f)))
125                 goto fail;
126
127         for (;;) {
128                 char *p, *s;
129                 int k;
130
131                 if (!(fgets(line, sizeof(line), f)))
132                         break;
133
134                 truncate_nl(line);
135
136                 if (strlen(line) < 53)
137                         continue;
138
139                 p = line + 53;
140                 p += strspn(p, WHITESPACE);
141                 p += strcspn(p, WHITESPACE);
142                 p += strspn(p, WHITESPACE);
143
144                 if (*p != '/')
145                         continue;
146
147                 if (!(s = strdup(p)))
148                         goto fail;
149
150                 if ((k = set_put(unix_sockets, s)) < 0) {
151                         free(s);
152
153                         if (k != -EEXIST)
154                                 goto fail;
155                 }
156         }
157
158         return;
159
160 fail:
161         set_free_free(unix_sockets);
162         unix_sockets = NULL;
163
164         if (f)
165                 fclose(f);
166 }
167
168 static bool unix_socket_alive(const char *fn) {
169         assert(fn);
170
171         load_unix_sockets();
172
173         if (unix_sockets)
174                 return !!set_get(unix_sockets, (char*) fn);
175
176         /* We don't know, so assume yes */
177         return true;
178 }
179
180 static int dir_cleanup(
181                 const char *p,
182                 DIR *d,
183                 const struct stat *ds,
184                 usec_t cutoff,
185                 dev_t rootdev,
186                 bool mountpoint,
187                 int maxdepth)
188 {
189         struct dirent *dent;
190         struct timespec times[2];
191         bool deleted = false;
192         char *sub_path = NULL;
193         int r = 0;
194
195         while ((dent = readdir(d))) {
196                 struct stat s;
197                 usec_t age;
198
199                 if (streq(dent->d_name, ".") ||
200                     streq(dent->d_name, ".."))
201                         continue;
202
203                 if (fstatat(dirfd(d), dent->d_name, &s, AT_SYMLINK_NOFOLLOW) < 0) {
204
205                         if (errno != ENOENT) {
206                                 log_error("stat(%s/%s) failed: %m", p, dent->d_name);
207                                 r = -errno;
208                         }
209
210                         continue;
211                 }
212
213                 /* Stay on the same filesystem */
214                 if (s.st_dev != rootdev)
215                         continue;
216
217                 /* Do not delete read-only files owned by root */
218                 if (s.st_uid == 0 && !(s.st_mode & S_IWUSR))
219                         continue;
220
221                 free(sub_path);
222                 sub_path = NULL;
223
224                 if (asprintf(&sub_path, "%s/%s", p, dent->d_name) < 0) {
225                         log_error("Out of memory");
226                         r = -ENOMEM;
227                         goto finish;
228                 }
229
230                 /* Is there an item configured for this path? */
231                 if (hashmap_get(items, sub_path))
232                         continue;
233
234                 if (find_glob(globs, sub_path))
235                         continue;
236
237                 if (S_ISDIR(s.st_mode)) {
238
239                         if (mountpoint &&
240                             streq(dent->d_name, "lost+found") &&
241                             s.st_uid == 0)
242                                 continue;
243
244                         if (maxdepth <= 0)
245                                 log_warning("Reached max depth on %s.", sub_path);
246                         else {
247                                 DIR *sub_dir;
248                                 int q;
249
250                                 sub_dir = xopendirat(dirfd(d), dent->d_name, O_NOFOLLOW);
251                                 if (sub_dir == NULL) {
252                                         if (errno != ENOENT) {
253                                                 log_error("opendir(%s/%s) failed: %m", p, dent->d_name);
254                                                 r = -errno;
255                                         }
256
257                                         continue;
258                                 }
259
260                                 q = dir_cleanup(sub_path, sub_dir, &s, cutoff, rootdev, false, maxdepth-1);
261                                 closedir(sub_dir);
262
263                                 if (q < 0)
264                                         r = q;
265                         }
266
267                         /* Ignore ctime, we change it when deleting */
268                         age = MAX(timespec_load(&s.st_mtim),
269                                   timespec_load(&s.st_atim));
270                         if (age >= cutoff)
271                                 continue;
272
273                         log_debug("rmdir '%s'\n", sub_path);
274
275                         if (unlinkat(dirfd(d), dent->d_name, AT_REMOVEDIR) < 0) {
276                                 if (errno != ENOENT && errno != ENOTEMPTY) {
277                                         log_error("rmdir(%s): %m", sub_path);
278                                         r = -errno;
279                                 }
280                         }
281
282                 } else {
283                         /* Skip files for which the sticky bit is
284                          * set. These are semantics we define, and are
285                          * unknown elsewhere. See XDG_RUNTIME_DIR
286                          * specification for details. */
287                         if (s.st_mode & S_ISVTX)
288                                 continue;
289
290                         if (mountpoint && S_ISREG(s.st_mode)) {
291                                 if (streq(dent->d_name, ".journal") &&
292                                     s.st_uid == 0)
293                                         continue;
294
295                                 if (streq(dent->d_name, "aquota.user") ||
296                                     streq(dent->d_name, "aquota.group"))
297                                         continue;
298                         }
299
300                         /* Ignore sockets that are listed in /proc/net/unix */
301                         if (S_ISSOCK(s.st_mode) && unix_socket_alive(sub_path))
302                                 continue;
303
304                         age = MAX3(timespec_load(&s.st_mtim),
305                                    timespec_load(&s.st_atim),
306                                    timespec_load(&s.st_ctim));
307
308                         if (age >= cutoff)
309                                 continue;
310
311                         log_debug("unlink '%s'\n", sub_path);
312
313                         if (unlinkat(dirfd(d), dent->d_name, 0) < 0) {
314                                 if (errno != ENOENT) {
315                                         log_error("unlink(%s): %m", sub_path);
316                                         r = -errno;
317                                 }
318                         }
319
320                         deleted = true;
321                 }
322         }
323
324 finish:
325         if (deleted) {
326                 /* Restore original directory timestamps */
327                 times[0] = ds->st_atim;
328                 times[1] = ds->st_mtim;
329
330                 if (futimens(dirfd(d), times) < 0)
331                         log_error("utimensat(%s): %m", p);
332         }
333
334         free(sub_path);
335
336         return r;
337 }
338
339 static int clean_item(Item *i) {
340         DIR *d;
341         struct stat s, ps;
342         bool mountpoint;
343         int r;
344         usec_t cutoff, n;
345
346         assert(i);
347
348         if (i->type != CREATE_DIRECTORY &&
349             i->type != TRUNCATE_DIRECTORY &&
350             i->type != IGNORE_PATH)
351                 return 0;
352
353         if (!i->age_set || i->age <= 0)
354                 return 0;
355
356         n = now(CLOCK_REALTIME);
357         if (n < i->age)
358                 return 0;
359
360         cutoff = n - i->age;
361
362         d = opendir(i->path);
363         if (!d) {
364                 if (errno == ENOENT)
365                         return 0;
366
367                 log_error("Failed to open directory %s: %m", i->path);
368                 return -errno;
369         }
370
371         if (fstat(dirfd(d), &s) < 0) {
372                 log_error("stat(%s) failed: %m", i->path);
373                 r = -errno;
374                 goto finish;
375         }
376
377         if (!S_ISDIR(s.st_mode)) {
378                 log_error("%s is not a directory.", i->path);
379                 r = -ENOTDIR;
380                 goto finish;
381         }
382
383         if (fstatat(dirfd(d), "..", &ps, AT_SYMLINK_NOFOLLOW) != 0) {
384                 log_error("stat(%s/..) failed: %m", i->path);
385                 r = -errno;
386                 goto finish;
387         }
388
389         mountpoint = s.st_dev != ps.st_dev ||
390                      (s.st_dev == ps.st_dev && s.st_ino == ps.st_ino);
391
392         r = dir_cleanup(i->path, d, &s, cutoff, s.st_dev, mountpoint, MAX_DEPTH);
393
394 finish:
395         if (d)
396                 closedir(d);
397
398         return r;
399 }
400
401 static int create_item(Item *i) {
402         int fd = -1, r;
403         mode_t u;
404         struct stat st;
405
406         assert(i);
407
408         switch (i->type) {
409
410         case IGNORE_PATH:
411         case REMOVE_PATH:
412         case RECURSIVE_REMOVE_PATH:
413                 return 0;
414
415         case CREATE_FILE:
416         case TRUNCATE_FILE:
417
418                 u = umask(0);
419                 fd = open(i->path, O_CREAT|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY|O_NOFOLLOW|
420                           (i->type == TRUNCATE_FILE ? O_TRUNC : 0), i->mode);
421                 umask(u);
422
423                 if (fd < 0) {
424                         log_error("Failed to create file %s: %m", i->path);
425                         r = -errno;
426                         goto finish;
427                 }
428
429                 if (fstat(fd, &st) < 0) {
430                         log_error("stat(%s) failed: %m", i->path);
431                         r = -errno;
432                         goto finish;
433                 }
434
435                 if (!S_ISREG(st.st_mode)) {
436                         log_error("%s is not a file.", i->path);
437                         r = -EEXIST;
438                         goto finish;
439                 }
440
441                 if (i->mode_set)
442                         if (fchmod(fd, i->mode) < 0) {
443                                 log_error("chmod(%s) failed: %m", i->path);
444                                 r = -errno;
445                                 goto finish;
446                         }
447
448                 if (i->uid_set || i->gid_set)
449                         if (fchown(fd,
450                                    i->uid_set ? i->uid : (uid_t) -1,
451                                    i->gid_set ? i->gid : (gid_t) -1) < 0) {
452                                 log_error("chown(%s) failed: %m", i->path);
453                                 r = -errno;
454                                 goto finish;
455                         }
456
457                 break;
458
459         case TRUNCATE_DIRECTORY:
460         case CREATE_DIRECTORY:
461
462                 u = umask(0);
463                 r = mkdir(i->path, i->mode);
464                 umask(u);
465
466                 if (r < 0 && errno != EEXIST) {
467                         log_error("Failed to create directory %s: %m", i->path);
468                         r = -errno;
469                         goto finish;
470                 }
471
472                 if (stat(i->path, &st) < 0) {
473                         log_error("stat(%s) failed: %m", i->path);
474                         r = -errno;
475                         goto finish;
476                 }
477
478                 if (!S_ISDIR(st.st_mode)) {
479                         log_error("%s is not a directory.", i->path);
480                         r = -EEXIST;
481                         goto finish;
482                 }
483
484                 if (i->mode_set)
485                         if (chmod(i->path, i->mode) < 0) {
486                                 log_error("chmod(%s) failed: %m", i->path);
487                                 r = -errno;
488                                 goto finish;
489                         }
490
491                 if (i->uid_set || i->gid_set)
492                         if (chown(i->path,
493                                   i->uid_set ? i->uid : (uid_t) -1,
494                                   i->gid_set ? i->gid : (gid_t) -1) < 0) {
495
496                                 log_error("chown(%s) failed: %m", i->path);
497                                 r = -errno;
498                                 goto finish;
499                         }
500
501                 break;
502         }
503
504         if ((r = label_fix(i->path)) < 0)
505                 goto finish;
506
507         log_debug("%s created successfully.", i->path);
508
509 finish:
510         if (fd >= 0)
511                 close_nointr_nofail(fd);
512
513         return r;
514 }
515
516 static int remove_item(Item *i, const char *instance) {
517         int r;
518
519         assert(i);
520
521         switch (i->type) {
522
523         case CREATE_FILE:
524         case TRUNCATE_FILE:
525         case CREATE_DIRECTORY:
526         case IGNORE_PATH:
527                 break;
528
529         case REMOVE_PATH:
530                 if (remove(instance) < 0 && errno != ENOENT) {
531                         log_error("remove(%s): %m", instance);
532                         return -errno;
533                 }
534
535                 break;
536
537         case TRUNCATE_DIRECTORY:
538         case RECURSIVE_REMOVE_PATH:
539                 if ((r = rm_rf(instance, false, i->type == RECURSIVE_REMOVE_PATH)) < 0 &&
540                     r != -ENOENT) {
541                         log_error("rm_rf(%s): %s", instance, strerror(-r));
542                         return r;
543                 }
544
545                 break;
546         }
547
548         return 0;
549 }
550
551 static int remove_item_glob(Item *i) {
552         assert(i);
553
554         switch (i->type) {
555
556         case CREATE_FILE:
557         case TRUNCATE_FILE:
558         case CREATE_DIRECTORY:
559         case IGNORE_PATH:
560                 break;
561
562         case REMOVE_PATH:
563         case TRUNCATE_DIRECTORY:
564         case RECURSIVE_REMOVE_PATH: {
565                 int r = 0, k;
566                 glob_t g;
567                 char **fn;
568
569                 zero(g);
570
571                 errno = 0;
572                 if ((k = glob(i->path, GLOB_NOSORT|GLOB_BRACE, NULL, &g)) != 0) {
573
574                         if (k != GLOB_NOMATCH) {
575                                 if (errno != 0)
576                                         errno = EIO;
577
578                                 log_error("glob(%s) failed: %m", i->path);
579                                 return -errno;
580                         }
581                 }
582
583                 STRV_FOREACH(fn, g.gl_pathv)
584                         if ((k = remove_item(i, *fn)) < 0)
585                                 r = k;
586
587                 globfree(&g);
588                 return r;
589         }
590         }
591
592         return 0;
593 }
594
595 static int process_item(Item *i) {
596         int r, q, p;
597
598         assert(i);
599
600         r = arg_create ? create_item(i) : 0;
601         q = arg_remove ? remove_item_glob(i) : 0;
602         p = arg_clean ? clean_item(i) : 0;
603
604         if (r < 0)
605                 return r;
606
607         if (q < 0)
608                 return q;
609
610         return p;
611 }
612
613 static void item_free(Item *i) {
614         assert(i);
615
616         free(i->path);
617         free(i);
618 }
619
620 static int parse_line(const char *fname, unsigned line, const char *buffer) {
621         Item *i;
622         char *mode = NULL, *user = NULL, *group = NULL, *age = NULL;
623         int r;
624
625         assert(fname);
626         assert(line >= 1);
627         assert(buffer);
628
629         if (!(i = new0(Item, 1))) {
630                 log_error("Out of memory");
631                 return -ENOMEM;
632         }
633
634         if (sscanf(buffer,
635                    "%c "
636                    "%ms "
637                    "%ms "
638                    "%ms "
639                    "%ms "
640                    "%ms",
641                    &i->type,
642                    &i->path,
643                    &mode,
644                    &user,
645                    &group,
646                    &age) < 2) {
647                 log_error("[%s:%u] Syntax error.", fname, line);
648                 r = -EIO;
649                 goto finish;
650         }
651
652         if (i->type != CREATE_FILE &&
653             i->type != TRUNCATE_FILE &&
654             i->type != CREATE_DIRECTORY &&
655             i->type != TRUNCATE_DIRECTORY &&
656             i->type != IGNORE_PATH &&
657             i->type != REMOVE_PATH &&
658             i->type != RECURSIVE_REMOVE_PATH) {
659                 log_error("[%s:%u] Unknown file type '%c'.", fname, line, i->type);
660                 r = -EBADMSG;
661                 goto finish;
662         }
663
664         if (!path_is_absolute(i->path)) {
665                 log_error("[%s:%u] Path '%s' not absolute.", fname, line, i->path);
666                 r = -EBADMSG;
667                 goto finish;
668         }
669
670         path_kill_slashes(i->path);
671
672         if (arg_prefix && !path_startswith(i->path, arg_prefix)) {
673                 r = 0;
674                 goto finish;
675         }
676
677         if (user && !streq(user, "-")) {
678                 unsigned long lu;
679                 struct passwd *p;
680
681                 if (streq(user, "root") || streq(user, "0"))
682                         i->uid = 0;
683                 else if (safe_atolu(user, &lu) >= 0)
684                         i->uid = (uid_t) lu;
685                 else if ((p = getpwnam(user)))
686                         i->uid = p->pw_uid;
687                 else {
688                         log_error("[%s:%u] Unknown user '%s'.", fname, line, user);
689                         r = -ENOENT;
690                         goto finish;
691                 }
692
693                 i->uid_set = true;
694         }
695
696         if (group && !streq(group, "-")) {
697                 unsigned long lu;
698                 struct group *g;
699
700                 if (streq(group, "root") || streq(group, "0"))
701                         i->gid = 0;
702                 else if (safe_atolu(group, &lu) >= 0)
703                         i->gid = (gid_t) lu;
704                 else if ((g = getgrnam(group)))
705                         i->gid = g->gr_gid;
706                 else {
707                         log_error("[%s:%u] Unknown group '%s'.", fname, line, group);
708                         r = -ENOENT;
709                         goto finish;
710                 }
711
712                 i->gid_set = true;
713         }
714
715         if (mode && !streq(mode, "-")) {
716                 unsigned m;
717
718                 if (sscanf(mode, "%o", &m) != 1) {
719                         log_error("[%s:%u] Invalid mode '%s'.", fname, line, mode);
720                         r = -ENOENT;
721                         goto finish;
722                 }
723
724                 i->mode = m;
725                 i->mode_set = true;
726         } else
727                 i->mode = i->type == CREATE_DIRECTORY ? 0755 : 0644;
728
729         if (age && !streq(age, "-")) {
730                 if (parse_usec(age, &i->age) < 0) {
731                         log_error("[%s:%u] Invalid age '%s'.", fname, line, age);
732                         r = -EBADMSG;
733                         goto finish;
734                 }
735
736                 i->age_set = true;
737         }
738
739         if ((r = hashmap_put(needs_glob(i->type) ? globs : items, i->path, i)) < 0) {
740                 if (r == -EEXIST) {
741                         log_warning("Two or more conflicting lines for %s configured, ignoring.", i->path);
742                         r = 0;
743                         goto finish;
744                 }
745
746                 log_error("Failed to insert item %s: %s", i->path, strerror(-r));
747                 goto finish;
748         }
749
750         i = NULL;
751         r = 0;
752
753 finish:
754         free(user);
755         free(group);
756         free(mode);
757         free(age);
758
759         if (i)
760                 item_free(i);
761
762         return r;
763 }
764
765 static int scandir_filter(const struct dirent *d) {
766         assert(d);
767
768         if (ignore_file(d->d_name))
769                 return 0;
770
771         if (d->d_type != DT_REG &&
772             d->d_type != DT_LNK)
773                 return 0;
774
775         return endswith(d->d_name, ".conf");
776 }
777
778 static int help(void) {
779
780         printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
781                "Creates, deletes and cleans up volatile and temporary files and directories.\n\n"
782                "  -h --help             Show this help\n"
783                "     --create           Create marked files/directories\n"
784                "     --clean            Clean up marked directories\n"
785                "     --remove           Remove marked files/directories\n"
786                "     --prefix=PATH      Only apply rules that apply to paths with the specified prefix\n",
787                program_invocation_short_name);
788
789         return 0;
790 }
791
792 static int parse_argv(int argc, char *argv[]) {
793
794         enum {
795                 ARG_CREATE,
796                 ARG_CLEAN,
797                 ARG_REMOVE,
798                 ARG_PREFIX
799         };
800
801         static const struct option options[] = {
802                 { "help",      no_argument,       NULL, 'h'           },
803                 { "create",    no_argument,       NULL, ARG_CREATE    },
804                 { "clean",     no_argument,       NULL, ARG_CLEAN     },
805                 { "remove",    no_argument,       NULL, ARG_REMOVE    },
806                 { "prefix",    required_argument, NULL, ARG_PREFIX    },
807                 { NULL,        0,                 NULL, 0             }
808         };
809
810         int c;
811
812         assert(argc >= 0);
813         assert(argv);
814
815         while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
816
817                 switch (c) {
818
819                 case 'h':
820                         help();
821                         return 0;
822
823                 case ARG_CREATE:
824                         arg_create = true;
825                         break;
826
827                 case ARG_CLEAN:
828                         arg_clean = true;
829                         break;
830
831                 case ARG_REMOVE:
832                         arg_remove = true;
833                         break;
834
835                 case ARG_PREFIX:
836                         arg_prefix = optarg;
837                         break;
838
839                 case '?':
840                         return -EINVAL;
841
842                 default:
843                         log_error("Unknown option code %c", c);
844                         return -EINVAL;
845                 }
846         }
847
848         if (!arg_clean && !arg_create && !arg_remove) {
849                 log_error("You need to specify at leat one of --clean, --create or --remove.");
850                 return -EINVAL;
851         }
852
853         return 1;
854 }
855
856 static int read_config_file(const char *fn, bool ignore_enoent) {
857         FILE *f;
858         unsigned v = 0;
859         int r = 0;
860
861         assert(fn);
862
863         if (!(f = fopen(fn, "re"))) {
864
865                 if (ignore_enoent && errno == ENOENT)
866                         return 0;
867
868                 log_error("Failed to open %s: %m", fn);
869                 return -errno;
870         }
871
872         for (;;) {
873                 char line[LINE_MAX], *l;
874                 int k;
875
876                 if (!(fgets(line, sizeof(line), f)))
877                         break;
878
879                 v++;
880
881                 l = strstrip(line);
882                 if (*l == '#' || *l == 0)
883                         continue;
884
885                 if ((k = parse_line(fn, v, l)) < 0)
886                         if (r == 0)
887                                 r = k;
888         }
889
890         if (ferror(f)) {
891                 log_error("Failed to read from file %s: %m", fn);
892                 if (r == 0)
893                         r = -EIO;
894         }
895
896         fclose(f);
897
898         return r;
899 }
900
901 int main(int argc, char *argv[]) {
902         int r;
903         Item *i;
904         Iterator iterator;
905
906         if ((r = parse_argv(argc, argv)) <= 0)
907                 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
908
909         log_set_target(LOG_TARGET_AUTO);
910         log_parse_environment();
911         log_open();
912
913         label_init();
914
915         items = hashmap_new(string_hash_func, string_compare_func);
916         globs = hashmap_new(string_hash_func, string_compare_func);
917
918         if (!items || !globs) {
919                 log_error("Out of memory");
920                 r = EXIT_FAILURE;
921                 goto finish;
922         }
923
924         r = EXIT_SUCCESS;
925
926         if (optind < argc) {
927                 int j;
928
929                 for (j = optind; j < argc; j++)
930                         if (read_config_file(argv[j], false) < 0)
931                                 r = EXIT_FAILURE;
932
933         } else {
934                 int n, j;
935                 struct dirent **de = NULL;
936
937                 if ((n = scandir("/etc/tmpfiles.d/", &de, scandir_filter, alphasort)) < 0) {
938
939                         if (errno != ENOENT) {
940                                 log_error("Failed to enumerate /etc/tmpfiles.d/ files: %m");
941                                 r = EXIT_FAILURE;
942                         }
943
944                         goto finish;
945                 }
946
947                 for (j = 0; j < n; j++) {
948                         int k;
949                         char *fn;
950
951                         k = asprintf(&fn, "/etc/tmpfiles.d/%s", de[j]->d_name);
952                         free(de[j]);
953
954                         if (k < 0) {
955                                 log_error("Failed to allocate file name.");
956                                 r = EXIT_FAILURE;
957                                 continue;
958                         }
959
960                         if (read_config_file(fn, true) < 0)
961                                 r = EXIT_FAILURE;
962
963                         free(fn);
964                 }
965
966                 free(de);
967         }
968
969         HASHMAP_FOREACH(i, globs, iterator)
970                 if (process_item(i) < 0)
971                         r = EXIT_FAILURE;
972
973         HASHMAP_FOREACH(i, items, iterator)
974                 if (process_item(i) < 0)
975                         r = EXIT_FAILURE;
976
977 finish:
978         while ((i = hashmap_steal_first(items)))
979                 item_free(i);
980
981         while ((i = hashmap_steal_first(globs)))
982                 item_free(i);
983
984         hashmap_free(items);
985         hashmap_free(globs);
986
987         set_free_free(unix_sockets);
988
989         label_finish();
990
991         return r;
992 }