chiark / gitweb /
cfd4a5af8acad9f038ed4b2b4473cd74f93ee0d7
[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_install_context_done_ _cleanup_(install_context_done)
48
49 static int lookup_paths_init_from_scope(LookupPaths *paths, UnitFileScope scope) {
50         assert(paths);
51         assert(scope >= 0);
52         assert(scope < _UNIT_FILE_SCOPE_MAX);
53
54         zero(*paths);
55
56         return lookup_paths_init(paths,
57                                  scope == UNIT_FILE_SYSTEM ? SYSTEMD_SYSTEM : SYSTEMD_USER,
58                                  scope == UNIT_FILE_USER,
59                                  NULL, NULL, NULL);
60 }
61
62 static int get_config_path(UnitFileScope scope, bool runtime, const char *root_dir, char **ret) {
63         char *p = NULL;
64         int r;
65
66         assert(scope >= 0);
67         assert(scope < _UNIT_FILE_SCOPE_MAX);
68         assert(ret);
69
70         switch (scope) {
71
72         case UNIT_FILE_SYSTEM:
73
74                 if (root_dir && runtime)
75                         asprintf(&p, "%s/run/systemd/system", root_dir);
76                 else if (runtime)
77                         p = strdup("/run/systemd/system");
78                 else if (root_dir)
79                         asprintf(&p, "%s/%s", root_dir, SYSTEM_CONFIG_UNIT_PATH);
80                 else
81                         p = strdup(SYSTEM_CONFIG_UNIT_PATH);
82
83                 break;
84
85         case UNIT_FILE_GLOBAL:
86
87                 if (root_dir)
88                         return -EINVAL;
89
90                 if (runtime)
91                         p = strdup("/run/systemd/user");
92                 else
93                         p = strdup(USER_CONFIG_UNIT_PATH);
94                 break;
95
96         case UNIT_FILE_USER:
97
98                 if (root_dir || runtime)
99                         return -EINVAL;
100
101                 r = user_config_home(&p);
102                 if (r <= 0)
103                         return r < 0 ? r : -ENOENT;
104
105                 break;
106
107         default:
108                 assert_not_reached("Bad scope");
109         }
110
111         if (!p)
112                 return -ENOMEM;
113
114         *ret = p;
115         return 0;
116 }
117
118 static int add_file_change(
119                 UnitFileChange **changes,
120                 unsigned *n_changes,
121                 UnitFileChangeType type,
122                 const char *path,
123                 const char *source) {
124
125         UnitFileChange *c;
126         unsigned i;
127
128         assert(path);
129         assert(!changes == !n_changes);
130
131         if (!changes)
132                 return 0;
133
134         c = realloc(*changes, (*n_changes + 1) * sizeof(UnitFileChange));
135         if (!c)
136                 return -ENOMEM;
137
138         *changes = c;
139         i = *n_changes;
140
141         c[i].type = type;
142         c[i].path = strdup(path);
143         if (!c[i].path)
144                 return -ENOMEM;
145
146         if (source) {
147                 c[i].source = strdup(source);
148                 if (!c[i].source) {
149                         free(c[i].path);
150                         return -ENOMEM;
151                 }
152         } else
153                 c[i].source = NULL;
154
155         *n_changes = i+1;
156         return 0;
157 }
158
159 static int mark_symlink_for_removal(
160                 Set **remove_symlinks_to,
161                 const char *p) {
162
163         char *n;
164         int r;
165
166         assert(p);
167
168         r = set_ensure_allocated(remove_symlinks_to, string_hash_func, string_compare_func);
169         if (r < 0)
170                 return r;
171
172         n = strdup(p);
173         if (!n)
174                 return -ENOMEM;
175
176         path_kill_slashes(n);
177
178         r = set_consume(*remove_symlinks_to, n);
179         if (r < 0)
180                 return r == -EEXIST ? 0 : r;
181
182         return 0;
183 }
184
185 static int remove_marked_symlinks_fd(
186                 Set *remove_symlinks_to,
187                 int fd,
188                 const char *path,
189                 const char *config_path,
190                 bool *deleted,
191                 UnitFileChange **changes,
192                 unsigned *n_changes,
193                 char** files) {
194
195         int r = 0;
196         _cleanup_closedir_ DIR *d = NULL;
197
198         assert(remove_symlinks_to);
199         assert(fd >= 0);
200         assert(path);
201         assert(config_path);
202         assert(deleted);
203
204         d = fdopendir(fd);
205         if (!d) {
206                 close_nointr_nofail(fd);
207                 return -errno;
208         }
209
210         rewinddir(d);
211
212         for (;;) {
213                 struct dirent *de;
214                 union dirent_storage buf;
215                 int k;
216
217                 k = readdir_r(d, &buf.de, &de);
218                 if (k != 0) {
219                         r = -errno;
220                         break;
221                 }
222
223                 if (!de)
224                         break;
225
226                 if (ignore_file(de->d_name))
227                         continue;
228
229                 dirent_ensure_type(d, de);
230
231                 if (de->d_type == DT_DIR) {
232                         int nfd, q;
233                         _cleanup_free_ char *p = NULL;
234
235                         nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
236                         if (nfd < 0) {
237                                 if (errno == ENOENT)
238                                         continue;
239
240                                 if (r == 0)
241                                         r = -errno;
242                                 continue;
243                         }
244
245                         p = path_make_absolute(de->d_name, path);
246                         if (!p) {
247                                 close_nointr_nofail(nfd);
248                                 return -ENOMEM;
249                         }
250
251                         /* This will close nfd, regardless whether it succeeds or not */
252                         q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, deleted, changes, n_changes, files);
253
254                         if (r == 0)
255                                 r = q;
256
257                 } else if (de->d_type == DT_LNK) {
258                         _cleanup_free_ char *p = NULL, *dest = NULL;
259                         int q;
260                         bool found;
261
262                         p = path_make_absolute(de->d_name, path);
263                         if (!p)
264                                 return -ENOMEM;
265
266                         q = readlink_and_canonicalize(p, &dest);
267                         if (q < 0) {
268                                 if (q == -ENOENT)
269                                         continue;
270
271                                 if (r == 0)
272                                         r = q;
273                                 continue;
274                         }
275
276                         found =
277                                 set_get(remove_symlinks_to, dest) ||
278                                 set_get(remove_symlinks_to, path_get_file_name(dest));
279
280                         if (unit_name_is_instance(p))
281                                 found = found && strv_contains(files, path_get_file_name(p));
282
283                         if (found) {
284
285                                 if (unlink(p) < 0 && errno != ENOENT) {
286
287                                         if (r == 0)
288                                                 r = -errno;
289                                 } else {
290                                         rmdir_parents(p, config_path);
291                                         path_kill_slashes(p);
292
293                                         add_file_change(changes, n_changes, UNIT_FILE_UNLINK, p, NULL);
294
295                                         if (!set_get(remove_symlinks_to, p)) {
296
297                                                 q = mark_symlink_for_removal(&remove_symlinks_to, p);
298                                                 if (q < 0) {
299                                                         if (r == 0)
300                                                                 r = q;
301                                                 } else
302                                                         *deleted = true;
303                                         }
304                                 }
305                         }
306                 }
307         }
308
309         return r;
310 }
311
312 static int remove_marked_symlinks(
313                 Set *remove_symlinks_to,
314                 const char *config_path,
315                 UnitFileChange **changes,
316                 unsigned *n_changes,
317                 char** files) {
318
319         int fd, r = 0;
320         bool deleted;
321
322         assert(config_path);
323
324         if (set_size(remove_symlinks_to) <= 0)
325                 return 0;
326
327         fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
328         if (fd < 0)
329                 return -errno;
330
331         do {
332                 int q, cfd;
333                 deleted = false;
334
335                 cfd = dup(fd);
336                 if (cfd < 0) {
337                         r = -errno;
338                         break;
339                 }
340
341                 /* This takes possession of cfd and closes it */
342                 q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, &deleted, changes, n_changes, files);
343                 if (r == 0)
344                         r = q;
345         } while (deleted);
346
347         close_nointr_nofail(fd);
348
349         return r;
350 }
351
352 static int find_symlinks_fd(
353                 const char *name,
354                 int fd,
355                 const char *path,
356                 const char *config_path,
357                 bool *same_name_link) {
358
359         int r = 0;
360         _cleanup_closedir_ DIR *d = NULL;
361
362         assert(name);
363         assert(fd >= 0);
364         assert(path);
365         assert(config_path);
366         assert(same_name_link);
367
368         d = fdopendir(fd);
369         if (!d) {
370                 close_nointr_nofail(fd);
371                 return -errno;
372         }
373
374         for (;;) {
375                 int k;
376                 struct dirent *de;
377                 union dirent_storage buf;
378
379                 k = readdir_r(d, &buf.de, &de);
380                 if (k != 0)
381                         return -errno;
382
383                 if (!de)
384                         return r;
385
386                 if (ignore_file(de->d_name))
387                         continue;
388
389                 dirent_ensure_type(d, de);
390
391                 if (de->d_type == DT_DIR) {
392                         int nfd, q;
393                         _cleanup_free_ char *p = NULL;
394
395                         nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
396                         if (nfd < 0) {
397                                 if (errno == ENOENT)
398                                         continue;
399
400                                 if (r == 0)
401                                         r = -errno;
402                                 continue;
403                         }
404
405                         p = path_make_absolute(de->d_name, path);
406                         if (!p) {
407                                 close_nointr_nofail(nfd);
408                                 return -ENOMEM;
409                         }
410
411                         /* This will close nfd, regardless whether it succeeds or not */
412                         q = find_symlinks_fd(name, nfd, p, config_path, same_name_link);
413
414                         if (q > 0)
415                                 return 1;
416
417                         if (r == 0)
418                                 r = q;
419
420                 } else if (de->d_type == DT_LNK) {
421                         _cleanup_free_ char *p = NULL, *dest = NULL;
422                         bool found_path, found_dest, b = false;
423                         int q;
424
425                         /* Acquire symlink name */
426                         p = path_make_absolute(de->d_name, path);
427                         if (!p)
428                                 return -ENOMEM;
429
430                         /* Acquire symlink destination */
431                         q = readlink_and_canonicalize(p, &dest);
432                         if (q < 0) {
433                                 if (q == -ENOENT)
434                                         continue;
435
436                                 if (r == 0)
437                                         r = q;
438                                 continue;
439                         }
440
441                         /* Check if the symlink itself matches what we
442                          * are looking for */
443                         if (path_is_absolute(name))
444                                 found_path = path_equal(p, name);
445                         else
446                                 found_path = streq(de->d_name, name);
447
448                         /* Check if what the symlink points to
449                          * matches what we are looking for */
450                         if (path_is_absolute(name))
451                                 found_dest = path_equal(dest, name);
452                         else
453                                 found_dest = streq(path_get_file_name(dest), name);
454
455                         if (found_path && found_dest) {
456                                 _cleanup_free_ char *t = NULL;
457
458                                 /* Filter out same name links in the main
459                                  * config path */
460                                 t = path_make_absolute(name, config_path);
461                                 if (!t)
462                                         return -ENOMEM;
463
464                                 b = path_equal(t, p);
465                         }
466
467                         if (b)
468                                 *same_name_link = true;
469                         else if (found_path || found_dest)
470                                 return 1;
471                 }
472         }
473
474         return r;
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, true)) {
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, true)) {
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);
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 = path_get_file_name(*i);
721
722                 if (!path_is_absolute(*i) ||
723                     !unit_name_is_valid(fn, true)) {
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 = path_get_file_name(path);
864
865         if (!unit_name_is_valid(name, true))
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                              const char *lvalue,
925                              int ltype,
926                              const char *rvalue,
927                              void *data,
928                              void *userdata) {
929
930         char *w;
931         size_t l;
932         char *state;
933         InstallContext *c = data;
934
935         assert(filename);
936         assert(lvalue);
937         assert(rvalue);
938
939         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
940                 _cleanup_free_ char *n;
941                 int r;
942
943                 n = strndup(w, l);
944                 if (!n)
945                         return -ENOMEM;
946
947                 r = install_info_add(c, n, NULL);
948                 if (r < 0)
949                         return r;
950         }
951
952         return 0;
953 }
954
955 static int config_parse_user(const char *unit,
956                              const char *filename,
957                              unsigned line,
958                              const char *section,
959                              const char *lvalue,
960                              int ltype,
961                              const char *rvalue,
962                              void *data,
963                              void *userdata) {
964
965         InstallInfo *i = data;
966         char* printed;
967         int r;
968
969         assert(filename);
970         assert(lvalue);
971         assert(rvalue);
972
973         r = install_full_printf(i, rvalue, &printed);
974         if (r < 0)
975                 return r;
976
977         free(i->user);
978         i->user = printed;
979
980         return 0;
981 }
982
983 static int unit_file_load(
984                 InstallContext *c,
985                 InstallInfo *info,
986                 const char *path,
987                 bool allow_symlink) {
988
989         const ConfigTableItem items[] = {
990                 { "Install", "Alias",      config_parse_strv, 0, &info->aliases     },
991                 { "Install", "WantedBy",   config_parse_strv, 0, &info->wanted_by   },
992                 { "Install", "RequiredBy", config_parse_strv, 0, &info->required_by },
993                 { "Install", "Also",       config_parse_also, 0, c                  },
994                 { "Exec",    "User",       config_parse_user, 0, info               },
995                 { NULL, NULL, NULL, 0, NULL }
996         };
997
998         int fd;
999         _cleanup_fclose_ FILE *f = NULL;
1000         int r;
1001
1002         assert(c);
1003         assert(info);
1004         assert(path);
1005
1006         fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|(allow_symlink ? 0 : O_NOFOLLOW));
1007         if (fd < 0)
1008                 return -errno;
1009
1010         f = fdopen(fd, "re");
1011         if (!f) {
1012                 close_nointr_nofail(fd);
1013                 return -ENOMEM;
1014         }
1015
1016         r = config_parse(NULL, path, f, NULL,
1017                          config_item_table_lookup, (void*) items, true, true, info);
1018         if (r < 0)
1019                 return r;
1020
1021         return
1022                 strv_length(info->aliases) +
1023                 strv_length(info->wanted_by) +
1024                 strv_length(info->required_by);
1025 }
1026
1027 static int unit_file_search(
1028                 InstallContext *c,
1029                 InstallInfo *info,
1030                 LookupPaths *paths,
1031                 const char *root_dir,
1032                 bool allow_symlink) {
1033
1034         char **p;
1035         int r;
1036
1037         assert(c);
1038         assert(info);
1039         assert(paths);
1040
1041         if (info->path)
1042                 return unit_file_load(c, info, info->path, allow_symlink);
1043
1044         assert(info->name);
1045
1046         STRV_FOREACH(p, paths->unit_path) {
1047                 char *path = NULL;
1048
1049                 if (isempty(root_dir))
1050                         asprintf(&path, "%s/%s", *p, info->name);
1051                 else
1052                         asprintf(&path, "%s/%s/%s", root_dir, *p, info->name);
1053
1054                 if (!path)
1055                         return -ENOMEM;
1056
1057                 r = unit_file_load(c, info, path, allow_symlink);
1058
1059                 if (r >= 0)
1060                         info->path = path;
1061                 else {
1062                         if (r == -ENOENT && unit_name_is_instance(info->name)) {
1063                                 /* Unit file doesn't exist, however instance enablement was requested.
1064                                  * We will check if it is possible to load template unit file. */
1065                                 char *template = NULL,
1066                                      *template_path = NULL,
1067                                      *template_dir = NULL;
1068
1069                                 template = unit_name_template(info->name);
1070                                 if (!template) {
1071                                         free(path);
1072                                         return -ENOMEM;
1073                                 }
1074
1075                                 /* We will reuse path variable since we don't need it anymore. */
1076                                 template_dir = path;
1077                                 *(strrchr(path, '/') + 1) = '\0';
1078
1079                                 template_path = strjoin(template_dir, template, NULL);
1080                                 if (!template_path) {
1081                                         free(path);
1082                                         free(template);
1083                                         return -ENOMEM;
1084                                 }
1085
1086                                 /* Let's try to load template unit. */
1087                                 r = unit_file_load(c, info, template_path, allow_symlink);
1088                                 if (r >= 0) {
1089                                         info->path = strdup(template_path);
1090                                         if (!info->path) {
1091                                                 free(path);
1092                                                 free(template);
1093                                                 free(template_path);
1094                                                 return -ENOMEM;
1095                                         }
1096                                 }
1097
1098                                 free(template);
1099                                 free(template_path);
1100                         }
1101                         free(path);
1102                 }
1103
1104                 if (r != -ENOENT && r != -ELOOP)
1105                         return r;
1106         }
1107
1108         return -ENOENT;
1109 }
1110
1111 static int unit_file_can_install(
1112                 LookupPaths *paths,
1113                 const char *root_dir,
1114                 const char *name,
1115                 bool allow_symlink) {
1116
1117         _cleanup_install_context_done_ InstallContext c = {};
1118         InstallInfo *i;
1119         int r;
1120
1121         assert(paths);
1122         assert(name);
1123
1124         r = install_info_add_auto(&c, name);
1125         if (r < 0)
1126                 return r;
1127
1128         assert_se(i = hashmap_first(c.will_install));
1129
1130         r = unit_file_search(&c, i, paths, root_dir, allow_symlink);
1131
1132         if (r >= 0)
1133                 r =
1134                         strv_length(i->aliases) +
1135                         strv_length(i->wanted_by) +
1136                         strv_length(i->required_by);
1137
1138         return r;
1139 }
1140
1141 static int create_symlink(
1142                 const char *old_path,
1143                 const char *new_path,
1144                 bool force,
1145                 UnitFileChange **changes,
1146                 unsigned *n_changes) {
1147
1148         _cleanup_free_ char *dest = NULL;
1149         int r;
1150
1151         assert(old_path);
1152         assert(new_path);
1153
1154         mkdir_parents_label(new_path, 0755);
1155
1156         if (symlink(old_path, new_path) >= 0) {
1157                 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
1158                 return 0;
1159         }
1160
1161         if (errno != EEXIST)
1162                 return -errno;
1163
1164         r = readlink_and_make_absolute(new_path, &dest);
1165         if (r < 0)
1166                 return r;
1167
1168         if (path_equal(dest, old_path))
1169                 return 0;
1170
1171         if (!force)
1172                 return -EEXIST;
1173
1174         unlink(new_path);
1175
1176         if (symlink(old_path, new_path) >= 0) {
1177                 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);
1178                 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
1179                 return 0;
1180         }
1181
1182         return -errno;
1183 }
1184
1185 static int install_info_symlink_alias(
1186                 InstallInfo *i,
1187                 const char *config_path,
1188                 bool force,
1189                 UnitFileChange **changes,
1190                 unsigned *n_changes) {
1191
1192         char **s;
1193         int r = 0, q;
1194
1195         assert(i);
1196         assert(config_path);
1197
1198         STRV_FOREACH(s, i->aliases) {
1199                 _cleanup_free_ char *alias_path = NULL, *dst = NULL;
1200
1201                 q = install_full_printf(i, *s, &dst);
1202                 if (q < 0)
1203                         return q;
1204
1205                 alias_path = path_make_absolute(dst, config_path);
1206                 if (!alias_path)
1207                         return -ENOMEM;
1208
1209                 q = create_symlink(i->path, alias_path, force, changes, n_changes);
1210                 if (r == 0)
1211                         r = q;
1212         }
1213
1214         return r;
1215 }
1216
1217 static int install_info_symlink_wants(
1218                 InstallInfo *i,
1219                 const char *config_path,
1220                 bool force,
1221                 UnitFileChange **changes,
1222                 unsigned *n_changes) {
1223
1224         char **s;
1225         int r = 0, q;
1226
1227         assert(i);
1228         assert(config_path);
1229
1230         STRV_FOREACH(s, i->wanted_by) {
1231                 _cleanup_free_ char *path = NULL, *dst = NULL;
1232
1233                 q = install_full_printf(i, *s, &dst);
1234                 if (q < 0)
1235                         return q;
1236
1237                 if (!unit_name_is_valid(dst, true)) {
1238                         r = -EINVAL;
1239                         continue;
1240                 }
1241
1242                 if (asprintf(&path, "%s/%s.wants/%s", config_path, dst, i->name) < 0)
1243                         return -ENOMEM;
1244
1245                 q = create_symlink(i->path, path, force, changes, n_changes);
1246
1247                 if (r == 0)
1248                         r = q;
1249         }
1250
1251         return r;
1252 }
1253
1254 static int install_info_symlink_requires(
1255                 InstallInfo *i,
1256                 const char *config_path,
1257                 bool force,
1258                 UnitFileChange **changes,
1259                 unsigned *n_changes) {
1260
1261         char **s;
1262         int r = 0, q;
1263
1264         assert(i);
1265         assert(config_path);
1266
1267         STRV_FOREACH(s, i->required_by) {
1268                 _cleanup_free_ char *path = NULL, *dst = NULL;
1269
1270                 q = install_full_printf(i, *s, &dst);
1271                 if (q < 0)
1272                         return q;
1273
1274                 if (!unit_name_is_valid(dst, true)) {
1275                         r = -EINVAL;
1276                         continue;
1277                 }
1278
1279                 if (asprintf(&path, "%s/%s.requires/%s", config_path, dst, i->name) < 0)
1280                         return -ENOMEM;
1281
1282                 q = create_symlink(i->path, path, force, changes, n_changes);
1283
1284                 if (r == 0)
1285                         r = q;
1286         }
1287
1288         return r;
1289 }
1290
1291 static int install_info_symlink_link(
1292                 InstallInfo *i,
1293                 LookupPaths *paths,
1294                 const char *config_path,
1295                 bool force,
1296                 UnitFileChange **changes,
1297                 unsigned *n_changes) {
1298
1299         int r;
1300         _cleanup_free_ char *path = NULL;
1301
1302         assert(i);
1303         assert(paths);
1304         assert(config_path);
1305         assert(i->path);
1306
1307         r = in_search_path(i->path, paths->unit_path);
1308         if (r != 0)
1309                 return r;
1310
1311         if (asprintf(&path, "%s/%s", config_path, i->name) < 0)
1312                 return -ENOMEM;
1313
1314         r = create_symlink(i->path, path, force, changes, n_changes);
1315         return r;
1316 }
1317
1318 static int install_info_apply(
1319                 InstallInfo *i,
1320                 LookupPaths *paths,
1321                 const char *config_path,
1322                 bool force,
1323                 UnitFileChange **changes,
1324                 unsigned *n_changes) {
1325
1326         int r, q;
1327
1328         assert(i);
1329         assert(paths);
1330         assert(config_path);
1331
1332         r = install_info_symlink_alias(i, config_path, force, changes, n_changes);
1333
1334         q = install_info_symlink_wants(i, config_path, force, changes, n_changes);
1335         if (r == 0)
1336                 r = q;
1337
1338         q = install_info_symlink_requires(i, config_path, force, changes, n_changes);
1339         if (r == 0)
1340                 r = q;
1341
1342         q = install_info_symlink_link(i, paths, config_path, force, changes, n_changes);
1343         if (r == 0)
1344                 r = q;
1345
1346         return r;
1347 }
1348
1349 static int install_context_apply(
1350                 InstallContext *c,
1351                 LookupPaths *paths,
1352                 const char *config_path,
1353                 const char *root_dir,
1354                 bool force,
1355                 UnitFileChange **changes,
1356                 unsigned *n_changes) {
1357
1358         InstallInfo *i;
1359         int r = 0, q;
1360
1361         assert(c);
1362         assert(paths);
1363         assert(config_path);
1364
1365         while ((i = hashmap_first(c->will_install))) {
1366
1367                 q = hashmap_ensure_allocated(&c->have_installed, string_hash_func, string_compare_func);
1368                 if (q < 0)
1369                         return q;
1370
1371                 assert_se(hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
1372
1373                 q = unit_file_search(c, i, paths, root_dir, false);
1374                 if (q < 0) {
1375                         if (r >= 0)
1376                                 r = q;
1377
1378                         return r;
1379                 } else if (r >= 0)
1380                         r += q;
1381
1382                 q = install_info_apply(i, paths, config_path, force, changes, n_changes);
1383                 if (r >= 0 && q < 0)
1384                         r = q;
1385         }
1386
1387         return r;
1388 }
1389
1390 static int install_context_mark_for_removal(
1391                 InstallContext *c,
1392                 LookupPaths *paths,
1393                 Set **remove_symlinks_to,
1394                 const char *config_path,
1395                 const char *root_dir) {
1396
1397         InstallInfo *i;
1398         int r = 0, q;
1399
1400         assert(c);
1401         assert(paths);
1402         assert(config_path);
1403
1404         /* Marks all items for removal */
1405
1406         while ((i = hashmap_first(c->will_install))) {
1407
1408                 q = hashmap_ensure_allocated(&c->have_installed, string_hash_func, string_compare_func);
1409                 if (q < 0)
1410                         return q;
1411
1412                 assert_se(hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
1413
1414                 q = unit_file_search(c, i, paths, root_dir, false);
1415                 if (q == -ENOENT) {
1416                         /* do nothing */
1417                 } else if (q < 0) {
1418                         if (r >= 0)
1419                                 r = q;
1420
1421                         return r;
1422                 } else if (r >= 0)
1423                         r += q;
1424
1425                 if (unit_name_is_instance(i->name)) {
1426                         char *unit_file;
1427
1428                         if (i->path) {
1429                                 unit_file = path_get_file_name(i->path);
1430
1431                                 if (unit_name_is_instance(unit_file))
1432                                         /* unit file named as instance exists, thus all symlinks
1433                                          * pointing to it will be removed */
1434                                         q = mark_symlink_for_removal(remove_symlinks_to, i->name);
1435                                 else
1436                                         /* does not exist, thus we will mark for removal symlinks
1437                                          * to template unit file */
1438                                         q = mark_symlink_for_removal(remove_symlinks_to, unit_file);
1439                         } else {
1440                                 /* If i->path is not set, it means that we didn't actually find
1441                                  * the unit file. But we can still remove symlinks to the
1442                                  * nonexistent template. */
1443                                 unit_file = unit_name_template(i->name);
1444                                 if (!unit_file)
1445                                         return log_oom();
1446
1447                                 q = mark_symlink_for_removal(remove_symlinks_to, unit_file);
1448                                 free(unit_file);
1449                         }
1450                 } else
1451                         q = mark_symlink_for_removal(remove_symlinks_to, i->name);
1452
1453                 if (r >= 0 && q < 0)
1454                         r = q;
1455         }
1456
1457         return r;
1458 }
1459
1460 int unit_file_enable(
1461                 UnitFileScope scope,
1462                 bool runtime,
1463                 const char *root_dir,
1464                 char *files[],
1465                 bool force,
1466                 UnitFileChange **changes,
1467                 unsigned *n_changes) {
1468
1469         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1470         _cleanup_install_context_done_ InstallContext c = {};
1471         char **i;
1472         _cleanup_free_ char *config_path = NULL;
1473         int r;
1474
1475         assert(scope >= 0);
1476         assert(scope < _UNIT_FILE_SCOPE_MAX);
1477
1478         r = lookup_paths_init_from_scope(&paths, scope);
1479         if (r < 0)
1480                 return r;
1481
1482         r = get_config_path(scope, runtime, root_dir, &config_path);
1483         if (r < 0)
1484                 return r;
1485
1486         STRV_FOREACH(i, files) {
1487                 r = install_info_add_auto(&c, *i);
1488                 if (r < 0)
1489                         return r;
1490         }
1491
1492         /* This will return the number of symlink rules that were
1493         supposed to be created, not the ones actually created. This is
1494         useful to determine whether the passed files had any
1495         installation data at all. */
1496         r = install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes);
1497         return r;
1498 }
1499
1500 int unit_file_disable(
1501                 UnitFileScope scope,
1502                 bool runtime,
1503                 const char *root_dir,
1504                 char *files[],
1505                 UnitFileChange **changes,
1506                 unsigned *n_changes) {
1507
1508         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1509         _cleanup_install_context_done_ InstallContext c = {};
1510         char **i;
1511         _cleanup_free_ char *config_path = NULL;
1512         _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
1513         int r, q;
1514
1515         assert(scope >= 0);
1516         assert(scope < _UNIT_FILE_SCOPE_MAX);
1517
1518         r = lookup_paths_init_from_scope(&paths, scope);
1519         if (r < 0)
1520                 return r;
1521
1522         r = get_config_path(scope, runtime, root_dir, &config_path);
1523         if (r < 0)
1524                 return r;
1525
1526         STRV_FOREACH(i, files) {
1527                 r = install_info_add_auto(&c, *i);
1528                 if (r < 0)
1529                         return r;
1530         }
1531
1532         r = install_context_mark_for_removal(&c, &paths, &remove_symlinks_to, config_path, root_dir);
1533
1534         q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
1535         if (r == 0)
1536                 r = q;
1537
1538         return r;
1539 }
1540
1541 int unit_file_reenable(
1542                 UnitFileScope scope,
1543                 bool runtime,
1544                 const char *root_dir,
1545                 char *files[],
1546                 bool force,
1547                 UnitFileChange **changes,
1548                 unsigned *n_changes) {
1549         int r;
1550
1551         r = unit_file_disable(scope, runtime, root_dir, files,
1552                               changes, n_changes);
1553         if (r < 0)
1554                 return r;
1555
1556         return unit_file_enable(scope, runtime, root_dir, files, force,
1557                                 changes, n_changes);
1558 }
1559
1560 int unit_file_set_default(
1561                 UnitFileScope scope,
1562                 const char *root_dir,
1563                 char *file,
1564                 UnitFileChange **changes,
1565                 unsigned *n_changes) {
1566
1567         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1568         _cleanup_install_context_done_ InstallContext c = {};
1569         _cleanup_free_ char *config_path = NULL;
1570         char *path;
1571         int r;
1572         InstallInfo *i = NULL;
1573
1574         assert(scope >= 0);
1575         assert(scope < _UNIT_FILE_SCOPE_MAX);
1576
1577         if (unit_name_to_type(file) != UNIT_TARGET)
1578                 return -EINVAL;
1579
1580         r = lookup_paths_init_from_scope(&paths, scope);
1581         if (r < 0)
1582                 return r;
1583
1584         r = get_config_path(scope, false, root_dir, &config_path);
1585         if (r < 0)
1586                 return r;
1587
1588         r = install_info_add_auto(&c, file);
1589         if (r < 0)
1590                 return r;
1591
1592         i = (InstallInfo*)hashmap_first(c.will_install);
1593
1594         r = unit_file_search(&c, i, &paths, root_dir, false);
1595         if (r < 0)
1596                 return r;
1597
1598         path = strappenda(config_path, "/default.target");
1599         r = create_symlink(i->path, path, true, changes, n_changes);
1600         if (r < 0)
1601                 return r;
1602
1603         return 0;
1604 }
1605
1606 int unit_file_get_default(
1607                 UnitFileScope scope,
1608                 const char *root_dir,
1609                 char **name) {
1610
1611         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1612         char **p;
1613         int r;
1614
1615         r = lookup_paths_init_from_scope(&paths, scope);
1616         if (r < 0)
1617                 return r;
1618
1619         STRV_FOREACH(p, paths.unit_path) {
1620                 _cleanup_free_ char *path = NULL, *tmp = NULL;
1621                 char *n;
1622
1623                 if (isempty(root_dir))
1624                         path = strappend(*p, "/default.target");
1625                 else
1626                         path = strjoin(root_dir, "/", *p, "/default.target", NULL);
1627
1628                 if (!path)
1629                         return -ENOMEM;
1630
1631                 r = readlink_malloc(path, &tmp);
1632                 if (r == -ENOENT)
1633                         continue;
1634                 if (r < 0)
1635                         return r;
1636
1637                 n = strdup(path_get_file_name(tmp));
1638                 if (!n)
1639                         return -ENOMEM;
1640
1641                 *name = n;
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 #define _cleanup_unitfilelist_free_ _cleanup_(unitfilelist_free)
1877
1878 int unit_file_get_list(
1879                 UnitFileScope scope,
1880                 const char *root_dir,
1881                 Hashmap *h) {
1882
1883         _cleanup_lookup_paths_free_ LookupPaths paths = {};
1884         char **i;
1885         _cleanup_free_ char *buf = NULL;
1886         _cleanup_closedir_ DIR *d = NULL;
1887         int r;
1888
1889         assert(scope >= 0);
1890         assert(scope < _UNIT_FILE_SCOPE_MAX);
1891         assert(h);
1892
1893         if (root_dir && scope != UNIT_FILE_SYSTEM)
1894                 return -EINVAL;
1895
1896         r = lookup_paths_init_from_scope(&paths, scope);
1897         if (r < 0)
1898                 return r;
1899
1900         STRV_FOREACH(i, paths.unit_path) {
1901                 const char *units_dir;
1902
1903                 free(buf);
1904                 buf = NULL;
1905
1906                 if (root_dir) {
1907                         if (asprintf(&buf, "%s/%s", root_dir, *i) < 0)
1908                                 return -ENOMEM;
1909
1910                         units_dir = buf;
1911                 } else
1912                         units_dir = *i;
1913
1914                 if (d)
1915                         closedir(d);
1916
1917                 d = opendir(units_dir);
1918                 if (!d) {
1919                         if (errno == ENOENT)
1920                                 continue;
1921
1922                         return -errno;
1923                 }
1924
1925                 for (;;) {
1926                         struct dirent *de;
1927                         union dirent_storage buffer;
1928                         _cleanup_unitfilelist_free_ UnitFileList *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);