diff options
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/install.c | 12 | ||||
-rw-r--r-- | src/shared/install.h | 2 | ||||
-rw-r--r-- | src/shared/path-lookup.c | 191 | ||||
-rw-r--r-- | src/shared/path-lookup.h | 33 |
4 files changed, 170 insertions, 68 deletions
diff --git a/src/shared/install.c b/src/shared/install.c index 0f08137f19..e232d76dd7 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -1060,7 +1060,7 @@ static int unit_file_search( assert(info->name); - STRV_FOREACH(p, paths->unit_path) { + STRV_FOREACH(p, paths->search_path) { _cleanup_free_ char *path = NULL; path = strjoin(*p, "/", info->name, NULL); @@ -1090,7 +1090,7 @@ static int unit_file_search( if (r < 0) return r; - STRV_FOREACH(p, paths->unit_path) { + STRV_FOREACH(p, paths->search_path) { _cleanup_free_ char *path = NULL; path = strjoin(*p, "/", template, NULL); @@ -1348,7 +1348,7 @@ static int install_info_symlink_link( assert(config_path); assert(i->path); - r = in_search_path(i->path, paths->unit_path); + r = in_search_path(i->path, paths->search_path); if (r != 0) return r; @@ -1672,7 +1672,7 @@ int unit_file_link( if (!S_ISREG(st.st_mode)) return -ENOTTY; - q = in_search_path(*i, paths.unit_path); + q = in_search_path(*i, paths.search_path); if (q < 0) return q; if (q > 0) @@ -2313,7 +2313,7 @@ int unit_file_preset_all( if (r < 0) return r; - STRV_FOREACH(i, paths.unit_path) { + STRV_FOREACH(i, paths.search_path) { _cleanup_closedir_ DIR *d = NULL; _cleanup_free_ char *units_dir; struct dirent *de; @@ -2389,7 +2389,7 @@ int unit_file_get_list( if (r < 0) return r; - STRV_FOREACH(i, paths.unit_path) { + STRV_FOREACH(i, paths.search_path) { _cleanup_closedir_ DIR *d = NULL; _cleanup_free_ char *units_dir; struct dirent *de; diff --git a/src/shared/install.h b/src/shared/install.h index c1a43e23e7..82b6d425eb 100644 --- a/src/shared/install.h +++ b/src/shared/install.h @@ -135,7 +135,7 @@ int unit_file_set_default(UnitFileScope scope, const char *root_dir, const char int unit_file_get_default(UnitFileScope scope, const char *root_dir, char **name); int unit_file_add_dependency(UnitFileScope scope, bool runtime, const char *root_dir, char **files, const char *target, UnitDependency dep, bool force, UnitFileChange **changes, unsigned *n_changes); -int unit_file_lookup_state(UnitFileScope scope, const char *root_dir,const LookupPaths *paths, const char *name, UnitFileState *ret); +int unit_file_lookup_state(UnitFileScope scope, const char *root_dir, const LookupPaths *paths, const char *name, UnitFileState *ret); int unit_file_get_state(UnitFileScope scope, const char *root_dir, const char *filename, UnitFileState *ret); int unit_file_get_list(UnitFileScope scope, const char *root_dir, Hashmap *h); diff --git a/src/shared/path-lookup.c b/src/shared/path-lookup.c index ac22a27ccb..ec3f5b53f4 100644 --- a/src/shared/path-lookup.c +++ b/src/shared/path-lookup.c @@ -235,43 +235,119 @@ char **generator_paths(ManagerRunningAs running_as) { NULL); } +static int acquire_generator_dirs( + ManagerRunningAs running_as, + char **generator, + char **generator_early, + char **generator_late) { + + _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL; + const char *prefix; + + assert(generator); + assert(generator_early); + assert(generator_late); + + if (running_as == MANAGER_SYSTEM) + prefix = "/run/systemd/"; + else { + const char *e; + + assert(running_as == MANAGER_USER); + + e = getenv("XDG_RUNTIME_DIR"); + if (!e) + return -EINVAL; + + prefix = strjoina(e, "/systemd/", NULL); + } + + x = strappend(prefix, "generator"); + if (!x) + return -ENOMEM; + + y = strappend(prefix, "generator.early"); + if (!y) + return -ENOMEM; + + z = strappend(prefix, "generator.late"); + if (!z) + return -ENOMEM; + + *generator = x; + *generator_early = y; + *generator_late = z; + + x = y = z = NULL; + return 0; +} + +static int patch_root_prefix(char **p, const char *root_dir) { + char *c; + + assert(p); + + if (!*p) + return 0; + + if (isempty(root_dir) || path_equal(root_dir, "/")) + return 0; + + c = prefix_root(root_dir, *p); + if (!c) + return -ENOMEM; + + free(*p); + *p = c; + + return 0; +} + int lookup_paths_init( LookupPaths *p, ManagerRunningAs running_as, bool personal, - const char *root_dir, - const char *generator, - const char *generator_early, - const char *generator_late) { + const char *root_dir) { - const char *e; + _cleanup_free_ char *generator = NULL, *generator_early = NULL, *generator_late = NULL; bool append = false; /* Add items from SYSTEMD_UNIT_PATH before normal directories */ + char **l = NULL; + const char *e; int r; assert(p); + assert(running_as >= 0); + assert(running_as < _MANAGER_RUNNING_AS_MAX); + + r = acquire_generator_dirs(running_as, &generator, &generator_early, &generator_late); + if (r < 0) + return r; /* First priority is whatever has been passed to us via env * vars */ e = getenv("SYSTEMD_UNIT_PATH"); if (e) { - if (endswith(e, ":")) { - e = strndupa(e, strlen(e) - 1); + const char *k; + + k = endswith(e, ":"); + if (k) { + e = strndupa(e, k - e); append = true; } /* FIXME: empty components in other places should be * rejected. */ - r = path_split_and_make_absolute(e, &p->unit_path); + r = path_split_and_make_absolute(e, &l); if (r < 0) return r; } else - p->unit_path = NULL; + l = NULL; - if (!p->unit_path || append) { + if (!l || append) { /* Let's figure something out. */ - _cleanup_strv_free_ char **unit_path; + _cleanup_strv_free_ char **add = NULL; /* For the user units we include share/ in the search * path in order to comply with the XDG basedir spec. @@ -281,85 +357,114 @@ int lookup_paths_init( if (running_as == MANAGER_USER) { if (personal) - unit_path = user_dirs(generator, generator_early, generator_late); + add = user_dirs(generator, generator_early, generator_late); else - unit_path = strv_new( + add = strv_new( /* If you modify this you also want to modify * systemduserunitpath= in systemd.pc.in, and * the arrays in user_dirs() above! */ - STRV_IFNOTNULL(generator_early), + generator_early, USER_CONFIG_UNIT_PATH, "/etc/systemd/user", "/run/systemd/user", - STRV_IFNOTNULL(generator), + generator, "/usr/local/lib/systemd/user", "/usr/local/share/systemd/user", USER_DATA_UNIT_PATH, "/usr/lib/systemd/user", "/usr/share/systemd/user", - STRV_IFNOTNULL(generator_late), + generator_late, NULL); } else - unit_path = strv_new( + add = strv_new( /* If you modify this you also want to modify * systemdsystemunitpath= in systemd.pc.in! */ - STRV_IFNOTNULL(generator_early), + generator_early, SYSTEM_CONFIG_UNIT_PATH, "/etc/systemd/system", "/run/systemd/system", - STRV_IFNOTNULL(generator), + generator, "/usr/local/lib/systemd/system", SYSTEM_DATA_UNIT_PATH, "/usr/lib/systemd/system", #ifdef HAVE_SPLIT_USR "/lib/systemd/system", #endif - STRV_IFNOTNULL(generator_late), + generator_late, NULL); - if (!unit_path) + if (!add) return -ENOMEM; - r = strv_extend_strv(&p->unit_path, unit_path, false); - if (r < 0) - return r; + if (l) { + r = strv_extend_strv(&l, add, false); + if (r < 0) + return r; + } else { + l = add; + add = NULL; + } } - if (!path_strv_resolve_uniq(p->unit_path, root_dir)) + r = patch_root_prefix(&generator, root_dir); + if (r < 0) + return r; + r = patch_root_prefix(&generator_early, root_dir); + if (r < 0) + return r; + r = patch_root_prefix(&generator_late, root_dir); + if (r < 0) + return r; + + if (!path_strv_resolve_uniq(l, root_dir)) return -ENOMEM; - if (!strv_isempty(p->unit_path)) { - _cleanup_free_ char *t = strv_join(p->unit_path, "\n\t"); + if (strv_isempty(l)) { + log_debug("Ignoring unit files."); + l = strv_free(l); + } else { + _cleanup_free_ char *t; + + t = strv_join(l, "\n\t"); if (!t) return -ENOMEM; + log_debug("Looking for unit files in (higher priority first):\n\t%s", t); - } else { - log_debug("Ignoring unit files."); - p->unit_path = strv_free(p->unit_path); } + p->search_path = l; + l = NULL; + + p->generator = generator; + p->generator_early = generator_early; + p->generator_late = generator_late; + generator = generator_early = generator_late = NULL; return 0; } void lookup_paths_free(LookupPaths *p) { - assert(p); + if (!p) + return; - p->unit_path = strv_free(p->unit_path); + p->search_path = strv_free(p->search_path); + p->generator = mfree(p->generator); + p->generator_early = mfree(p->generator_early); + p->generator_late = mfree(p->generator_late); } -int lookup_paths_init_from_scope(LookupPaths *paths, - UnitFileScope scope, - const char *root_dir) { - assert(paths); +int lookup_paths_init_from_scope( + LookupPaths *p, + UnitFileScope scope, + const char *root_dir) { + + assert(p); assert(scope >= 0); assert(scope < _UNIT_FILE_SCOPE_MAX); - zero(*paths); - - return lookup_paths_init(paths, - scope == UNIT_FILE_SYSTEM ? MANAGER_SYSTEM : MANAGER_USER, - scope == UNIT_FILE_USER, - root_dir, - NULL, NULL, NULL); + return lookup_paths_init( + p, + scope == UNIT_FILE_SYSTEM ? MANAGER_SYSTEM : MANAGER_USER, + scope == UNIT_FILE_USER, + root_dir); } diff --git a/src/shared/path-lookup.h b/src/shared/path-lookup.h index c53d293072..1e3bce21a4 100644 --- a/src/shared/path-lookup.h +++ b/src/shared/path-lookup.h @@ -20,37 +20,34 @@ ***/ #include <stdbool.h> + +typedef struct LookupPaths LookupPaths; +typedef enum ManagerRunningAs ManagerRunningAs; + +#include "install.h" #include "macro.h" -typedef struct LookupPaths { - char **unit_path; -} LookupPaths; +struct LookupPaths { + char **search_path; + char *generator; + char *generator_early; + char *generator_late; +}; -typedef enum ManagerRunningAs { +enum ManagerRunningAs { MANAGER_SYSTEM, MANAGER_USER, _MANAGER_RUNNING_AS_MAX, _MANAGER_RUNNING_AS_INVALID = -1 -} ManagerRunningAs; +}; int user_config_home(char **config_home); int user_runtime_dir(char **runtime_dir); char **generator_paths(ManagerRunningAs running_as); -int lookup_paths_init(LookupPaths *p, - ManagerRunningAs running_as, - bool personal, - const char *root_dir, - const char *generator, - const char *generator_early, - const char *generator_late); - -#include "install.h" - -int lookup_paths_init_from_scope(LookupPaths *paths, - UnitFileScope scope, - const char *root_dir); +int lookup_paths_init(LookupPaths *p, ManagerRunningAs running_as, bool personal, const char *root_dir); +int lookup_paths_init_from_scope(LookupPaths *p, UnitFileScope scope, const char *root_dir); void lookup_paths_free(LookupPaths *p); #define _cleanup_lookup_paths_free_ _cleanup_(lookup_paths_free) |