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