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