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