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