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