chiark / gitweb /
cc61c01e20d05ad2587606a3fa725f6e45de4037
[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         char *w;
950         size_t l;
951         char *state;
952         InstallContext *c = data;
953
954         assert(filename);
955         assert(lvalue);
956         assert(rvalue);
957
958         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
959                 _cleanup_free_ char *n;
960                 int r;
961
962                 n = strndup(w, l);
963                 if (!n)
964                         return -ENOMEM;
965
966                 r = install_info_add(c, n, NULL);
967                 if (r < 0)
968                         return r;
969         }
970
971         return 0;
972 }
973
974 static int config_parse_user(
975                 const char *unit,
976                 const char *filename,
977                 unsigned line,
978                 const char *section,
979                 unsigned section_line,
980                 const char *lvalue,
981                 int ltype,
982                 const char *rvalue,
983                 void *data,
984                 void *userdata) {
985
986         InstallInfo *i = data;
987         char *printed;
988         int r;
989
990         assert(filename);
991         assert(lvalue);
992         assert(rvalue);
993
994         r = install_full_printf(i, rvalue, &printed);
995         if (r < 0)
996                 return r;
997
998         free(i->user);
999         i->user = printed;
1000
1001         return 0;
1002 }
1003
1004 static int config_parse_default_instance(
1005                 const char *unit,
1006                 const char *filename,
1007                 unsigned line,
1008                 const char *section,
1009                 unsigned section_line,
1010                 const char *lvalue,
1011                 int ltype,
1012                 const char *rvalue,
1013                 void *data,
1014                 void *userdata) {
1015
1016         InstallInfo *i = data;
1017         char *printed;
1018         int r;
1019
1020         assert(filename);
1021         assert(lvalue);
1022         assert(rvalue);
1023
1024         r = install_full_printf(i, rvalue, &printed);
1025         if (r < 0)
1026                 return r;
1027
1028         if (!unit_instance_is_valid(printed))
1029                 return -EINVAL;
1030
1031         free(i->default_instance);
1032         i->default_instance = printed;
1033
1034         return 0;
1035 }
1036
1037 static int unit_file_load(
1038                 InstallContext *c,
1039                 InstallInfo *info,
1040                 const char *path,
1041                 const char *root_dir,
1042                 bool allow_symlink) {
1043
1044         const ConfigTableItem items[] = {
1045                 { "Install", "Alias",           config_parse_strv,             0, &info->aliases           },
1046                 { "Install", "WantedBy",        config_parse_strv,             0, &info->wanted_by         },
1047                 { "Install", "RequiredBy",      config_parse_strv,             0, &info->required_by       },
1048                 { "Install", "DefaultInstance", config_parse_default_instance, 0, info                     },
1049                 { "Install", "Also",            config_parse_also,             0, c                        },
1050                 { "Exec",    "User",            config_parse_user,             0, info                     },
1051                 {}
1052         };
1053
1054         _cleanup_fclose_ FILE *f = NULL;
1055         int fd, r;
1056
1057         assert(c);
1058         assert(info);
1059         assert(path);
1060
1061         if (!isempty(root_dir))
1062                 path = strappenda3(root_dir, "/", path);
1063
1064         fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|(allow_symlink ? 0 : O_NOFOLLOW));
1065         if (fd < 0)
1066                 return -errno;
1067
1068         f = fdopen(fd, "re");
1069         if (!f) {
1070                 safe_close(fd);
1071                 return -ENOMEM;
1072         }
1073
1074         r = config_parse(NULL, path, f,
1075                          NULL,
1076                          config_item_table_lookup, items,
1077                          true, true, false, info);
1078         if (r < 0)
1079                 return r;
1080
1081         return
1082                 (int) strv_length(info->aliases) +
1083                 (int) strv_length(info->wanted_by) +
1084                 (int) strv_length(info->required_by);
1085 }
1086
1087 static int unit_file_search(
1088                 InstallContext *c,
1089                 InstallInfo *info,
1090                 LookupPaths *paths,
1091                 const char *root_dir,
1092                 bool allow_symlink) {
1093
1094         char **p;
1095         int r;
1096
1097         assert(c);
1098         assert(info);
1099         assert(paths);
1100
1101         if (info->path)
1102                 return unit_file_load(c, info, info->path, root_dir, allow_symlink);
1103
1104         assert(info->name);
1105
1106         STRV_FOREACH(p, paths->unit_path) {
1107                 _cleanup_free_ char *path = NULL;
1108
1109                 path = strjoin(*p, "/", info->name, NULL);
1110                 if (!path)
1111                         return -ENOMEM;
1112
1113                 r = unit_file_load(c, info, path, root_dir, allow_symlink);
1114                 if (r >= 0) {
1115                         info->path = path;
1116                         path = NULL;
1117                         return r;
1118                 }
1119                 if (r != -ENOENT && r != -ELOOP)
1120                         return r;
1121         }
1122
1123         if (unit_name_is_instance(info->name)) {
1124
1125                 /* Unit file doesn't exist, however instance
1126                  * enablement was requested.  We will check if it is
1127                  * possible to load template unit file. */
1128
1129                 _cleanup_free_ char *template = NULL;
1130
1131                 template = unit_name_template(info->name);
1132                 if (!template)
1133                         return -ENOMEM;
1134
1135                 STRV_FOREACH(p, paths->unit_path) {
1136                         _cleanup_free_ char *path = NULL;
1137
1138                         path = strjoin(*p, "/", template, NULL);
1139                         if (!path)
1140                                 return -ENOMEM;
1141
1142                         r = unit_file_load(c, info, path, root_dir, allow_symlink);
1143                         if (r >= 0) {
1144                                 info->path = path;
1145                                 path = NULL;
1146                                 return r;
1147                         }
1148                         if (r != -ENOENT && r != -ELOOP)
1149                                 return r;
1150                 }
1151         }
1152
1153         return -ENOENT;
1154 }
1155
1156 static int unit_file_can_install(
1157                 LookupPaths *paths,
1158                 const char *root_dir,
1159                 const char *name,
1160                 bool allow_symlink) {
1161
1162         _cleanup_install_context_done_ InstallContext c = {};
1163         InstallInfo *i;
1164         int r;
1165
1166         assert(paths);
1167         assert(name);
1168
1169         r = install_info_add_auto(&c, name);
1170         if (r < 0)
1171                 return r;
1172
1173         assert_se(i = hashmap_first(c.will_install));
1174
1175         r = unit_file_search(&c, i, paths, root_dir, allow_symlink);
1176
1177         if (r >= 0)
1178                 r =
1179                         (int) strv_length(i->aliases) +
1180                         (int) strv_length(i->wanted_by) +
1181                         (int) strv_length(i->required_by);
1182
1183         return r;
1184 }
1185
1186 static int create_symlink(
1187                 const char *old_path,
1188                 const char *new_path,
1189                 bool force,
1190                 UnitFileChange **changes,
1191                 unsigned *n_changes) {
1192
1193         _cleanup_free_ char *dest = NULL;
1194         int r;
1195
1196         assert(old_path);
1197         assert(new_path);
1198
1199         mkdir_parents_label(new_path, 0755);
1200
1201         if (symlink(old_path, new_path) >= 0) {
1202                 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
1203                 return 0;
1204         }
1205
1206         if (errno != EEXIST)
1207                 return -errno;
1208
1209         r = readlink_and_make_absolute(new_path, &dest);
1210         if (r < 0)
1211                 return r;
1212
1213         if (path_equal(dest, old_path))
1214                 return 0;
1215
1216         if (!force)
1217                 return -EEXIST;
1218
1219         r = symlink_atomic(old_path, new_path);
1220         if (r < 0)
1221                 return r;
1222
1223         add_file_change(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);
1224         add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
1225
1226         return 0;
1227 }
1228
1229 static int install_info_symlink_alias(
1230                 InstallInfo *i,
1231                 const char *config_path,
1232                 bool force,
1233                 UnitFileChange **changes,
1234                 unsigned *n_changes) {
1235
1236         char **s;
1237         int r = 0, q;
1238
1239         assert(i);
1240         assert(config_path);
1241
1242         STRV_FOREACH(s, i->aliases) {
1243                 _cleanup_free_ char *alias_path = NULL, *dst = NULL;
1244
1245                 q = install_full_printf(i, *s, &dst);
1246                 if (q < 0)
1247                         return q;
1248
1249                 alias_path = path_make_absolute(dst, config_path);
1250                 if (!alias_path)
1251                         return -ENOMEM;
1252
1253                 q = create_symlink(i->path, alias_path, force, changes, n_changes);
1254                 if (r == 0)
1255                         r = q;
1256         }
1257
1258         return r;
1259 }
1260
1261 static int install_info_symlink_wants(
1262                 InstallInfo *i,
1263                 const char *config_path,
1264                 char **list,
1265                 const char *suffix,
1266                 bool force,
1267                 UnitFileChange **changes,
1268                 unsigned *n_changes) {
1269
1270         _cleanup_free_ char *buf = NULL;
1271         const char *n;
1272         char **s;
1273         int r = 0, q;
1274
1275         assert(i);
1276         assert(config_path);
1277
1278         if (unit_name_is_template(i->name)) {
1279
1280                 /* Don't install any symlink if there's no default
1281                  * instance configured */
1282
1283                 if (!i->default_instance)
1284                         return 0;
1285
1286                 buf = unit_name_replace_instance(i->name, i->default_instance);
1287                 if (!buf)
1288                         return -ENOMEM;
1289
1290                 n = buf;
1291         } else
1292                 n = i->name;
1293
1294         STRV_FOREACH(s, list) {
1295                 _cleanup_free_ char *path = NULL, *dst = NULL;
1296
1297                 q = install_full_printf(i, *s, &dst);
1298                 if (q < 0)
1299                         return q;
1300
1301                 if (!unit_name_is_valid(dst, TEMPLATE_VALID)) {
1302                         r = -EINVAL;
1303                         continue;
1304                 }
1305
1306                 path = strjoin(config_path, "/", dst, suffix, n, NULL);
1307                 if (!path)
1308                         return -ENOMEM;
1309
1310                 q = create_symlink(i->path, path, force, changes, n_changes);
1311                 if (r == 0)
1312                         r = q;
1313         }
1314
1315         return r;
1316 }
1317
1318 static int install_info_symlink_link(
1319                 InstallInfo *i,
1320                 LookupPaths *paths,
1321                 const char *config_path,
1322                 const char *root_dir,
1323                 bool force,
1324                 UnitFileChange **changes,
1325                 unsigned *n_changes) {
1326
1327         _cleanup_free_ char *path = NULL;
1328         int r;
1329
1330         assert(i);
1331         assert(paths);
1332         assert(config_path);
1333         assert(i->path);
1334
1335         r = in_search_path(i->path, paths->unit_path);
1336         if (r != 0)
1337                 return r;
1338
1339         path = strjoin(config_path, "/", i->name, NULL);
1340         if (!path)
1341                 return -ENOMEM;
1342
1343         return create_symlink(i->path, path, force, changes, n_changes);
1344 }
1345
1346 static int install_info_apply(
1347                 InstallInfo *i,
1348                 LookupPaths *paths,
1349                 const char *config_path,
1350                 const char *root_dir,
1351                 bool force,
1352                 UnitFileChange **changes,
1353                 unsigned *n_changes) {
1354
1355         int r, q;
1356
1357         assert(i);
1358         assert(paths);
1359         assert(config_path);
1360
1361         r = install_info_symlink_alias(i, config_path, force, changes, n_changes);
1362
1363         q = install_info_symlink_wants(i, config_path, i->wanted_by, ".wants/", force, changes, n_changes);
1364         if (r == 0)
1365                 r = q;
1366
1367         q = install_info_symlink_wants(i, config_path, i->required_by, ".requires/", force, changes, n_changes);
1368         if (r == 0)
1369                 r = q;
1370
1371         q = install_info_symlink_link(i, paths, config_path, root_dir, force, changes, n_changes);
1372         if (r == 0)
1373                 r = q;
1374
1375         return r;
1376 }
1377
1378 static int install_context_apply(
1379                 InstallContext *c,
1380                 LookupPaths *paths,
1381                 const char *config_path,
1382                 const char *root_dir,
1383                 bool force,
1384                 UnitFileChange **changes,
1385                 unsigned *n_changes) {
1386
1387         InstallInfo *i;
1388         int r = 0, q;
1389
1390         assert(c);
1391         assert(paths);
1392         assert(config_path);
1393
1394         while ((i = hashmap_first(c->will_install))) {
1395
1396                 q = hashmap_ensure_allocated(&c->have_installed, string_hash_func, string_compare_func);
1397                 if (q < 0)
1398                         return q;
1399
1400                 assert_se(hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
1401
1402                 q = unit_file_search(c, i, paths, root_dir, false);
1403                 if (q < 0) {
1404                         if (r >= 0)
1405                                 r = q;
1406
1407                         return r;
1408                 } else if (r >= 0)
1409                         r += q;
1410
1411                 q = install_info_apply(i, paths, config_path, root_dir, force, changes, n_changes);
1412                 if (r >= 0 && q < 0)
1413                         r = q;
1414         }
1415
1416         return r;
1417 }
1418
1419 static int install_context_mark_for_removal(
1420                 InstallContext *c,
1421                 LookupPaths *paths,
1422                 Set **remove_symlinks_to,
1423                 const char *config_path,
1424                 const char *root_dir) {
1425
1426         InstallInfo *i;
1427         int r = 0, q;
1428
1429         assert(c);
1430         assert(paths);
1431         assert(config_path);
1432
1433         /* Marks all items for removal */
1434
1435         while ((i = hashmap_first(c->will_install))) {
1436
1437                 q = hashmap_ensure_allocated(&c->have_installed, string_hash_func, string_compare_func);
1438                 if (q < 0)
1439                         return q;
1440
1441                 assert_se(hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
1442
1443                 q = unit_file_search(c, i, paths, root_dir, false);
1444                 if (q == -ENOENT) {
1445                         /* do nothing */
1446                 } else if (q < 0) {
1447                         if (r >= 0)
1448                                 r = q;
1449
1450                         return r;
1451                 } else if (r >= 0)
1452                         r += q;
1453
1454                 if (unit_name_is_instance(i->name)) {
1455                         char *unit_file;
1456
1457                         if (i->path) {
1458                                 unit_file = basename(i->path);
1459
1460                                 if (unit_name_is_instance(unit_file))
1461                                         /* unit file named as instance exists, thus all symlinks
1462                                          * pointing to it will be removed */
1463                                         q = mark_symlink_for_removal(remove_symlinks_to, i->name);
1464                                 else
1465                                         /* does not exist, thus we will mark for removal symlinks
1466                                          * to template unit file */
1467                                         q = mark_symlink_for_removal(remove_symlinks_to, unit_file);
1468                         } else {
1469                                 /* If i->path is not set, it means that we didn't actually find
1470                                  * the unit file. But we can still remove symlinks to the
1471                                  * nonexistent template. */
1472                                 unit_file = unit_name_template(i->name);
1473                                 if (!unit_file)
1474                                         return log_oom();
1475
1476                                 q = mark_symlink_for_removal(remove_symlinks_to, unit_file);
1477                                 free(unit_file);
1478                         }
1479                 } else
1480                         q = mark_symlink_for_removal(remove_symlinks_to, i->name);
1481
1482                 if (r >= 0 && q < 0)
1483                         r = q;
1484         }
1485
1486         return r;
1487 }
1488
1489 int unit_file_enable(
1490                 UnitFileScope scope,
1491                 bool runtime,
1492                 const char *root_dir,
1493                 char **files,
1494                 bool force,
1495                 UnitFileChange **changes,
1496                 unsigned *n_changes) {
1497
1498         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1499         _cleanup_install_context_done_ InstallContext c = {};
1500         char **i;
1501         _cleanup_free_ char *config_path = NULL;
1502         int r;
1503
1504         assert(scope >= 0);
1505         assert(scope < _UNIT_FILE_SCOPE_MAX);
1506
1507         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1508         if (r < 0)
1509                 return r;
1510
1511         r = get_config_path(scope, runtime, root_dir, &config_path);
1512         if (r < 0)
1513                 return r;
1514
1515         STRV_FOREACH(i, files) {
1516                 r = install_info_add_auto(&c, *i);
1517                 if (r < 0)
1518                         return r;
1519         }
1520
1521         /* This will return the number of symlink rules that were
1522         supposed to be created, not the ones actually created. This is
1523         useful to determine whether the passed files had any
1524         installation data at all. */
1525
1526         return install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes);
1527 }
1528
1529 int unit_file_disable(
1530                 UnitFileScope scope,
1531                 bool runtime,
1532                 const char *root_dir,
1533                 char **files,
1534                 UnitFileChange **changes,
1535                 unsigned *n_changes) {
1536
1537         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1538         _cleanup_install_context_done_ InstallContext c = {};
1539         char **i;
1540         _cleanup_free_ char *config_path = NULL;
1541         _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
1542         int r, q;
1543
1544         assert(scope >= 0);
1545         assert(scope < _UNIT_FILE_SCOPE_MAX);
1546
1547         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1548         if (r < 0)
1549                 return r;
1550
1551         r = get_config_path(scope, runtime, root_dir, &config_path);
1552         if (r < 0)
1553                 return r;
1554
1555         STRV_FOREACH(i, files) {
1556                 r = install_info_add_auto(&c, *i);
1557                 if (r < 0)
1558                         return r;
1559         }
1560
1561         r = install_context_mark_for_removal(&c, &paths, &remove_symlinks_to, config_path, root_dir);
1562
1563         q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
1564         if (r == 0)
1565                 r = q;
1566
1567         return r;
1568 }
1569
1570 int unit_file_reenable(
1571                 UnitFileScope scope,
1572                 bool runtime,
1573                 const char *root_dir,
1574                 char **files,
1575                 bool force,
1576                 UnitFileChange **changes,
1577                 unsigned *n_changes) {
1578         int r;
1579
1580         r = unit_file_disable(scope, runtime, root_dir, files,
1581                               changes, n_changes);
1582         if (r < 0)
1583                 return r;
1584
1585         return unit_file_enable(scope, runtime, root_dir, files, force,
1586                                 changes, n_changes);
1587 }
1588
1589 int unit_file_set_default(
1590                 UnitFileScope scope,
1591                 const char *root_dir,
1592                 const char *file,
1593                 bool force,
1594                 UnitFileChange **changes,
1595                 unsigned *n_changes) {
1596
1597         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1598         _cleanup_install_context_done_ InstallContext c = {};
1599         _cleanup_free_ char *config_path = NULL;
1600         char *path;
1601         int r;
1602         InstallInfo *i = NULL;
1603
1604         assert(scope >= 0);
1605         assert(scope < _UNIT_FILE_SCOPE_MAX);
1606         assert(file);
1607
1608         if (unit_name_to_type(file) != UNIT_TARGET)
1609                 return -EINVAL;
1610
1611         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1612         if (r < 0)
1613                 return r;
1614
1615         r = get_config_path(scope, false, root_dir, &config_path);
1616         if (r < 0)
1617                 return r;
1618
1619         r = install_info_add_auto(&c, file);
1620         if (r < 0)
1621                 return r;
1622
1623         assert_se(i = hashmap_first(c.will_install));
1624
1625         r = unit_file_search(&c, i, &paths, root_dir, false);
1626         if (r < 0)
1627                 return r;
1628
1629         path = strappenda(config_path, "/" SPECIAL_DEFAULT_TARGET);
1630
1631         r = create_symlink(i->path, path, force, changes, n_changes);
1632         if (r < 0)
1633                 return r;
1634
1635         return 0;
1636 }
1637
1638 int unit_file_get_default(
1639                 UnitFileScope scope,
1640                 const char *root_dir,
1641                 char **name) {
1642
1643         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1644         char **p;
1645         int r;
1646
1647         assert(scope >= 0);
1648         assert(scope < _UNIT_FILE_SCOPE_MAX);
1649         assert(name);
1650
1651         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1652         if (r < 0)
1653                 return r;
1654
1655         STRV_FOREACH(p, paths.unit_path) {
1656                 _cleanup_free_ char *path = NULL, *tmp = NULL;
1657                 char *n;
1658
1659                 path = path_join(root_dir, *p, SPECIAL_DEFAULT_TARGET);
1660                 if (!path)
1661                         return -ENOMEM;
1662
1663                 r = readlink_malloc(path, &tmp);
1664                 if (r == -ENOENT)
1665                         continue;
1666                 else if (r == -EINVAL)
1667                         /* not a symlink */
1668                         n = strdup(SPECIAL_DEFAULT_TARGET);
1669                 else if (r < 0)
1670                         return r;
1671                 else
1672                         n = strdup(basename(tmp));
1673
1674                 if (!n)
1675                         return -ENOMEM;
1676
1677                 *name = n;
1678                 return 0;
1679         }
1680
1681         return -ENOENT;
1682 }
1683
1684 UnitFileState unit_file_get_state(
1685                 UnitFileScope scope,
1686                 const char *root_dir,
1687                 const char *name) {
1688
1689         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1690         UnitFileState state = _UNIT_FILE_STATE_INVALID;
1691         char **i;
1692         _cleanup_free_ char *path = NULL;
1693         int r;
1694
1695         assert(scope >= 0);
1696         assert(scope < _UNIT_FILE_SCOPE_MAX);
1697         assert(name);
1698
1699         if (root_dir && scope != UNIT_FILE_SYSTEM)
1700                 return -EINVAL;
1701
1702         if (!unit_name_is_valid(name, TEMPLATE_VALID))
1703                 return -EINVAL;
1704
1705         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1706         if (r < 0)
1707                 return r;
1708
1709         STRV_FOREACH(i, paths.unit_path) {
1710                 struct stat st;
1711                 char *partial;
1712
1713                 free(path);
1714                 path = NULL;
1715
1716                 path = path_join(root_dir, *i, name);
1717                 if (!path)
1718                         return -ENOMEM;
1719
1720                 if (root_dir)
1721                         partial = path + strlen(root_dir);
1722                 else
1723                         partial = path;
1724
1725                 /*
1726                  * Search for a unit file in our default paths, to
1727                  * be sure, that there are no broken symlinks.
1728                  */
1729                 if (lstat(path, &st) < 0) {
1730                         r = -errno;
1731                         if (errno != ENOENT)
1732                                 return r;
1733
1734                         if (!unit_name_is_instance(name))
1735                                 continue;
1736                 } else {
1737                         if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode))
1738                                 return -ENOENT;
1739
1740                         r = null_or_empty_path(path);
1741                         if (r < 0 && r != -ENOENT)
1742                                 return r;
1743                         else if (r > 0) {
1744                                 state = path_startswith(*i, "/run") ?
1745                                         UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
1746                                 return state;
1747                         }
1748                 }
1749
1750                 r = find_symlinks_in_scope(scope, root_dir, name, &state);
1751                 if (r < 0)
1752                         return r;
1753                 else if (r > 0)
1754                         return state;
1755
1756                 r = unit_file_can_install(&paths, root_dir, partial, true);
1757                 if (r < 0 && errno != ENOENT)
1758                         return r;
1759                 else if (r > 0)
1760                         return UNIT_FILE_DISABLED;
1761                 else if (r == 0)
1762                         return UNIT_FILE_STATIC;
1763         }
1764
1765         return r < 0 ? r : state;
1766 }
1767
1768 int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name) {
1769         _cleanup_strv_free_ char **files = NULL;
1770         char **p;
1771         int r;
1772
1773         assert(scope >= 0);
1774         assert(scope < _UNIT_FILE_SCOPE_MAX);
1775         assert(name);
1776
1777         if (scope == UNIT_FILE_SYSTEM)
1778                 r = conf_files_list(&files, ".preset", root_dir,
1779                                     "/etc/systemd/system-preset",
1780                                     "/usr/local/lib/systemd/system-preset",
1781                                     "/usr/lib/systemd/system-preset",
1782 #ifdef HAVE_SPLIT_USR
1783                                     "/lib/systemd/system-preset",
1784 #endif
1785                                     NULL);
1786         else if (scope == UNIT_FILE_GLOBAL)
1787                 r = conf_files_list(&files, ".preset", root_dir,
1788                                     "/etc/systemd/user-preset",
1789                                     "/usr/local/lib/systemd/user-preset",
1790                                     "/usr/lib/systemd/user-preset",
1791                                     NULL);
1792         else
1793                 return 1;
1794
1795         if (r < 0)
1796                 return r;
1797
1798         STRV_FOREACH(p, files) {
1799                 _cleanup_fclose_ FILE *f;
1800
1801                 f = fopen(*p, "re");
1802                 if (!f) {
1803                         if (errno == ENOENT)
1804                                 continue;
1805
1806                         return -errno;
1807                 }
1808
1809                 for (;;) {
1810                         char line[LINE_MAX], *l;
1811
1812                         if (!fgets(line, sizeof(line), f))
1813                                 break;
1814
1815                         l = strstrip(line);
1816                         if (!*l)
1817                                 continue;
1818
1819                         if (strchr(COMMENTS "\n", *l))
1820                                 continue;
1821
1822                         if (first_word(l, "enable")) {
1823                                 l += 6;
1824                                 l += strspn(l, WHITESPACE);
1825
1826                                 if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
1827                                         log_debug("Preset file says enable %s.", name);
1828                                         return 1;
1829                                 }
1830
1831                         } else if (first_word(l, "disable")) {
1832                                 l += 7;
1833                                 l += strspn(l, WHITESPACE);
1834
1835                                 if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
1836                                         log_debug("Preset file says disable %s.", name);
1837                                         return 0;
1838                                 }
1839
1840                         } else
1841                                 log_debug("Couldn't parse line '%s'", l);
1842                 }
1843         }
1844
1845         /* Default is "enable" */
1846         log_debug("Preset file doesn't say anything about %s, enabling.", name);
1847         return 1;
1848 }
1849
1850 int unit_file_preset(
1851                 UnitFileScope scope,
1852                 bool runtime,
1853                 const char *root_dir,
1854                 char **files,
1855                 UnitFilePresetMode mode,
1856                 bool force,
1857                 UnitFileChange **changes,
1858                 unsigned *n_changes) {
1859
1860         _cleanup_install_context_done_ InstallContext plus = {}, minus = {};
1861         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1862         _cleanup_free_ char *config_path = NULL;
1863         char **i;
1864         int r, q;
1865
1866         assert(scope >= 0);
1867         assert(scope < _UNIT_FILE_SCOPE_MAX);
1868         assert(mode < _UNIT_FILE_PRESET_MAX);
1869
1870         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1871         if (r < 0)
1872                 return r;
1873
1874         r = get_config_path(scope, runtime, root_dir, &config_path);
1875         if (r < 0)
1876                 return r;
1877
1878         STRV_FOREACH(i, files) {
1879
1880                 if (!unit_name_is_valid(*i, TEMPLATE_VALID))
1881                         return -EINVAL;
1882
1883                 r = unit_file_query_preset(scope, root_dir, *i);
1884                 if (r < 0)
1885                         return r;
1886
1887                 if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
1888                         r = install_info_add_auto(&plus, *i);
1889                 else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
1890                         r = install_info_add_auto(&minus, *i);
1891                 else
1892                         r = 0;
1893                 if (r < 0)
1894                         return r;
1895         }
1896
1897         r = 0;
1898
1899         if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
1900                 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
1901
1902                 r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
1903
1904                 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
1905                 if (r == 0)
1906                         r = q;
1907         }
1908
1909         if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
1910                 /* Returns number of symlinks that where supposed to be installed. */
1911                 q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
1912                 if (r == 0)
1913                         r = q;
1914         }
1915
1916         return r;
1917 }
1918
1919 int unit_file_preset_all(
1920                 UnitFileScope scope,
1921                 bool runtime,
1922                 const char *root_dir,
1923                 UnitFilePresetMode mode,
1924                 bool force,
1925                 UnitFileChange **changes,
1926                 unsigned *n_changes) {
1927
1928         _cleanup_install_context_done_ InstallContext plus = {}, minus = {};
1929         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1930         _cleanup_free_ char *config_path = NULL;
1931         char **i;
1932         int r, q;
1933
1934         assert(scope >= 0);
1935         assert(scope < _UNIT_FILE_SCOPE_MAX);
1936         assert(mode < _UNIT_FILE_PRESET_MAX);
1937
1938         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1939         if (r < 0)
1940                 return r;
1941
1942         r = get_config_path(scope, runtime, root_dir, &config_path);
1943         if (r < 0)
1944                 return r;
1945
1946         STRV_FOREACH(i, paths.unit_path) {
1947                 _cleanup_closedir_ DIR *d = NULL;
1948                 _cleanup_free_ char *units_dir;
1949
1950                 units_dir = path_join(root_dir, *i, NULL);
1951                 if (!units_dir)
1952                         return -ENOMEM;
1953
1954                 d = opendir(units_dir);
1955                 if (!d) {
1956                         if (errno == ENOENT)
1957                                 continue;
1958
1959                         return -errno;
1960                 }
1961
1962                 for (;;) {
1963                         struct dirent *de;
1964
1965                         errno = 0;
1966                         de = readdir(d);
1967                         if (!de && errno != 0)
1968                                 return -errno;
1969
1970                         if (!de)
1971                                 break;
1972
1973                         if (ignore_file(de->d_name))
1974                                 continue;
1975
1976                         if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
1977                                 continue;
1978
1979                         dirent_ensure_type(d, de);
1980
1981                         if (de->d_type != DT_REG)
1982                                 continue;
1983
1984                         r = unit_file_query_preset(scope, root_dir, de->d_name);
1985                         if (r < 0)
1986                                 return r;
1987
1988                         if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
1989                                 r = install_info_add_auto(&plus, de->d_name);
1990                         else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
1991                                 r = install_info_add_auto(&minus, de->d_name);
1992                         else
1993                                 r = 0;
1994                         if (r < 0)
1995                                 return r;
1996                 }
1997         }
1998
1999         r = 0;
2000
2001         if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
2002                 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
2003
2004                 r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
2005
2006                 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, NULL);
2007                 if (r == 0)
2008                         r = q;
2009         }
2010
2011         if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
2012                 q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
2013                 if (r == 0)
2014                         r = q;
2015         }
2016
2017         return r;
2018 }
2019
2020 static void unitfilelist_free(UnitFileList **f) {
2021         if (!*f)
2022                 return;
2023
2024         free((*f)->path);
2025         free(*f);
2026 }
2027 #define _cleanup_unitfilelist_free_ _cleanup_(unitfilelist_free)
2028
2029 int unit_file_get_list(
2030                 UnitFileScope scope,
2031                 const char *root_dir,
2032                 Hashmap *h) {
2033
2034         _cleanup_lookup_paths_free_ LookupPaths paths = {};
2035         char **i;
2036         int r;
2037
2038         assert(scope >= 0);
2039         assert(scope < _UNIT_FILE_SCOPE_MAX);
2040         assert(h);
2041
2042         if (root_dir && scope != UNIT_FILE_SYSTEM)
2043                 return -EINVAL;
2044
2045         r = lookup_paths_init_from_scope(&paths, scope, root_dir);
2046         if (r < 0)
2047                 return r;
2048
2049         STRV_FOREACH(i, paths.unit_path) {
2050                 _cleanup_closedir_ DIR *d = NULL;
2051                 _cleanup_free_ char *units_dir;
2052
2053                 units_dir = path_join(root_dir, *i, NULL);
2054                 if (!units_dir)
2055                         return -ENOMEM;
2056
2057                 d = opendir(units_dir);
2058                 if (!d) {
2059                         if (errno == ENOENT)
2060                                 continue;
2061
2062                         return -errno;
2063                 }
2064
2065                 for (;;) {
2066                         _cleanup_unitfilelist_free_ UnitFileList *f = NULL;
2067                         struct dirent *de;
2068
2069                         errno = 0;
2070                         de = readdir(d);
2071                         if (!de && errno != 0)
2072                                 return -errno;
2073
2074                         if (!de)
2075                                 break;
2076
2077                         if (ignore_file(de->d_name))
2078                                 continue;
2079
2080                         if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
2081                                 continue;
2082
2083                         if (hashmap_get(h, de->d_name))
2084                                 continue;
2085
2086                         dirent_ensure_type(d, de);
2087
2088                         if (!IN_SET(de->d_type, DT_LNK, DT_REG))
2089                                 continue;
2090
2091                         f = new0(UnitFileList, 1);
2092                         if (!f)
2093                                 return -ENOMEM;
2094
2095                         f->path = path_make_absolute(de->d_name, units_dir);
2096                         if (!f->path)
2097                                 return -ENOMEM;
2098
2099                         r = null_or_empty_path(f->path);
2100                         if (r < 0 && r != -ENOENT)
2101                                 return r;
2102                         else if (r > 0) {
2103                                 f->state =
2104                                         path_startswith(*i, "/run") ?
2105                                         UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
2106                                 goto found;
2107                         }
2108
2109                         r = find_symlinks_in_scope(scope, root_dir, de->d_name, &f->state);
2110                         if (r < 0)
2111                                 return r;
2112                         else if (r > 0) {
2113                                 f->state = UNIT_FILE_ENABLED;
2114                                 goto found;
2115                         }
2116
2117                         r = unit_file_can_install(&paths, root_dir, f->path, true);
2118                         if (r == -EINVAL ||  /* Invalid setting? */
2119                             r == -EBADMSG || /* Invalid format? */
2120                             r == -ENOENT     /* Included file not found? */)
2121                                 f->state = UNIT_FILE_INVALID;
2122                         else if (r < 0)
2123                                 return r;
2124                         else if (r > 0)
2125                                 f->state = UNIT_FILE_DISABLED;
2126                         else
2127                                 f->state = UNIT_FILE_STATIC;
2128
2129                 found:
2130                         r = hashmap_put(h, basename(f->path), f);
2131                         if (r < 0)
2132                                 return r;
2133                         f = NULL; /* prevent cleanup */
2134                 }
2135         }
2136
2137         return r;
2138 }
2139
2140 static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
2141         [UNIT_FILE_ENABLED] = "enabled",
2142         [UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime",
2143         [UNIT_FILE_LINKED] = "linked",
2144         [UNIT_FILE_LINKED_RUNTIME] = "linked-runtime",
2145         [UNIT_FILE_MASKED] = "masked",
2146         [UNIT_FILE_MASKED_RUNTIME] = "masked-runtime",
2147         [UNIT_FILE_STATIC] = "static",
2148         [UNIT_FILE_DISABLED] = "disabled",
2149         [UNIT_FILE_INVALID] = "invalid",
2150 };
2151
2152 DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
2153
2154 static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
2155         [UNIT_FILE_SYMLINK] = "symlink",
2156         [UNIT_FILE_UNLINK] = "unlink",
2157 };
2158
2159 DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
2160
2161 static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = {
2162         [UNIT_FILE_PRESET_FULL] = "full",
2163         [UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
2164         [UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
2165 };
2166
2167 DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode, UnitFilePresetMode);