File: | build-scan/../src/shared/path-lookup.c |
Warning: | line 528, column 24 Potential leak of memory pointed to by 'global_runtime_config' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ | |||
2 | ||||
3 | #include <errno(*__errno_location ()).h> | |||
4 | #include <stdio.h> | |||
5 | #include <stdlib.h> | |||
6 | #include <string.h> | |||
7 | ||||
8 | #include "alloc-util.h" | |||
9 | #include "fileio.h" | |||
10 | #include "fs-util.h" | |||
11 | #include "install.h" | |||
12 | #include "log.h" | |||
13 | #include "macro.h" | |||
14 | #include "mkdir.h" | |||
15 | #include "path-lookup.h" | |||
16 | #include "path-util.h" | |||
17 | #include "rm-rf.h" | |||
18 | #include "stat-util.h" | |||
19 | #include "string-util.h" | |||
20 | #include "strv.h" | |||
21 | #include "user-util.h" | |||
22 | #include "util.h" | |||
23 | ||||
24 | int xdg_user_runtime_dir(char **ret, const char *suffix) { | |||
25 | const char *e; | |||
26 | char *j; | |||
27 | ||||
28 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/shared/path-lookup.c", 28 , __PRETTY_FUNCTION__); } while (0); | |||
29 | assert(suffix)do { if ((__builtin_expect(!!(!(suffix)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("suffix"), "../src/shared/path-lookup.c" , 29, __PRETTY_FUNCTION__); } while (0); | |||
30 | ||||
31 | e = getenv("XDG_RUNTIME_DIR"); | |||
32 | if (!e) | |||
33 | return -ENXIO6; | |||
34 | ||||
35 | j = strappend(e, suffix); | |||
36 | if (!j) | |||
37 | return -ENOMEM12; | |||
38 | ||||
39 | *ret = j; | |||
40 | return 0; | |||
41 | } | |||
42 | ||||
43 | int xdg_user_config_dir(char **ret, const char *suffix) { | |||
44 | const char *e; | |||
45 | char *j; | |||
46 | int r; | |||
47 | ||||
48 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/shared/path-lookup.c", 48 , __PRETTY_FUNCTION__); } while (0); | |||
49 | ||||
50 | e = getenv("XDG_CONFIG_HOME"); | |||
51 | if (e) | |||
52 | j = strappend(e, suffix); | |||
53 | else { | |||
54 | _cleanup_free___attribute__((cleanup(freep))) char *home = NULL((void*)0); | |||
55 | ||||
56 | r = get_home_dir(&home); | |||
57 | if (r < 0) | |||
58 | return r; | |||
59 | ||||
60 | j = strjoin(home, "/.config", suffix)strjoin_real((home), "/.config", suffix, ((void*)0)); | |||
61 | } | |||
62 | ||||
63 | if (!j) | |||
64 | return -ENOMEM12; | |||
65 | ||||
66 | *ret = j; | |||
67 | return 0; | |||
68 | } | |||
69 | ||||
70 | int xdg_user_data_dir(char **ret, const char *suffix) { | |||
71 | const char *e; | |||
72 | char *j; | |||
73 | int r; | |||
74 | ||||
75 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/shared/path-lookup.c", 75 , __PRETTY_FUNCTION__); } while (0); | |||
76 | assert(suffix)do { if ((__builtin_expect(!!(!(suffix)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("suffix"), "../src/shared/path-lookup.c" , 76, __PRETTY_FUNCTION__); } while (0); | |||
77 | ||||
78 | /* We don't treat /etc/xdg/systemd here as the spec | |||
79 | * suggests because we assume that is a link to | |||
80 | * /etc/systemd/ anyway. */ | |||
81 | ||||
82 | e = getenv("XDG_DATA_HOME"); | |||
83 | if (e) | |||
84 | j = strappend(e, suffix); | |||
85 | else { | |||
86 | _cleanup_free___attribute__((cleanup(freep))) char *home = NULL((void*)0); | |||
87 | ||||
88 | r = get_home_dir(&home); | |||
89 | if (r < 0) | |||
90 | return r; | |||
91 | ||||
92 | j = strjoin(home, "/.local/share", suffix)strjoin_real((home), "/.local/share", suffix, ((void*)0)); | |||
93 | } | |||
94 | if (!j) | |||
95 | return -ENOMEM12; | |||
96 | ||||
97 | *ret = j; | |||
98 | return 1; | |||
99 | } | |||
100 | ||||
101 | static const char* const user_data_unit_paths[] = { | |||
102 | "/usr/local/lib/systemd/user", | |||
103 | "/usr/local/share/systemd/user", | |||
104 | USER_DATA_UNIT_PATH"/usr/lib/systemd/user", | |||
105 | "/usr/lib/systemd/user", | |||
106 | "/usr/share/systemd/user", | |||
107 | NULL((void*)0) | |||
108 | }; | |||
109 | ||||
110 | static const char* const user_config_unit_paths[] = { | |||
111 | USER_CONFIG_UNIT_PATH"/etc/systemd/user", | |||
112 | "/etc/systemd/user", | |||
113 | NULL((void*)0) | |||
114 | }; | |||
115 | ||||
116 | int xdg_user_dirs(char ***ret_config_dirs, char ***ret_data_dirs) { | |||
117 | /* Implement the mechanisms defined in | |||
118 | * | |||
119 | * http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html | |||
120 | * | |||
121 | * We look in both the config and the data dirs because we | |||
122 | * want to encourage that distributors ship their unit files | |||
123 | * as data, and allow overriding as configuration. | |||
124 | */ | |||
125 | const char *e; | |||
126 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **config_dirs = NULL((void*)0), **data_dirs = NULL((void*)0); | |||
127 | ||||
128 | e = getenv("XDG_CONFIG_DIRS"); | |||
129 | if (e) { | |||
130 | config_dirs = strv_split(e, ":"); | |||
131 | if (!config_dirs) | |||
132 | return -ENOMEM12; | |||
133 | } | |||
134 | ||||
135 | e = getenv("XDG_DATA_DIRS"); | |||
136 | if (e) | |||
137 | data_dirs = strv_split(e, ":"); | |||
138 | else | |||
139 | data_dirs = strv_new("/usr/local/share", | |||
140 | "/usr/share", | |||
141 | NULL((void*)0)); | |||
142 | if (!data_dirs) | |||
143 | return -ENOMEM12; | |||
144 | ||||
145 | *ret_config_dirs = config_dirs; | |||
146 | *ret_data_dirs = data_dirs; | |||
147 | config_dirs = data_dirs = NULL((void*)0); | |||
148 | return 0; | |||
149 | } | |||
150 | ||||
151 | static char** user_dirs( | |||
152 | const char *persistent_config, | |||
153 | const char *runtime_config, | |||
154 | const char *global_persistent_config, | |||
155 | const char *global_runtime_config, | |||
156 | const char *generator, | |||
157 | const char *generator_early, | |||
158 | const char *generator_late, | |||
159 | const char *transient, | |||
160 | const char *persistent_control, | |||
161 | const char *runtime_control) { | |||
162 | ||||
163 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **config_dirs = NULL((void*)0), **data_dirs = NULL((void*)0); | |||
164 | _cleanup_free___attribute__((cleanup(freep))) char *data_home = NULL((void*)0); | |||
165 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **res = NULL((void*)0); | |||
166 | int r; | |||
167 | ||||
168 | r = xdg_user_dirs(&config_dirs, &data_dirs); | |||
169 | if (r < 0) | |||
170 | return NULL((void*)0); | |||
171 | ||||
172 | r = xdg_user_data_dir(&data_home, "/systemd/user"); | |||
173 | if (r < 0 && r != -ENXIO6) | |||
174 | return NULL((void*)0); | |||
175 | ||||
176 | /* Now merge everything we found. */ | |||
177 | if (strv_extend(&res, persistent_control) < 0) | |||
178 | return NULL((void*)0); | |||
179 | ||||
180 | if (strv_extend(&res, runtime_control) < 0) | |||
181 | return NULL((void*)0); | |||
182 | ||||
183 | if (strv_extend(&res, transient) < 0) | |||
184 | return NULL((void*)0); | |||
185 | ||||
186 | if (strv_extend(&res, generator_early) < 0) | |||
187 | return NULL((void*)0); | |||
188 | ||||
189 | if (strv_extend_strv_concat(&res, config_dirs, "/systemd/user") < 0) | |||
190 | return NULL((void*)0); | |||
191 | ||||
192 | if (strv_extend(&res, persistent_config) < 0) | |||
193 | return NULL((void*)0); | |||
194 | ||||
195 | /* global config has lower priority than the user config of the same type */ | |||
196 | if (strv_extend(&res, global_persistent_config) < 0) | |||
197 | return NULL((void*)0); | |||
198 | ||||
199 | if (strv_extend_strv(&res, (char**) user_config_unit_paths, false0) < 0) | |||
200 | return NULL((void*)0); | |||
201 | ||||
202 | if (strv_extend(&res, runtime_config) < 0) | |||
203 | return NULL((void*)0); | |||
204 | ||||
205 | if (strv_extend(&res, global_runtime_config) < 0) | |||
206 | return NULL((void*)0); | |||
207 | ||||
208 | if (strv_extend(&res, generator) < 0) | |||
209 | return NULL((void*)0); | |||
210 | ||||
211 | if (strv_extend(&res, data_home) < 0) | |||
212 | return NULL((void*)0); | |||
213 | ||||
214 | if (strv_extend_strv_concat(&res, data_dirs, "/systemd/user") < 0) | |||
215 | return NULL((void*)0); | |||
216 | ||||
217 | if (strv_extend_strv(&res, (char**) user_data_unit_paths, false0) < 0) | |||
218 | return NULL((void*)0); | |||
219 | ||||
220 | if (strv_extend(&res, generator_late) < 0) | |||
221 | return NULL((void*)0); | |||
222 | ||||
223 | if (path_strv_make_absolute_cwd(res) < 0) | |||
224 | return NULL((void*)0); | |||
225 | ||||
226 | return TAKE_PTR(res)({ typeof(res) _ptr_ = (res); (res) = ((void*)0); _ptr_; }); | |||
227 | } | |||
228 | ||||
229 | bool_Bool path_is_user_data_dir(const char *path) { | |||
230 | assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("path"), "../src/shared/path-lookup.c", 230 , __PRETTY_FUNCTION__); } while (0); | |||
231 | ||||
232 | return strv_contains((char**) user_data_unit_paths, path)(!!strv_find(((char**) user_data_unit_paths), (path))); | |||
233 | } | |||
234 | ||||
235 | bool_Bool path_is_user_config_dir(const char *path) { | |||
236 | assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("path"), "../src/shared/path-lookup.c", 236 , __PRETTY_FUNCTION__); } while (0); | |||
237 | ||||
238 | return strv_contains((char**) user_config_unit_paths, path)(!!strv_find(((char**) user_config_unit_paths), (path))); | |||
239 | } | |||
240 | ||||
241 | static int acquire_generator_dirs( | |||
242 | UnitFileScope scope, | |||
243 | const char *tempdir, | |||
244 | char **generator, | |||
245 | char **generator_early, | |||
246 | char **generator_late) { | |||
247 | ||||
248 | _cleanup_free___attribute__((cleanup(freep))) char *x = NULL((void*)0), *y = NULL((void*)0), *z = NULL((void*)0); | |||
249 | const char *prefix; | |||
250 | ||||
251 | assert(generator)do { if ((__builtin_expect(!!(!(generator)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("generator"), "../src/shared/path-lookup.c" , 251, __PRETTY_FUNCTION__); } while (0); | |||
252 | assert(generator_early)do { if ((__builtin_expect(!!(!(generator_early)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("generator_early"), "../src/shared/path-lookup.c" , 252, __PRETTY_FUNCTION__); } while (0); | |||
253 | assert(generator_late)do { if ((__builtin_expect(!!(!(generator_late)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("generator_late"), "../src/shared/path-lookup.c" , 253, __PRETTY_FUNCTION__); } while (0); | |||
254 | assert(IN_SET(scope, UNIT_FILE_SYSTEM, UNIT_FILE_USER, UNIT_FILE_GLOBAL))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended[20 - sizeof((int[]){UNIT_FILE_SYSTEM, UNIT_FILE_USER, UNIT_FILE_GLOBAL })/sizeof(int)]; switch(scope) { case UNIT_FILE_SYSTEM: case UNIT_FILE_USER : case UNIT_FILE_GLOBAL: _found = 1; break; default: break; } _found; }))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("IN_SET(scope, UNIT_FILE_SYSTEM, UNIT_FILE_USER, UNIT_FILE_GLOBAL)" ), "../src/shared/path-lookup.c", 254, __PRETTY_FUNCTION__); } while (0); | |||
255 | ||||
256 | if (scope == UNIT_FILE_GLOBAL) | |||
257 | return -EOPNOTSUPP95; | |||
258 | ||||
259 | if (tempdir) | |||
260 | prefix = tempdir; | |||
261 | else if (scope == UNIT_FILE_SYSTEM) | |||
262 | prefix = "/run/systemd"; | |||
263 | else { | |||
264 | /* UNIT_FILE_USER */ | |||
265 | const char *e; | |||
266 | ||||
267 | e = getenv("XDG_RUNTIME_DIR"); | |||
268 | if (!e) | |||
269 | return -ENXIO6; | |||
270 | ||||
271 | prefix = strjoina(e, "/systemd")({ const char *_appendees_[] = { e, "/systemd" }; char *_d_, * _p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p(typeof (_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | |||
272 | } | |||
273 | ||||
274 | x = strappend(prefix, "/generator"); | |||
275 | if (!x) | |||
276 | return -ENOMEM12; | |||
277 | ||||
278 | y = strappend(prefix, "/generator.early"); | |||
279 | if (!y) | |||
280 | return -ENOMEM12; | |||
281 | ||||
282 | z = strappend(prefix, "/generator.late"); | |||
283 | if (!z) | |||
284 | return -ENOMEM12; | |||
285 | ||||
286 | *generator = TAKE_PTR(x)({ typeof(x) _ptr_ = (x); (x) = ((void*)0); _ptr_; }); | |||
287 | *generator_early = TAKE_PTR(y)({ typeof(y) _ptr_ = (y); (y) = ((void*)0); _ptr_; }); | |||
288 | *generator_late = TAKE_PTR(z)({ typeof(z) _ptr_ = (z); (z) = ((void*)0); _ptr_; }); | |||
289 | ||||
290 | return 0; | |||
291 | } | |||
292 | ||||
293 | static int acquire_transient_dir( | |||
294 | UnitFileScope scope, | |||
295 | const char *tempdir, | |||
296 | char **ret) { | |||
297 | ||||
298 | char *transient; | |||
299 | ||||
300 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/shared/path-lookup.c", 300 , __PRETTY_FUNCTION__); } while (0); | |||
301 | assert(IN_SET(scope, UNIT_FILE_SYSTEM, UNIT_FILE_USER, UNIT_FILE_GLOBAL))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended[20 - sizeof((int[]){UNIT_FILE_SYSTEM, UNIT_FILE_USER, UNIT_FILE_GLOBAL })/sizeof(int)]; switch(scope) { case UNIT_FILE_SYSTEM: case UNIT_FILE_USER : case UNIT_FILE_GLOBAL: _found = 1; break; default: break; } _found; }))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("IN_SET(scope, UNIT_FILE_SYSTEM, UNIT_FILE_USER, UNIT_FILE_GLOBAL)" ), "../src/shared/path-lookup.c", 301, __PRETTY_FUNCTION__); } while (0); | |||
302 | ||||
303 | if (scope == UNIT_FILE_GLOBAL) | |||
304 | return -EOPNOTSUPP95; | |||
305 | ||||
306 | if (tempdir) | |||
307 | transient = strjoin(tempdir, "/transient")strjoin_real((tempdir), "/transient", ((void*)0)); | |||
308 | else if (scope == UNIT_FILE_SYSTEM) | |||
309 | transient = strdup("/run/systemd/transient"); | |||
310 | else | |||
311 | return xdg_user_runtime_dir(ret, "/systemd/transient"); | |||
312 | ||||
313 | if (!transient) | |||
314 | return -ENOMEM12; | |||
315 | *ret = transient; | |||
316 | return 0; | |||
317 | } | |||
318 | ||||
319 | static int acquire_config_dirs(UnitFileScope scope, char **persistent, char **runtime) { | |||
320 | _cleanup_free___attribute__((cleanup(freep))) char *a = NULL((void*)0), *b = NULL((void*)0); | |||
321 | int r; | |||
322 | ||||
323 | assert(persistent)do { if ((__builtin_expect(!!(!(persistent)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("persistent"), "../src/shared/path-lookup.c" , 323, __PRETTY_FUNCTION__); } while (0); | |||
324 | assert(runtime)do { if ((__builtin_expect(!!(!(runtime)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("runtime"), "../src/shared/path-lookup.c" , 324, __PRETTY_FUNCTION__); } while (0); | |||
325 | ||||
326 | switch (scope) { | |||
327 | ||||
328 | case UNIT_FILE_SYSTEM: | |||
329 | a = strdup(SYSTEM_CONFIG_UNIT_PATH"/etc/systemd/system"); | |||
330 | b = strdup("/run/systemd/system"); | |||
331 | break; | |||
332 | ||||
333 | case UNIT_FILE_GLOBAL: | |||
334 | a = strdup(USER_CONFIG_UNIT_PATH"/etc/systemd/user"); | |||
335 | b = strdup("/run/systemd/user"); | |||
336 | break; | |||
337 | ||||
338 | case UNIT_FILE_USER: | |||
339 | r = xdg_user_config_dir(&a, "/systemd/user"); | |||
340 | if (r < 0 && r != -ENXIO6) | |||
341 | return r; | |||
342 | ||||
343 | r = xdg_user_runtime_dir(runtime, "/systemd/user"); | |||
344 | if (r < 0) { | |||
345 | if (r != -ENXIO6) | |||
346 | return r; | |||
347 | ||||
348 | /* If XDG_RUNTIME_DIR is not set, don't consider that fatal, simply initialize the runtime | |||
349 | * directory to NULL */ | |||
350 | *runtime = NULL((void*)0); | |||
351 | } | |||
352 | ||||
353 | *persistent = TAKE_PTR(a)({ typeof(a) _ptr_ = (a); (a) = ((void*)0); _ptr_; }); | |||
354 | ||||
355 | return 0; | |||
356 | ||||
357 | default: | |||
358 | assert_not_reached("Hmm, unexpected scope value.")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, ( "Hmm, unexpected scope value."), "../src/shared/path-lookup.c" , 358, __PRETTY_FUNCTION__); } while (0); | |||
359 | } | |||
360 | ||||
361 | if (!a || !b) | |||
362 | return -ENOMEM12; | |||
363 | ||||
364 | *persistent = TAKE_PTR(a)({ typeof(a) _ptr_ = (a); (a) = ((void*)0); _ptr_; }); | |||
365 | *runtime = TAKE_PTR(b)({ typeof(b) _ptr_ = (b); (b) = ((void*)0); _ptr_; }); | |||
366 | ||||
367 | return 0; | |||
368 | } | |||
369 | ||||
370 | static int acquire_control_dirs(UnitFileScope scope, char **persistent, char **runtime) { | |||
371 | _cleanup_free___attribute__((cleanup(freep))) char *a = NULL((void*)0); | |||
372 | int r; | |||
373 | ||||
374 | assert(persistent)do { if ((__builtin_expect(!!(!(persistent)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("persistent"), "../src/shared/path-lookup.c" , 374, __PRETTY_FUNCTION__); } while (0); | |||
375 | assert(runtime)do { if ((__builtin_expect(!!(!(runtime)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("runtime"), "../src/shared/path-lookup.c" , 375, __PRETTY_FUNCTION__); } while (0); | |||
376 | ||||
377 | switch (scope) { | |||
378 | ||||
379 | case UNIT_FILE_SYSTEM: { | |||
380 | _cleanup_free___attribute__((cleanup(freep))) char *b = NULL((void*)0); | |||
381 | ||||
382 | a = strdup("/etc/systemd/system.control"); | |||
383 | if (!a) | |||
384 | return -ENOMEM12; | |||
385 | ||||
386 | b = strdup("/run/systemd/system.control"); | |||
387 | if (!b) | |||
388 | return -ENOMEM12; | |||
389 | ||||
390 | *runtime = TAKE_PTR(b)({ typeof(b) _ptr_ = (b); (b) = ((void*)0); _ptr_; }); | |||
391 | ||||
392 | break; | |||
393 | } | |||
394 | ||||
395 | case UNIT_FILE_USER: | |||
396 | r = xdg_user_config_dir(&a, "/systemd/user.control"); | |||
397 | if (r < 0 && r != -ENXIO6) | |||
398 | return r; | |||
399 | ||||
400 | r = xdg_user_runtime_dir(runtime, "/systemd/user.control"); | |||
401 | if (r < 0) { | |||
402 | if (r != -ENXIO6) | |||
403 | return r; | |||
404 | ||||
405 | /* If XDG_RUNTIME_DIR is not set, don't consider this fatal, simply initialize the directory to | |||
406 | * NULL */ | |||
407 | *runtime = NULL((void*)0); | |||
408 | } | |||
409 | ||||
410 | break; | |||
411 | ||||
412 | case UNIT_FILE_GLOBAL: | |||
413 | return -EOPNOTSUPP95; | |||
414 | ||||
415 | default: | |||
416 | assert_not_reached("Hmm, unexpected scope value.")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, ( "Hmm, unexpected scope value."), "../src/shared/path-lookup.c" , 416, __PRETTY_FUNCTION__); } while (0); | |||
417 | } | |||
418 | ||||
419 | *persistent = TAKE_PTR(a)({ typeof(a) _ptr_ = (a); (a) = ((void*)0); _ptr_; }); | |||
420 | ||||
421 | return 0; | |||
422 | } | |||
423 | ||||
424 | static int patch_root_prefix(char **p, const char *root_dir) { | |||
425 | char *c; | |||
426 | ||||
427 | assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("p"), "../src/shared/path-lookup.c", 427 , __PRETTY_FUNCTION__); } while (0); | |||
428 | ||||
429 | if (!*p) | |||
430 | return 0; | |||
431 | ||||
432 | c = prefix_root(root_dir, *p); | |||
433 | if (!c) | |||
434 | return -ENOMEM12; | |||
435 | ||||
436 | free(*p); | |||
437 | *p = c; | |||
438 | ||||
439 | return 0; | |||
440 | } | |||
441 | ||||
442 | static int patch_root_prefix_strv(char **l, const char *root_dir) { | |||
443 | char **i; | |||
444 | int r; | |||
445 | ||||
446 | if (!root_dir) | |||
447 | return 0; | |||
448 | ||||
449 | STRV_FOREACH(i, l)for ((i) = (l); (i) && *(i); (i)++) { | |||
450 | r = patch_root_prefix(i, root_dir); | |||
451 | if (r < 0) | |||
452 | return r; | |||
453 | } | |||
454 | ||||
455 | return 0; | |||
456 | } | |||
457 | ||||
458 | int lookup_paths_init( | |||
459 | LookupPaths *p, | |||
460 | UnitFileScope scope, | |||
461 | LookupPathsFlags flags, | |||
462 | const char *root_dir) { | |||
463 | ||||
464 | _cleanup_(rmdir_and_freep)__attribute__((cleanup(rmdir_and_freep))) char *tempdir = NULL((void*)0); | |||
465 | _cleanup_free___attribute__((cleanup(freep))) char | |||
466 | *root = NULL((void*)0), | |||
467 | *persistent_config = NULL((void*)0), *runtime_config = NULL((void*)0), | |||
468 | *global_persistent_config = NULL((void*)0), *global_runtime_config = NULL((void*)0), | |||
469 | *generator = NULL((void*)0), *generator_early = NULL((void*)0), *generator_late = NULL((void*)0), | |||
470 | *transient = NULL((void*)0), | |||
471 | *persistent_control = NULL((void*)0), *runtime_control = NULL((void*)0); | |||
472 | bool_Bool append = false0; /* Add items from SYSTEMD_UNIT_PATH before normal directories */ | |||
473 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **paths = NULL((void*)0); | |||
474 | const char *e; | |||
475 | int r; | |||
476 | ||||
477 | assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("p"), "../src/shared/path-lookup.c", 477 , __PRETTY_FUNCTION__); } while (0); | |||
| ||||
478 | assert(scope >= 0)do { if ((__builtin_expect(!!(!(scope >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("scope >= 0"), "../src/shared/path-lookup.c" , 478, __PRETTY_FUNCTION__); } while (0); | |||
479 | assert(scope < _UNIT_FILE_SCOPE_MAX)do { if ((__builtin_expect(!!(!(scope < _UNIT_FILE_SCOPE_MAX )),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("scope < _UNIT_FILE_SCOPE_MAX" ), "../src/shared/path-lookup.c", 479, __PRETTY_FUNCTION__); } while (0); | |||
480 | ||||
481 | #if HAVE_SPLIT_USR0 | |||
482 | flags |= LOOKUP_PATHS_SPLIT_USR; | |||
483 | #endif | |||
484 | ||||
485 | if (!empty_or_root(root_dir)) { | |||
486 | if (scope == UNIT_FILE_USER) | |||
487 | return -EINVAL22; | |||
488 | ||||
489 | r = is_dir(root_dir, true1); | |||
490 | if (r < 0) | |||
491 | return r; | |||
492 | if (r == 0) | |||
493 | return -ENOTDIR20; | |||
494 | ||||
495 | root = strdup(root_dir); | |||
496 | if (!root) | |||
497 | return -ENOMEM12; | |||
498 | } | |||
499 | ||||
500 | if (flags & LOOKUP_PATHS_TEMPORARY_GENERATED) { | |||
501 | r = mkdtemp_malloc("/tmp/systemd-temporary-XXXXXX", &tempdir); | |||
502 | if (r < 0) | |||
503 | return log_error_errno(r, "Failed to create temporary directory: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/shared/path-lookup.c", 503, __func__, "Failed to create temporary directory: %m" ) : -abs(_e); }); | |||
504 | } | |||
505 | ||||
506 | /* Note: when XDG_RUNTIME_DIR is not set this will not return -ENXIO, but simply set runtime_config to NULL */ | |||
507 | r = acquire_config_dirs(scope, &persistent_config, &runtime_config); | |||
508 | if (r
| |||
509 | return r; | |||
510 | ||||
511 | if (scope
| |||
512 | r = acquire_config_dirs(UNIT_FILE_GLOBAL, &global_persistent_config, &global_runtime_config); | |||
513 | if (r
| |||
514 | return r; | |||
515 | } | |||
516 | ||||
517 | if ((flags & LOOKUP_PATHS_EXCLUDE_GENERATED) == 0) { | |||
518 | /* Note: if XDG_RUNTIME_DIR is not set, this will fail completely with ENXIO */ | |||
519 | r = acquire_generator_dirs(scope, tempdir, | |||
520 | &generator, &generator_early, &generator_late); | |||
521 | if (r < 0 && !IN_SET(r, -EOPNOTSUPP, -ENXIO)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){-95, -6})/sizeof(int)]; switch(r) { case -95: case -6: _found = 1; break; default: break; } _found; } )) | |||
522 | return r; | |||
523 | } | |||
524 | ||||
525 | /* Note: if XDG_RUNTIME_DIR is not set, this will fail completely with ENXIO */ | |||
526 | r = acquire_transient_dir(scope, tempdir, &transient); | |||
527 | if (r < 0 && !IN_SET(r, -EOPNOTSUPP, -ENXIO)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){-95, -6})/sizeof(int)]; switch(r) { case -95: case -6: _found = 1; break; default: break; } _found; } )) | |||
528 | return r; | |||
| ||||
529 | ||||
530 | /* Note: when XDG_RUNTIME_DIR is not set this will not return -ENXIO, but simply set runtime_control to NULL */ | |||
531 | r = acquire_control_dirs(scope, &persistent_control, &runtime_control); | |||
532 | if (r < 0 && r != -EOPNOTSUPP95) | |||
533 | return r; | |||
534 | ||||
535 | /* First priority is whatever has been passed to us via env vars */ | |||
536 | e = getenv("SYSTEMD_UNIT_PATH"); | |||
537 | if (e) { | |||
538 | const char *k; | |||
539 | ||||
540 | k = endswith(e, ":"); | |||
541 | if (k) { | |||
542 | e = strndupa(e, k - e)(__extension__ ({ const char *__old = (e); size_t __len = strnlen (__old, (k - e)); char *__new = (char *) __builtin_alloca (__len + 1); __new[__len] = '\0'; (char *) memcpy (__new, __old, __len ); })); | |||
543 | append = true1; | |||
544 | } | |||
545 | ||||
546 | /* FIXME: empty components in other places should be rejected. */ | |||
547 | ||||
548 | r = path_split_and_make_absolute(e, &paths); | |||
549 | if (r < 0) | |||
550 | return r; | |||
551 | } | |||
552 | ||||
553 | if (!paths || append) { | |||
554 | /* Let's figure something out. */ | |||
555 | ||||
556 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **add = NULL((void*)0); | |||
557 | ||||
558 | /* For the user units we include share/ in the search | |||
559 | * path in order to comply with the XDG basedir spec. | |||
560 | * For the system stuff we avoid such nonsense. OTOH | |||
561 | * we include /lib in the search path for the system | |||
562 | * stuff but avoid it for user stuff. */ | |||
563 | ||||
564 | switch (scope) { | |||
565 | ||||
566 | case UNIT_FILE_SYSTEM: | |||
567 | add = strv_new( | |||
568 | /* If you modify this you also want to modify | |||
569 | * systemdsystemunitpath= in systemd.pc.in! */ | |||
570 | STRV_IFNOTNULL(persistent_control), | |||
571 | STRV_IFNOTNULL(runtime_control), | |||
572 | STRV_IFNOTNULL(transient), | |||
573 | STRV_IFNOTNULL(generator_early), | |||
574 | persistent_config, | |||
575 | SYSTEM_CONFIG_UNIT_PATH"/etc/systemd/system", | |||
576 | "/etc/systemd/system", | |||
577 | runtime_config, | |||
578 | "/run/systemd/system", | |||
579 | STRV_IFNOTNULL(generator), | |||
580 | "/usr/local/lib/systemd/system", | |||
581 | SYSTEM_DATA_UNIT_PATH"/usr/lib/systemd/system", | |||
582 | "/usr/lib/systemd/system", | |||
583 | STRV_IFNOTNULL(flags & LOOKUP_PATHS_SPLIT_USR ? "/lib/systemd/system" : NULL((void*)0)), | |||
584 | STRV_IFNOTNULL(generator_late), | |||
585 | NULL((void*)0)); | |||
586 | break; | |||
587 | ||||
588 | case UNIT_FILE_GLOBAL: | |||
589 | add = strv_new( | |||
590 | /* If you modify this you also want to modify | |||
591 | * systemduserunitpath= in systemd.pc.in, and | |||
592 | * the arrays in user_dirs() above! */ | |||
593 | STRV_IFNOTNULL(persistent_control), | |||
594 | STRV_IFNOTNULL(runtime_control), | |||
595 | STRV_IFNOTNULL(transient), | |||
596 | STRV_IFNOTNULL(generator_early), | |||
597 | persistent_config, | |||
598 | USER_CONFIG_UNIT_PATH"/etc/systemd/user", | |||
599 | "/etc/systemd/user", | |||
600 | runtime_config, | |||
601 | "/run/systemd/user", | |||
602 | STRV_IFNOTNULL(generator), | |||
603 | "/usr/local/share/systemd/user", | |||
604 | "/usr/share/systemd/user", | |||
605 | "/usr/local/lib/systemd/user", | |||
606 | USER_DATA_UNIT_PATH"/usr/lib/systemd/user", | |||
607 | "/usr/lib/systemd/user", | |||
608 | STRV_IFNOTNULL(generator_late), | |||
609 | NULL((void*)0)); | |||
610 | break; | |||
611 | ||||
612 | case UNIT_FILE_USER: | |||
613 | add = user_dirs(persistent_config, runtime_config, | |||
614 | global_persistent_config, global_runtime_config, | |||
615 | generator, generator_early, generator_late, | |||
616 | transient, | |||
617 | persistent_control, runtime_control); | |||
618 | break; | |||
619 | ||||
620 | default: | |||
621 | assert_not_reached("Hmm, unexpected scope?")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, ( "Hmm, unexpected scope?"), "../src/shared/path-lookup.c", 621 , __PRETTY_FUNCTION__); } while (0); | |||
622 | } | |||
623 | ||||
624 | if (!add) | |||
625 | return -ENOMEM12; | |||
626 | ||||
627 | if (paths) { | |||
628 | r = strv_extend_strv(&paths, add, true1); | |||
629 | if (r < 0) | |||
630 | return r; | |||
631 | } else | |||
632 | /* Small optimization: if paths is NULL (and it usually is), we can simply assign 'add' to it, | |||
633 | * and don't have to copy anything */ | |||
634 | paths = TAKE_PTR(add)({ typeof(add) _ptr_ = (add); (add) = ((void*)0); _ptr_; }); | |||
635 | } | |||
636 | ||||
637 | r = patch_root_prefix(&persistent_config, root); | |||
638 | if (r < 0) | |||
639 | return r; | |||
640 | r = patch_root_prefix(&runtime_config, root); | |||
641 | if (r < 0) | |||
642 | return r; | |||
643 | ||||
644 | r = patch_root_prefix(&generator, root); | |||
645 | if (r < 0) | |||
646 | return r; | |||
647 | r = patch_root_prefix(&generator_early, root); | |||
648 | if (r < 0) | |||
649 | return r; | |||
650 | r = patch_root_prefix(&generator_late, root); | |||
651 | if (r < 0) | |||
652 | return r; | |||
653 | ||||
654 | r = patch_root_prefix(&transient, root); | |||
655 | if (r < 0) | |||
656 | return r; | |||
657 | ||||
658 | r = patch_root_prefix(&persistent_control, root); | |||
659 | if (r < 0) | |||
660 | return r; | |||
661 | ||||
662 | r = patch_root_prefix(&runtime_control, root); | |||
663 | if (r < 0) | |||
664 | return r; | |||
665 | ||||
666 | r = patch_root_prefix_strv(paths, root); | |||
667 | if (r < 0) | |||
668 | return -ENOMEM12; | |||
669 | ||||
670 | p->search_path = strv_uniq(paths); | |||
671 | paths = NULL((void*)0); | |||
672 | ||||
673 | p->persistent_config = TAKE_PTR(persistent_config)({ typeof(persistent_config) _ptr_ = (persistent_config); (persistent_config ) = ((void*)0); _ptr_; }); | |||
674 | p->runtime_config = TAKE_PTR(runtime_config)({ typeof(runtime_config) _ptr_ = (runtime_config); (runtime_config ) = ((void*)0); _ptr_; }); | |||
675 | ||||
676 | p->generator = TAKE_PTR(generator)({ typeof(generator) _ptr_ = (generator); (generator) = ((void *)0); _ptr_; }); | |||
677 | p->generator_early = TAKE_PTR(generator_early)({ typeof(generator_early) _ptr_ = (generator_early); (generator_early ) = ((void*)0); _ptr_; }); | |||
678 | p->generator_late = TAKE_PTR(generator_late)({ typeof(generator_late) _ptr_ = (generator_late); (generator_late ) = ((void*)0); _ptr_; }); | |||
679 | ||||
680 | p->transient = TAKE_PTR(transient)({ typeof(transient) _ptr_ = (transient); (transient) = ((void *)0); _ptr_; }); | |||
681 | ||||
682 | p->persistent_control = TAKE_PTR(persistent_control)({ typeof(persistent_control) _ptr_ = (persistent_control); ( persistent_control) = ((void*)0); _ptr_; }); | |||
683 | p->runtime_control = TAKE_PTR(runtime_control)({ typeof(runtime_control) _ptr_ = (runtime_control); (runtime_control ) = ((void*)0); _ptr_; }); | |||
684 | ||||
685 | p->root_dir = TAKE_PTR(root)({ typeof(root) _ptr_ = (root); (root) = ((void*)0); _ptr_; } ); | |||
686 | p->temporary_dir = TAKE_PTR(tempdir)({ typeof(tempdir) _ptr_ = (tempdir); (tempdir) = ((void*)0); _ptr_; }); | |||
687 | ||||
688 | return 0; | |||
689 | } | |||
690 | ||||
691 | void lookup_paths_free(LookupPaths *p) { | |||
692 | if (!p) | |||
693 | return; | |||
694 | ||||
695 | p->search_path = strv_free(p->search_path); | |||
696 | ||||
697 | p->persistent_config = mfree(p->persistent_config); | |||
698 | p->runtime_config = mfree(p->runtime_config); | |||
699 | ||||
700 | p->generator = mfree(p->generator); | |||
701 | p->generator_early = mfree(p->generator_early); | |||
702 | p->generator_late = mfree(p->generator_late); | |||
703 | ||||
704 | p->transient = mfree(p->transient); | |||
705 | ||||
706 | p->persistent_control = mfree(p->persistent_control); | |||
707 | p->runtime_control = mfree(p->runtime_control); | |||
708 | ||||
709 | p->root_dir = mfree(p->root_dir); | |||
710 | p->temporary_dir = mfree(p->temporary_dir); | |||
711 | } | |||
712 | ||||
713 | int lookup_paths_reduce(LookupPaths *p) { | |||
714 | _cleanup_free___attribute__((cleanup(freep))) struct stat *stats = NULL((void*)0); | |||
715 | size_t n_stats = 0, allocated = 0; | |||
716 | size_t c = 0; | |||
717 | int r; | |||
718 | ||||
719 | assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("p"), "../src/shared/path-lookup.c", 719 , __PRETTY_FUNCTION__); } while (0); | |||
720 | ||||
721 | /* Drop duplicates and non-existing directories from the search path. We figure out whether two directories are | |||
722 | * the same by comparing their device and inode numbers. */ | |||
723 | ||||
724 | if (!p->search_path) | |||
725 | return 0; | |||
726 | ||||
727 | while (p->search_path[c]) { | |||
728 | struct stat st; | |||
729 | size_t k; | |||
730 | ||||
731 | /* Never strip the transient and control directories from the path */ | |||
732 | if (path_equal_ptr(p->search_path[c], p->transient) || | |||
733 | path_equal_ptr(p->search_path[c], p->persistent_control) || | |||
734 | path_equal_ptr(p->search_path[c], p->runtime_control)) { | |||
735 | c++; | |||
736 | continue; | |||
737 | } | |||
738 | ||||
739 | r = chase_symlinks_and_stat(p->search_path[c], p->root_dir, 0, NULL((void*)0), &st); | |||
740 | if (r == -ENOENT2) | |||
741 | goto remove_item; | |||
742 | if (r < 0) { | |||
743 | /* If something we don't grok happened, let's better leave it in. */ | |||
744 | log_debug_errno(r, "Failed to chase and stat %s: %m", p->search_path[c])({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/shared/path-lookup.c", 744, __func__, "Failed to chase and stat %s: %m" , p->search_path[c]) : -abs(_e); }); | |||
745 | c++; | |||
746 | continue; | |||
747 | } | |||
748 | ||||
749 | for (k = 0; k < n_stats; k++) | |||
750 | if (stats[k].st_dev == st.st_dev && | |||
751 | stats[k].st_ino == st.st_ino) | |||
752 | break; | |||
753 | ||||
754 | if (k < n_stats) /* Is there already an entry with the same device/inode? */ | |||
755 | goto remove_item; | |||
756 | ||||
757 | if (!GREEDY_REALLOC(stats, allocated, n_stats+1)greedy_realloc((void**) &(stats), &(allocated), (n_stats +1), sizeof((stats)[0]))) | |||
758 | return -ENOMEM12; | |||
759 | ||||
760 | stats[n_stats++] = st; | |||
761 | c++; | |||
762 | continue; | |||
763 | ||||
764 | remove_item: | |||
765 | free(p->search_path[c]); | |||
766 | memmove(p->search_path + c, | |||
767 | p->search_path + c + 1, | |||
768 | (strv_length(p->search_path + c + 1) + 1) * sizeof(char*)); | |||
769 | } | |||
770 | ||||
771 | if (strv_isempty(p->search_path)) { | |||
772 | log_debug("Ignoring unit files.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/shared/path-lookup.c", 772, __func__, "Ignoring unit files." ) : -abs(_e); }); | |||
773 | p->search_path = strv_free(p->search_path); | |||
774 | } else { | |||
775 | _cleanup_free___attribute__((cleanup(freep))) char *t; | |||
776 | ||||
777 | t = strv_join(p->search_path, "\n\t"); | |||
778 | if (!t) | |||
779 | return -ENOMEM12; | |||
780 | ||||
781 | log_debug("Looking for unit files in (higher priority first):\n\t%s", t)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/shared/path-lookup.c", 781, __func__, "Looking for unit files in (higher priority first):\n\t%s" , t) : -abs(_e); }); | |||
782 | } | |||
783 | ||||
784 | return 0; | |||
785 | } | |||
786 | ||||
787 | int lookup_paths_mkdir_generator(LookupPaths *p) { | |||
788 | int r, q; | |||
789 | ||||
790 | assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("p"), "../src/shared/path-lookup.c", 790 , __PRETTY_FUNCTION__); } while (0); | |||
791 | ||||
792 | if (!p->generator || !p->generator_early || !p->generator_late) | |||
793 | return -EINVAL22; | |||
794 | ||||
795 | r = mkdir_p_label(p->generator, 0755); | |||
796 | ||||
797 | q = mkdir_p_label(p->generator_early, 0755); | |||
798 | if (q < 0 && r >= 0) | |||
799 | r = q; | |||
800 | ||||
801 | q = mkdir_p_label(p->generator_late, 0755); | |||
802 | if (q < 0 && r >= 0) | |||
803 | r = q; | |||
804 | ||||
805 | return r; | |||
806 | } | |||
807 | ||||
808 | void lookup_paths_trim_generator(LookupPaths *p) { | |||
809 | assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("p"), "../src/shared/path-lookup.c", 809 , __PRETTY_FUNCTION__); } while (0); | |||
810 | ||||
811 | /* Trim empty dirs */ | |||
812 | ||||
813 | if (p->generator) | |||
814 | (void) rmdir(p->generator); | |||
815 | if (p->generator_early) | |||
816 | (void) rmdir(p->generator_early); | |||
817 | if (p->generator_late) | |||
818 | (void) rmdir(p->generator_late); | |||
819 | } | |||
820 | ||||
821 | void lookup_paths_flush_generator(LookupPaths *p) { | |||
822 | assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("p"), "../src/shared/path-lookup.c", 822 , __PRETTY_FUNCTION__); } while (0); | |||
823 | ||||
824 | /* Flush the generated unit files in full */ | |||
825 | ||||
826 | if (p->generator) | |||
827 | (void) rm_rf(p->generator, REMOVE_ROOT|REMOVE_PHYSICAL); | |||
828 | if (p->generator_early) | |||
829 | (void) rm_rf(p->generator_early, REMOVE_ROOT|REMOVE_PHYSICAL); | |||
830 | if (p->generator_late) | |||
831 | (void) rm_rf(p->generator_late, REMOVE_ROOT|REMOVE_PHYSICAL); | |||
832 | ||||
833 | if (p->temporary_dir) | |||
834 | (void) rm_rf(p->temporary_dir, REMOVE_ROOT|REMOVE_PHYSICAL); | |||
835 | } | |||
836 | ||||
837 | char **generator_binary_paths(UnitFileScope scope) { | |||
838 | ||||
839 | switch (scope) { | |||
840 | ||||
841 | case UNIT_FILE_SYSTEM: | |||
842 | return strv_new("/run/systemd/system-generators", | |||
843 | "/etc/systemd/system-generators", | |||
844 | "/usr/local/lib/systemd/system-generators", | |||
845 | SYSTEM_GENERATOR_PATH"/usr/lib/systemd/system-generators", | |||
846 | NULL((void*)0)); | |||
847 | ||||
848 | case UNIT_FILE_GLOBAL: | |||
849 | case UNIT_FILE_USER: | |||
850 | return strv_new("/run/systemd/user-generators", | |||
851 | "/etc/systemd/user-generators", | |||
852 | "/usr/local/lib/systemd/user-generators", | |||
853 | USER_GENERATOR_PATH"/usr/lib/systemd/user-generators", | |||
854 | NULL((void*)0)); | |||
855 | ||||
856 | default: | |||
857 | assert_not_reached("Hmm, unexpected scope.")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, ( "Hmm, unexpected scope."), "../src/shared/path-lookup.c", 857 , __PRETTY_FUNCTION__); } while (0); | |||
858 | } | |||
859 | } |