]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/install.c
shared/install: when unit contains only Also=, report 'indirect'
[thirdparty/systemd.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 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 strv_free(i->also);
844 free(i->default_instance);
845 free(i);
846 }
847
848 static void install_info_hashmap_free(OrderedHashmap *m) {
849 InstallInfo *i;
850
851 if (!m)
852 return;
853
854 while ((i = ordered_hashmap_steal_first(m)))
855 install_info_free(i);
856
857 ordered_hashmap_free(m);
858 }
859
860 static void install_context_done(InstallContext *c) {
861 assert(c);
862
863 install_info_hashmap_free(c->will_install);
864 install_info_hashmap_free(c->have_installed);
865
866 c->will_install = c->have_installed = NULL;
867 }
868
869 static int install_info_add(
870 InstallContext *c,
871 const char *name,
872 const char *path) {
873 InstallInfo *i = NULL;
874 int r;
875
876 assert(c);
877 assert(name || path);
878
879 if (!name)
880 name = basename(path);
881
882 if (!unit_name_is_valid(name, TEMPLATE_VALID))
883 return -EINVAL;
884
885 if (ordered_hashmap_get(c->have_installed, name) ||
886 ordered_hashmap_get(c->will_install, name))
887 return 0;
888
889 r = ordered_hashmap_ensure_allocated(&c->will_install, &string_hash_ops);
890 if (r < 0)
891 return r;
892
893 i = new0(InstallInfo, 1);
894 if (!i)
895 return -ENOMEM;
896
897 i->name = strdup(name);
898 if (!i->name) {
899 r = -ENOMEM;
900 goto fail;
901 }
902
903 if (path) {
904 i->path = strdup(path);
905 if (!i->path) {
906 r = -ENOMEM;
907 goto fail;
908 }
909 }
910
911 r = ordered_hashmap_put(c->will_install, i->name, i);
912 if (r < 0)
913 goto fail;
914
915 return 0;
916
917 fail:
918 if (i)
919 install_info_free(i);
920
921 return r;
922 }
923
924 static int install_info_add_auto(
925 InstallContext *c,
926 const char *name_or_path) {
927
928 assert(c);
929 assert(name_or_path);
930
931 if (path_is_absolute(name_or_path))
932 return install_info_add(c, NULL, name_or_path);
933 else
934 return install_info_add(c, name_or_path, NULL);
935 }
936
937 static int config_parse_also(
938 const char *unit,
939 const char *filename,
940 unsigned line,
941 const char *section,
942 unsigned section_line,
943 const char *lvalue,
944 int ltype,
945 const char *rvalue,
946 void *data,
947 void *userdata) {
948
949 size_t l;
950 const char *word, *state;
951 InstallContext *c = data;
952 InstallInfo *i = userdata;
953
954 assert(filename);
955 assert(lvalue);
956 assert(rvalue);
957
958 FOREACH_WORD_QUOTED(word, l, rvalue, state) {
959 _cleanup_free_ char *n;
960 int r;
961
962 n = strndup(word, l);
963 if (!n)
964 return -ENOMEM;
965
966 r = install_info_add(c, n, NULL);
967 if (r < 0)
968 return r;
969
970 r = strv_extend(&i->also, n);
971 if (r < 0)
972 return r;
973 }
974 if (!isempty(state))
975 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
976 "Trailing garbage, ignoring.");
977
978 return 0;
979 }
980
981 static int config_parse_user(
982 const char *unit,
983 const char *filename,
984 unsigned line,
985 const char *section,
986 unsigned section_line,
987 const char *lvalue,
988 int ltype,
989 const char *rvalue,
990 void *data,
991 void *userdata) {
992
993 InstallInfo *i = data;
994 char *printed;
995 int r;
996
997 assert(filename);
998 assert(lvalue);
999 assert(rvalue);
1000
1001 r = install_full_printf(i, rvalue, &printed);
1002 if (r < 0)
1003 return r;
1004
1005 free(i->user);
1006 i->user = printed;
1007
1008 return 0;
1009 }
1010
1011 static int config_parse_default_instance(
1012 const char *unit,
1013 const char *filename,
1014 unsigned line,
1015 const char *section,
1016 unsigned section_line,
1017 const char *lvalue,
1018 int ltype,
1019 const char *rvalue,
1020 void *data,
1021 void *userdata) {
1022
1023 InstallInfo *i = data;
1024 char *printed;
1025 int r;
1026
1027 assert(filename);
1028 assert(lvalue);
1029 assert(rvalue);
1030
1031 r = install_full_printf(i, rvalue, &printed);
1032 if (r < 0)
1033 return r;
1034
1035 if (!unit_instance_is_valid(printed)) {
1036 free(printed);
1037 return -EINVAL;
1038 }
1039
1040 free(i->default_instance);
1041 i->default_instance = printed;
1042
1043 return 0;
1044 }
1045
1046 static int unit_file_load(
1047 InstallContext *c,
1048 InstallInfo *info,
1049 const char *path,
1050 const char *root_dir,
1051 bool allow_symlink,
1052 bool load,
1053 bool *also) {
1054
1055 const ConfigTableItem items[] = {
1056 { "Install", "Alias", config_parse_strv, 0, &info->aliases },
1057 { "Install", "WantedBy", config_parse_strv, 0, &info->wanted_by },
1058 { "Install", "RequiredBy", config_parse_strv, 0, &info->required_by },
1059 { "Install", "DefaultInstance", config_parse_default_instance, 0, info },
1060 { "Install", "Also", config_parse_also, 0, c },
1061 { "Exec", "User", config_parse_user, 0, info },
1062 {}
1063 };
1064
1065 _cleanup_fclose_ FILE *f = NULL;
1066 int fd, r;
1067
1068 assert(c);
1069 assert(info);
1070 assert(path);
1071
1072 if (!isempty(root_dir))
1073 path = strappenda(root_dir, "/", path);
1074
1075 if (!load) {
1076 r = access(path, F_OK) ? -errno : 0;
1077 return r;
1078 }
1079
1080 fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|(allow_symlink ? 0 : O_NOFOLLOW));
1081 if (fd < 0)
1082 return -errno;
1083
1084 f = fdopen(fd, "re");
1085 if (!f) {
1086 safe_close(fd);
1087 return -ENOMEM;
1088 }
1089
1090 r = config_parse(NULL, path, f,
1091 NULL,
1092 config_item_table_lookup, items,
1093 true, true, false, info);
1094 if (r < 0)
1095 return r;
1096
1097 if (also)
1098 *also = !strv_isempty(info->also);
1099
1100 return
1101 (int) strv_length(info->aliases) +
1102 (int) strv_length(info->wanted_by) +
1103 (int) strv_length(info->required_by);
1104 }
1105
1106 static int unit_file_search(
1107 InstallContext *c,
1108 InstallInfo *info,
1109 LookupPaths *paths,
1110 const char *root_dir,
1111 bool allow_symlink,
1112 bool load,
1113 bool *also) {
1114
1115 char **p;
1116 int r;
1117
1118 assert(c);
1119 assert(info);
1120 assert(paths);
1121
1122 if (info->path)
1123 return unit_file_load(c, info, info->path, root_dir, allow_symlink, load, also);
1124
1125 assert(info->name);
1126
1127 STRV_FOREACH(p, paths->unit_path) {
1128 _cleanup_free_ char *path = NULL;
1129
1130 path = strjoin(*p, "/", info->name, NULL);
1131 if (!path)
1132 return -ENOMEM;
1133
1134 r = unit_file_load(c, info, path, root_dir, allow_symlink, load, also);
1135 if (r >= 0) {
1136 info->path = path;
1137 path = NULL;
1138 return r;
1139 }
1140 if (r != -ENOENT && r != -ELOOP)
1141 return r;
1142 }
1143
1144 if (unit_name_is_instance(info->name)) {
1145
1146 /* Unit file doesn't exist, however instance
1147 * enablement was requested. We will check if it is
1148 * possible to load template unit file. */
1149
1150 _cleanup_free_ char *template = NULL;
1151
1152 template = unit_name_template(info->name);
1153 if (!template)
1154 return -ENOMEM;
1155
1156 STRV_FOREACH(p, paths->unit_path) {
1157 _cleanup_free_ char *path = NULL;
1158
1159 path = strjoin(*p, "/", template, NULL);
1160 if (!path)
1161 return -ENOMEM;
1162
1163 r = unit_file_load(c, info, path, root_dir, allow_symlink, load, also);
1164 if (r >= 0) {
1165 info->path = path;
1166 path = NULL;
1167 return r;
1168 }
1169 if (r != -ENOENT && r != -ELOOP)
1170 return r;
1171 }
1172 }
1173
1174 return -ENOENT;
1175 }
1176
1177 static int unit_file_can_install(
1178 LookupPaths *paths,
1179 const char *root_dir,
1180 const char *name,
1181 bool allow_symlink,
1182 bool *also) {
1183
1184 _cleanup_(install_context_done) InstallContext c = {};
1185 InstallInfo *i;
1186 int r;
1187
1188 assert(paths);
1189 assert(name);
1190
1191 r = install_info_add_auto(&c, name);
1192 if (r < 0)
1193 return r;
1194
1195 assert_se(i = ordered_hashmap_first(c.will_install));
1196
1197 r = unit_file_search(&c, i, paths, root_dir, allow_symlink, true, also);
1198
1199 if (r >= 0)
1200 r =
1201 (int) strv_length(i->aliases) +
1202 (int) strv_length(i->wanted_by) +
1203 (int) strv_length(i->required_by);
1204
1205 return r;
1206 }
1207
1208 static int create_symlink(
1209 const char *old_path,
1210 const char *new_path,
1211 bool force,
1212 UnitFileChange **changes,
1213 unsigned *n_changes) {
1214
1215 _cleanup_free_ char *dest = NULL;
1216 int r;
1217
1218 assert(old_path);
1219 assert(new_path);
1220
1221 mkdir_parents_label(new_path, 0755);
1222
1223 if (symlink(old_path, new_path) >= 0) {
1224 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
1225 return 0;
1226 }
1227
1228 if (errno != EEXIST)
1229 return -errno;
1230
1231 r = readlink_and_make_absolute(new_path, &dest);
1232 if (r < 0)
1233 return r;
1234
1235 if (path_equal(dest, old_path))
1236 return 0;
1237
1238 if (!force)
1239 return -EEXIST;
1240
1241 r = symlink_atomic(old_path, new_path);
1242 if (r < 0)
1243 return r;
1244
1245 add_file_change(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);
1246 add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
1247
1248 return 0;
1249 }
1250
1251 static int install_info_symlink_alias(
1252 InstallInfo *i,
1253 const char *config_path,
1254 bool force,
1255 UnitFileChange **changes,
1256 unsigned *n_changes) {
1257
1258 char **s;
1259 int r = 0, q;
1260
1261 assert(i);
1262 assert(config_path);
1263
1264 STRV_FOREACH(s, i->aliases) {
1265 _cleanup_free_ char *alias_path = NULL, *dst = NULL;
1266
1267 q = install_full_printf(i, *s, &dst);
1268 if (q < 0)
1269 return q;
1270
1271 alias_path = path_make_absolute(dst, config_path);
1272 if (!alias_path)
1273 return -ENOMEM;
1274
1275 q = create_symlink(i->path, alias_path, force, changes, n_changes);
1276 if (r == 0)
1277 r = q;
1278 }
1279
1280 return r;
1281 }
1282
1283 static int install_info_symlink_wants(
1284 InstallInfo *i,
1285 const char *config_path,
1286 char **list,
1287 const char *suffix,
1288 bool force,
1289 UnitFileChange **changes,
1290 unsigned *n_changes) {
1291
1292 _cleanup_free_ char *buf = NULL;
1293 const char *n;
1294 char **s;
1295 int r = 0, q;
1296
1297 assert(i);
1298 assert(config_path);
1299
1300 if (unit_name_is_template(i->name)) {
1301
1302 /* Don't install any symlink if there's no default
1303 * instance configured */
1304
1305 if (!i->default_instance)
1306 return 0;
1307
1308 buf = unit_name_replace_instance(i->name, i->default_instance);
1309 if (!buf)
1310 return -ENOMEM;
1311
1312 n = buf;
1313 } else
1314 n = i->name;
1315
1316 STRV_FOREACH(s, list) {
1317 _cleanup_free_ char *path = NULL, *dst = NULL;
1318
1319 q = install_full_printf(i, *s, &dst);
1320 if (q < 0)
1321 return q;
1322
1323 if (!unit_name_is_valid(dst, TEMPLATE_VALID)) {
1324 r = -EINVAL;
1325 continue;
1326 }
1327
1328 path = strjoin(config_path, "/", dst, suffix, n, NULL);
1329 if (!path)
1330 return -ENOMEM;
1331
1332 q = create_symlink(i->path, path, force, changes, n_changes);
1333 if (r == 0)
1334 r = q;
1335 }
1336
1337 return r;
1338 }
1339
1340 static int install_info_symlink_link(
1341 InstallInfo *i,
1342 LookupPaths *paths,
1343 const char *config_path,
1344 const char *root_dir,
1345 bool force,
1346 UnitFileChange **changes,
1347 unsigned *n_changes) {
1348
1349 _cleanup_free_ char *path = NULL;
1350 int r;
1351
1352 assert(i);
1353 assert(paths);
1354 assert(config_path);
1355 assert(i->path);
1356
1357 r = in_search_path(i->path, paths->unit_path);
1358 if (r != 0)
1359 return r;
1360
1361 path = strjoin(config_path, "/", i->name, NULL);
1362 if (!path)
1363 return -ENOMEM;
1364
1365 return create_symlink(i->path, path, force, changes, n_changes);
1366 }
1367
1368 static int install_info_apply(
1369 InstallInfo *i,
1370 LookupPaths *paths,
1371 const char *config_path,
1372 const char *root_dir,
1373 bool force,
1374 UnitFileChange **changes,
1375 unsigned *n_changes) {
1376
1377 int r, q;
1378
1379 assert(i);
1380 assert(paths);
1381 assert(config_path);
1382
1383 r = install_info_symlink_alias(i, config_path, force, changes, n_changes);
1384
1385 q = install_info_symlink_wants(i, config_path, i->wanted_by, ".wants/", force, changes, n_changes);
1386 if (r == 0)
1387 r = q;
1388
1389 q = install_info_symlink_wants(i, config_path, i->required_by, ".requires/", force, changes, n_changes);
1390 if (r == 0)
1391 r = q;
1392
1393 q = install_info_symlink_link(i, paths, config_path, root_dir, force, changes, n_changes);
1394 if (r == 0)
1395 r = q;
1396
1397 return r;
1398 }
1399
1400 static int install_context_apply(
1401 InstallContext *c,
1402 LookupPaths *paths,
1403 const char *config_path,
1404 const char *root_dir,
1405 bool force,
1406 UnitFileChange **changes,
1407 unsigned *n_changes) {
1408
1409 InstallInfo *i;
1410 int r, q;
1411
1412 assert(c);
1413 assert(paths);
1414 assert(config_path);
1415
1416 if (!ordered_hashmap_isempty(c->will_install)) {
1417 r = ordered_hashmap_ensure_allocated(&c->have_installed, &string_hash_ops);
1418 if (r < 0)
1419 return r;
1420
1421 r = ordered_hashmap_reserve(c->have_installed, ordered_hashmap_size(c->will_install));
1422 if (r < 0)
1423 return r;
1424 }
1425
1426 r = 0;
1427 while ((i = ordered_hashmap_first(c->will_install))) {
1428 assert_se(ordered_hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
1429
1430 q = unit_file_search(c, i, paths, root_dir, false, true, NULL);
1431 if (q < 0) {
1432 if (r >= 0)
1433 r = q;
1434
1435 return r;
1436 } else if (r >= 0)
1437 r += q;
1438
1439 q = install_info_apply(i, paths, config_path, root_dir, force, changes, n_changes);
1440 if (r >= 0 && q < 0)
1441 r = q;
1442 }
1443
1444 return r;
1445 }
1446
1447 static int install_context_mark_for_removal(
1448 InstallContext *c,
1449 LookupPaths *paths,
1450 Set **remove_symlinks_to,
1451 const char *config_path,
1452 const char *root_dir) {
1453
1454 InstallInfo *i;
1455 int r, q;
1456
1457 assert(c);
1458 assert(paths);
1459 assert(config_path);
1460
1461 /* Marks all items for removal */
1462
1463 if (!ordered_hashmap_isempty(c->will_install)) {
1464 r = ordered_hashmap_ensure_allocated(&c->have_installed, &string_hash_ops);
1465 if (r < 0)
1466 return r;
1467
1468 r = ordered_hashmap_reserve(c->have_installed, ordered_hashmap_size(c->will_install));
1469 if (r < 0)
1470 return r;
1471 }
1472
1473 r = 0;
1474 while ((i = ordered_hashmap_first(c->will_install))) {
1475 assert_se(ordered_hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
1476
1477 q = unit_file_search(c, i, paths, root_dir, false, true, NULL);
1478 if (q == -ENOENT) {
1479 /* do nothing */
1480 } else if (q < 0) {
1481 if (r >= 0)
1482 r = q;
1483
1484 return r;
1485 } else if (r >= 0)
1486 r += q;
1487
1488 if (unit_name_is_instance(i->name)) {
1489 char *unit_file;
1490
1491 if (i->path) {
1492 unit_file = basename(i->path);
1493
1494 if (unit_name_is_instance(unit_file))
1495 /* unit file named as instance exists, thus all symlinks
1496 * pointing to it will be removed */
1497 q = mark_symlink_for_removal(remove_symlinks_to, i->name);
1498 else
1499 /* does not exist, thus we will mark for removal symlinks
1500 * to template unit file */
1501 q = mark_symlink_for_removal(remove_symlinks_to, unit_file);
1502 } else {
1503 /* If i->path is not set, it means that we didn't actually find
1504 * the unit file. But we can still remove symlinks to the
1505 * nonexistent template. */
1506 unit_file = unit_name_template(i->name);
1507 if (!unit_file)
1508 return log_oom();
1509
1510 q = mark_symlink_for_removal(remove_symlinks_to, unit_file);
1511 free(unit_file);
1512 }
1513 } else
1514 q = mark_symlink_for_removal(remove_symlinks_to, i->name);
1515
1516 if (r >= 0 && q < 0)
1517 r = q;
1518 }
1519
1520 return r;
1521 }
1522
1523 int unit_file_add_dependency(
1524 UnitFileScope scope,
1525 bool runtime,
1526 const char *root_dir,
1527 char **files,
1528 char *target,
1529 UnitDependency dep,
1530 bool force,
1531 UnitFileChange **changes,
1532 unsigned *n_changes) {
1533
1534 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1535 _cleanup_(install_context_done) InstallContext c = {};
1536 _cleanup_free_ char *config_path = NULL;
1537 char **i;
1538 int r;
1539 InstallInfo *info;
1540
1541 assert(scope >= 0);
1542 assert(scope < _UNIT_FILE_SCOPE_MAX);
1543
1544 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1545 if (r < 0)
1546 return r;
1547
1548 r = get_config_path(scope, runtime, root_dir, &config_path);
1549 if (r < 0)
1550 return r;
1551
1552 STRV_FOREACH(i, files) {
1553 UnitFileState state;
1554
1555 state = unit_file_get_state(scope, root_dir, *i);
1556 if (state < 0) {
1557 log_error("Failed to get unit file state for %s: %s", *i, strerror(-state));
1558 return state;
1559 }
1560
1561 if (state == UNIT_FILE_MASKED || state == UNIT_FILE_MASKED_RUNTIME) {
1562 log_error("Failed to enable unit: Unit %s is masked", *i);
1563 return -ENOTSUP;
1564 }
1565
1566 r = install_info_add_auto(&c, *i);
1567 if (r < 0)
1568 return r;
1569 }
1570
1571 if (!ordered_hashmap_isempty(c.will_install)) {
1572 r = ordered_hashmap_ensure_allocated(&c.have_installed, &string_hash_ops);
1573 if (r < 0)
1574 return r;
1575
1576 r = ordered_hashmap_reserve(c.have_installed, ordered_hashmap_size(c.will_install));
1577 if (r < 0)
1578 return r;
1579 }
1580
1581 while ((info = ordered_hashmap_first(c.will_install))) {
1582 assert_se(ordered_hashmap_move_one(c.have_installed, c.will_install, info->name) == 0);
1583
1584 r = unit_file_search(&c, info, &paths, root_dir, false, false, NULL);
1585 if (r < 0)
1586 return r;
1587
1588 if (dep == UNIT_WANTS)
1589 r = strv_extend(&info->wanted_by, target);
1590 else if (dep == UNIT_REQUIRES)
1591 r = strv_extend(&info->required_by, target);
1592 else
1593 r = -EINVAL;
1594
1595 if (r < 0)
1596 return r;
1597
1598 r = install_info_apply(info, &paths, config_path, root_dir, force, changes, n_changes);
1599 if (r < 0)
1600 return r;
1601 }
1602
1603 return 0;
1604 }
1605
1606 int unit_file_enable(
1607 UnitFileScope scope,
1608 bool runtime,
1609 const char *root_dir,
1610 char **files,
1611 bool force,
1612 UnitFileChange **changes,
1613 unsigned *n_changes) {
1614
1615 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1616 _cleanup_(install_context_done) InstallContext c = {};
1617 char **i;
1618 _cleanup_free_ char *config_path = NULL;
1619 int r;
1620
1621 assert(scope >= 0);
1622 assert(scope < _UNIT_FILE_SCOPE_MAX);
1623
1624 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1625 if (r < 0)
1626 return r;
1627
1628 r = get_config_path(scope, runtime, root_dir, &config_path);
1629 if (r < 0)
1630 return r;
1631
1632 STRV_FOREACH(i, files) {
1633 UnitFileState state;
1634
1635 /* We only want to know if this unit is masked, so we ignore
1636 * errors from unit_file_get_state, deferring other checks.
1637 * This allows templated units to be enabled on the fly. */
1638 state = unit_file_get_state(scope, root_dir, *i);
1639 if (state == UNIT_FILE_MASKED || state == UNIT_FILE_MASKED_RUNTIME) {
1640 log_error("Failed to enable unit: Unit %s is masked", *i);
1641 return -ENOTSUP;
1642 }
1643
1644 r = install_info_add_auto(&c, *i);
1645 if (r < 0)
1646 return r;
1647 }
1648
1649 /* This will return the number of symlink rules that were
1650 supposed to be created, not the ones actually created. This is
1651 useful to determine whether the passed files had any
1652 installation data at all. */
1653
1654 return install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes);
1655 }
1656
1657 int unit_file_disable(
1658 UnitFileScope scope,
1659 bool runtime,
1660 const char *root_dir,
1661 char **files,
1662 UnitFileChange **changes,
1663 unsigned *n_changes) {
1664
1665 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1666 _cleanup_(install_context_done) InstallContext c = {};
1667 char **i;
1668 _cleanup_free_ char *config_path = NULL;
1669 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
1670 int r, q;
1671
1672 assert(scope >= 0);
1673 assert(scope < _UNIT_FILE_SCOPE_MAX);
1674
1675 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1676 if (r < 0)
1677 return r;
1678
1679 r = get_config_path(scope, runtime, root_dir, &config_path);
1680 if (r < 0)
1681 return r;
1682
1683 STRV_FOREACH(i, files) {
1684 r = install_info_add_auto(&c, *i);
1685 if (r < 0)
1686 return r;
1687 }
1688
1689 r = install_context_mark_for_removal(&c, &paths, &remove_symlinks_to, config_path, root_dir);
1690
1691 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
1692 if (r >= 0)
1693 r = q;
1694
1695 return r;
1696 }
1697
1698 int unit_file_reenable(
1699 UnitFileScope scope,
1700 bool runtime,
1701 const char *root_dir,
1702 char **files,
1703 bool force,
1704 UnitFileChange **changes,
1705 unsigned *n_changes) {
1706 int r;
1707
1708 r = unit_file_disable(scope, runtime, root_dir, files,
1709 changes, n_changes);
1710 if (r < 0)
1711 return r;
1712
1713 return unit_file_enable(scope, runtime, root_dir, files, force,
1714 changes, n_changes);
1715 }
1716
1717 int unit_file_set_default(
1718 UnitFileScope scope,
1719 const char *root_dir,
1720 const char *file,
1721 bool force,
1722 UnitFileChange **changes,
1723 unsigned *n_changes) {
1724
1725 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1726 _cleanup_(install_context_done) InstallContext c = {};
1727 _cleanup_free_ char *config_path = NULL;
1728 char *path;
1729 int r;
1730 InstallInfo *i = NULL;
1731
1732 assert(scope >= 0);
1733 assert(scope < _UNIT_FILE_SCOPE_MAX);
1734 assert(file);
1735
1736 if (unit_name_to_type(file) != UNIT_TARGET)
1737 return -EINVAL;
1738
1739 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1740 if (r < 0)
1741 return r;
1742
1743 r = get_config_path(scope, false, root_dir, &config_path);
1744 if (r < 0)
1745 return r;
1746
1747 r = install_info_add_auto(&c, file);
1748 if (r < 0)
1749 return r;
1750
1751 assert_se(i = ordered_hashmap_first(c.will_install));
1752
1753 r = unit_file_search(&c, i, &paths, root_dir, false, true, NULL);
1754 if (r < 0)
1755 return r;
1756
1757 path = strappenda(config_path, "/" SPECIAL_DEFAULT_TARGET);
1758
1759 r = create_symlink(i->path, path, force, changes, n_changes);
1760 if (r < 0)
1761 return r;
1762
1763 return 0;
1764 }
1765
1766 int unit_file_get_default(
1767 UnitFileScope scope,
1768 const char *root_dir,
1769 char **name) {
1770
1771 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1772 char **p;
1773 int r;
1774
1775 assert(scope >= 0);
1776 assert(scope < _UNIT_FILE_SCOPE_MAX);
1777 assert(name);
1778
1779 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1780 if (r < 0)
1781 return r;
1782
1783 STRV_FOREACH(p, paths.unit_path) {
1784 _cleanup_free_ char *path = NULL, *tmp = NULL;
1785 char *n;
1786
1787 path = path_join(root_dir, *p, SPECIAL_DEFAULT_TARGET);
1788 if (!path)
1789 return -ENOMEM;
1790
1791 r = readlink_malloc(path, &tmp);
1792 if (r == -ENOENT)
1793 continue;
1794 else if (r == -EINVAL)
1795 /* not a symlink */
1796 n = strdup(SPECIAL_DEFAULT_TARGET);
1797 else if (r < 0)
1798 return r;
1799 else
1800 n = strdup(basename(tmp));
1801
1802 if (!n)
1803 return -ENOMEM;
1804
1805 *name = n;
1806 return 0;
1807 }
1808
1809 return -ENOENT;
1810 }
1811
1812 UnitFileState unit_file_get_state(
1813 UnitFileScope scope,
1814 const char *root_dir,
1815 const char *name) {
1816
1817 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1818 UnitFileState state = _UNIT_FILE_STATE_INVALID;
1819 char **i;
1820 _cleanup_free_ char *path = NULL;
1821 int r;
1822
1823 assert(scope >= 0);
1824 assert(scope < _UNIT_FILE_SCOPE_MAX);
1825 assert(name);
1826
1827 if (root_dir && scope != UNIT_FILE_SYSTEM)
1828 return -EINVAL;
1829
1830 if (!unit_name_is_valid(name, TEMPLATE_VALID))
1831 return -EINVAL;
1832
1833 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1834 if (r < 0)
1835 return r;
1836
1837 STRV_FOREACH(i, paths.unit_path) {
1838 struct stat st;
1839 char *partial;
1840 bool also = false;
1841
1842 free(path);
1843 path = NULL;
1844
1845 path = path_join(root_dir, *i, name);
1846 if (!path)
1847 return -ENOMEM;
1848
1849 if (root_dir)
1850 partial = path + strlen(root_dir);
1851 else
1852 partial = path;
1853
1854 /*
1855 * Search for a unit file in our default paths, to
1856 * be sure, that there are no broken symlinks.
1857 */
1858 if (lstat(path, &st) < 0) {
1859 r = -errno;
1860 if (errno != ENOENT)
1861 return r;
1862
1863 if (!unit_name_is_instance(name))
1864 continue;
1865 } else {
1866 if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode))
1867 return -ENOENT;
1868
1869 r = null_or_empty_path(path);
1870 if (r < 0 && r != -ENOENT)
1871 return r;
1872 else if (r > 0) {
1873 state = path_startswith(*i, "/run") ?
1874 UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
1875 return state;
1876 }
1877 }
1878
1879 r = find_symlinks_in_scope(scope, root_dir, name, &state);
1880 if (r < 0)
1881 return r;
1882 else if (r > 0)
1883 return state;
1884
1885 r = unit_file_can_install(&paths, root_dir, partial, true, &also);
1886 if (r < 0 && errno != ENOENT)
1887 return r;
1888 else if (r > 0)
1889 return UNIT_FILE_DISABLED;
1890 else if (r == 0) {
1891 if (also)
1892 return UNIT_FILE_INDIRECT;
1893 return UNIT_FILE_STATIC;
1894 }
1895 }
1896
1897 return r < 0 ? r : state;
1898 }
1899
1900 int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name) {
1901 _cleanup_strv_free_ char **files = NULL;
1902 char **p;
1903 int r;
1904
1905 assert(scope >= 0);
1906 assert(scope < _UNIT_FILE_SCOPE_MAX);
1907 assert(name);
1908
1909 if (scope == UNIT_FILE_SYSTEM)
1910 r = conf_files_list(&files, ".preset", root_dir,
1911 "/etc/systemd/system-preset",
1912 "/usr/local/lib/systemd/system-preset",
1913 "/usr/lib/systemd/system-preset",
1914 #ifdef HAVE_SPLIT_USR
1915 "/lib/systemd/system-preset",
1916 #endif
1917 NULL);
1918 else if (scope == UNIT_FILE_GLOBAL)
1919 r = conf_files_list(&files, ".preset", root_dir,
1920 "/etc/systemd/user-preset",
1921 "/usr/local/lib/systemd/user-preset",
1922 "/usr/lib/systemd/user-preset",
1923 NULL);
1924 else
1925 return 1;
1926
1927 if (r < 0)
1928 return r;
1929
1930 STRV_FOREACH(p, files) {
1931 _cleanup_fclose_ FILE *f;
1932
1933 f = fopen(*p, "re");
1934 if (!f) {
1935 if (errno == ENOENT)
1936 continue;
1937
1938 return -errno;
1939 }
1940
1941 for (;;) {
1942 char line[LINE_MAX], *l;
1943
1944 if (!fgets(line, sizeof(line), f))
1945 break;
1946
1947 l = strstrip(line);
1948 if (!*l)
1949 continue;
1950
1951 if (strchr(COMMENTS "\n", *l))
1952 continue;
1953
1954 if (first_word(l, "enable")) {
1955 l += 6;
1956 l += strspn(l, WHITESPACE);
1957
1958 if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
1959 log_debug("Preset file says enable %s.", name);
1960 return 1;
1961 }
1962
1963 } else if (first_word(l, "disable")) {
1964 l += 7;
1965 l += strspn(l, WHITESPACE);
1966
1967 if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
1968 log_debug("Preset file says disable %s.", name);
1969 return 0;
1970 }
1971
1972 } else
1973 log_debug("Couldn't parse line '%s'", l);
1974 }
1975 }
1976
1977 /* Default is "enable" */
1978 log_debug("Preset file doesn't say anything about %s, enabling.", name);
1979 return 1;
1980 }
1981
1982 int unit_file_preset(
1983 UnitFileScope scope,
1984 bool runtime,
1985 const char *root_dir,
1986 char **files,
1987 UnitFilePresetMode mode,
1988 bool force,
1989 UnitFileChange **changes,
1990 unsigned *n_changes) {
1991
1992 _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
1993 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1994 _cleanup_free_ char *config_path = NULL;
1995 char **i;
1996 int r, q;
1997
1998 assert(scope >= 0);
1999 assert(scope < _UNIT_FILE_SCOPE_MAX);
2000 assert(mode < _UNIT_FILE_PRESET_MAX);
2001
2002 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
2003 if (r < 0)
2004 return r;
2005
2006 r = get_config_path(scope, runtime, root_dir, &config_path);
2007 if (r < 0)
2008 return r;
2009
2010 STRV_FOREACH(i, files) {
2011
2012 if (!unit_name_is_valid(*i, TEMPLATE_VALID))
2013 return -EINVAL;
2014
2015 r = unit_file_query_preset(scope, root_dir, *i);
2016 if (r < 0)
2017 return r;
2018
2019 if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
2020 r = install_info_add_auto(&plus, *i);
2021 else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
2022 r = install_info_add_auto(&minus, *i);
2023 else
2024 r = 0;
2025 if (r < 0)
2026 return r;
2027 }
2028
2029 r = 0;
2030
2031 if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
2032 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
2033
2034 r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
2035
2036 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
2037 if (r == 0)
2038 r = q;
2039 }
2040
2041 if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
2042 /* Returns number of symlinks that where supposed to be installed. */
2043 q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
2044 if (r == 0)
2045 r = q;
2046 }
2047
2048 return r;
2049 }
2050
2051 int unit_file_preset_all(
2052 UnitFileScope scope,
2053 bool runtime,
2054 const char *root_dir,
2055 UnitFilePresetMode mode,
2056 bool force,
2057 UnitFileChange **changes,
2058 unsigned *n_changes) {
2059
2060 _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
2061 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2062 _cleanup_free_ char *config_path = NULL;
2063 char **i;
2064 int r, q;
2065
2066 assert(scope >= 0);
2067 assert(scope < _UNIT_FILE_SCOPE_MAX);
2068 assert(mode < _UNIT_FILE_PRESET_MAX);
2069
2070 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
2071 if (r < 0)
2072 return r;
2073
2074 r = get_config_path(scope, runtime, root_dir, &config_path);
2075 if (r < 0)
2076 return r;
2077
2078 STRV_FOREACH(i, paths.unit_path) {
2079 _cleanup_closedir_ DIR *d = NULL;
2080 _cleanup_free_ char *units_dir;
2081
2082 units_dir = path_join(root_dir, *i, NULL);
2083 if (!units_dir)
2084 return -ENOMEM;
2085
2086 d = opendir(units_dir);
2087 if (!d) {
2088 if (errno == ENOENT)
2089 continue;
2090
2091 return -errno;
2092 }
2093
2094 for (;;) {
2095 struct dirent *de;
2096
2097 errno = 0;
2098 de = readdir(d);
2099 if (!de && errno != 0)
2100 return -errno;
2101
2102 if (!de)
2103 break;
2104
2105 if (ignore_file(de->d_name))
2106 continue;
2107
2108 if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
2109 continue;
2110
2111 dirent_ensure_type(d, de);
2112
2113 if (de->d_type != DT_REG)
2114 continue;
2115
2116 r = unit_file_query_preset(scope, root_dir, de->d_name);
2117 if (r < 0)
2118 return r;
2119
2120 if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
2121 r = install_info_add_auto(&plus, de->d_name);
2122 else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
2123 r = install_info_add_auto(&minus, de->d_name);
2124 else
2125 r = 0;
2126 if (r < 0)
2127 return r;
2128 }
2129 }
2130
2131 r = 0;
2132
2133 if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
2134 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
2135
2136 r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
2137
2138 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, NULL);
2139 if (r == 0)
2140 r = q;
2141 }
2142
2143 if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
2144 q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
2145 if (r == 0)
2146 r = q;
2147 }
2148
2149 return r;
2150 }
2151
2152 static void unit_file_list_free_one(UnitFileList *f) {
2153 if (!f)
2154 return;
2155
2156 free(f->path);
2157 free(f);
2158 }
2159
2160 DEFINE_TRIVIAL_CLEANUP_FUNC(UnitFileList*, unit_file_list_free_one);
2161
2162 int unit_file_get_list(
2163 UnitFileScope scope,
2164 const char *root_dir,
2165 Hashmap *h) {
2166
2167 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2168 char **i;
2169 int r;
2170
2171 assert(scope >= 0);
2172 assert(scope < _UNIT_FILE_SCOPE_MAX);
2173 assert(h);
2174
2175 if (root_dir && scope != UNIT_FILE_SYSTEM)
2176 return -EINVAL;
2177
2178 if (root_dir) {
2179 r = access(root_dir, F_OK);
2180 if (r < 0)
2181 return -errno;
2182 }
2183
2184 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
2185 if (r < 0)
2186 return r;
2187
2188 STRV_FOREACH(i, paths.unit_path) {
2189 _cleanup_closedir_ DIR *d = NULL;
2190 _cleanup_free_ char *units_dir;
2191
2192 units_dir = path_join(root_dir, *i, NULL);
2193 if (!units_dir)
2194 return -ENOMEM;
2195
2196 d = opendir(units_dir);
2197 if (!d) {
2198 if (errno == ENOENT)
2199 continue;
2200
2201 return -errno;
2202 }
2203
2204 for (;;) {
2205 _cleanup_(unit_file_list_free_onep) UnitFileList *f = NULL;
2206 struct dirent *de;
2207 _cleanup_free_ char *path = NULL;
2208
2209 errno = 0;
2210 de = readdir(d);
2211 if (!de && errno != 0)
2212 return -errno;
2213
2214 if (!de)
2215 break;
2216
2217 if (ignore_file(de->d_name))
2218 continue;
2219
2220 if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
2221 continue;
2222
2223 if (hashmap_get(h, de->d_name))
2224 continue;
2225
2226 dirent_ensure_type(d, de);
2227
2228 if (!IN_SET(de->d_type, DT_LNK, DT_REG))
2229 continue;
2230
2231 f = new0(UnitFileList, 1);
2232 if (!f)
2233 return -ENOMEM;
2234
2235 f->path = path_make_absolute(de->d_name, units_dir);
2236 if (!f->path)
2237 return -ENOMEM;
2238
2239 r = null_or_empty_path(f->path);
2240 if (r < 0 && r != -ENOENT)
2241 return r;
2242 else if (r > 0) {
2243 f->state =
2244 path_startswith(*i, "/run") ?
2245 UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
2246 goto found;
2247 }
2248
2249 r = find_symlinks_in_scope(scope, root_dir, de->d_name, &f->state);
2250 if (r < 0)
2251 return r;
2252 else if (r > 0) {
2253 f->state = UNIT_FILE_ENABLED;
2254 goto found;
2255 }
2256
2257 path = path_make_absolute(de->d_name, *i);
2258 if (!path)
2259 return -ENOMEM;
2260
2261 r = unit_file_can_install(&paths, root_dir, path, true, NULL);
2262 if (r == -EINVAL || /* Invalid setting? */
2263 r == -EBADMSG || /* Invalid format? */
2264 r == -ENOENT /* Included file not found? */)
2265 f->state = UNIT_FILE_INVALID;
2266 else if (r < 0)
2267 return r;
2268 else if (r > 0)
2269 f->state = UNIT_FILE_DISABLED;
2270 else
2271 f->state = UNIT_FILE_STATIC;
2272
2273 found:
2274 r = hashmap_put(h, basename(f->path), f);
2275 if (r < 0)
2276 return r;
2277 f = NULL; /* prevent cleanup */
2278 }
2279 }
2280
2281 return r;
2282 }
2283
2284 static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
2285 [UNIT_FILE_ENABLED] = "enabled",
2286 [UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime",
2287 [UNIT_FILE_LINKED] = "linked",
2288 [UNIT_FILE_LINKED_RUNTIME] = "linked-runtime",
2289 [UNIT_FILE_MASKED] = "masked",
2290 [UNIT_FILE_MASKED_RUNTIME] = "masked-runtime",
2291 [UNIT_FILE_STATIC] = "static",
2292 [UNIT_FILE_DISABLED] = "disabled",
2293 [UNIT_FILE_INDIRECT] = "indirect",
2294 [UNIT_FILE_INVALID] = "invalid",
2295 };
2296
2297 DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
2298
2299 static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
2300 [UNIT_FILE_SYMLINK] = "symlink",
2301 [UNIT_FILE_UNLINK] = "unlink",
2302 };
2303
2304 DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
2305
2306 static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = {
2307 [UNIT_FILE_PRESET_FULL] = "full",
2308 [UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
2309 [UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
2310 };
2311
2312 DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode, UnitFilePresetMode);