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