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