]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/dropin.c
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 char prefix
[DECIMAL_STR_MAX(unsigned)];
47 _cleanup_free_
char *b
= NULL
;
55 sprintf(prefix
, "%u", level
);
57 b
= xescape(name
, "/.");
61 if (!filename_is_valid(b
))
64 p
= strjoin(dir
, "/", unit
, ".d");
68 q
= strjoin(p
, "/", prefix
, "-", b
, ".conf");
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 unit_file_find_dir(
120 const char *original_root
,
124 _cleanup_free_
char *chased
= NULL
;
129 r
= chase_symlinks(path
, original_root
, 0, &chased
);
130 if (r
== -ENOENT
) /* Ignore -ENOENT, after all most units won't have a drop-in dir */
133 return log_full_errno(LOG_WARNING
, r
, "Failed to canonicalize path %s: %m", path
);
135 r
= strv_push(dirs
, chased
);
143 static int unit_file_find_dirs(
144 const char *original_root
,
145 Set
*unit_path_cache
,
146 const char *unit_path
,
158 path
= strjoina(unit_path
, "/", name
, suffix
);
160 if (!unit_path_cache
|| set_get(unit_path_cache
, path
)) {
161 r
= unit_file_find_dir(original_root
, path
, dirs
);
166 if (unit_name_is_valid(name
, UNIT_NAME_INSTANCE
)) {
167 /* Also try the template dir */
169 _cleanup_free_
char *template = NULL
;
171 r
= unit_name_template(name
, &template);
173 return log_error_errno(r
, "Failed to generate template from unit name: %m");
175 return unit_file_find_dirs(original_root
, unit_path_cache
, unit_path
, template, suffix
, dirs
);
181 int unit_file_find_dropin_paths(
182 const char *original_root
,
184 Set
*unit_path_cache
,
185 const char *dir_suffix
,
186 const char *file_suffix
,
190 _cleanup_strv_free_
char **dirs
= NULL
;
197 SET_FOREACH(t
, names
, i
)
198 STRV_FOREACH(p
, lookup_path
)
199 unit_file_find_dirs(original_root
, unit_path_cache
, *p
, t
, dir_suffix
, &dirs
);
201 if (strv_isempty(dirs
)) {
206 r
= conf_files_list_strv(ret
, file_suffix
, NULL
, (const char**) dirs
);
208 return log_warning_errno(r
, "Failed to create the list of configuration files: %m");