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