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