]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/dropin.c
Introduce '## ' as internal comment prefix in .in files and filter out a comment...
[thirdparty/systemd.git] / src / shared / dropin.c
CommitLineData
29686440
ZJS
1/***
2 This file is part of systemd.
3
4 Copyright 2014 Zbigniew Jędrzejewski-Szmek
5
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.
10
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.
15
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/>.
18***/
19
a8fbdf54
TA
20#include <errno.h>
21#include <stdarg.h>
22#include <stdio.h>
23#include <stdlib.h>
24
b5efdb8a 25#include "alloc-util.h"
1a7f1b38 26#include "conf-files.h"
8fb3f009 27#include "dirent-util.h"
3ffd4af2 28#include "dropin.h"
4f5dd394 29#include "escape.h"
3ffd4af2 30#include "fd-util.h"
4f5dd394 31#include "fileio-label.h"
17e78d18 32#include "fs-util.h"
a8fbdf54
TA
33#include "hashmap.h"
34#include "log.h"
35#include "macro.h"
4f5dd394 36#include "mkdir.h"
bb15fafe 37#include "path-util.h"
a8fbdf54 38#include "set.h"
07630cea 39#include "string-util.h"
4f5dd394 40#include "strv.h"
a8fbdf54 41#include "unit-name.h"
29686440 42
8eea8687 43int drop_in_file(const char *dir, const char *unit, unsigned level,
29686440
ZJS
44 const char *name, char **_p, char **_q) {
45
46 _cleanup_free_ char *b = NULL;
47 char *p, *q;
48
8eea8687
ZJS
49 char prefix[DECIMAL_STR_MAX(unsigned)];
50
29686440
ZJS
51 assert(unit);
52 assert(name);
53 assert(_p);
54 assert(_q);
55
8eea8687
ZJS
56 sprintf(prefix, "%u", level);
57
29686440
ZJS
58 b = xescape(name, "/.");
59 if (!b)
60 return -ENOMEM;
61
ae6c3cc0 62 if (!filename_is_valid(b))
29686440
ZJS
63 return -EINVAL;
64
605405c6 65 p = strjoin(dir, "/", unit, ".d");
29686440
ZJS
66 if (!p)
67 return -ENOMEM;
68
605405c6 69 q = strjoin(p, "/", prefix, "-", b, ".conf");
29686440
ZJS
70 if (!q) {
71 free(p);
72 return -ENOMEM;
73 }
74
75 *_p = p;
76 *_q = q;
77 return 0;
78}
79
8eea8687 80int write_drop_in(const char *dir, const char *unit, unsigned level,
29686440
ZJS
81 const char *name, const char *data) {
82
83 _cleanup_free_ char *p = NULL, *q = NULL;
84 int r;
85
86 assert(dir);
87 assert(unit);
88 assert(name);
89 assert(data);
90
8eea8687 91 r = drop_in_file(dir, unit, level, name, &p, &q);
29686440
ZJS
92 if (r < 0)
93 return r;
94
45519fd6 95 (void) mkdir_p(p, 0755);
29686440
ZJS
96 return write_string_file_atomic_label(q, data);
97}
98
8eea8687 99int write_drop_in_format(const char *dir, const char *unit, unsigned level,
29686440
ZJS
100 const char *name, const char *format, ...) {
101 _cleanup_free_ char *p = NULL;
102 va_list ap;
103 int r;
104
105 assert(dir);
106 assert(unit);
107 assert(name);
108 assert(format);
109
110 va_start(ap, format);
111 r = vasprintf(&p, format, ap);
112 va_end(ap);
113
114 if (r < 0)
115 return -ENOMEM;
116
8eea8687 117 return write_drop_in(dir, unit, level, name, p);
29686440 118}
1a7f1b38 119
dcc4f30e 120static int unit_file_find_dir(
17e78d18 121 const char *original_root,
dcc4f30e
ZJS
122 const char *path,
123 char ***dirs) {
1a7f1b38 124
17e78d18 125 _cleanup_free_ char *chased = NULL;
1a7f1b38
ZJS
126 int r;
127
128 assert(path);
129
17e78d18
ZJS
130 r = chase_symlinks(path, original_root, 0, &chased);
131 if (r < 0)
132 return log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING,
133 r, "Failed to canonicalize path %s: %m", path);
134
dcc4f30e
ZJS
135 r = strv_push(dirs, chased);
136 if (r < 0)
137 return log_oom();
1a7f1b38 138
dcc4f30e 139 chased = NULL;
1a7f1b38
ZJS
140 return 0;
141}
142
dcc4f30e 143static int unit_file_find_dirs(
17e78d18 144 const char *original_root,
7410616c 145 Set *unit_path_cache,
1a7f1b38
ZJS
146 const char *unit_path,
147 const char *name,
148 const char *suffix,
dcc4f30e 149 char ***dirs) {
1a7f1b38
ZJS
150
151 _cleanup_free_ char *path = NULL;
7410616c 152 int r;
1a7f1b38
ZJS
153
154 assert(unit_path);
155 assert(name);
156 assert(suffix);
157
605405c6 158 path = strjoin(unit_path, "/", name, suffix);
1a7f1b38
ZJS
159 if (!path)
160 return log_oom();
161
dcc4f30e
ZJS
162 if (!unit_path_cache || set_get(unit_path_cache, path)) {
163 r = unit_file_find_dir(original_root, path, dirs);
164 if (r < 0)
165 return r;
166 }
1a7f1b38 167
7410616c 168 if (unit_name_is_valid(name, UNIT_NAME_INSTANCE)) {
1a7f1b38
ZJS
169 _cleanup_free_ char *template = NULL, *p = NULL;
170 /* Also try the template dir */
171
7410616c
LP
172 r = unit_name_template(name, &template);
173 if (r < 0)
174 return log_error_errno(r, "Failed to generate template from unit name: %m");
1a7f1b38 175
605405c6 176 p = strjoin(unit_path, "/", template, suffix);
1a7f1b38
ZJS
177 if (!p)
178 return log_oom();
179
dcc4f30e
ZJS
180 if (!unit_path_cache || set_get(unit_path_cache, p)) {
181 r = unit_file_find_dir(original_root, p, dirs);
182 if (r < 0)
183 return r;
184 }
1a7f1b38
ZJS
185 }
186
187 return 0;
188}
189
190int unit_file_find_dropin_paths(
17e78d18 191 const char *original_root,
1a7f1b38
ZJS
192 char **lookup_path,
193 Set *unit_path_cache,
95778782
ZJS
194 const char *dir_suffix,
195 const char *file_suffix,
1a7f1b38
ZJS
196 Set *names,
197 char ***paths) {
198
dcc4f30e 199 _cleanup_strv_free_ char **dirs = NULL, **ans = NULL;
1a7f1b38 200 Iterator i;
dcc4f30e 201 char *t, **p;
1a7f1b38
ZJS
202 int r;
203
204 assert(paths);
205
dcc4f30e 206 SET_FOREACH(t, names, i)
1a7f1b38 207 STRV_FOREACH(p, lookup_path)
dcc4f30e 208 unit_file_find_dirs(original_root, unit_path_cache, *p, t, dir_suffix, &dirs);
1a7f1b38 209
dcc4f30e 210 if (strv_isempty(dirs))
1a7f1b38
ZJS
211 return 0;
212
dcc4f30e 213 r = conf_files_list_strv(&ans, file_suffix, NULL, (const char**) dirs);
1a7f1b38 214 if (r < 0)
95778782 215 return log_warning_errno(r, "Failed to sort the list of configuration files: %m");
1a7f1b38
ZJS
216
217 *paths = ans;
218 ans = NULL;
219 return 1;
220}