chiark / gitweb /
Revert "Implement SocketUser= and SocketGroup= for [Socket]"
[elogind.git] / src / core / load-dropin.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 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 <dirent.h>
23 #include <errno.h>
24
25 #include "unit.h"
26 #include "load-dropin.h"
27 #include "log.h"
28 #include "strv.h"
29 #include "unit-name.h"
30
31 static int iterate_dir(Unit *u, const char *path, UnitDependency dependency) {
32         DIR *d;
33         struct dirent *de;
34         int r;
35
36         assert(u);
37         assert(path);
38
39         d = opendir(path);
40         if (!d) {
41
42                 if (errno == ENOENT)
43                         return 0;
44
45                 return -errno;
46         }
47
48         while ((de = readdir(d))) {
49                 char *f;
50
51                 if (ignore_file(de->d_name))
52                         continue;
53
54                 f = strjoin(path, "/", de->d_name, NULL);
55                 if (!f) {
56                         r = -ENOMEM;
57                         goto finish;
58                 }
59
60                 r = unit_add_dependency_by_name(u, dependency, de->d_name, f, true);
61                 free(f);
62
63                 if (r < 0)
64                         log_error("Cannot add dependency %s to %s, ignoring: %s", de->d_name, u->id, strerror(-r));
65         }
66
67         r = 0;
68
69 finish:
70         closedir(d);
71         return r;
72 }
73
74 static int process_dir(Unit *u, const char *unit_path, const char *name, const char *suffix, UnitDependency dependency) {
75         int r;
76         char *path;
77
78         assert(u);
79         assert(unit_path);
80         assert(name);
81         assert(suffix);
82
83         path = strjoin(unit_path, "/", name, suffix, NULL);
84         if (!path)
85                 return -ENOMEM;
86
87         if (u->manager->unit_path_cache &&
88             !set_get(u->manager->unit_path_cache, path))
89                 r = 0;
90         else
91                 r = iterate_dir(u, path, dependency);
92         free(path);
93
94         if (r < 0)
95                 return r;
96
97         if (u->instance) {
98                 char *template;
99                 /* Also try the template dir */
100
101                 template = unit_name_template(name);
102                 if (!template)
103                         return -ENOMEM;
104
105                 path = strjoin(unit_path, "/", template, suffix, NULL);
106                 free(template);
107
108                 if (!path)
109                         return -ENOMEM;
110
111                 if (u->manager->unit_path_cache &&
112                     !set_get(u->manager->unit_path_cache, path))
113                         r = 0;
114                 else
115                         r = iterate_dir(u, path, dependency);
116                 free(path);
117
118                 if (r < 0)
119                         return r;
120         }
121
122         return 0;
123 }
124
125 int unit_load_dropin(Unit *u) {
126         Iterator i;
127         char *t;
128
129         assert(u);
130
131         /* Load dependencies from supplementary drop-in directories */
132
133         SET_FOREACH(t, u->names, i) {
134                 char **p;
135
136                 STRV_FOREACH(p, u->manager->lookup_paths.unit_path) {
137                         int r;
138
139                         r = process_dir(u, *p, t, ".wants", UNIT_WANTS);
140                         if (r < 0)
141                                 return r;
142
143                         r = process_dir(u, *p, t, ".requires", UNIT_REQUIRES);
144                         if (r < 0)
145                                 return r;
146                 }
147         }
148
149         return 0;
150 }