]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/install.c
Merge pull request #347 from poettering/check-api-docs
[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 mark_symlink_for_removal(
116 Set **remove_symlinks_to,
117 const char *p) {
118
119 char *n;
120 int r;
121
122 assert(p);
123
124 r = set_ensure_allocated(remove_symlinks_to, &string_hash_ops);
125 if (r < 0)
126 return r;
127
128 n = strdup(p);
129 if (!n)
130 return -ENOMEM;
131
132 path_kill_slashes(n);
133
134 r = set_consume(*remove_symlinks_to, n);
135 if (r < 0)
136 return r == -EEXIST ? 0 : r;
137
138 return 0;
139 }
140
141 static int remove_marked_symlinks_fd(
142 Set *remove_symlinks_to,
143 int fd,
144 const char *path,
145 const char *config_path,
146 bool *deleted,
147 UnitFileChange **changes,
148 unsigned *n_changes,
149 char** instance_whitelist) {
150
151 _cleanup_closedir_ DIR *d = NULL;
152 int r = 0;
153
154 assert(remove_symlinks_to);
155 assert(fd >= 0);
156 assert(path);
157 assert(config_path);
158 assert(deleted);
159
160 d = fdopendir(fd);
161 if (!d) {
162 safe_close(fd);
163 return -errno;
164 }
165
166 rewinddir(d);
167
168 for (;;) {
169 struct dirent *de;
170
171 errno = 0;
172 de = readdir(d);
173 if (!de && errno != 0) {
174 r = -errno;
175 break;
176 }
177
178 if (!de)
179 break;
180
181 if (hidden_file(de->d_name))
182 continue;
183
184 dirent_ensure_type(d, de);
185
186 if (de->d_type == DT_DIR) {
187 int nfd, q;
188 _cleanup_free_ char *p = NULL;
189
190 nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
191 if (nfd < 0) {
192 if (errno == ENOENT)
193 continue;
194
195 if (r == 0)
196 r = -errno;
197 continue;
198 }
199
200 p = path_make_absolute(de->d_name, path);
201 if (!p) {
202 safe_close(nfd);
203 return -ENOMEM;
204 }
205
206 /* This will close nfd, regardless whether it succeeds or not */
207 q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, deleted, changes, n_changes, instance_whitelist);
208 if (q < 0 && r == 0)
209 r = q;
210
211 } else if (de->d_type == DT_LNK) {
212 _cleanup_free_ char *p = NULL, *dest = NULL;
213 int q;
214 bool found;
215
216 if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
217 continue;
218
219 if (unit_name_is_valid(de->d_name, UNIT_NAME_INSTANCE) &&
220 instance_whitelist &&
221 !strv_contains(instance_whitelist, de->d_name)) {
222
223 _cleanup_free_ char *w = NULL;
224
225 /* OK, the file is not listed directly
226 * in the whitelist, so let's check if
227 * the template of it might be
228 * listed. */
229
230 r = unit_name_template(de->d_name, &w);
231 if (r < 0)
232 return r;
233
234 if (!strv_contains(instance_whitelist, w))
235 continue;
236 }
237
238 p = path_make_absolute(de->d_name, path);
239 if (!p)
240 return -ENOMEM;
241
242 q = readlink_and_canonicalize(p, &dest);
243 if (q < 0) {
244 if (q == -ENOENT)
245 continue;
246
247 if (r == 0)
248 r = q;
249 continue;
250 }
251
252 found =
253 set_get(remove_symlinks_to, dest) ||
254 set_get(remove_symlinks_to, basename(dest));
255
256 if (!found)
257 continue;
258
259 if (unlink(p) < 0 && errno != ENOENT) {
260 if (r == 0)
261 r = -errno;
262 continue;
263 }
264
265 path_kill_slashes(p);
266 rmdir_parents(p, config_path);
267 unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, p, NULL);
268
269 if (!set_get(remove_symlinks_to, p)) {
270
271 q = mark_symlink_for_removal(&remove_symlinks_to, p);
272 if (q < 0) {
273 if (r == 0)
274 r = q;
275 } else
276 *deleted = true;
277 }
278 }
279 }
280
281 return r;
282 }
283
284 static int remove_marked_symlinks(
285 Set *remove_symlinks_to,
286 const char *config_path,
287 UnitFileChange **changes,
288 unsigned *n_changes,
289 char** instance_whitelist) {
290
291 _cleanup_close_ int fd = -1;
292 int r = 0;
293 bool deleted;
294
295 assert(config_path);
296
297 if (set_size(remove_symlinks_to) <= 0)
298 return 0;
299
300 fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
301 if (fd < 0)
302 return -errno;
303
304 do {
305 int q, cfd;
306 deleted = false;
307
308 cfd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
309 if (cfd < 0) {
310 r = -errno;
311 break;
312 }
313
314 /* This takes possession of cfd and closes it */
315 q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, &deleted, changes, n_changes, instance_whitelist);
316 if (r == 0)
317 r = q;
318 } while (deleted);
319
320 return r;
321 }
322
323 static int find_symlinks_fd(
324 const char *name,
325 int fd,
326 const char *path,
327 const char *config_path,
328 bool *same_name_link) {
329
330 int r = 0;
331 _cleanup_closedir_ DIR *d = NULL;
332
333 assert(name);
334 assert(fd >= 0);
335 assert(path);
336 assert(config_path);
337 assert(same_name_link);
338
339 d = fdopendir(fd);
340 if (!d) {
341 safe_close(fd);
342 return -errno;
343 }
344
345 for (;;) {
346 struct dirent *de;
347
348 errno = 0;
349 de = readdir(d);
350 if (!de && errno != 0)
351 return -errno;
352
353 if (!de)
354 return r;
355
356 if (hidden_file(de->d_name))
357 continue;
358
359 dirent_ensure_type(d, de);
360
361 if (de->d_type == DT_DIR) {
362 int nfd, q;
363 _cleanup_free_ char *p = NULL;
364
365 nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
366 if (nfd < 0) {
367 if (errno == ENOENT)
368 continue;
369
370 if (r == 0)
371 r = -errno;
372 continue;
373 }
374
375 p = path_make_absolute(de->d_name, path);
376 if (!p) {
377 safe_close(nfd);
378 return -ENOMEM;
379 }
380
381 /* This will close nfd, regardless whether it succeeds or not */
382 q = find_symlinks_fd(name, nfd, p, config_path, same_name_link);
383 if (q > 0)
384 return 1;
385 if (r == 0)
386 r = q;
387
388 } else if (de->d_type == DT_LNK) {
389 _cleanup_free_ char *p = NULL, *dest = NULL;
390 bool found_path, found_dest, b = false;
391 int q;
392
393 /* Acquire symlink name */
394 p = path_make_absolute(de->d_name, path);
395 if (!p)
396 return -ENOMEM;
397
398 /* Acquire symlink destination */
399 q = readlink_and_canonicalize(p, &dest);
400 if (q < 0) {
401 if (q == -ENOENT)
402 continue;
403
404 if (r == 0)
405 r = q;
406 continue;
407 }
408
409 /* Check if the symlink itself matches what we
410 * are looking for */
411 if (path_is_absolute(name))
412 found_path = path_equal(p, name);
413 else
414 found_path = streq(de->d_name, name);
415
416 /* Check if what the symlink points to
417 * matches what we are looking for */
418 if (path_is_absolute(name))
419 found_dest = path_equal(dest, name);
420 else
421 found_dest = streq(basename(dest), name);
422
423 if (found_path && found_dest) {
424 _cleanup_free_ char *t = NULL;
425
426 /* Filter out same name links in the main
427 * config path */
428 t = path_make_absolute(name, config_path);
429 if (!t)
430 return -ENOMEM;
431
432 b = path_equal(t, p);
433 }
434
435 if (b)
436 *same_name_link = true;
437 else if (found_path || found_dest)
438 return 1;
439 }
440 }
441 }
442
443 static int find_symlinks(
444 const char *name,
445 const char *config_path,
446 bool *same_name_link) {
447
448 int fd;
449
450 assert(name);
451 assert(config_path);
452 assert(same_name_link);
453
454 fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
455 if (fd < 0) {
456 if (errno == ENOENT)
457 return 0;
458 return -errno;
459 }
460
461 /* This takes possession of fd and closes it */
462 return find_symlinks_fd(name, fd, config_path, config_path, same_name_link);
463 }
464
465 static int find_symlinks_in_scope(
466 UnitFileScope scope,
467 const char *root_dir,
468 const char *name,
469 UnitFileState *state) {
470
471 int r;
472 _cleanup_free_ char *normal_path = NULL, *runtime_path = NULL;
473 bool same_name_link_runtime = false, same_name_link = false;
474
475 assert(scope >= 0);
476 assert(scope < _UNIT_FILE_SCOPE_MAX);
477 assert(name);
478
479 /* First look in runtime config path */
480 r = get_config_path(scope, true, root_dir, &normal_path);
481 if (r < 0)
482 return r;
483
484 r = find_symlinks(name, normal_path, &same_name_link_runtime);
485 if (r < 0)
486 return r;
487 else if (r > 0) {
488 *state = UNIT_FILE_ENABLED_RUNTIME;
489 return r;
490 }
491
492 /* Then look in the normal config path */
493 r = get_config_path(scope, false, root_dir, &runtime_path);
494 if (r < 0)
495 return r;
496
497 r = find_symlinks(name, runtime_path, &same_name_link);
498 if (r < 0)
499 return r;
500 else if (r > 0) {
501 *state = UNIT_FILE_ENABLED;
502 return r;
503 }
504
505 /* Hmm, we didn't find it, but maybe we found the same name
506 * link? */
507 if (same_name_link_runtime) {
508 *state = UNIT_FILE_LINKED_RUNTIME;
509 return 1;
510 } else if (same_name_link) {
511 *state = UNIT_FILE_LINKED;
512 return 1;
513 }
514
515 return 0;
516 }
517
518 int unit_file_mask(
519 UnitFileScope scope,
520 bool runtime,
521 const char *root_dir,
522 char **files,
523 bool force,
524 UnitFileChange **changes,
525 unsigned *n_changes) {
526
527 char **i;
528 _cleanup_free_ char *prefix = NULL;
529 int r;
530
531 assert(scope >= 0);
532 assert(scope < _UNIT_FILE_SCOPE_MAX);
533
534 r = get_config_path(scope, runtime, root_dir, &prefix);
535 if (r < 0)
536 return r;
537
538 STRV_FOREACH(i, files) {
539 _cleanup_free_ char *path = NULL;
540
541 if (!unit_name_is_valid(*i, UNIT_NAME_ANY)) {
542 if (r == 0)
543 r = -EINVAL;
544 continue;
545 }
546
547 path = path_make_absolute(*i, prefix);
548 if (!path) {
549 r = -ENOMEM;
550 break;
551 }
552
553 if (symlink("/dev/null", path) >= 0) {
554 unit_file_changes_add(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null");
555 continue;
556 }
557
558 if (errno == EEXIST) {
559
560 if (null_or_empty_path(path) > 0)
561 continue;
562
563 if (force) {
564 if (symlink_atomic("/dev/null", path) >= 0) {
565 unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
566 unit_file_changes_add(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null");
567 continue;
568 }
569 }
570
571 if (r == 0)
572 r = -EEXIST;
573 } else {
574 if (r == 0)
575 r = -errno;
576 }
577 }
578
579 return r;
580 }
581
582 int unit_file_unmask(
583 UnitFileScope scope,
584 bool runtime,
585 const char *root_dir,
586 char **files,
587 UnitFileChange **changes,
588 unsigned *n_changes) {
589
590 char **i, *config_path = NULL;
591 int r, q;
592 Set *remove_symlinks_to = NULL;
593
594 assert(scope >= 0);
595 assert(scope < _UNIT_FILE_SCOPE_MAX);
596
597 r = get_config_path(scope, runtime, root_dir, &config_path);
598 if (r < 0)
599 goto finish;
600
601 STRV_FOREACH(i, files) {
602 _cleanup_free_ char *path = NULL;
603
604 if (!unit_name_is_valid(*i, UNIT_NAME_ANY)) {
605 if (r == 0)
606 r = -EINVAL;
607 continue;
608 }
609
610 path = path_make_absolute(*i, config_path);
611 if (!path) {
612 r = -ENOMEM;
613 break;
614 }
615
616 q = null_or_empty_path(path);
617 if (q > 0) {
618 if (unlink(path) < 0)
619 q = -errno;
620 else {
621 q = mark_symlink_for_removal(&remove_symlinks_to, path);
622 unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
623 }
624 }
625
626 if (q != -ENOENT && r == 0)
627 r = q;
628 }
629
630
631 finish:
632 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
633 if (r == 0)
634 r = q;
635
636 set_free_free(remove_symlinks_to);
637 free(config_path);
638
639 return r;
640 }
641
642 int unit_file_link(
643 UnitFileScope scope,
644 bool runtime,
645 const char *root_dir,
646 char **files,
647 bool force,
648 UnitFileChange **changes,
649 unsigned *n_changes) {
650
651 _cleanup_lookup_paths_free_ LookupPaths paths = {};
652 char **i;
653 _cleanup_free_ char *config_path = NULL;
654 int r, q;
655
656 assert(scope >= 0);
657 assert(scope < _UNIT_FILE_SCOPE_MAX);
658
659 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
660 if (r < 0)
661 return r;
662
663 r = get_config_path(scope, runtime, root_dir, &config_path);
664 if (r < 0)
665 return r;
666
667 STRV_FOREACH(i, files) {
668 _cleanup_free_ char *path = NULL;
669 char *fn;
670 struct stat st;
671
672 fn = basename(*i);
673
674 if (!path_is_absolute(*i) ||
675 !unit_name_is_valid(fn, UNIT_NAME_ANY)) {
676 if (r == 0)
677 r = -EINVAL;
678 continue;
679 }
680
681 if (lstat(*i, &st) < 0) {
682 if (r == 0)
683 r = -errno;
684 continue;
685 }
686
687 if (!S_ISREG(st.st_mode)) {
688 r = -ENOENT;
689 continue;
690 }
691
692 q = in_search_path(*i, paths.unit_path);
693 if (q < 0)
694 return q;
695
696 if (q > 0)
697 continue;
698
699 path = path_make_absolute(fn, config_path);
700 if (!path)
701 return -ENOMEM;
702
703 if (symlink(*i, path) >= 0) {
704 unit_file_changes_add(changes, n_changes, UNIT_FILE_SYMLINK, path, *i);
705 continue;
706 }
707
708 if (errno == EEXIST) {
709 _cleanup_free_ char *dest = NULL;
710
711 q = readlink_and_make_absolute(path, &dest);
712 if (q < 0 && errno != ENOENT) {
713 if (r == 0)
714 r = q;
715 continue;
716 }
717
718 if (q >= 0 && path_equal(dest, *i))
719 continue;
720
721 if (force) {
722 if (symlink_atomic(*i, path) >= 0) {
723 unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
724 unit_file_changes_add(changes, n_changes, UNIT_FILE_SYMLINK, path, *i);
725 continue;
726 }
727 }
728
729 if (r == 0)
730 r = -EEXIST;
731 } else {
732 if (r == 0)
733 r = -errno;
734 }
735 }
736
737 return r;
738 }
739
740 void unit_file_list_free(Hashmap *h) {
741 UnitFileList *i;
742
743 while ((i = hashmap_steal_first(h))) {
744 free(i->path);
745 free(i);
746 }
747
748 hashmap_free(h);
749 }
750
751 int unit_file_changes_add(
752 UnitFileChange **changes,
753 unsigned *n_changes,
754 UnitFileChangeType type,
755 const char *path,
756 const char *source) {
757
758 UnitFileChange *c;
759 unsigned i;
760
761 assert(path);
762 assert(!changes == !n_changes);
763
764 if (!changes)
765 return 0;
766
767 c = realloc(*changes, (*n_changes + 1) * sizeof(UnitFileChange));
768 if (!c)
769 return -ENOMEM;
770
771 *changes = c;
772 i = *n_changes;
773
774 c[i].type = type;
775 c[i].path = strdup(path);
776 if (!c[i].path)
777 return -ENOMEM;
778
779 path_kill_slashes(c[i].path);
780
781 if (source) {
782 c[i].source = strdup(source);
783 if (!c[i].source) {
784 free(c[i].path);
785 return -ENOMEM;
786 }
787
788 path_kill_slashes(c[i].path);
789 } else
790 c[i].source = NULL;
791
792 *n_changes = i+1;
793 return 0;
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(UnitFileInstallInfo *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 UnitFileInstallInfo *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 UnitFileInstallInfo *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, UNIT_NAME_ANY))
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(UnitFileInstallInfo, 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 UnitFileInstallInfo *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 UnitFileInstallInfo *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 UnitFileInstallInfo *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 UnitFileInstallInfo *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 UnitFileInstallInfo *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_valid(info->name, UNIT_NAME_INSTANCE)) {
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 r = unit_name_template(info->name, &template);
1130 if (r < 0)
1131 return r;
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 UnitFileInstallInfo *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 unit_file_changes_add(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 unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);
1223 unit_file_changes_add(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
1224
1225 return 0;
1226 }
1227
1228 static int install_info_symlink_alias(
1229 UnitFileInstallInfo *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 UnitFileInstallInfo *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_valid(i->name, UNIT_NAME_TEMPLATE)) {
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 r = unit_name_replace_instance(i->name, i->default_instance, &buf);
1286 if (r < 0)
1287 return r;
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, UNIT_NAME_ANY)) {
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 UnitFileInstallInfo *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 UnitFileInstallInfo *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 UnitFileInstallInfo *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 UnitFileInstallInfo *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_valid(i->name, UNIT_NAME_INSTANCE)) {
1466 char *unit_file;
1467
1468 if (i->path) {
1469 unit_file = basename(i->path);
1470
1471 if (unit_name_is_valid(unit_file, UNIT_NAME_INSTANCE))
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 r = unit_name_template(i->name, &unit_file);
1484 if (r < 0)
1485 return r;
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 UnitFileInstallInfo *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 UnitFileInstallInfo *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 = 0;
1797
1798 assert(paths);
1799
1800 if (!unit_name_is_valid(name, UNIT_NAME_ANY))
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_valid(name, UNIT_NAME_INSTANCE))
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") ? UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
1838 return state;
1839 }
1840 }
1841
1842 r = find_symlinks_in_scope(scope, root_dir, name, &state);
1843 if (r < 0)
1844 return r;
1845 else if (r > 0)
1846 return state;
1847
1848 r = unit_file_can_install(paths, root_dir, partial, true, &also);
1849 if (r < 0 && errno != ENOENT)
1850 return r;
1851 else if (r > 0)
1852 return UNIT_FILE_DISABLED;
1853 else if (r == 0) {
1854 if (also)
1855 return UNIT_FILE_INDIRECT;
1856 return UNIT_FILE_STATIC;
1857 }
1858 }
1859
1860 return r < 0 ? r : state;
1861 }
1862
1863 UnitFileState unit_file_get_state(
1864 UnitFileScope scope,
1865 const char *root_dir,
1866 const char *name) {
1867
1868 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1869 int r;
1870
1871 assert(scope >= 0);
1872 assert(scope < _UNIT_FILE_SCOPE_MAX);
1873 assert(name);
1874
1875 if (root_dir && scope != UNIT_FILE_SYSTEM)
1876 return -EINVAL;
1877
1878 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1879 if (r < 0)
1880 return r;
1881
1882 return unit_file_lookup_state(scope, root_dir, &paths, name);
1883 }
1884
1885 int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name) {
1886 _cleanup_strv_free_ char **files = NULL;
1887 char **p;
1888 int r;
1889
1890 assert(scope >= 0);
1891 assert(scope < _UNIT_FILE_SCOPE_MAX);
1892 assert(name);
1893
1894 if (scope == UNIT_FILE_SYSTEM)
1895 r = conf_files_list(&files, ".preset", root_dir,
1896 "/etc/systemd/system-preset",
1897 "/usr/local/lib/systemd/system-preset",
1898 "/usr/lib/systemd/system-preset",
1899 #ifdef HAVE_SPLIT_USR
1900 "/lib/systemd/system-preset",
1901 #endif
1902 NULL);
1903 else if (scope == UNIT_FILE_GLOBAL)
1904 r = conf_files_list(&files, ".preset", root_dir,
1905 "/etc/systemd/user-preset",
1906 "/usr/local/lib/systemd/user-preset",
1907 "/usr/lib/systemd/user-preset",
1908 NULL);
1909 else
1910 return 1;
1911
1912 if (r < 0)
1913 return r;
1914
1915 STRV_FOREACH(p, files) {
1916 _cleanup_fclose_ FILE *f;
1917
1918 f = fopen(*p, "re");
1919 if (!f) {
1920 if (errno == ENOENT)
1921 continue;
1922
1923 return -errno;
1924 }
1925
1926 for (;;) {
1927 char line[LINE_MAX], *l;
1928
1929 if (!fgets(line, sizeof(line), f))
1930 break;
1931
1932 l = strstrip(line);
1933 if (!*l)
1934 continue;
1935
1936 if (strchr(COMMENTS "\n", *l))
1937 continue;
1938
1939 if (first_word(l, "enable")) {
1940 l += 6;
1941 l += strspn(l, WHITESPACE);
1942
1943 if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
1944 log_debug("Preset file says enable %s.", name);
1945 return 1;
1946 }
1947
1948 } else if (first_word(l, "disable")) {
1949 l += 7;
1950 l += strspn(l, WHITESPACE);
1951
1952 if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
1953 log_debug("Preset file says disable %s.", name);
1954 return 0;
1955 }
1956
1957 } else
1958 log_debug("Couldn't parse line '%s'", l);
1959 }
1960 }
1961
1962 /* Default is "enable" */
1963 log_debug("Preset file doesn't say anything about %s, enabling.", name);
1964 return 1;
1965 }
1966
1967 int unit_file_preset(
1968 UnitFileScope scope,
1969 bool runtime,
1970 const char *root_dir,
1971 char **files,
1972 UnitFilePresetMode mode,
1973 bool force,
1974 UnitFileChange **changes,
1975 unsigned *n_changes) {
1976
1977 _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
1978 _cleanup_lookup_paths_free_ LookupPaths paths = {};
1979 _cleanup_free_ char *config_path = NULL;
1980 char **i;
1981 int r, q;
1982
1983 assert(scope >= 0);
1984 assert(scope < _UNIT_FILE_SCOPE_MAX);
1985 assert(mode < _UNIT_FILE_PRESET_MAX);
1986
1987 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
1988 if (r < 0)
1989 return r;
1990
1991 r = get_config_path(scope, runtime, root_dir, &config_path);
1992 if (r < 0)
1993 return r;
1994
1995 STRV_FOREACH(i, files) {
1996
1997 if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
1998 return -EINVAL;
1999
2000 r = unit_file_query_preset(scope, root_dir, *i);
2001 if (r < 0)
2002 return r;
2003
2004 if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
2005 r = install_info_add_auto(&plus, *i);
2006 else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
2007 r = install_info_add_auto(&minus, *i);
2008 else
2009 r = 0;
2010 if (r < 0)
2011 return r;
2012 }
2013
2014 r = 0;
2015
2016 if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
2017 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
2018
2019 r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
2020
2021 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
2022 if (r == 0)
2023 r = q;
2024 }
2025
2026 if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
2027 /* Returns number of symlinks that where supposed to be installed. */
2028 q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
2029 if (r == 0)
2030 r = q;
2031 }
2032
2033 return r;
2034 }
2035
2036 int unit_file_preset_all(
2037 UnitFileScope scope,
2038 bool runtime,
2039 const char *root_dir,
2040 UnitFilePresetMode mode,
2041 bool force,
2042 UnitFileChange **changes,
2043 unsigned *n_changes) {
2044
2045 _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
2046 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2047 _cleanup_free_ char *config_path = NULL;
2048 char **i;
2049 int r, q;
2050
2051 assert(scope >= 0);
2052 assert(scope < _UNIT_FILE_SCOPE_MAX);
2053 assert(mode < _UNIT_FILE_PRESET_MAX);
2054
2055 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
2056 if (r < 0)
2057 return r;
2058
2059 r = get_config_path(scope, runtime, root_dir, &config_path);
2060 if (r < 0)
2061 return r;
2062
2063 STRV_FOREACH(i, paths.unit_path) {
2064 _cleanup_closedir_ DIR *d = NULL;
2065 _cleanup_free_ char *units_dir;
2066
2067 units_dir = path_join(root_dir, *i, NULL);
2068 if (!units_dir)
2069 return -ENOMEM;
2070
2071 d = opendir(units_dir);
2072 if (!d) {
2073 if (errno == ENOENT)
2074 continue;
2075
2076 return -errno;
2077 }
2078
2079 for (;;) {
2080 struct dirent *de;
2081
2082 errno = 0;
2083 de = readdir(d);
2084 if (!de && errno != 0)
2085 return -errno;
2086
2087 if (!de)
2088 break;
2089
2090 if (hidden_file(de->d_name))
2091 continue;
2092
2093 if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
2094 continue;
2095
2096 dirent_ensure_type(d, de);
2097
2098 if (de->d_type != DT_REG)
2099 continue;
2100
2101 r = unit_file_query_preset(scope, root_dir, de->d_name);
2102 if (r < 0)
2103 return r;
2104
2105 if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
2106 r = install_info_add_auto(&plus, de->d_name);
2107 else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
2108 r = install_info_add_auto(&minus, de->d_name);
2109 else
2110 r = 0;
2111 if (r < 0)
2112 return r;
2113 }
2114 }
2115
2116 r = 0;
2117
2118 if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
2119 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
2120
2121 r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
2122
2123 q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, NULL);
2124 if (r == 0)
2125 r = q;
2126 }
2127
2128 if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
2129 q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
2130 if (r == 0)
2131 r = q;
2132 }
2133
2134 return r;
2135 }
2136
2137 static void unit_file_list_free_one(UnitFileList *f) {
2138 if (!f)
2139 return;
2140
2141 free(f->path);
2142 free(f);
2143 }
2144
2145 DEFINE_TRIVIAL_CLEANUP_FUNC(UnitFileList*, unit_file_list_free_one);
2146
2147 int unit_file_get_list(
2148 UnitFileScope scope,
2149 const char *root_dir,
2150 Hashmap *h) {
2151
2152 _cleanup_lookup_paths_free_ LookupPaths paths = {};
2153 char **i;
2154 int r;
2155
2156 assert(scope >= 0);
2157 assert(scope < _UNIT_FILE_SCOPE_MAX);
2158 assert(h);
2159
2160 if (root_dir && scope != UNIT_FILE_SYSTEM)
2161 return -EINVAL;
2162
2163 if (root_dir) {
2164 r = access(root_dir, F_OK);
2165 if (r < 0)
2166 return -errno;
2167 }
2168
2169 r = lookup_paths_init_from_scope(&paths, scope, root_dir);
2170 if (r < 0)
2171 return r;
2172
2173 STRV_FOREACH(i, paths.unit_path) {
2174 _cleanup_closedir_ DIR *d = NULL;
2175 _cleanup_free_ char *units_dir;
2176
2177 units_dir = path_join(root_dir, *i, NULL);
2178 if (!units_dir)
2179 return -ENOMEM;
2180
2181 d = opendir(units_dir);
2182 if (!d) {
2183 if (errno == ENOENT)
2184 continue;
2185
2186 return -errno;
2187 }
2188
2189 for (;;) {
2190 _cleanup_(unit_file_list_free_onep) UnitFileList *f = NULL;
2191 struct dirent *de;
2192 _cleanup_free_ char *path = NULL;
2193
2194 errno = 0;
2195 de = readdir(d);
2196 if (!de && errno != 0)
2197 return -errno;
2198
2199 if (!de)
2200 break;
2201
2202 if (hidden_file(de->d_name))
2203 continue;
2204
2205 if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
2206 continue;
2207
2208 if (hashmap_get(h, de->d_name))
2209 continue;
2210
2211 dirent_ensure_type(d, de);
2212
2213 if (!IN_SET(de->d_type, DT_LNK, DT_REG))
2214 continue;
2215
2216 f = new0(UnitFileList, 1);
2217 if (!f)
2218 return -ENOMEM;
2219
2220 f->path = path_make_absolute(de->d_name, units_dir);
2221 if (!f->path)
2222 return -ENOMEM;
2223
2224 r = null_or_empty_path(f->path);
2225 if (r < 0 && r != -ENOENT)
2226 return r;
2227 else if (r > 0) {
2228 f->state =
2229 path_startswith(*i, "/run") ?
2230 UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
2231 goto found;
2232 }
2233
2234 r = find_symlinks_in_scope(scope, root_dir, de->d_name, &f->state);
2235 if (r < 0)
2236 return r;
2237 else if (r > 0) {
2238 f->state = UNIT_FILE_ENABLED;
2239 goto found;
2240 }
2241
2242 path = path_make_absolute(de->d_name, *i);
2243 if (!path)
2244 return -ENOMEM;
2245
2246 r = unit_file_can_install(&paths, root_dir, path, true, NULL);
2247 if (r == -EINVAL || /* Invalid setting? */
2248 r == -EBADMSG || /* Invalid format? */
2249 r == -ENOENT /* Included file not found? */)
2250 f->state = UNIT_FILE_INVALID;
2251 else if (r < 0)
2252 return r;
2253 else if (r > 0)
2254 f->state = UNIT_FILE_DISABLED;
2255 else
2256 f->state = UNIT_FILE_STATIC;
2257
2258 found:
2259 r = hashmap_put(h, basename(f->path), f);
2260 if (r < 0)
2261 return r;
2262 f = NULL; /* prevent cleanup */
2263 }
2264 }
2265
2266 return r;
2267 }
2268
2269 static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
2270 [UNIT_FILE_ENABLED] = "enabled",
2271 [UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime",
2272 [UNIT_FILE_LINKED] = "linked",
2273 [UNIT_FILE_LINKED_RUNTIME] = "linked-runtime",
2274 [UNIT_FILE_MASKED] = "masked",
2275 [UNIT_FILE_MASKED_RUNTIME] = "masked-runtime",
2276 [UNIT_FILE_STATIC] = "static",
2277 [UNIT_FILE_DISABLED] = "disabled",
2278 [UNIT_FILE_INDIRECT] = "indirect",
2279 [UNIT_FILE_INVALID] = "invalid",
2280 };
2281
2282 DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
2283
2284 static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
2285 [UNIT_FILE_SYMLINK] = "symlink",
2286 [UNIT_FILE_UNLINK] = "unlink",
2287 };
2288
2289 DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
2290
2291 static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = {
2292 [UNIT_FILE_PRESET_FULL] = "full",
2293 [UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
2294 [UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
2295 };
2296
2297 DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode, UnitFilePresetMode);