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