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