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/>.
26 #include "alloc-util.h"
27 #include "conf-files.h"
31 #include "fileio-label.h"
36 #include "path-util.h"
38 #include "string-util.h"
40 #include "unit-name.h"
42 int drop_in_file(const char *dir
, const char *unit
, unsigned level
,
43 const char *name
, char **_p
, char **_q
) {
45 _cleanup_free_
char *b
= NULL
;
48 char prefix
[DECIMAL_STR_MAX(unsigned)];
55 sprintf(prefix
, "%u", level
);
57 b
= xescape(name
, "/.");
61 if (!filename_is_valid(b
))
64 p
= strjoin(dir
, "/", unit
, ".d", NULL
);
68 q
= strjoin(p
, "/", prefix
, "-", b
, ".conf", NULL
);
79 int write_drop_in(const char *dir
, const char *unit
, unsigned level
,
80 const char *name
, const char *data
) {
82 _cleanup_free_
char *p
= NULL
, *q
= NULL
;
90 r
= drop_in_file(dir
, unit
, level
, name
, &p
, &q
);
94 (void) mkdir_p(p
, 0755);
95 return write_string_file_atomic_label(q
, data
);
98 int write_drop_in_format(const char *dir
, const char *unit
, unsigned level
,
99 const char *name
, const char *format
, ...) {
100 _cleanup_free_
char *p
= NULL
;
109 va_start(ap
, format
);
110 r
= vasprintf(&p
, format
, ap
);
116 return write_drop_in(dir
, unit
, level
, name
, p
);
119 static int iterate_dir(
121 UnitDependency dependency
,
122 dependency_consumer_t consumer
,
126 _cleanup_closedir_
DIR *d
= NULL
;
131 /* The config directories are special, since the order of the
132 * drop-ins matters */
133 if (dependency
< 0) {
134 r
= strv_extend(strv
, path
);
148 return log_error_errno(errno
, "Failed to open directory %s: %m", path
);
153 _cleanup_free_
char *f
= NULL
;
157 if (!de
&& errno
> 0)
158 return log_error_errno(errno
, "Failed to read directory %s: %m", path
);
163 if (hidden_or_backup_file(de
->d_name
))
166 f
= strjoin(path
, "/", de
->d_name
, NULL
);
170 r
= consumer(dependency
, de
->d_name
, f
, arg
);
178 int unit_file_process_dir(
179 Set
*unit_path_cache
,
180 const char *unit_path
,
183 UnitDependency dependency
,
184 dependency_consumer_t consumer
,
188 _cleanup_free_
char *path
= NULL
;
195 path
= strjoin(unit_path
, "/", name
, suffix
, NULL
);
199 if (!unit_path_cache
|| set_get(unit_path_cache
, path
))
200 (void) iterate_dir(path
, dependency
, consumer
, arg
, strv
);
202 if (unit_name_is_valid(name
, UNIT_NAME_INSTANCE
)) {
203 _cleanup_free_
char *template = NULL
, *p
= NULL
;
204 /* Also try the template dir */
206 r
= unit_name_template(name
, &template);
208 return log_error_errno(r
, "Failed to generate template from unit name: %m");
210 p
= strjoin(unit_path
, "/", template, suffix
, NULL
);
214 if (!unit_path_cache
|| set_get(unit_path_cache
, p
))
215 (void) iterate_dir(p
, dependency
, consumer
, arg
, strv
);
221 int unit_file_find_dropin_paths(
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(unit_path_cache
, *p
, t
, ".d", _UNIT_DEPENDENCY_INVALID
, NULL
, NULL
, &strv
);
241 if (strv_isempty(strv
))
244 r
= conf_files_list_strv(&ans
, ".conf", NULL
, (const char**) strv
);
246 return log_warning_errno(r
, "Failed to get list of configuration files: %m");