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