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