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