chiark / gitweb /
bus-util: make more properties settable in --property=
[elogind.git] / src / shared / install.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2011 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty <of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <fnmatch.h>
27
28 #include "util.h"
29 #include "mkdir.h"
30 #include "hashmap.h"
31 #include "set.h"
32 #include "path-util.h"
33 #include "path-lookup.h"
34 #include "strv.h"
35 #include "unit-name.h"
36 #include "install.h"
37 #include "conf-parser.h"
38 #include "conf-files.h"
39 #include "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                         bool also = false;
2194
2195                         errno = 0;
2196                         de = readdir(d);
2197                         if (!de && errno != 0)
2198                                 return -errno;
2199
2200                         if (!de)
2201                                 break;
2202
2203                         if (hidden_file(de->d_name))
2204                                 continue;
2205
2206                         if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
2207                                 continue;
2208
2209                         if (hashmap_get(h, de->d_name))
2210                                 continue;
2211
2212                         dirent_ensure_type(d, de);
2213
2214                         if (!IN_SET(de->d_type, DT_LNK, DT_REG))
2215                                 continue;
2216
2217                         f = new0(UnitFileList, 1);
2218                         if (!f)
2219                                 return -ENOMEM;
2220
2221                         f->path = path_make_absolute(de->d_name, units_dir);
2222                         if (!f->path)
2223                                 return -ENOMEM;
2224
2225                         r = null_or_empty_path(f->path);
2226                         if (r < 0 && r != -ENOENT)
2227                                 return r;
2228                         else if (r > 0) {
2229                                 f->state =
2230                                         path_startswith(*i, "/run") ?
2231                                         UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED;
2232                                 goto found;
2233                         }
2234
2235                         r = find_symlinks_in_scope(scope, root_dir, de->d_name, &f->state);
2236                         if (r < 0)
2237                                 return r;
2238                         else if (r > 0) {
2239                                 f->state = UNIT_FILE_ENABLED;
2240                                 goto found;
2241                         }
2242
2243                         path = path_make_absolute(de->d_name, *i);
2244                         if (!path)
2245                                 return -ENOMEM;
2246
2247                         r = unit_file_can_install(&paths, root_dir, path, true, &also);
2248                         if (r == -EINVAL ||  /* Invalid setting? */
2249                             r == -EBADMSG || /* Invalid format? */
2250                             r == -ENOENT     /* Included file not found? */)
2251                                 f->state = UNIT_FILE_INVALID;
2252                         else if (r < 0)
2253                                 return r;
2254                         else if (r > 0)
2255                                 f->state = UNIT_FILE_DISABLED;
2256                         else
2257                                 f->state = also ? UNIT_FILE_INDIRECT : UNIT_FILE_STATIC;
2258
2259                 found:
2260                         r = hashmap_put(h, basename(f->path), f);
2261                         if (r < 0)
2262                                 return r;
2263                         f = NULL; /* prevent cleanup */
2264                 }
2265         }
2266
2267         return 0;
2268 }
2269
2270 static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
2271         [UNIT_FILE_ENABLED] = "enabled",
2272         [UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime",
2273         [UNIT_FILE_LINKED] = "linked",
2274         [UNIT_FILE_LINKED_RUNTIME] = "linked-runtime",
2275         [UNIT_FILE_MASKED] = "masked",
2276         [UNIT_FILE_MASKED_RUNTIME] = "masked-runtime",
2277         [UNIT_FILE_STATIC] = "static",
2278         [UNIT_FILE_DISABLED] = "disabled",
2279         [UNIT_FILE_INDIRECT] = "indirect",
2280         [UNIT_FILE_INVALID] = "invalid",
2281 };
2282
2283 DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
2284
2285 static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
2286         [UNIT_FILE_SYMLINK] = "symlink",
2287         [UNIT_FILE_UNLINK] = "unlink",
2288 };
2289
2290 DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
2291
2292 static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = {
2293         [UNIT_FILE_PRESET_FULL] = "full",
2294         [UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
2295         [UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
2296 };
2297
2298 DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode, UnitFilePresetMode);