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