diff --git a/src/shared/install.c b/src/shared/install.c index a9d75f3..28a801f 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -36,6 +36,7 @@ #include "install.h" #include "conf-parser.h" #include "conf-files.h" +#include "specifier.h" typedef struct { char *name; @@ -51,6 +52,30 @@ typedef struct { Hashmap *have_installed; } InstallContext; +char *name_printf(char * prefix, char * instance, char* format) { + + /* + * This will use the passed string as format string and + * replace the following specifiers, if any: + * + * %p: the unit prefix (foo) + * %i: the instance (bar) + */ + + char empty_prefix[] = "%p"; + char empty_instance[] = "%i"; + + const Specifier table[] = { + { 'p', specifier_string, prefix ? : empty_prefix}, + { 'i', specifier_string, instance ? : empty_instance}, + { 0, NULL, NULL } + }; + + assert(format); + + return specifier_printf(format, table, NULL); +} + static int lookup_paths_init_from_scope(LookupPaths *paths, UnitFileScope scope) { assert(paths); assert(scope >= 0); @@ -1271,13 +1296,21 @@ static int install_info_symlink_wants( STRV_FOREACH(s, i->wanted_by) { char *path; + char *instance = NULL; + char *prefix = NULL; + char *dst = NULL; - if (!unit_name_is_valid(*s, true)) { + unit_name_to_instance(i->name, &instance); + prefix = unit_name_to_prefix(i->name); + + dst = name_printf(prefix, instance, *s); + + 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); diff --git a/src/shared/install.h b/src/shared/install.h index 5524991..b43367a 100644 --- a/src/shared/install.h +++ b/src/shared/install.h @@ -85,3 +85,5 @@ UnitFileState unit_file_state_from_string(const char *s); const char *unit_file_change_type_to_string(UnitFileChangeType s); UnitFileChangeType unit_file_change_type_from_string(const char *s); + +char *name_printf(char * prefix, char * instance, char * format);