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