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