chiark / gitweb /
systemctl: fail in the case that no unit files were found
[elogind.git] / src / shared / install.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2011 Lennart Poettering
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 <errno.h>
23 #include <fcntl.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <fnmatch.h>
27
28 #include "util.h"
29 #include "mkdir.h"
30 #include "hashmap.h"
31 #include "set.h"
32 #include "path-util.h"
33 #include "path-lookup.h"
34 #include "strv.h"
35 #include "unit-name.h"
36 #include "install.h"
37 #include "conf-parser.h"
38 #include "conf-files.h"
39 #include "specifier.h"
40 #include "install-printf.h"
41 #include "special.h"
42
43 typedef struct {
44         Hashmap *will_install;
45         Hashmap *have_installed;
46 } InstallContext;
47
48 #define _cleanup_install_context_done_ _cleanup_(install_context_done)
49
50 static int in_search_path(const char *path, char **search) {
51         _cleanup_free_ char *parent = NULL;
52         int r;
53
54         assert(path);
55
56         r = path_get_parent(path, &parent);
57         if (r < 0)
58                 return r;
59
60         return strv_contains(search, parent);
61 }
62
63 static int lookup_paths_init_from_scope(LookupPaths *paths,
64                                         UnitFileScope scope,
65                                         const char *root_dir) {
66         assert(paths);
67         assert(scope >= 0);
68         assert(scope < _UNIT_FILE_SCOPE_MAX);
69
70         zero(*paths);
71
72         return lookup_paths_init(paths,
73                                  scope == UNIT_FILE_SYSTEM ? SYSTEMD_SYSTEM : SYSTEMD_USER,
74                                  scope == UNIT_FILE_USER,
75                                  root_dir,
76                                  NULL, NULL, NULL);
77 }
78
79 static int get_config_path(UnitFileScope scope, bool runtime, const char *root_dir, char **ret) {
80         char *p = NULL;
81         int r;
82
83         assert(scope >= 0);
84         assert(scope < _UNIT_FILE_SCOPE_MAX);
85         assert(ret);
86
87         switch (scope) {
88
89         case UNIT_FILE_SYSTEM:
90
91                 if (runtime)
92                         p = path_join(root_dir, "/run/systemd/system", NULL);
93                 else
94                         p = path_join(root_dir, SYSTEM_CONFIG_UNIT_PATH, NULL);
95                 break;
96
97         case UNIT_FILE_GLOBAL:
98
99                 if (root_dir)
100                         return -EINVAL;
101
102                 if (runtime)
103                         p = strdup("/run/systemd/user");
104                 else
105                         p = strdup(USER_CONFIG_UNIT_PATH);
106                 break;
107
108         case UNIT_FILE_USER:
109
110                 if (root_dir || runtime)
111                         return -EINVAL;
112
113                 r = user_config_home(&p);
114                 if (r <= 0)
115                         return r < 0 ? r : -ENOENT;
116
117                 break;
118
119         default:
120                 assert_not_reached("Bad scope");
121         }
122
123         if (!p)
124                 return -ENOMEM;
125
126         *ret = p;
127         return 0;
128 }
129
130 static int add_file_change(
131                 UnitFileChange **changes,
132                 unsigned *n_changes,
133                 UnitFileChangeType type,
134                 const char *path,
135                 const char *source) {
136
137         UnitFileChange *c;
138         unsigned i;
139
140         assert(path);
141         assert(!changes == !n_changes);
142
143         if (!changes)
144                 return 0;
145
146         c = realloc(*changes, (*n_changes + 1) * sizeof(UnitFileChange));
147         if (!c)
148                 return -ENOMEM;
149
150         *changes = c;
151         i = *n_changes;
152
153         c[i].type = type;
154         c[i].path = strdup(path);
155         if (!c[i].path)
156                 return -ENOMEM;
157
158         path_kill_slashes(c[i].path);
159
160         if (source) {
161                 c[i].source = strdup(source);
162                 if (!c[i].source) {
163                         free(c[i].path);
164                         return -ENOMEM;
165                 }
166
167                 path_kill_slashes(c[i].path);
168         } else
169                 c[i].source = NULL;
170
171         *n_changes = i+1;
172         return 0;
173 }
174
175 static int mark_symlink_for_removal(
176                 Set **remove_symlinks_to,
177                 const char *p) {
178
179         char *n;
180         int r;
181
182         assert(p);
183
184         r = set_ensure_allocated(remove_symlinks_to, string_hash_func, string_compare_func);
185         if (r < 0)
186                 return r;
187
188         n = strdup(p);
189         if (!n)
190                 return -ENOMEM;
191
192         path_kill_slashes(n);
193
194         r = set_consume(*remove_symlinks_to, n);
195         if (r < 0)
196                 return r == -EEXIST ? 0 : r;
197
198         return 0;
199 }
200
201 static int remove_marked_symlinks_fd(
202                 Set *remove_symlinks_to,
203                 int fd,
204                 const char *path,
205                 const char *config_path,
206                 bool *deleted,
207                 UnitFileChange **changes,
208                 unsigned *n_changes,
209                 char** instance_whitelist) {
210
211         _cleanup_closedir_ DIR *d = NULL;
212         int r = 0;
213
214         assert(remove_symlinks_to);
215         assert(fd >= 0);
216         assert(path);
217         assert(config_path);
218         assert(deleted);
219
220         d = fdopendir(fd);
221         if (!d) {
222                 safe_close(fd);
223                 return -errno;
224         }
225
226         rewinddir(d);
227
228         for (;;) {
229                 struct dirent *de;
230
231                 errno = 0;
232                 de = readdir(d);
233                 if (!de && errno != 0) {
234                         r = -errno;
235                         break;
236                 }
237
238                 if (!de)
239                         break;
240
241                 if (ignore_file(de->d_name))
242                         continue;
243
244                 dirent_ensure_type(d, de);
245
246                 if (de->d_type == DT_DIR) {
247                         int nfd, q;
248                         _cleanup_free_ char *p = NULL;
249
250                         nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
251                         if (nfd < 0) {
252                                 if (errno == ENOENT)
253                                         continue;
254
255                                 if (r == 0)
256                                         r = -errno;
257                                 continue;
258                         }
259
260                         p = path_make_absolute(de->d_name, path);
261                         if (!p) {
262                                 safe_close(nfd);
263                                 return -ENOMEM;
264                         }
265
266                         /* This will close nfd, regardless whether it succeeds or not */
267                         q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, deleted, changes, n_changes, instance_whitelist);
268                         if (q < 0 && r == 0)
269                                 r = q;
270
271                 } else if (de->d_type == DT_LNK) {
272                         _cleanup_free_ char *p = NULL, *dest = NULL;
273                         int q;
274                         bool found;
275
276                         if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
277                                 continue;
278
279                         if (unit_name_is_instance(de->d_name) &&
280                             instance_whitelist &&
281                             !strv_contains(instance_whitelist, de->d_name)) {
282
283                                 _cleanup_free_ char *w;
284
285                                 /* OK, the file is not listed directly
286                                  * in the whitelist, so let's check if
287                                  * the template of it might be
288                                  * listed. */
289
290                                 w = unit_name_template(de->d_name);
291                                 if (!w)
292                                         return -ENOMEM;
293
294                                 if (!strv_contains(instance_whitelist, w))
295                                         continue;
296                         }
297
298                         p = path_make_absolute(de->d_name, path);
299                         if (!p)
300                                 return -ENOMEM;
301
302                         q = readlink_and_canonicalize(p, &dest);
303                         if (q < 0) {
304                                 if (q == -ENOENT)
305                                         continue;
306
307                                 if (r == 0)
308                                         r = q;
309                                 continue;
310                         }
311
312                         found =
313                                 set_get(remove_symlinks_to, dest) ||
314                                 set_get(remove_symlinks_to, basename(dest));
315
316                         if (!found)
317                                 continue;
318
319                         if (unlink(p) < 0 && errno != ENOENT) {
320                                 if (r == 0)
321                                         r = -errno;
322                                 continue;
323                         }
324
325                         path_kill_slashes(p);
326                         rmdir_parents(p, config_path);
327                         add_file_change(changes, n_changes, UNIT_FILE_UNLINK, p, NULL);
328
329                         if (!set_get(remove_symlinks_to, p)) {
330
331                                 q = mark_symlink_for_removal(&remove_symlinks_to, p);
332                                 if (q < 0) {
333                                         if (r == 0)
334                                                 r = q;
335                                 } else
336                                         *deleted = true;
337                         }
338                 }
339         }
340
341         return r;
342 }
343
344 static int remove_marked_symlinks(
345                 Set *remove_symlinks_to,
346                 const char *config_path,
347                 UnitFileChange **changes,
348                 unsigned *n_changes,
349                 char** instance_whitelist) {
350
351         _cleanup_close_ int fd = -1;
352         int r = 0;
353         bool deleted;
354
355         assert(config_path);
356
357         if (set_size(remove_symlinks_to) <= 0)
358                 return 0;
359
360         fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
361         if (fd < 0)
362                 return -errno;
363
364         do {
365                 int q, cfd;
366                 deleted = false;
367
368                 cfd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
369                 if (cfd < 0) {
370                         r = -errno;
371                         break;
372                 }
373
374                 /* This takes possession of cfd and closes it */
375                 q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, &deleted, changes, n_changes, instance_whitelist);
376                 if (r == 0)
377                         r = q;
378         } while (deleted);
379
380         return r;
381 }
382
383 static int find_symlinks_fd(
384                 const char *name,
385                 int fd,
386                 const char *path,
387                 const char *config_path,
388                 bool *same_name_link) {
389
390         int r = 0;
391         _cleanup_closedir_ DIR *d = NULL;
392
393         assert(name);
394         assert(fd >= 0);
395         assert(path);
396         assert(config_path);
397         assert(same_name_link);
398
399         d = fdopendir(fd);
400         if (!d) {
401                 safe_close(fd);
402                 return -errno;
403         }
404
405         for (;;) {
406                 struct dirent *de;
407
408                 errno = 0;
409                 de = readdir(d);
410                 if (!de && errno != 0)
411                         return -errno;
412
413                 if (!de)
414                         return r;
415
416                 if (ignore_file(de->d_name))
417                         continue;
418
419                 dirent_ensure_type(d, de);
420
421                 if (de->d_type == DT_DIR) {
422                         int nfd, q;
423                         _cleanup_free_ char *p = NULL;
424
425                         nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
426                         if (nfd < 0) {
427                                 if (errno == ENOENT)
428                                         continue;
429
430                                 if (r == 0)
431                                         r = -errno;
432                                 continue;
433                         }
434
435                         p = path_make_absolute(de->d_name, path);
436                         if (!p) {
437                                 safe_close(nfd);
438                                 return -ENOMEM;
439                         }
440
441                         /* This will close nfd, regardless whether it succeeds or not */
442                         q = find_symlinks_fd(name, nfd, p, config_path, same_name_link);
443                         if (q > 0)
444                                 return 1;
445                         if (r == 0)
446                                 r = q;
447
448                 } else if (de->d_type == DT_LNK) {
449                         _cleanup_free_ char *p = NULL, *dest = NULL;
450                         bool found_path, found_dest, b = false;
451                         int q;
452
453                         /* Acquire symlink name */
454                         p = path_make_absolute(de->d_name, path);
455                         if (!p)
456                                 return -ENOMEM;
457
458                         /* Acquire symlink destination */
459                         q = readlink_and_canonicalize(p, &dest);
460                         if (q < 0) {
461                                 if (q == -ENOENT)
462                                         continue;
463
464                                 if (r == 0)
465                                         r = q;
466                                 continue;
467                         }
468
469                         /* Check if the symlink itself matches what we
470                          * are looking for */
471                         if (path_is_absolute(name))
472                                 found_path = path_equal(p, name);
473                         else
474                                 found_path = streq(de->d_name, name);
475
476                         /* Check if what the symlink points to
477                          * matches what we are looking for */
478                         if (path_is_absolute(name))
479                                 found_dest = path_equal(dest, name);
480                         else
481                                 found_dest = streq(basename(dest), name);
482
483                         if (found_path && found_dest) {
484                                 _cleanup_free_ char *t = NULL;
485
486                                 /* Filter out same name links in the main
487                                  * config path */
488                                 t = path_make_absolute(name, config_path);
489                                 if (!t)
490                                         return -ENOMEM;
491
492                                 b = path_equal(t, p);
493                         }
494
495                         if (b)
496                                 *same_name_link = true;
497                         else if (found_path || found_dest)
498                                 return 1;
499                 }
500         }
501 }
502
503 static int find_symlinks(
504                 const char *name,
505                 const char *config_path,
506                 bool *same_name_link) {
507
508         int fd;
509
510         assert(name);
511         assert(config_path);
512         assert(same_name_link);
513
514         fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
515         if (fd < 0) {
516                 if (errno == ENOENT)
517                         return 0;
518                 return -errno;
519         }
520
521         /* This takes possession of fd and closes it */
522         return find_symlinks_fd(name, fd, config_path, config_path, same_name_link);
523 }
524
525 static int find_symlinks_in_scope(
526                 UnitFileScope scope,
527                 const char *root_dir,
528                 const char *name,
529                 UnitFileState *state) {
530
531         int r;
532         _cleanup_free_ char *path2 = NULL;
533         bool same_name_link_runtime = false, same_name_link = false;
534
535         assert(scope >= 0);
536         assert(scope < _UNIT_FILE_SCOPE_MAX);
537         assert(name);
538
539         if (scope == UNIT_FILE_SYSTEM || scope == UNIT_FILE_GLOBAL) {
540                 _cleanup_free_ char *path = NULL;
541
542                 /* First look in runtime config path */
543                 r = get_config_path(scope, true, root_dir, &path);
544                 if (r < 0)
545                         return r;
546
547                 r = find_symlinks(name, path, &same_name_link_runtime);
548                 if (r < 0)
549                         return r;
550                 else if (r > 0) {
551                         *state = UNIT_FILE_ENABLED_RUNTIME;
552                         return r;
553                 }
554         }
555
556         /* Then look in the normal config path */
557         r = get_config_path(scope, false, root_dir, &path2);
558         if (r < 0)
559                 return r;
560
561         r = find_symlinks(name, path2, &same_name_link);
562         if (r < 0)
563                 return r;
564         else if (r > 0) {
565                 *state = UNIT_FILE_ENABLED;
566                 return r;
567         }
568
569         /* Hmm, we didn't find it, but maybe we found the same name
570          * link? */
571         if (same_name_link_runtime) {
572                 *state = UNIT_FILE_LINKED_RUNTIME;
573                 return 1;
574         } else if (same_name_link) {
575                 *state = UNIT_FILE_LINKED;
576                 return 1;
577         }
578
579         return 0;
580 }
581
582 int unit_file_mask(
583                 UnitFileScope scope,
584                 bool runtime,
585                 const char *root_dir,
586                 char **files,
587                 bool force,
588                 UnitFileChange **changes,
589                 unsigned *n_changes) {
590
591         char **i;
592         _cleanup_free_ char *prefix = NULL;
593         int r;
594
595         assert(scope >= 0);
596         assert(scope < _UNIT_FILE_SCOPE_MAX);
597
598         r = get_config_path(scope, runtime, root_dir, &prefix);
599         if (r < 0)
600                 return r;
601
602         STRV_FOREACH(i, files) {
603                 _cleanup_free_ char *path = NULL;
604
605                 if (!unit_name_is_valid(*i, TEMPLATE_VALID)) {
606                         if (r == 0)
607                                 r = -EINVAL;
608                         continue;
609                 }
610
611                 path = path_make_absolute(*i, prefix);
612                 if (!path) {
613                         r = -ENOMEM;
614                         break;
615                 }
616
617                 if (symlink("/dev/null", path) >= 0) {
618                         add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null");
619                         continue;
620                 }
621
622                 if (errno == EEXIST) {
623
624                         if (null_or_empty_path(path) > 0)
625                                 continue;
626
627                         if (force) {
628                                 if (symlink_atomic("/dev/null", path) >= 0) {
629                                         add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
630                                         add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null");
631                                         continue;
632                                 }
633                         }
634
635                         if (r == 0)
636                                 r = -EEXIST;
637                 } else {
638                         if (r == 0)
639                                 r = -errno;
640                 }
641         }
642
643         return r;
644 }
645
646 int unit_file_unmask(
647                 UnitFileScope scope,
648                 bool runtime,
649                 const char *root_dir,
650                 char **files,
651                 UnitFileChange **changes,
652                 unsigned *n_changes) {
653
654         char **i, *config_path = NULL;
655         int r, q;
656         Set *remove_symlinks_to = NULL;
657
658         assert(scope >= 0);
659         assert(scope < _UNIT_FILE_SCOPE_MAX);
660
661         r = get_config_path(scope, runtime, root_dir, &config_path);
662         if (r < 0)
663                 goto finish;
664
665         STRV_FOREACH(i, files) {
666                 char *path;
667
668                 if (!unit_name_is_valid(*i, TEMPLATE_VALID)) {
669                         if (r == 0)
670                                 r = -EINVAL;
671                         continue;
672                 }
673
674                 path = path_make_absolute(*i, config_path);
675                 if (!path) {
676                         r = -ENOMEM;
677                         break;
678                 }
679
680                 q = null_or_empty_path(path);
681                 if (q > 0) {
682                         if (unlink(path) >= 0) {
683                                 mark_symlink_for_removal(&remove_symlinks_to, path);
684                                 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
685
686                                 free(path);
687                                 continue;
688                         }
689
690                         q = -errno;
691                 }
692
693                 if (q != -ENOENT && r == 0)
694                         r = q;
695
696                 free(path);
697         }
698
699
700 finish:
701         q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
702         if (r == 0)
703                 r = q;
704
705         set_free_free(remove_symlinks_to);
706         free(config_path);
707
708         return r;
709 }
710
711 int unit_file_link(
712                 UnitFileScope scope,
713                 bool runtime,
714                 const char *root_dir,
715                 char **files,
716                 bool force,
717                 UnitFileChange **changes,
718                 unsigned *n_changes) {
719
720         _cleanup_lookup_paths_free_ LookupPaths paths = {};
721         char **i;
722         _cleanup_free_ char *config_path = NULL;
723         int r, q;
724
725         assert(scope >= 0);
726         assert(scope < _UNIT_FILE_SCOPE_MAX);
727
728         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
729         if (r < 0)
730                 return r;
731
732         r = get_config_path(scope, runtime, root_dir, &config_path);
733         if (r < 0)
734                 return r;
735
736         STRV_FOREACH(i, files) {
737                 _cleanup_free_ char *path = NULL;
738                 char *fn;
739                 struct stat st;
740
741                 fn = basename(*i);
742
743                 if (!path_is_absolute(*i) ||
744                     !unit_name_is_valid(fn, TEMPLATE_VALID)) {
745                         if (r == 0)
746                                 r = -EINVAL;
747                         continue;
748                 }
749
750                 if (lstat(*i, &st) < 0) {
751                         if (r == 0)
752                                 r = -errno;
753                         continue;
754                 }
755
756                 if (!S_ISREG(st.st_mode)) {
757                         r = -ENOENT;
758                         continue;
759                 }
760
761                 q = in_search_path(*i, paths.unit_path);
762                 if (q < 0)
763                         return q;
764
765                 if (q > 0)
766                         continue;
767
768                 path = path_make_absolute(fn, config_path);
769                 if (!path)
770                         return -ENOMEM;
771
772                 if (symlink(*i, path) >= 0) {
773                         add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, *i);
774                         continue;
775                 }
776
777                 if (errno == EEXIST) {
778                         _cleanup_free_ char *dest = NULL;
779
780                         q = readlink_and_make_absolute(path, &dest);
781                         if (q < 0 && errno != ENOENT) {
782                                 if (r == 0)
783                                         r = q;
784                                 continue;
785                         }
786
787                         if (q >= 0 && path_equal(dest, *i))
788                                 continue;
789
790                         if (force) {
791                                 if (symlink_atomic(*i, path) >= 0) {
792                                         add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
793                                         add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, *i);
794                                         continue;
795                                 }
796                         }
797
798                         if (r == 0)
799                                 r = -EEXIST;
800                 } else {
801                         if (r == 0)
802                                 r = -errno;
803                 }
804         }
805
806         return r;
807 }
808
809 void unit_file_list_free(Hashmap *h) {
810         UnitFileList *i;
811
812         while ((i = hashmap_steal_first(h))) {
813                 free(i->path);
814                 free(i);
815         }
816
817         hashmap_free(h);
818 }
819
820 void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes) {
821         unsigned i;
822
823         assert(changes || n_changes == 0);
824
825         if (!changes)
826                 return;
827
828         for (i = 0; i < n_changes; i++) {
829                 free(changes[i].path);
830                 free(changes[i].source);
831         }
832
833         free(changes);
834 }
835
836 static void install_info_free(InstallInfo *i) {
837         assert(i);
838
839         free(i->name);
840         free(i->path);
841         strv_free(i->aliases);
842         strv_free(i->wanted_by);
843         strv_free(i->required_by);
844         free(i->default_instance);
845         free(i);
846 }
847
848 static void install_info_hashmap_free(Hashmap *m) {
849         InstallInfo *i;
850
851         if (!m)
852                 return;
853
854         while ((i = hashmap_steal_first(m)))
855                 install_info_free(i);
856
857         hashmap_free(m);
858 }
859
860 static void install_context_done(InstallContext *c) {
861         assert(c);
862
863         install_info_hashmap_free(c->will_install);
864         install_info_hashmap_free(c->have_installed);
865
866         c->will_install = c->have_installed = NULL;
867 }
868
869 static int install_info_add(
870                 InstallContext *c,
871                 const char *name,
872                 const char *path) {
873         InstallInfo *i = NULL;
874         int r;
875
876         assert(c);
877         assert(name || path);
878
879         if (!name)
880                 name = basename(path);
881
882         if (!unit_name_is_valid(name, TEMPLATE_VALID))
883                 return -EINVAL;
884
885         if (hashmap_get(c->have_installed, name) ||
886             hashmap_get(c->will_install, name))
887                 return 0;
888
889         r = hashmap_ensure_allocated(&c->will_install, string_hash_func, string_compare_func);
890         if (r < 0)
891                 return r;
892
893         i = new0(InstallInfo, 1);
894         if (!i)
895                 return -ENOMEM;
896
897         i->name = strdup(name);
898         if (!i->name) {
899                 r = -ENOMEM;
900                 goto fail;
901         }
902
903         if (path) {
904                 i->path = strdup(path);
905                 if (!i->path) {
906                         r = -ENOMEM;
907                         goto fail;
908                 }
909         }
910
911         r = hashmap_put(c->will_install, i->name, i);
912         if (r < 0)
913                 goto fail;
914
915         return 0;
916
917 fail:
918         if (i)
919                 install_info_free(i);
920
921         return r;
922 }
923
924 static int install_info_add_auto(
925                 InstallContext *c,
926                 const char *name_or_path) {
927
928         assert(c);
929         assert(name_or_path);
930
931         if (path_is_absolute(name_or_path))
932                 return install_info_add(c, NULL, name_or_path);
933         else
934                 return install_info_add(c, name_or_path, NULL);
935 }
936
937 static int config_parse_also(
938                 const char *unit,
939                 const char *filename,
940                 unsigned line,
941                 const char *section,
942                 unsigned section_line,
943                 const char *lvalue,
944                 int ltype,
945                 const char *rvalue,
946                 void *data,
947                 void *userdata) {
948
949         size_t l;
950         const char *word, *state;
951         InstallContext *c = data;
952
953         assert(filename);
954         assert(lvalue);
955         assert(rvalue);
956
957         FOREACH_WORD_QUOTED(word, l, rvalue, state) {
958                 _cleanup_free_ char *n;
959                 int r;
960
961                 n = strndup(word, l);
962                 if (!n)
963                         return -ENOMEM;
964
965                 r = install_info_add(c, n, NULL);
966                 if (r < 0)
967                         return r;
968         }
969         if (!isempty(state))
970                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
971                            "Trailing garbage, ignoring.");
972
973         return 0;
974 }
975
976 static int config_parse_user(
977                 const char *unit,
978                 const char *filename,
979                 unsigned line,
980                 const char *section,
981                 unsigned section_line,
982                 const char *lvalue,
983                 int ltype,
984                 const char *rvalue,
985                 void *data,
986                 void *userdata) {
987
988         InstallInfo *i = data;
989         char *printed;
990         int r;
991
992         assert(filename);
993         assert(lvalue);
994         assert(rvalue);
995
996         r = install_full_printf(i, rvalue, &printed);
997         if (r < 0)
998                 return r;
999
1000         free(i->user);
1001         i->user = printed;
1002
1003         return 0;
1004 }
1005
1006 static int config_parse_default_instance(
1007                 const char *unit,
1008                 const char *filename,
1009                 unsigned line,
1010                 const char *section,
1011                 unsigned section_line,
1012                 const char *lvalue,
1013                 int ltype,
1014                 const char *rvalue,
1015                 void *data,
1016                 void *userdata) {
1017
1018         InstallInfo *i = data;
1019         char *printed;
1020         int r;
1021
1022         assert(filename);
1023         assert(lvalue);
1024         assert(rvalue);
1025
1026         r = install_full_printf(i, rvalue, &printed);
1027         if (r < 0)
1028                 return r;
1029
1030         if (!unit_instance_is_valid(printed))
1031                 return -EINVAL;
1032
1033         free(i->default_instance);
1034         i->default_instance = printed;
1035
1036         return 0;
1037 }
1038
1039 static int unit_file_load(
1040                 InstallContext *c,
1041                 InstallInfo *info,
1042                 const char *path,
1043                 const char *root_dir,
1044                 bool allow_symlink) {
1045
1046         const ConfigTableItem items[] = {
1047                 { "Install", "Alias",           config_parse_strv,             0, &info->aliases           },
1048                 { "Install", "WantedBy",        config_parse_strv,             0, &info->wanted_by         },
1049                 { "Install", "RequiredBy",      config_parse_strv,             0, &info->required_by       },
1050                 { "Install", "DefaultInstance", config_parse_default_instance, 0, info                     },
1051                 { "Install", "Also",            config_parse_also,             0, c                        },
1052                 { "Exec",    "User",            config_parse_user,             0, info                     },
1053                 {}
1054         };
1055
1056         _cleanup_fclose_ FILE *f = NULL;
1057         int fd, r;
1058
1059         assert(c);
1060         assert(info);
1061         assert(path);
1062
1063         if (!isempty(root_dir))
1064                 path = strappenda(root_dir, "/", path);
1065
1066         fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|(allow_symlink ? 0 : O_NOFOLLOW));
1067         if (fd < 0)
1068                 return -errno;
1069
1070         f = fdopen(fd, "re");
1071         if (!f) {
1072                 safe_close(fd);
1073                 return -ENOMEM;
1074         }
1075
1076         r = config_parse(NULL, path, f,
1077                          NULL,
1078                          config_item_table_lookup, items,
1079                          true, true, false, info);
1080         if (r < 0)
1081                 return r;
1082
1083         return
1084                 (int) strv_length(info->aliases) +
1085                 (int) strv_length(info->wanted_by) +
1086                 (int) strv_length(info->required_by);
1087 }
1088
1089 static int unit_file_search(
1090                 InstallContext *c,
1091                 InstallInfo *info,
1092                 LookupPaths *paths,
1093                 const char *root_dir,
1094                 bool allow_symlink) {
1095
1096         char **p;
1097         int r;
1098
1099         assert(c);
1100         assert(info);
1101         assert(paths);
1102
1103         if (info->path)
1104                 return unit_file_load(c, info, info->path, root_dir, allow_symlink);
1105
1106         assert(info->name);
1107
1108         STRV_FOREACH(p, paths->unit_path) {
1109                 _cleanup_free_ char *path = NULL;
1110
1111                 path = strjoin(*p, "/", info->name, NULL);
1112                 if (!path)
1113                         return -ENOMEM;
1114
1115                 r = unit_file_load(c, info, path, root_dir, allow_symlink);
1116                 if (r >= 0) {
1117                         info->path = path;
1118                         path = NULL;
1119                         return r;
1120                 }
1121                 if (r != -ENOENT && r != -ELOOP)
1122                         return r;
1123         }
1124
1125         if (unit_name_is_instance(info->name)) {
1126
1127                 /* Unit file doesn't exist, however instance
1128                  * enablement was requested.  We will check if it is
1129                  * possible to load template unit file. */
1130
1131                 _cleanup_free_ char *template = NULL;
1132
1133                 template = unit_name_template(info->name);
1134                 if (!template)
1135                         return -ENOMEM;
1136
1137                 STRV_FOREACH(p, paths->unit_path) {
1138                         _cleanup_free_ char *path = NULL;
1139
1140                         path = strjoin(*p, "/", template, NULL);
1141                         if (!path)
1142                                 return -ENOMEM;
1143
1144                         r = unit_file_load(c, info, path, root_dir, allow_symlink);
1145                         if (r >= 0) {
1146                                 info->path = path;
1147                                 path = NULL;
1148                                 return r;
1149                         }
1150                         if (r != -ENOENT && r != -ELOOP)
1151                                 return r;
1152                 }
1153         }
1154
1155         return -ENOENT;
1156 }
1157
1158 static int unit_file_can_install(
1159                 LookupPaths *paths,
1160                 const char *root_dir,
1161                 const char *name,
1162                 bool allow_symlink) {
1163
1164         _cleanup_install_context_done_ InstallContext c = {};
1165         InstallInfo *i;
1166         int r;
1167
1168         assert(paths);
1169         assert(name);
1170
1171         r = install_info_add_auto(&c, name);
1172         if (r < 0)
1173                 return r;
1174
1175         assert_se(i = hashmap_first(c.will_install));
1176
1177         r = unit_file_search(&c, i, paths, root_dir, allow_symlink);
1178
1179         if (r >= 0)
1180                 r =
1181                         (int) strv_length(i->aliases) +
1182                         (int) strv_length(i->wanted_by) +
1183                         (int) strv_length(i->required_by);
1184
1185         return r;
1186 }
1187
1188 static int create_symlink(
1189                 const char *old_path,
1190                 const char *new_path,
1191                 bool force,
1192                 UnitFileChange **changes,
1193                 unsigned *n_changes) {
1194
1195         _cleanup_free_ char *dest = NULL;
1196         int r;
1197
1198         assert(old_path);
1199         assert(new_path);
1200
1201         mkdir_parents_label(new_path, 0755);
1202
1203         if (symlink(old_path, new_path) >= 0) {
1204                 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
1205                 return 0;
1206         }
1207
1208         if (errno != EEXIST)
1209                 return -errno;
1210
1211         r = readlink_and_make_absolute(new_path, &dest);
1212         if (r < 0)
1213                 return r;
1214
1215         if (path_equal(dest, old_path))
1216                 return 0;
1217
1218         if (!force)
1219                 return -EEXIST;
1220
1221         r = symlink_atomic(old_path, new_path);
1222         if (r < 0)
1223                 return r;
1224
1225         add_file_change(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);
1226         add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
1227
1228         return 0;
1229 }
1230
1231 static int install_info_symlink_alias(
1232                 InstallInfo *i,
1233                 const char *config_path,
1234                 bool force,
1235                 UnitFileChange **changes,
1236                 unsigned *n_changes) {
1237
1238         char **s;
1239         int r = 0, q;
1240
1241         assert(i);
1242         assert(config_path);
1243
1244         STRV_FOREACH(s, i->aliases) {
1245                 _cleanup_free_ char *alias_path = NULL, *dst = NULL;
1246
1247                 q = install_full_printf(i, *s, &dst);
1248                 if (q < 0)
1249                         return q;
1250
1251                 alias_path = path_make_absolute(dst, config_path);
1252                 if (!alias_path)
1253                         return -ENOMEM;
1254
1255                 q = create_symlink(i->path, alias_path, force, changes, n_changes);
1256                 if (r == 0)
1257                         r = q;
1258         }
1259
1260         return r;
1261 }
1262
1263 static int install_info_symlink_wants(
1264                 InstallInfo *i,
1265                 const char *config_path,
1266                 char **list,
1267                 const char *suffix,
1268                 bool force,
1269                 UnitFileChange **changes,
1270                 unsigned *n_changes) {
1271
1272         _cleanup_free_ char *buf = NULL;
1273         const char *n;
1274         char **s;
1275         int r = 0, q;
1276
1277         assert(i);
1278         assert(config_path);
1279
1280         if (unit_name_is_template(i->name)) {
1281
1282                 /* Don't install any symlink if there's no default
1283                  * instance configured */
1284
1285                 if (!i->default_instance)
1286                         return 0;
1287
1288                 buf = unit_name_replace_instance(i->name, i->default_instance);
1289                 if (!buf)
1290                         return -ENOMEM;
1291
1292                 n = buf;
1293         } else
1294                 n = i->name;
1295
1296         STRV_FOREACH(s, list) {
1297                 _cleanup_free_ char *path = NULL, *dst = NULL;
1298
1299                 q = install_full_printf(i, *s, &dst);
1300                 if (q < 0)
1301                         return q;
1302
1303                 if (!unit_name_is_valid(dst, TEMPLATE_VALID)) {
1304                         r = -EINVAL;
1305                         continue;
1306                 }
1307
1308                 path = strjoin(config_path, "/", dst, suffix, n, NULL);
1309                 if (!path)
1310                         return -ENOMEM;
1311
1312                 q = create_symlink(i->path, path, force, changes, n_changes);
1313                 if (r == 0)
1314                         r = q;
1315         }
1316
1317         return r;
1318 }
1319
1320 static int install_info_symlink_link(
1321                 InstallInfo *i,
1322                 LookupPaths *paths,
1323                 const char *config_path,
1324                 const char *root_dir,
1325                 bool force,
1326                 UnitFileChange **changes,
1327                 unsigned *n_changes) {
1328
1329         _cleanup_free_ char *path = NULL;
1330         int r;
1331
1332         assert(i);
1333         assert(paths);
1334         assert(config_path);
1335         assert(i->path);
1336
1337         r = in_search_path(i->path, paths->unit_path);
1338         if (r != 0)
1339                 return r;
1340
1341         path = strjoin(config_path, "/", i->name, NULL);
1342         if (!path)
1343                 return -ENOMEM;
1344
1345         return create_symlink(i->path, path, force, changes, n_changes);
1346 }
1347
1348 static int install_info_apply(
1349                 InstallInfo *i,
1350                 LookupPaths *paths,
1351                 const char *config_path,
1352                 const char *root_dir,
1353                 bool force,
1354                 UnitFileChange **changes,
1355                 unsigned *n_changes) {
1356
1357         int r, q;
1358
1359         assert(i);
1360         assert(paths);
1361         assert(config_path);
1362
1363         r = install_info_symlink_alias(i, config_path, force, changes, n_changes);
1364
1365         q = install_info_symlink_wants(i, config_path, i->wanted_by, ".wants/", force, changes, n_changes);
1366         if (r == 0)
1367                 r = q;
1368
1369         q = install_info_symlink_wants(i, config_path, i->required_by, ".requires/", force, changes, n_changes);
1370         if (r == 0)
1371                 r = q;
1372
1373         q = install_info_symlink_link(i, paths, config_path, root_dir, force, changes, n_changes);
1374         if (r == 0)
1375                 r = q;
1376
1377         return r;
1378 }
1379
1380 static int install_context_apply(
1381                 InstallContext *c,
1382                 LookupPaths *paths,
1383                 const char *config_path,
1384                 const char *root_dir,
1385                 bool force,
1386                 UnitFileChange **changes,
1387                 unsigned *n_changes) {
1388
1389         InstallInfo *i;
1390         int r = 0, q;
1391
1392         assert(c);
1393         assert(paths);
1394         assert(config_path);
1395
1396         while ((i = hashmap_first(c->will_install))) {
1397
1398                 q = hashmap_ensure_allocated(&c->have_installed, string_hash_func, string_compare_func);
1399                 if (q < 0)
1400                         return q;
1401
1402                 assert_se(hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
1403
1404                 q = unit_file_search(c, i, paths, root_dir, false);
1405                 if (q < 0) {
1406                         if (r >= 0)
1407                                 r = q;
1408
1409                         return r;
1410                 } else if (r >= 0)
1411                         r += q;
1412
1413                 q = install_info_apply(i, paths, config_path, root_dir, force, changes, n_changes);
1414                 if (r >= 0 && q < 0)
1415                         r = q;
1416         }
1417
1418         return r;
1419 }
1420
1421 static int install_context_mark_for_removal(
1422                 InstallContext *c,
1423                 LookupPaths *paths,
1424                 Set **remove_symlinks_to,
1425                 const char *config_path,
1426                 const char *root_dir) {
1427
1428         InstallInfo *i;
1429         int r = 0, q;
1430
1431         assert(c);
1432         assert(paths);
1433         assert(config_path);
1434
1435         /* Marks all items for removal */
1436
1437         while ((i = hashmap_first(c->will_install))) {
1438
1439                 q = hashmap_ensure_allocated(&c->have_installed, string_hash_func, string_compare_func);
1440                 if (q < 0)
1441                         return q;
1442
1443                 assert_se(hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
1444
1445                 q = unit_file_search(c, i, paths, root_dir, false);
1446                 if (q == -ENOENT) {
1447                         /* do nothing */
1448                 } else if (q < 0) {
1449                         if (r >= 0)
1450                                 r = q;
1451
1452                         return r;
1453                 } else if (r >= 0)
1454                         r += q;
1455
1456                 if (unit_name_is_instance(i->name)) {
1457                         char *unit_file;
1458
1459                         if (i->path) {
1460                                 unit_file = basename(i->path);
1461
1462                                 if (unit_name_is_instance(unit_file))
1463                                         /* unit file named as instance exists, thus all symlinks
1464                                          * pointing to it will be removed */
1465                                         q = mark_symlink_for_removal(remove_symlinks_to, i->name);
1466                                 else
1467                                         /* does not exist, thus we will mark for removal symlinks
1468                                          * to template unit file */
1469                                         q = mark_symlink_for_removal(remove_symlinks_to, unit_file);
1470                         } else {
1471                                 /* If i->path is not set, it means that we didn't actually find
1472                                  * the unit file. But we can still remove symlinks to the
1473                                  * nonexistent template. */
1474                                 unit_file = unit_name_template(i->name);
1475                                 if (!unit_file)
1476                                         return log_oom();
1477
1478                                 q = mark_symlink_for_removal(remove_symlinks_to, unit_file);
1479                                 free(unit_file);
1480                         }
1481                 } else
1482                         q = mark_symlink_for_removal(remove_symlinks_to, i->name);
1483
1484                 if (r >= 0 && q < 0)
1485                         r = q;
1486         }
1487
1488         return r;
1489 }
1490
1491 int unit_file_enable(
1492                 UnitFileScope scope,
1493                 bool runtime,
1494                 const char *root_dir,
1495                 char **files,
1496                 bool force,
1497                 UnitFileChange **changes,
1498                 unsigned *n_changes) {
1499
1500         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1501         _cleanup_install_context_done_ InstallContext c = {};
1502         char **i;
1503         _cleanup_free_ char *config_path = NULL;
1504         int r;
1505
1506         assert(scope >= 0);
1507         assert(scope < _UNIT_FILE_SCOPE_MAX);
1508
1509         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1510         if (r < 0)
1511                 return r;
1512
1513         r = get_config_path(scope, runtime, root_dir, &config_path);
1514         if (r < 0)
1515                 return r;
1516
1517         STRV_FOREACH(i, files) {
1518                 r = install_info_add_auto(&c, *i);
1519                 if (r < 0)
1520                         return r;
1521         }
1522
1523         /* This will return the number of symlink rules that were
1524         supposed to be created, not the ones actually created. This is
1525         useful to determine whether the passed files had any
1526         installation data at all. */
1527
1528         return install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes);
1529 }
1530
1531 int unit_file_disable(
1532                 UnitFileScope scope,
1533                 bool runtime,
1534                 const char *root_dir,
1535                 char **files,
1536                 UnitFileChange **changes,
1537                 unsigned *n_changes) {
1538
1539         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1540         _cleanup_install_context_done_ InstallContext c = {};
1541         char **i;
1542         _cleanup_free_ char *config_path = NULL;
1543         _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
1544         int r, q;
1545
1546         assert(scope >= 0);
1547         assert(scope < _UNIT_FILE_SCOPE_MAX);
1548
1549         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1550         if (r < 0)
1551                 return r;
1552
1553         r = get_config_path(scope, runtime, root_dir, &config_path);
1554         if (r < 0)
1555                 return r;
1556
1557         STRV_FOREACH(i, files) {
1558                 r = install_info_add_auto(&c, *i);
1559                 if (r < 0)
1560                         return r;
1561         }
1562
1563         r = install_context_mark_for_removal(&c, &paths, &remove_symlinks_to, config_path, root_dir);
1564
1565         q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
1566         if (r == 0)
1567                 r = q;
1568
1569         return r;
1570 }
1571
1572 int unit_file_reenable(
1573                 UnitFileScope scope,
1574                 bool runtime,
1575                 const char *root_dir,
1576                 char **files,
1577                 bool force,
1578                 UnitFileChange **changes,
1579                 unsigned *n_changes) {
1580         int r;
1581
1582         r = unit_file_disable(scope, runtime, root_dir, files,
1583                               changes, n_changes);
1584         if (r < 0)
1585                 return r;
1586
1587         return unit_file_enable(scope, runtime, root_dir, files, force,
1588                                 changes, n_changes);
1589 }
1590
1591 int unit_file_set_default(
1592                 UnitFileScope scope,
1593                 const char *root_dir,
1594                 const char *file,
1595                 bool force,
1596                 UnitFileChange **changes,
1597                 unsigned *n_changes) {
1598
1599         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1600         _cleanup_install_context_done_ InstallContext c = {};
1601         _cleanup_free_ char *config_path = NULL;
1602         char *path;
1603         int r;
1604         InstallInfo *i = NULL;
1605
1606         assert(scope >= 0);
1607         assert(scope < _UNIT_FILE_SCOPE_MAX);
1608         assert(file);
1609
1610         if (unit_name_to_type(file) != UNIT_TARGET)
1611                 return -EINVAL;
1612
1613         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1614         if (r < 0)
1615                 return r;
1616
1617         r = get_config_path(scope, false, root_dir, &config_path);
1618         if (r < 0)
1619                 return r;
1620
1621         r = install_info_add_auto(&c, file);
1622         if (r < 0)
1623                 return r;
1624
1625         assert_se(i = hashmap_first(c.will_install));
1626
1627         r = unit_file_search(&c, i, &paths, root_dir, false);
1628         if (r < 0)
1629                 return r;
1630
1631         path = strappenda(config_path, "/" SPECIAL_DEFAULT_TARGET);
1632
1633         r = create_symlink(i->path, path, force, changes, n_changes);
1634         if (r < 0)
1635                 return r;
1636
1637         return 0;
1638 }
1639
1640 int unit_file_get_default(
1641                 UnitFileScope scope,
1642                 const char *root_dir,
1643                 char **name) {
1644
1645         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1646         char **p;
1647         int r;
1648
1649         assert(scope >= 0);
1650         assert(scope < _UNIT_FILE_SCOPE_MAX);
1651         assert(name);
1652
1653         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1654         if (r < 0)
1655                 return r;
1656
1657         STRV_FOREACH(p, paths.unit_path) {
1658                 _cleanup_free_ char *path = NULL, *tmp = NULL;
1659                 char *n;
1660
1661                 path = path_join(root_dir, *p, SPECIAL_DEFAULT_TARGET);
1662                 if (!path)
1663                         return -ENOMEM;
1664
1665                 r = readlink_malloc(path, &tmp);
1666                 if (r == -ENOENT)
1667                         continue;
1668                 else if (r == -EINVAL)
1669                         /* not a symlink */
1670                         n = strdup(SPECIAL_DEFAULT_TARGET);
1671                 else if (r < 0)
1672                         return r;
1673                 else
1674                         n = strdup(basename(tmp));
1675
1676                 if (!n)
1677                         return -ENOMEM;
1678
1679                 *name = n;
1680                 return 0;
1681         }
1682
1683         return -ENOENT;
1684 }
1685
1686 UnitFileState unit_file_get_state(
1687                 UnitFileScope scope,
1688                 const char *root_dir,
1689                 const char *name) {
1690
1691         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1692         UnitFileState state = _UNIT_FILE_STATE_INVALID;
1693         char **i;
1694         _cleanup_free_ char *path = NULL;
1695         int r;
1696
1697         assert(scope >= 0);
1698         assert(scope < _UNIT_FILE_SCOPE_MAX);
1699         assert(name);
1700
1701         if (root_dir && scope != UNIT_FILE_SYSTEM)
1702                 return -EINVAL;
1703
1704         if (!unit_name_is_valid(name, TEMPLATE_VALID))
1705                 return -EINVAL;
1706
1707         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1708         if (r < 0)
1709                 return r;
1710
1711         STRV_FOREACH(i, paths.unit_path) {
1712                 struct stat st;
1713                 char *partial;
1714
1715                 free(path);
1716                 path = NULL;
1717
1718                 path = path_join(root_dir, *i, name);
1719                 if (!path)
1720                         return -ENOMEM;
1721
1722                 if (root_dir)
1723                         partial = path + strlen(root_dir);
1724                 else
1725                         partial = path;
1726
1727                 /*
1728                  * Search for a unit file in our default paths, to
1729                  * be sure, that there are no broken symlinks.
1730                  */
1731                 if (lstat(path, &st) < 0) {
1732                         r = -errno;
1733                         if (errno != ENOENT)
1734                                 return r;
1735
1736                         if (!unit_name_is_instance(name))
1737                                 continue;
1738                 } else {
1739                         if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode))
1740                                 return -ENOENT;
1741
1742                         r = null_or_empty_path(path);
1743                         if (r < 0 && r != -ENOENT)
1744                                 return r;
1745                         else if (r > 0) {
1746                                 state = path_startswith(*i, "/run") ?
1747                                         UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
1748                                 return state;
1749                         }
1750                 }
1751
1752                 r = find_symlinks_in_scope(scope, root_dir, name, &state);
1753                 if (r < 0)
1754                         return r;
1755                 else if (r > 0)
1756                         return state;
1757
1758                 r = unit_file_can_install(&paths, root_dir, partial, true);
1759                 if (r < 0 && errno != ENOENT)
1760                         return r;
1761                 else if (r > 0)
1762                         return UNIT_FILE_DISABLED;
1763                 else if (r == 0)
1764                         return UNIT_FILE_STATIC;
1765         }
1766
1767         return r < 0 ? r : state;
1768 }
1769
1770 int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name) {
1771         _cleanup_strv_free_ char **files = NULL;
1772         char **p;
1773         int r;
1774
1775         assert(scope >= 0);
1776         assert(scope < _UNIT_FILE_SCOPE_MAX);
1777         assert(name);
1778
1779         if (scope == UNIT_FILE_SYSTEM)
1780                 r = conf_files_list(&files, ".preset", root_dir,
1781                                     "/etc/systemd/system-preset",
1782                                     "/usr/local/lib/systemd/system-preset",
1783                                     "/usr/lib/systemd/system-preset",
1784 #ifdef HAVE_SPLIT_USR
1785                                     "/lib/systemd/system-preset",
1786 #endif
1787                                     NULL);
1788         else if (scope == UNIT_FILE_GLOBAL)
1789                 r = conf_files_list(&files, ".preset", root_dir,
1790                                     "/etc/systemd/user-preset",
1791                                     "/usr/local/lib/systemd/user-preset",
1792                                     "/usr/lib/systemd/user-preset",
1793                                     NULL);
1794         else
1795                 return 1;
1796
1797         if (r < 0)
1798                 return r;
1799
1800         STRV_FOREACH(p, files) {
1801                 _cleanup_fclose_ FILE *f;
1802
1803                 f = fopen(*p, "re");
1804                 if (!f) {
1805                         if (errno == ENOENT)
1806                                 continue;
1807
1808                         return -errno;
1809                 }
1810
1811                 for (;;) {
1812                         char line[LINE_MAX], *l;
1813
1814                         if (!fgets(line, sizeof(line), f))
1815                                 break;
1816
1817                         l = strstrip(line);
1818                         if (!*l)
1819                                 continue;
1820
1821                         if (strchr(COMMENTS "\n", *l))
1822                                 continue;
1823
1824                         if (first_word(l, "enable")) {
1825                                 l += 6;
1826                                 l += strspn(l, WHITESPACE);
1827
1828                                 if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
1829                                         log_debug("Preset file says enable %s.", name);
1830                                         return 1;
1831                                 }
1832
1833                         } else if (first_word(l, "disable")) {
1834                                 l += 7;
1835                                 l += strspn(l, WHITESPACE);
1836
1837                                 if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
1838                                         log_debug("Preset file says disable %s.", name);
1839                                         return 0;
1840                                 }
1841
1842                         } else
1843                                 log_debug("Couldn't parse line '%s'", l);
1844                 }
1845         }
1846
1847         /* Default is "enable" */
1848         log_debug("Preset file doesn't say anything about %s, enabling.", name);
1849         return 1;
1850 }
1851
1852 int unit_file_preset(
1853                 UnitFileScope scope,
1854                 bool runtime,
1855                 const char *root_dir,
1856                 char **files,
1857                 UnitFilePresetMode mode,
1858                 bool force,
1859                 UnitFileChange **changes,
1860                 unsigned *n_changes) {
1861
1862         _cleanup_install_context_done_ InstallContext plus = {}, minus = {};
1863         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1864         _cleanup_free_ char *config_path = NULL;
1865         char **i;
1866         int r, q;
1867
1868         assert(scope >= 0);
1869         assert(scope < _UNIT_FILE_SCOPE_MAX);
1870         assert(mode < _UNIT_FILE_PRESET_MAX);
1871
1872         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1873         if (r < 0)
1874                 return r;
1875
1876         r = get_config_path(scope, runtime, root_dir, &config_path);
1877         if (r < 0)
1878                 return r;
1879
1880         STRV_FOREACH(i, files) {
1881
1882                 if (!unit_name_is_valid(*i, TEMPLATE_VALID))
1883                         return -EINVAL;
1884
1885                 r = unit_file_query_preset(scope, root_dir, *i);
1886                 if (r < 0)
1887                         return r;
1888
1889                 if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
1890                         r = install_info_add_auto(&plus, *i);
1891                 else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
1892                         r = install_info_add_auto(&minus, *i);
1893                 else
1894                         r = 0;
1895                 if (r < 0)
1896                         return r;
1897         }
1898
1899         r = 0;
1900
1901         if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
1902                 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
1903
1904                 r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
1905
1906                 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
1907                 if (r == 0)
1908                         r = q;
1909         }
1910
1911         if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
1912                 /* Returns number of symlinks that where supposed to be installed. */
1913                 q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
1914                 if (r == 0)
1915                         r = q;
1916         }
1917
1918         return r;
1919 }
1920
1921 int unit_file_preset_all(
1922                 UnitFileScope scope,
1923                 bool runtime,
1924                 const char *root_dir,
1925                 UnitFilePresetMode mode,
1926                 bool force,
1927                 UnitFileChange **changes,
1928                 unsigned *n_changes) {
1929
1930         _cleanup_install_context_done_ InstallContext plus = {}, minus = {};
1931         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1932         _cleanup_free_ char *config_path = NULL;
1933         char **i;
1934         int r, q;
1935
1936         assert(scope >= 0);
1937         assert(scope < _UNIT_FILE_SCOPE_MAX);
1938         assert(mode < _UNIT_FILE_PRESET_MAX);
1939
1940         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1941         if (r < 0)
1942                 return r;
1943
1944         r = get_config_path(scope, runtime, root_dir, &config_path);
1945         if (r < 0)
1946                 return r;
1947
1948         STRV_FOREACH(i, paths.unit_path) {
1949                 _cleanup_closedir_ DIR *d = NULL;
1950                 _cleanup_free_ char *units_dir;
1951
1952                 units_dir = path_join(root_dir, *i, NULL);
1953                 if (!units_dir)
1954                         return -ENOMEM;
1955
1956                 d = opendir(units_dir);
1957                 if (!d) {
1958                         if (errno == ENOENT)
1959                                 continue;
1960
1961                         return -errno;
1962                 }
1963
1964                 for (;;) {
1965                         struct dirent *de;
1966
1967                         errno = 0;
1968                         de = readdir(d);
1969                         if (!de && errno != 0)
1970                                 return -errno;
1971
1972                         if (!de)
1973                                 break;
1974
1975                         if (ignore_file(de->d_name))
1976                                 continue;
1977
1978                         if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
1979                                 continue;
1980
1981                         dirent_ensure_type(d, de);
1982
1983                         if (de->d_type != DT_REG)
1984                                 continue;
1985
1986                         r = unit_file_query_preset(scope, root_dir, de->d_name);
1987                         if (r < 0)
1988                                 return r;
1989
1990                         if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
1991                                 r = install_info_add_auto(&plus, de->d_name);
1992                         else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
1993                                 r = install_info_add_auto(&minus, de->d_name);
1994                         else
1995                                 r = 0;
1996                         if (r < 0)
1997                                 return r;
1998                 }
1999         }
2000
2001         r = 0;
2002
2003         if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
2004                 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
2005
2006                 r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
2007
2008                 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, NULL);
2009                 if (r == 0)
2010                         r = q;
2011         }
2012
2013         if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
2014                 q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
2015                 if (r == 0)
2016                         r = q;
2017         }
2018
2019         return r;
2020 }
2021
2022 static void unitfilelist_free(UnitFileList **f) {
2023         if (!*f)
2024                 return;
2025
2026         free((*f)->path);
2027         free(*f);
2028 }
2029 #define _cleanup_unitfilelist_free_ _cleanup_(unitfilelist_free)
2030
2031 int unit_file_get_list(
2032                 UnitFileScope scope,
2033                 const char *root_dir,
2034                 Hashmap *h) {
2035
2036         _cleanup_lookup_paths_free_ LookupPaths paths = {};
2037         char **i;
2038         int r;
2039
2040         assert(scope >= 0);
2041         assert(scope < _UNIT_FILE_SCOPE_MAX);
2042         assert(h);
2043
2044         if (root_dir && scope != UNIT_FILE_SYSTEM)
2045                 return -EINVAL;
2046
2047         if (root_dir) {
2048                 r = access(root_dir, F_OK);
2049                 if (r < 0)
2050                         return -errno;
2051         }
2052
2053         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
2054         if (r < 0)
2055                 return r;
2056
2057         STRV_FOREACH(i, paths.unit_path) {
2058                 _cleanup_closedir_ DIR *d = NULL;
2059                 _cleanup_free_ char *units_dir;
2060
2061                 units_dir = path_join(root_dir, *i, NULL);
2062                 if (!units_dir)
2063                         return -ENOMEM;
2064
2065                 d = opendir(units_dir);
2066                 if (!d) {
2067                         if (errno == ENOENT)
2068                                 continue;
2069
2070                         return -errno;
2071                 }
2072
2073                 for (;;) {
2074                         _cleanup_unitfilelist_free_ UnitFileList *f = NULL;
2075                         struct dirent *de;
2076
2077                         errno = 0;
2078                         de = readdir(d);
2079                         if (!de && errno != 0)
2080                                 return -errno;
2081
2082                         if (!de)
2083                                 break;
2084
2085                         if (ignore_file(de->d_name))
2086                                 continue;
2087
2088                         if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
2089                                 continue;
2090
2091                         if (hashmap_get(h, de->d_name))
2092                                 continue;
2093
2094                         dirent_ensure_type(d, de);
2095
2096                         if (!IN_SET(de->d_type, DT_LNK, DT_REG))
2097                                 continue;
2098
2099                         f = new0(UnitFileList, 1);
2100                         if (!f)
2101                                 return -ENOMEM;
2102
2103                         f->path = path_make_absolute(de->d_name, units_dir);
2104                         if (!f->path)
2105                                 return -ENOMEM;
2106
2107                         r = null_or_empty_path(f->path);
2108                         if (r < 0 && r != -ENOENT)
2109                                 return r;
2110                         else if (r > 0) {
2111                                 f->state =
2112                                         path_startswith(*i, "/run") ?
2113                                         UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
2114                                 goto found;
2115                         }
2116
2117                         r = find_symlinks_in_scope(scope, root_dir, de->d_name, &f->state);
2118                         if (r < 0)
2119                                 return r;
2120                         else if (r > 0) {
2121                                 f->state = UNIT_FILE_ENABLED;
2122                                 goto found;
2123                         }
2124
2125                         r = unit_file_can_install(&paths, root_dir, f->path, true);
2126                         if (r == -EINVAL ||  /* Invalid setting? */
2127                             r == -EBADMSG || /* Invalid format? */
2128                             r == -ENOENT     /* Included file not found? */)
2129                                 f->state = UNIT_FILE_INVALID;
2130                         else if (r < 0)
2131                                 return r;
2132                         else if (r > 0)
2133                                 f->state = UNIT_FILE_DISABLED;
2134                         else
2135                                 f->state = UNIT_FILE_STATIC;
2136
2137                 found:
2138                         r = hashmap_put(h, basename(f->path), f);
2139                         if (r < 0)
2140                                 return r;
2141                         f = NULL; /* prevent cleanup */
2142                 }
2143         }
2144
2145         return r;
2146 }
2147
2148 static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
2149         [UNIT_FILE_ENABLED] = "enabled",
2150         [UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime",
2151         [UNIT_FILE_LINKED] = "linked",
2152         [UNIT_FILE_LINKED_RUNTIME] = "linked-runtime",
2153         [UNIT_FILE_MASKED] = "masked",
2154         [UNIT_FILE_MASKED_RUNTIME] = "masked-runtime",
2155         [UNIT_FILE_STATIC] = "static",
2156         [UNIT_FILE_DISABLED] = "disabled",
2157         [UNIT_FILE_INVALID] = "invalid",
2158 };
2159
2160 DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
2161
2162 static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
2163         [UNIT_FILE_SYMLINK] = "symlink",
2164         [UNIT_FILE_UNLINK] = "unlink",
2165 };
2166
2167 DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
2168
2169 static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = {
2170         [UNIT_FILE_PRESET_FULL] = "full",
2171         [UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
2172         [UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
2173 };
2174
2175 DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode, UnitFilePresetMode);