summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/install.c12
-rw-r--r--src/shared/install.h2
-rw-r--r--src/shared/path-lookup.c191
-rw-r--r--src/shared/path-lookup.h33
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)