chiark / gitweb /
install: allow %u an and %U specifiers in WantedBy/RequiredBy/Alias
[elogind.git] / src / shared / install.c
index 24905e1af637b3fef03b5f68b8df25e49e9f22f8..b82d1891dd3846af67ae6b1879b82400c936ea3f 100644 (file)
 #include "install.h"
 #include "conf-parser.h"
 #include "conf-files.h"
-
-typedef struct {
-        char *name;
-        char *path;
-
-        char **aliases;
-        char **wanted_by;
-        char **required_by;
-} InstallInfo;
+#include "specifier.h"
+#include "install-printf.h"
 
 typedef struct {
         Hashmap *will_install;
@@ -963,6 +956,33 @@ static int config_parse_also(
         return 0;
 }
 
+static int config_parse_user(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        InstallInfo *i = data;
+        char* printed;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        printed = install_full_printf(i, rvalue);
+        if (!printed)
+                return -ENOMEM;
+
+        free(i->user);
+        i->user = printed;
+
+        return 0;
+}
+
 static int unit_file_load(
                 InstallContext *c,
                 InstallInfo *info,
@@ -974,6 +994,7 @@ static int unit_file_load(
                 { "Install", "WantedBy",   config_parse_strv, 0, &info->wanted_by   },
                 { "Install", "RequiredBy", config_parse_strv, 0, &info->required_by },
                 { "Install", "Also",       config_parse_also, 0, c                  },
+                { "Exec",    "User",       config_parse_user, 0, info               },
                 { NULL, NULL, NULL, 0, NULL }
         };
 
@@ -1177,16 +1198,17 @@ static int install_info_symlink_alias(
         assert(config_path);
 
         STRV_FOREACH(s, i->aliases) {
-                char *alias_path;
+                char _cleanup_free_ *alias_path = NULL, *dst = NULL;
 
-                alias_path = path_make_absolute(*s, config_path);
+                dst = install_full_printf(i, *s);
+                if (!dst)
+                        return -ENOMEM;
 
+                alias_path = path_make_absolute(dst, config_path);
                 if (!alias_path)
                         return -ENOMEM;
 
                 q = create_symlink(i->path, alias_path, force, changes, n_changes);
-                free(alias_path);
-
                 if (r == 0)
                         r = q;
         }
@@ -1208,18 +1230,21 @@ static int install_info_symlink_wants(
         assert(config_path);
 
         STRV_FOREACH(s, i->wanted_by) {
-                char *path;
+                char _cleanup_free_ *path = NULL, *dst = NULL;
+
+                dst = install_full_printf(i, *s);
+                if (!dst)
+                        return -ENOMEM;
 
-                if (!unit_name_is_valid(*s, true)) {
+                if (!unit_name_is_valid(dst, true)) {
                         r = -EINVAL;
                         continue;
                 }
 
-                if (asprintf(&path, "%s/%s.wants/%s", config_path, *s, i->name) < 0)
+                if (asprintf(&path, "%s/%s.wants/%s", config_path, dst, i->name) < 0)
                         return -ENOMEM;
 
                 q = create_symlink(i->path, path, force, changes, n_changes);
-                free(path);
 
                 if (r == 0)
                         r = q;
@@ -1242,18 +1267,21 @@ static int install_info_symlink_requires(
         assert(config_path);
 
         STRV_FOREACH(s, i->required_by) {
-                char *path;
+                char _cleanup_free_ *path = NULL, *dst = NULL;
+
+                dst = install_full_printf(i, *s);
+                if (!dst)
+                        return -ENOMEM;
 
-                if (!unit_name_is_valid(*s, true)) {
+                if (!unit_name_is_valid(dst, true)) {
                         r = -EINVAL;
                         continue;
                 }
 
-                if (asprintf(&path, "%s/%s.requires/%s", config_path, *s, i->name) < 0)
+                if (asprintf(&path, "%s/%s.requires/%s", config_path, dst, i->name) < 0)
                         return -ENOMEM;
 
                 q = create_symlink(i->path, path, force, changes, n_changes);
-                free(path);
 
                 if (r == 0)
                         r = q;