2 This file is part of systemd.
4 Copyright 2014 Zbigniew Jędrzejewski-Szmek
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include "alloc-util.h"
26 #include "conf-files.h"
27 #include "dirent-util.h"
31 #include "fileio-label.h"
37 #include "path-util.h"
39 #include "string-util.h"
41 #include "unit-name.h"
43 int drop_in_file(const char *dir
, const char *unit
, unsigned level
,
44 const char *name
, char **_p
, char **_q
) {
46 _cleanup_free_
char *b
= NULL
;
49 char prefix
[DECIMAL_STR_MAX(unsigned)];
56 sprintf(prefix
, "%u", level
);
58 b
= xescape(name
, "/.");
62 if (!filename_is_valid(b
))
65 p
= strjoin(dir
, "/", unit
, ".d");
69 q
= strjoin(p
, "/", prefix
, "-", b
, ".conf");
80 int write_drop_in(const char *dir
, const char *unit
, unsigned level
,
81 const char *name
, const char *data
) {
83 _cleanup_free_
char *p
= NULL
, *q
= NULL
;
91 r
= drop_in_file(dir
, unit
, level
, name
, &p
, &q
);
95 (void) mkdir_p(p
, 0755);
96 return write_string_file_atomic_label(q
, data
);
99 int write_drop_in_format(const char *dir
, const char *unit
, unsigned level
,
100 const char *name
, const char *format
, ...) {
101 _cleanup_free_
char *p
= NULL
;
110 va_start(ap
, format
);
111 r
= vasprintf(&p
, format
, ap
);
117 return write_drop_in(dir
, unit
, level
, name
, p
);
120 static int iterate_dir(
122 const char *original_root
,
123 UnitDependency dependency
,
124 dependency_consumer_t consumer
,
128 _cleanup_free_
char *chased
= NULL
;
129 _cleanup_closedir_
DIR *d
= NULL
;
135 r
= chase_symlinks(path
, original_root
, 0, &chased
);
137 return log_full_errno(r
== -ENOENT
? LOG_DEBUG
: LOG_WARNING
,
138 r
, "Failed to canonicalize path %s: %m", path
);
140 /* The config directories are special, since the order of the
141 * drop-ins matters */
142 if (dependency
< 0) {
143 r
= strv_push(strv
, chased
);
158 return log_warning_errno(errno
, "Failed to open directory %s: %m", path
);
161 FOREACH_DIRENT(de
, d
, return log_warning_errno(errno
, "Failed to read directory %s: %m", path
)) {
162 _cleanup_free_
char *f
= NULL
;
164 f
= strjoin(path
, "/", de
->d_name
);
168 r
= consumer(dependency
, de
->d_name
, f
, arg
);
176 int unit_file_process_dir(
177 const char *original_root
,
178 Set
*unit_path_cache
,
179 const char *unit_path
,
182 UnitDependency dependency
,
183 dependency_consumer_t consumer
,
187 _cleanup_free_
char *path
= NULL
;
194 path
= strjoin(unit_path
, "/", name
, suffix
);
198 if (!unit_path_cache
|| set_get(unit_path_cache
, path
))
199 (void) iterate_dir(path
, original_root
, dependency
, consumer
, arg
, strv
);
201 if (unit_name_is_valid(name
, UNIT_NAME_INSTANCE
)) {
202 _cleanup_free_
char *template = NULL
, *p
= NULL
;
203 /* Also try the template dir */
205 r
= unit_name_template(name
, &template);
207 return log_error_errno(r
, "Failed to generate template from unit name: %m");
209 p
= strjoin(unit_path
, "/", template, suffix
);
213 if (!unit_path_cache
|| set_get(unit_path_cache
, p
))
214 (void) iterate_dir(p
, original_root
, dependency
, consumer
, arg
, strv
);
220 int unit_file_find_dropin_paths(
221 const char *original_root
,
223 Set
*unit_path_cache
,
227 _cleanup_strv_free_
char **strv
= NULL
, **ans
= NULL
;
234 SET_FOREACH(t
, names
, i
) {
237 STRV_FOREACH(p
, lookup_path
)
238 unit_file_process_dir(original_root
, unit_path_cache
, *p
, t
, ".d",
239 _UNIT_DEPENDENCY_INVALID
, NULL
, NULL
, &strv
);
242 if (strv_isempty(strv
))
245 r
= conf_files_list_strv(&ans
, ".conf", NULL
, (const char**) strv
);
247 return log_warning_errno(r
, "Failed to get list of configuration files: %m");