mirror of
https://github.com/systemd/systemd
synced 2026-03-19 11:34:46 +01:00
Compare commits
3 Commits
eb70d9450c
...
de61a04b18
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de61a04b18 | ||
|
|
0c651d32d4 | ||
|
|
274b0d3fc1 |
2
README
2
README
@ -85,7 +85,7 @@ REQUIREMENTS:
|
|||||||
|
|
||||||
Optional but strongly recommended:
|
Optional but strongly recommended:
|
||||||
CONFIG_IPV6
|
CONFIG_IPV6
|
||||||
CONFIG_AUTOFS4_FS
|
CONFIG_AUTOFS_FS
|
||||||
CONFIG_TMPFS_XATTR
|
CONFIG_TMPFS_XATTR
|
||||||
CONFIG_{TMPFS,EXT4_FS,XFS,BTRFS_FS,...}_POSIX_ACL
|
CONFIG_{TMPFS,EXT4_FS,XFS,BTRFS_FS,...}_POSIX_ACL
|
||||||
CONFIG_SECCOMP
|
CONFIG_SECCOMP
|
||||||
|
|||||||
@ -210,7 +210,7 @@ Note that these configurations snippets do not need to be the only configuration
|
|||||||
|
|
||||||
To make this explicitly clear: this specification is designed with "free" operating systems in mind, starting Windows or macOS is out of focus with these configuration snippets, use boot-loader specific solutions for that. In the text above, if we say "OS" we hence imply "free", i.e. primarily Linux (though this could be easily be extended to the BSDs and whatnot).
|
To make this explicitly clear: this specification is designed with "free" operating systems in mind, starting Windows or macOS is out of focus with these configuration snippets, use boot-loader specific solutions for that. In the text above, if we say "OS" we hence imply "free", i.e. primarily Linux (though this could be easily be extended to the BSDs and whatnot).
|
||||||
|
|
||||||
Note that all paths used in the configuration snippets use a Unix-style "/" as path separator. This needs to be converted to an EFI-style "\" separator in EFI boot loaders.
|
Note that all paths used in the configuration snippets use a Unix-style "/" as path separator. This needs to be converted to an EFI-style "\\" separator in EFI boot loaders.
|
||||||
|
|
||||||
|
|
||||||
## Logic
|
## Logic
|
||||||
|
|||||||
@ -2660,7 +2660,7 @@ int config_parse_environ(
|
|||||||
if (u)
|
if (u)
|
||||||
r = unit_env_printf(u, word, &resolved);
|
r = unit_env_printf(u, word, &resolved);
|
||||||
else
|
else
|
||||||
r = specifier_printf(word, sc_arg_max(), system_and_tmp_specifier_table, NULL, &resolved);
|
r = specifier_printf(word, sc_arg_max(), system_and_tmp_specifier_table, NULL, NULL, &resolved);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Failed to resolve specifiers in %s, ignoring: %m", word);
|
"Failed to resolve specifiers in %s, ignoring: %m", word);
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
#include "unit.h"
|
#include "unit.h"
|
||||||
#include "user-util.h"
|
#include "user-util.h"
|
||||||
|
|
||||||
static int specifier_prefix_and_instance(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_prefix_and_instance(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
const Unit *u = userdata;
|
const Unit *u = userdata;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
@ -20,7 +20,7 @@ static int specifier_prefix_and_instance(char specifier, const void *data, const
|
|||||||
return unit_name_to_prefix_and_instance(u->id, ret);
|
return unit_name_to_prefix_and_instance(u->id, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int specifier_prefix(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_prefix(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
const Unit *u = userdata;
|
const Unit *u = userdata;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
@ -28,7 +28,7 @@ static int specifier_prefix(char specifier, const void *data, const void *userda
|
|||||||
return unit_name_to_prefix(u->id, ret);
|
return unit_name_to_prefix(u->id, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int specifier_prefix_unescaped(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_prefix_unescaped(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
_cleanup_free_ char *p = NULL;
|
_cleanup_free_ char *p = NULL;
|
||||||
const Unit *u = userdata;
|
const Unit *u = userdata;
|
||||||
int r;
|
int r;
|
||||||
@ -42,7 +42,7 @@ static int specifier_prefix_unescaped(char specifier, const void *data, const vo
|
|||||||
return unit_name_unescape(p, ret);
|
return unit_name_unescape(p, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int specifier_instance_unescaped(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_instance_unescaped(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
const Unit *u = userdata;
|
const Unit *u = userdata;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
@ -50,7 +50,7 @@ static int specifier_instance_unescaped(char specifier, const void *data, const
|
|||||||
return unit_name_unescape(strempty(u->instance), ret);
|
return unit_name_unescape(strempty(u->instance), ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int specifier_last_component(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_last_component(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
const Unit *u = userdata;
|
const Unit *u = userdata;
|
||||||
_cleanup_free_ char *prefix = NULL;
|
_cleanup_free_ char *prefix = NULL;
|
||||||
char *dash;
|
char *dash;
|
||||||
@ -64,24 +64,24 @@ static int specifier_last_component(char specifier, const void *data, const void
|
|||||||
|
|
||||||
dash = strrchr(prefix, '-');
|
dash = strrchr(prefix, '-');
|
||||||
if (dash)
|
if (dash)
|
||||||
return specifier_string(specifier, dash + 1, userdata, ret);
|
return specifier_string(specifier, dash + 1, root, userdata, ret);
|
||||||
|
|
||||||
*ret = TAKE_PTR(prefix);
|
*ret = TAKE_PTR(prefix);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int specifier_last_component_unescaped(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_last_component_unescaped(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
_cleanup_free_ char *p = NULL;
|
_cleanup_free_ char *p = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = specifier_last_component(specifier, data, userdata, &p);
|
r = specifier_last_component(specifier, data, root, userdata, &p);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
return unit_name_unescape(p, ret);
|
return unit_name_unescape(p, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int specifier_filename(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_filename(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
const Unit *u = userdata;
|
const Unit *u = userdata;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
@ -96,7 +96,7 @@ static void bad_specifier(const Unit *u, char specifier) {
|
|||||||
log_unit_warning(u, "Specifier '%%%c' used in unit configuration, which is deprecated. Please update your unit file, as it does not work as intended.", specifier);
|
log_unit_warning(u, "Specifier '%%%c' used in unit configuration, which is deprecated. Please update your unit file, as it does not work as intended.", specifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int specifier_cgroup(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_cgroup(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
const Unit *u = userdata;
|
const Unit *u = userdata;
|
||||||
char *n;
|
char *n;
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ static int specifier_cgroup(char specifier, const void *data, const void *userda
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int specifier_cgroup_root(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_cgroup_root(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
const Unit *u = userdata;
|
const Unit *u = userdata;
|
||||||
char *n;
|
char *n;
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ static int specifier_cgroup_root(char specifier, const void *data, const void *u
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int specifier_cgroup_slice(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_cgroup_slice(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
const Unit *u = userdata, *slice;
|
const Unit *u = userdata, *slice;
|
||||||
char *n;
|
char *n;
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ static int specifier_cgroup_slice(char specifier, const void *data, const void *
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int specifier_special_directory(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_special_directory(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
const Unit *u = userdata;
|
const Unit *u = userdata;
|
||||||
char *n = NULL;
|
char *n = NULL;
|
||||||
|
|
||||||
@ -198,7 +198,7 @@ int unit_name_printf(const Unit *u, const char* format, char **ret) {
|
|||||||
assert(format);
|
assert(format);
|
||||||
assert(ret);
|
assert(ret);
|
||||||
|
|
||||||
return specifier_printf(format, UNIT_NAME_MAX, table, u, ret);
|
return specifier_printf(format, UNIT_NAME_MAX, table, NULL, u, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int unit_full_printf_full(const Unit *u, const char *format, size_t max_length, char **ret) {
|
int unit_full_printf_full(const Unit *u, const char *format, size_t max_length, char **ret) {
|
||||||
@ -262,5 +262,5 @@ int unit_full_printf_full(const Unit *u, const char *format, size_t max_length,
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
return specifier_printf(format, max_length, table, u, ret);
|
return specifier_printf(format, max_length, table, NULL, u, ret);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -973,7 +973,7 @@ static int config_parse_label(
|
|||||||
/* Nota bene: the empty label is a totally valid one. Let's hence not follow our usual rule of
|
/* Nota bene: the empty label is a totally valid one. Let's hence not follow our usual rule of
|
||||||
* assigning the empty string to reset to default here, but really accept it as label to set. */
|
* assigning the empty string to reset to default here, but really accept it as label to set. */
|
||||||
|
|
||||||
r = specifier_printf(rvalue, GPT_LABEL_MAX, system_and_tmp_specifier_table, NULL, &resolved);
|
r = specifier_printf(rvalue, GPT_LABEL_MAX, system_and_tmp_specifier_table, arg_root, NULL, &resolved);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Failed to expand specifiers in Label=, ignoring: %s", rvalue);
|
"Failed to expand specifiers in Label=, ignoring: %s", rvalue);
|
||||||
@ -1138,7 +1138,7 @@ static int config_parse_copy_files(
|
|||||||
if (!isempty(p))
|
if (!isempty(p))
|
||||||
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), "Too many arguments: %s", rvalue);
|
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), "Too many arguments: %s", rvalue);
|
||||||
|
|
||||||
r = specifier_printf(source, PATH_MAX-1, system_and_tmp_specifier_table, NULL, &resolved_source);
|
r = specifier_printf(source, PATH_MAX-1, system_and_tmp_specifier_table, arg_root, NULL, &resolved_source);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Failed to expand specifiers in CopyFiles= source, ignoring: %s", rvalue);
|
"Failed to expand specifiers in CopyFiles= source, ignoring: %s", rvalue);
|
||||||
@ -1149,7 +1149,7 @@ static int config_parse_copy_files(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = specifier_printf(target, PATH_MAX-1, system_and_tmp_specifier_table, NULL, &resolved_target);
|
r = specifier_printf(target, PATH_MAX-1, system_and_tmp_specifier_table, arg_root, NULL, &resolved_target);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Failed to expand specifiers in CopyFiles= target, ignoring: %s", resolved_target);
|
"Failed to expand specifiers in CopyFiles= target, ignoring: %s", resolved_target);
|
||||||
@ -1198,7 +1198,7 @@ static int config_parse_copy_blocks(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = specifier_printf(rvalue, PATH_MAX-1, system_and_tmp_specifier_table, NULL, &d);
|
r = specifier_printf(rvalue, PATH_MAX-1, system_and_tmp_specifier_table, arg_root, NULL, &d);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Failed to expand specifiers in CopyBlocks= source path, ignoring: %s", rvalue);
|
"Failed to expand specifiers in CopyBlocks= source path, ignoring: %s", rvalue);
|
||||||
@ -1246,7 +1246,7 @@ static int config_parse_make_dirs(
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = specifier_printf(word, PATH_MAX-1, system_and_tmp_specifier_table, NULL, &d);
|
r = specifier_printf(word, PATH_MAX-1, system_and_tmp_specifier_table, arg_root, NULL, &d);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Failed to expand specifiers in MakeDirectories= parameter, ignoring: %s", word);
|
"Failed to expand specifiers in MakeDirectories= parameter, ignoring: %s", word);
|
||||||
|
|||||||
@ -255,7 +255,7 @@ int config_parse_dnssd_service_name(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = specifier_printf(rvalue, DNS_LABEL_MAX, specifier_table, NULL, &name);
|
r = specifier_printf(rvalue, DNS_LABEL_MAX, specifier_table, NULL, NULL, &name);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Invalid service instance name template '%s', ignoring assignment: %m", rvalue);
|
"Invalid service instance name template '%s', ignoring assignment: %m", rvalue);
|
||||||
|
|||||||
@ -135,7 +135,7 @@ static int dnssd_service_load(Manager *manager, const char *filename) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int specifier_dnssd_host_name(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_dnssd_host_name(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
DnssdService *s = (DnssdService *) userdata;
|
DnssdService *s = (DnssdService *) userdata;
|
||||||
char *n;
|
char *n;
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ int dnssd_render_instance_name(DnssdService *s, char **ret_name) {
|
|||||||
assert(s);
|
assert(s);
|
||||||
assert(s->name_template);
|
assert(s->name_template);
|
||||||
|
|
||||||
r = specifier_printf(s->name_template, DNS_LABEL_MAX, specifier_table, s, &name);
|
r = specifier_printf(s->name_template, DNS_LABEL_MAX, specifier_table, NULL, s, &name);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_debug_errno(r, "Failed to replace specifiers: %m");
|
return log_debug_errno(r, "Failed to replace specifiers: %m");
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
#include "unit-name.h"
|
#include "unit-name.h"
|
||||||
#include "user-util.h"
|
#include "user-util.h"
|
||||||
|
|
||||||
static int specifier_prefix_and_instance(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_prefix_and_instance(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
const UnitFileInstallInfo *i = userdata;
|
const UnitFileInstallInfo *i = userdata;
|
||||||
_cleanup_free_ char *prefix = NULL;
|
_cleanup_free_ char *prefix = NULL;
|
||||||
int r;
|
int r;
|
||||||
@ -37,7 +37,7 @@ static int specifier_prefix_and_instance(char specifier, const void *data, const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int specifier_name(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_name(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
const UnitFileInstallInfo *i = userdata;
|
const UnitFileInstallInfo *i = userdata;
|
||||||
char *ans;
|
char *ans;
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ static int specifier_name(char specifier, const void *data, const void *userdata
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int specifier_prefix(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_prefix(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
const UnitFileInstallInfo *i = userdata;
|
const UnitFileInstallInfo *i = userdata;
|
||||||
|
|
||||||
assert(i);
|
assert(i);
|
||||||
@ -61,7 +61,7 @@ static int specifier_prefix(char specifier, const void *data, const void *userda
|
|||||||
return unit_name_to_prefix(i->name, ret);
|
return unit_name_to_prefix(i->name, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int specifier_instance(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_instance(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
const UnitFileInstallInfo *i = userdata;
|
const UnitFileInstallInfo *i = userdata;
|
||||||
char *instance;
|
char *instance;
|
||||||
int r;
|
int r;
|
||||||
@ -82,12 +82,12 @@ static int specifier_instance(char specifier, const void *data, const void *user
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int specifier_last_component(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_last_component(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
_cleanup_free_ char *prefix = NULL;
|
_cleanup_free_ char *prefix = NULL;
|
||||||
char *dash;
|
char *dash;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = specifier_prefix(specifier, data, userdata, &prefix);
|
r = specifier_prefix(specifier, data, root, userdata, &prefix);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ static int specifier_last_component(char specifier, const void *data, const void
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int install_full_printf_internal(const UnitFileInstallInfo *i, const char *format, size_t max_length, char **ret) {
|
int install_full_printf_internal(const UnitFileInstallInfo *i, const char *format, size_t max_length, const char *root, char **ret) {
|
||||||
/* This is similar to unit_name_printf() */
|
/* This is similar to unit_name_printf() */
|
||||||
|
|
||||||
const Specifier table[] = {
|
const Specifier table[] = {
|
||||||
@ -123,5 +123,5 @@ int install_full_printf_internal(const UnitFileInstallInfo *i, const char *forma
|
|||||||
assert(format);
|
assert(format);
|
||||||
assert(ret);
|
assert(ret);
|
||||||
|
|
||||||
return specifier_printf(format, max_length, table, i, ret);
|
return specifier_printf(format, max_length, table, root, i, ret);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,10 +4,11 @@
|
|||||||
#include "install.h"
|
#include "install.h"
|
||||||
#include "unit-name.h"
|
#include "unit-name.h"
|
||||||
|
|
||||||
int install_full_printf_internal(const UnitFileInstallInfo *i, const char *format, size_t max_length, char **ret);
|
int install_full_printf_internal(const UnitFileInstallInfo *i, const char *format, size_t max_length, const char *root, char **ret);
|
||||||
static inline int install_name_printf(const UnitFileInstallInfo *i, const char *format, char **ret) {
|
|
||||||
return install_full_printf_internal(i, format, UNIT_NAME_MAX, ret);
|
static inline int install_name_printf(const UnitFileInstallInfo *i, const char *format, const char *root, char **ret) {
|
||||||
|
return install_full_printf_internal(i, format, UNIT_NAME_MAX, root, ret);
|
||||||
}
|
}
|
||||||
static inline int install_path_printf(const UnitFileInstallInfo *i, const char *format, char **ret) {
|
static inline int install_path_printf(const UnitFileInstallInfo *i, const char *format, const char *root, char **ret) {
|
||||||
return install_full_printf_internal(i, format, PATH_MAX-1, ret);
|
return install_full_printf_internal(i, format, PATH_MAX-1, root, ret);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -963,6 +963,7 @@ static void install_info_free(UnitFileInstallInfo *i) {
|
|||||||
|
|
||||||
free(i->name);
|
free(i->name);
|
||||||
free(i->path);
|
free(i->path);
|
||||||
|
free(i->root);
|
||||||
strv_free(i->aliases);
|
strv_free(i->aliases);
|
||||||
strv_free(i->wanted_by);
|
strv_free(i->wanted_by);
|
||||||
strv_free(i->required_by);
|
strv_free(i->required_by);
|
||||||
@ -1023,6 +1024,7 @@ static int install_info_add(
|
|||||||
InstallContext *c,
|
InstallContext *c,
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *path,
|
const char *path,
|
||||||
|
const char *root,
|
||||||
bool auxiliary,
|
bool auxiliary,
|
||||||
UnitFileInstallInfo **ret) {
|
UnitFileInstallInfo **ret) {
|
||||||
|
|
||||||
@ -1066,6 +1068,14 @@ static int install_info_add(
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (root) {
|
||||||
|
i->root = strdup(root);
|
||||||
|
if (!i->root) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (path) {
|
if (path) {
|
||||||
i->path = strdup(path);
|
i->path = strdup(path);
|
||||||
if (!i->path) {
|
if (!i->path) {
|
||||||
@ -1147,11 +1157,11 @@ static int config_parse_also(
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
r = install_name_printf(info, word, &printed);
|
r = install_name_printf(info, word, info->root, &printed);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = install_info_add(c, printed, NULL, true, NULL);
|
r = install_info_add(c, printed, NULL, info->root, /* auxiliary= */ true, NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -1194,7 +1204,7 @@ static int config_parse_default_instance(
|
|||||||
return log_syntax(unit, LOG_WARNING, filename, line, 0,
|
return log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||||
"DefaultInstance= only makes sense for template units, ignoring.");
|
"DefaultInstance= only makes sense for template units, ignoring.");
|
||||||
|
|
||||||
r = install_name_printf(i, rvalue, &printed);
|
r = install_name_printf(i, rvalue, i->root, &printed);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -1637,7 +1647,7 @@ static int install_info_traverse(
|
|||||||
bn = buffer;
|
bn = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = install_info_add(c, bn, NULL, false, &i);
|
r = install_info_add(c, bn, NULL, paths->root_dir, /* auxiliary= */ false, &i);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -1676,9 +1686,9 @@ static int install_info_add_auto(
|
|||||||
|
|
||||||
pp = prefix_roota(paths->root_dir, name_or_path);
|
pp = prefix_roota(paths->root_dir, name_or_path);
|
||||||
|
|
||||||
return install_info_add(c, NULL, pp, false, ret);
|
return install_info_add(c, NULL, pp, paths->root_dir, /* auxiliary= */ false, ret);
|
||||||
} else
|
} else
|
||||||
return install_info_add(c, name_or_path, NULL, false, ret);
|
return install_info_add(c, name_or_path, NULL, paths->root_dir, /* auxiliary= */ false, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int install_info_discover(
|
static int install_info_discover(
|
||||||
@ -1820,7 +1830,7 @@ static int install_info_symlink_alias(
|
|||||||
STRV_FOREACH(s, i->aliases) {
|
STRV_FOREACH(s, i->aliases) {
|
||||||
_cleanup_free_ char *alias_path = NULL, *dst = NULL, *dst_updated = NULL;
|
_cleanup_free_ char *alias_path = NULL, *dst = NULL, *dst_updated = NULL;
|
||||||
|
|
||||||
q = install_path_printf(i, *s, &dst);
|
q = install_path_printf(i, *s, i->root, &dst);
|
||||||
if (q < 0)
|
if (q < 0)
|
||||||
return q;
|
return q;
|
||||||
|
|
||||||
@ -1905,7 +1915,7 @@ static int install_info_symlink_wants(
|
|||||||
STRV_FOREACH(s, list) {
|
STRV_FOREACH(s, list) {
|
||||||
_cleanup_free_ char *path = NULL, *dst = NULL;
|
_cleanup_free_ char *path = NULL, *dst = NULL;
|
||||||
|
|
||||||
q = install_name_printf(i, *s, &dst);
|
q = install_name_printf(i, *s, i->root, &dst);
|
||||||
if (q < 0)
|
if (q < 0)
|
||||||
return q;
|
return q;
|
||||||
|
|
||||||
@ -2687,7 +2697,7 @@ int unit_file_disable(
|
|||||||
if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
|
if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
r = install_info_add(&c, *i, NULL, false, NULL);
|
r = install_info_add(&c, *i, NULL, paths.root_dir, /* auxiliary= */ false, NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -79,6 +79,7 @@ enum UnitFileType {
|
|||||||
struct UnitFileInstallInfo {
|
struct UnitFileInstallInfo {
|
||||||
char *name;
|
char *name;
|
||||||
char *path;
|
char *path;
|
||||||
|
char *root;
|
||||||
|
|
||||||
char **aliases;
|
char **aliases;
|
||||||
char **wanted_by;
|
char **wanted_by;
|
||||||
|
|||||||
@ -10,9 +10,11 @@
|
|||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "architecture.h"
|
#include "architecture.h"
|
||||||
|
#include "fd-util.h"
|
||||||
#include "format-util.h"
|
#include "format-util.h"
|
||||||
#include "fs-util.h"
|
#include "fs-util.h"
|
||||||
#include "hostname-util.h"
|
#include "hostname-util.h"
|
||||||
|
#include "id128-util.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "os-util.h"
|
#include "os-util.h"
|
||||||
#include "specifier.h"
|
#include "specifier.h"
|
||||||
@ -29,7 +31,7 @@
|
|||||||
* and "%" used for escaping. */
|
* and "%" used for escaping. */
|
||||||
#define POSSIBLE_SPECIFIERS ALPHANUMERICAL "%"
|
#define POSSIBLE_SPECIFIERS ALPHANUMERICAL "%"
|
||||||
|
|
||||||
int specifier_printf(const char *text, size_t max_length, const Specifier table[], const void *userdata, char **ret) {
|
int specifier_printf(const char *text, size_t max_length, const Specifier table[], const char *root, const void *userdata, char **ret) {
|
||||||
_cleanup_free_ char *result = NULL;
|
_cleanup_free_ char *result = NULL;
|
||||||
bool percent = false;
|
bool percent = false;
|
||||||
const char *f;
|
const char *f;
|
||||||
@ -60,7 +62,7 @@ int specifier_printf(const char *text, size_t max_length, const Specifier table[
|
|||||||
_cleanup_free_ char *w = NULL;
|
_cleanup_free_ char *w = NULL;
|
||||||
size_t k, j;
|
size_t k, j;
|
||||||
|
|
||||||
r = i->lookup(i->specifier, i->data, userdata, &w);
|
r = i->lookup(i->specifier, i->data, root, userdata, &w);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -104,7 +106,7 @@ int specifier_printf(const char *text, size_t max_length, const Specifier table[
|
|||||||
|
|
||||||
/* Generic handler for simple string replacements */
|
/* Generic handler for simple string replacements */
|
||||||
|
|
||||||
int specifier_string(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_string(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
char *n;
|
char *n;
|
||||||
|
|
||||||
n = strdup(strempty(data));
|
n = strdup(strempty(data));
|
||||||
@ -115,12 +117,21 @@ int specifier_string(char specifier, const void *data, const void *userdata, cha
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_machine_id(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_machine_id(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
sd_id128_t id;
|
sd_id128_t id;
|
||||||
char *n;
|
char *n;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = sd_id128_get_machine(&id);
|
if (root) {
|
||||||
|
_cleanup_close_ int fd = -1;
|
||||||
|
|
||||||
|
fd = chase_symlinks_and_open("/etc/machine-id", root, CHASE_PREFIX_ROOT, O_RDONLY|O_CLOEXEC|O_NOCTTY, NULL);
|
||||||
|
if (fd < 0)
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
r = id128_read_fd(fd, ID128_PLAIN, &id);
|
||||||
|
} else
|
||||||
|
r = sd_id128_get_machine(&id);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -132,7 +143,7 @@ int specifier_machine_id(char specifier, const void *data, const void *userdata,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_boot_id(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_boot_id(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
sd_id128_t id;
|
sd_id128_t id;
|
||||||
char *n;
|
char *n;
|
||||||
int r;
|
int r;
|
||||||
@ -149,7 +160,7 @@ int specifier_boot_id(char specifier, const void *data, const void *userdata, ch
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_host_name(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_host_name(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
char *n;
|
char *n;
|
||||||
|
|
||||||
n = gethostname_malloc();
|
n = gethostname_malloc();
|
||||||
@ -160,7 +171,7 @@ int specifier_host_name(char specifier, const void *data, const void *userdata,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_short_host_name(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_short_host_name(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
char *n;
|
char *n;
|
||||||
|
|
||||||
n = gethostname_short_malloc();
|
n = gethostname_short_malloc();
|
||||||
@ -171,7 +182,7 @@ int specifier_short_host_name(char specifier, const void *data, const void *user
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_kernel_release(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_kernel_release(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
struct utsname uts;
|
struct utsname uts;
|
||||||
char *n;
|
char *n;
|
||||||
int r;
|
int r;
|
||||||
@ -188,7 +199,7 @@ int specifier_kernel_release(char specifier, const void *data, const void *userd
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_architecture(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_architecture(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
char *t;
|
char *t;
|
||||||
|
|
||||||
t = strdup(architecture_to_string(uname_architecture()));
|
t = strdup(architecture_to_string(uname_architecture()));
|
||||||
@ -199,11 +210,11 @@ int specifier_architecture(char specifier, const void *data, const void *userdat
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int specifier_os_release_common(const char *field, char **ret) {
|
static int specifier_os_release_common(const char *field, const char *root, char **ret) {
|
||||||
char *t = NULL;
|
char *t = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = parse_os_release(NULL, field, &t);
|
r = parse_os_release(root, field, &t);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (!t) {
|
if (!t) {
|
||||||
@ -218,31 +229,31 @@ static int specifier_os_release_common(const char *field, char **ret) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_os_id(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_os_id(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
return specifier_os_release_common("ID", ret);
|
return specifier_os_release_common("ID", root, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_os_version_id(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_os_version_id(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
return specifier_os_release_common("VERSION_ID", ret);
|
return specifier_os_release_common("VERSION_ID", root, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_os_build_id(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_os_build_id(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
return specifier_os_release_common("BUILD_ID", ret);
|
return specifier_os_release_common("BUILD_ID", root, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_os_variant_id(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_os_variant_id(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
return specifier_os_release_common("VARIANT_ID", ret);
|
return specifier_os_release_common("VARIANT_ID", root, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_os_image_id(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_os_image_id(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
return specifier_os_release_common("IMAGE_ID", ret);
|
return specifier_os_release_common("IMAGE_ID", root, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_os_image_version(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_os_image_version(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
return specifier_os_release_common("IMAGE_VERSION", ret);
|
return specifier_os_release_common("IMAGE_VERSION", root, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_group_name(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_group_name(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
char *t;
|
char *t;
|
||||||
|
|
||||||
t = gid_to_name(getgid());
|
t = gid_to_name(getgid());
|
||||||
@ -253,14 +264,14 @@ int specifier_group_name(char specifier, const void *data, const void *userdata,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_group_id(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_group_id(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
if (asprintf(ret, UID_FMT, getgid()) < 0)
|
if (asprintf(ret, UID_FMT, getgid()) < 0)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_user_name(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_user_name(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
char *t;
|
char *t;
|
||||||
|
|
||||||
/* If we are UID 0 (root), this will not result in NSS, otherwise it might. This is good, as we want to be able
|
/* If we are UID 0 (root), this will not result in NSS, otherwise it might. This is good, as we want to be able
|
||||||
@ -278,7 +289,7 @@ int specifier_user_name(char specifier, const void *data, const void *userdata,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_user_id(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_user_id(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
|
|
||||||
if (asprintf(ret, UID_FMT, getuid()) < 0)
|
if (asprintf(ret, UID_FMT, getuid()) < 0)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -286,7 +297,7 @@ int specifier_user_id(char specifier, const void *data, const void *userdata, ch
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_user_home(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_user_home(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
|
|
||||||
/* On PID 1 (which runs as root) this will not result in NSS,
|
/* On PID 1 (which runs as root) this will not result in NSS,
|
||||||
* which is good. See above */
|
* which is good. See above */
|
||||||
@ -294,7 +305,7 @@ int specifier_user_home(char specifier, const void *data, const void *userdata,
|
|||||||
return get_home_dir(ret);
|
return get_home_dir(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_user_shell(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_user_shell(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
|
|
||||||
/* On PID 1 (which runs as root) this will not result in NSS,
|
/* On PID 1 (which runs as root) this will not result in NSS,
|
||||||
* which is good. See above */
|
* which is good. See above */
|
||||||
@ -302,15 +313,18 @@ int specifier_user_shell(char specifier, const void *data, const void *userdata,
|
|||||||
return get_shell(ret);
|
return get_shell(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_tmp_dir(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_tmp_dir(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
const char *p;
|
const char *p;
|
||||||
char *copy;
|
char *copy;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = tmp_dir(&p);
|
if (root) /* If root dir is set, don't honour $TMP or similar */
|
||||||
if (r < 0)
|
p = "/tmp";
|
||||||
return r;
|
else {
|
||||||
|
r = tmp_dir(&p);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
copy = strdup(p);
|
copy = strdup(p);
|
||||||
if (!copy)
|
if (!copy)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -319,15 +333,18 @@ int specifier_tmp_dir(char specifier, const void *data, const void *userdata, ch
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int specifier_var_tmp_dir(char specifier, const void *data, const void *userdata, char **ret) {
|
int specifier_var_tmp_dir(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
const char *p;
|
const char *p;
|
||||||
char *copy;
|
char *copy;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = var_tmp_dir(&p);
|
if (root)
|
||||||
if (r < 0)
|
p = "/var/tmp";
|
||||||
return r;
|
else {
|
||||||
|
r = var_tmp_dir(&p);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
copy = strdup(p);
|
copy = strdup(p);
|
||||||
if (!copy)
|
if (!copy)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
|
|
||||||
typedef int (*SpecifierCallback)(char specifier, const void *data, const void *userdata, char **ret);
|
typedef int (*SpecifierCallback)(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
|
|
||||||
typedef struct Specifier {
|
typedef struct Specifier {
|
||||||
const char specifier;
|
const char specifier;
|
||||||
@ -11,32 +11,32 @@ typedef struct Specifier {
|
|||||||
const void *data;
|
const void *data;
|
||||||
} Specifier;
|
} Specifier;
|
||||||
|
|
||||||
int specifier_printf(const char *text, size_t max_length, const Specifier table[], const void *userdata, char **ret);
|
int specifier_printf(const char *text, size_t max_length, const Specifier table[], const char *root, const void *userdata, char **ret);
|
||||||
|
|
||||||
int specifier_string(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_string(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
|
|
||||||
int specifier_machine_id(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_machine_id(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_boot_id(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_boot_id(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_host_name(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_host_name(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_short_host_name(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_short_host_name(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_kernel_release(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_kernel_release(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_architecture(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_architecture(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_os_id(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_os_id(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_os_version_id(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_os_version_id(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_os_build_id(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_os_build_id(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_os_variant_id(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_os_variant_id(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_os_image_id(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_os_image_id(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_os_image_version(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_os_image_version(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
|
|
||||||
int specifier_group_name(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_group_name(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_group_id(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_group_id(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_user_name(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_user_name(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_user_id(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_user_id(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_user_home(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_user_home(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_user_shell(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_user_shell(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
|
|
||||||
int specifier_tmp_dir(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_tmp_dir(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
int specifier_var_tmp_dir(char specifier, const void *data, const void *userdata, char **ret);
|
int specifier_var_tmp_dir(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
|
|
||||||
/* Typically, in places where one of the above specifier is to be resolved the other similar ones are to be
|
/* Typically, in places where one of the above specifier is to be resolved the other similar ones are to be
|
||||||
* resolved, too. Hence let's define common macros for the relevant array entries.
|
* resolved, too. Hence let's define common macros for the relevant array entries.
|
||||||
|
|||||||
@ -1509,7 +1509,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
|||||||
name = mfree(name);
|
name = mfree(name);
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
r = specifier_printf(name, NAME_MAX, system_and_tmp_specifier_table, NULL, &resolved_name);
|
r = specifier_printf(name, NAME_MAX, system_and_tmp_specifier_table, arg_root, NULL, &resolved_name);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m", fname, line, name);
|
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m", fname, line, name);
|
||||||
|
|
||||||
@ -1524,7 +1524,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
|||||||
id = mfree(id);
|
id = mfree(id);
|
||||||
|
|
||||||
if (id) {
|
if (id) {
|
||||||
r = specifier_printf(id, PATH_MAX-1, system_and_tmp_specifier_table, NULL, &resolved_id);
|
r = specifier_printf(id, PATH_MAX-1, system_and_tmp_specifier_table, arg_root, NULL, &resolved_id);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
||||||
fname, line, name);
|
fname, line, name);
|
||||||
@ -1535,7 +1535,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
|||||||
description = mfree(description);
|
description = mfree(description);
|
||||||
|
|
||||||
if (description) {
|
if (description) {
|
||||||
r = specifier_printf(description, LONG_LINE_MAX, system_and_tmp_specifier_table, NULL, &resolved_description);
|
r = specifier_printf(description, LONG_LINE_MAX, system_and_tmp_specifier_table, arg_root, NULL, &resolved_description);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
||||||
fname, line, description);
|
fname, line, description);
|
||||||
@ -1551,7 +1551,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
|||||||
home = mfree(home);
|
home = mfree(home);
|
||||||
|
|
||||||
if (home) {
|
if (home) {
|
||||||
r = specifier_printf(home, PATH_MAX-1, system_and_tmp_specifier_table, NULL, &resolved_home);
|
r = specifier_printf(home, PATH_MAX-1, system_and_tmp_specifier_table, arg_root, NULL, &resolved_home);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
||||||
fname, line, home);
|
fname, line, home);
|
||||||
@ -1567,7 +1567,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
|||||||
shell = mfree(shell);
|
shell = mfree(shell);
|
||||||
|
|
||||||
if (shell) {
|
if (shell) {
|
||||||
r = specifier_printf(shell, PATH_MAX-1, system_and_tmp_specifier_table, NULL, &resolved_shell);
|
r = specifier_printf(shell, PATH_MAX-1, system_and_tmp_specifier_table, arg_root, NULL, &resolved_shell);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
||||||
fname, line, shell);
|
fname, line, shell);
|
||||||
|
|||||||
@ -498,8 +498,8 @@ static void test_install_printf(void) {
|
|||||||
|
|
||||||
_cleanup_free_ char *mid = NULL, *bid = NULL, *host = NULL, *gid = NULL, *group = NULL, *uid = NULL, *user = NULL;
|
_cleanup_free_ char *mid = NULL, *bid = NULL, *host = NULL, *gid = NULL, *group = NULL, *uid = NULL, *user = NULL;
|
||||||
|
|
||||||
assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid);
|
assert_se(specifier_machine_id('m', NULL, NULL, NULL, &mid) >= 0 && mid);
|
||||||
assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid);
|
assert_se(specifier_boot_id('b', NULL, NULL, NULL, &bid) >= 0 && bid);
|
||||||
assert_se(host = gethostname_malloc());
|
assert_se(host = gethostname_malloc());
|
||||||
assert_se(group = gid_to_name(getgid()));
|
assert_se(group = gid_to_name(getgid()));
|
||||||
assert_se(asprintf(&gid, UID_FMT, getgid()) >= 0);
|
assert_se(asprintf(&gid, UID_FMT, getgid()) >= 0);
|
||||||
@ -512,7 +512,7 @@ static void test_install_printf(void) {
|
|||||||
_cleanup_free_ char \
|
_cleanup_free_ char \
|
||||||
*d1 = strdup(i.name), \
|
*d1 = strdup(i.name), \
|
||||||
*d2 = strdup(i.path); \
|
*d2 = strdup(i.path); \
|
||||||
assert_se(install_name_printf(&src, pattern, &t) >= 0 || !result); \
|
assert_se(install_name_printf(&src, pattern, NULL, &t) >= 0 || !result); \
|
||||||
memzero(i.name, strlen(i.name)); \
|
memzero(i.name, strlen(i.name)); \
|
||||||
memzero(i.path, strlen(i.path)); \
|
memzero(i.path, strlen(i.path)); \
|
||||||
assert_se(d1 && d2); \
|
assert_se(d1 && d2); \
|
||||||
|
|||||||
@ -69,7 +69,7 @@ static void test_specifier_printf(void) {
|
|||||||
|
|
||||||
log_info("/* %s */", __func__);
|
log_info("/* %s */", __func__);
|
||||||
|
|
||||||
r = specifier_printf("xxx a=%X b=%Y yyy", SIZE_MAX, table, NULL, &w);
|
r = specifier_printf("xxx a=%X b=%Y yyy", SIZE_MAX, table, NULL, NULL, &w);
|
||||||
assert_se(r >= 0);
|
assert_se(r >= 0);
|
||||||
assert_se(w);
|
assert_se(w);
|
||||||
|
|
||||||
@ -77,13 +77,13 @@ static void test_specifier_printf(void) {
|
|||||||
assert_se(streq(w, "xxx a=AAAA b=BBBB yyy"));
|
assert_se(streq(w, "xxx a=AAAA b=BBBB yyy"));
|
||||||
|
|
||||||
free(w);
|
free(w);
|
||||||
r = specifier_printf("machine=%m, boot=%b, host=%H, version=%v, arch=%a", SIZE_MAX, table, NULL, &w);
|
r = specifier_printf("machine=%m, boot=%b, host=%H, version=%v, arch=%a", SIZE_MAX, table, NULL, NULL, &w);
|
||||||
assert_se(r >= 0);
|
assert_se(r >= 0);
|
||||||
assert_se(w);
|
assert_se(w);
|
||||||
puts(w);
|
puts(w);
|
||||||
|
|
||||||
w = mfree(w);
|
w = mfree(w);
|
||||||
specifier_printf("os=%o, os-version=%w, build=%B, variant=%W", SIZE_MAX, table, NULL, &w);
|
specifier_printf("os=%o, os-version=%w, build=%B, variant=%W", SIZE_MAX, table, NULL, NULL, &w);
|
||||||
if (w)
|
if (w)
|
||||||
puts(w);
|
puts(w);
|
||||||
}
|
}
|
||||||
@ -97,7 +97,7 @@ static void test_specifiers(void) {
|
|||||||
|
|
||||||
xsprintf(spec, "%%%c", s->specifier);
|
xsprintf(spec, "%%%c", s->specifier);
|
||||||
|
|
||||||
assert_se(specifier_printf(spec, SIZE_MAX, specifier_table, NULL, &resolved) >= 0);
|
assert_se(specifier_printf(spec, SIZE_MAX, specifier_table, NULL, NULL, &resolved) >= 0);
|
||||||
|
|
||||||
log_info("%%%c → %s", s->specifier, resolved);
|
log_info("%%%c → %s", s->specifier, resolved);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -228,8 +228,8 @@ static int test_unit_printf(void) {
|
|||||||
|
|
||||||
log_info("/* %s */", __func__);
|
log_info("/* %s */", __func__);
|
||||||
|
|
||||||
assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid);
|
assert_se(specifier_machine_id('m', NULL, NULL, NULL, &mid) >= 0 && mid);
|
||||||
assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid);
|
assert_se(specifier_boot_id('b', NULL, NULL, NULL, &bid) >= 0 && bid);
|
||||||
assert_se(host = gethostname_malloc());
|
assert_se(host = gethostname_malloc());
|
||||||
assert_se(user = uid_to_name(getuid()));
|
assert_se(user = uid_to_name(getuid()));
|
||||||
assert_se(group = gid_to_name(getgid()));
|
assert_se(group = gid_to_name(getgid()));
|
||||||
|
|||||||
@ -200,8 +200,8 @@ STATIC_DESTRUCTOR_REGISTER(arg_exclude_prefixes, freep);
|
|||||||
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
|
||||||
|
|
||||||
static int specifier_machine_id_safe(char specifier, const void *data, const void *userdata, char **ret);
|
static int specifier_machine_id_safe(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
static int specifier_directory(char specifier, const void *data, const void *userdata, char **ret);
|
static int specifier_directory(char specifier, const void *data, const char *root, const void *userdata, char **ret);
|
||||||
|
|
||||||
static const Specifier specifier_table[] = {
|
static const Specifier specifier_table[] = {
|
||||||
{ 'a', specifier_architecture, NULL },
|
{ 'a', specifier_architecture, NULL },
|
||||||
@ -228,21 +228,20 @@ static const Specifier specifier_table[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int specifier_machine_id_safe(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_machine_id_safe(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* If /etc/machine_id is missing or empty (e.g. in a chroot environment)
|
/* If /etc/machine_id is missing or empty (e.g. in a chroot environment) return a recognizable error
|
||||||
* return a recognizable error so that the caller can skip the rule
|
* so that the caller can skip the rule gracefully. */
|
||||||
* gracefully. */
|
|
||||||
|
|
||||||
r = specifier_machine_id(specifier, data, userdata, ret);
|
r = specifier_machine_id(specifier, data, root, userdata, ret);
|
||||||
if (IN_SET(r, -ENOENT, -ENOMEDIUM))
|
if (IN_SET(r, -ENOENT, -ENOMEDIUM))
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int specifier_directory(char specifier, const void *data, const void *userdata, char **ret) {
|
static int specifier_directory(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
|
||||||
struct table_entry {
|
struct table_entry {
|
||||||
uint64_t type;
|
uint64_t type;
|
||||||
const char *suffix;
|
const char *suffix;
|
||||||
@ -262,8 +261,10 @@ static int specifier_directory(char specifier, const void *data, const void *use
|
|||||||
[DIRECTORY_LOGS] = { SD_PATH_USER_CONFIGURATION, "log" },
|
[DIRECTORY_LOGS] = { SD_PATH_USER_CONFIGURATION, "log" },
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned i;
|
|
||||||
const struct table_entry *paths;
|
const struct table_entry *paths;
|
||||||
|
_cleanup_free_ char *p = NULL;
|
||||||
|
unsigned i;
|
||||||
|
int r;
|
||||||
|
|
||||||
assert_cc(ELEMENTSOF(paths_system) == ELEMENTSOF(paths_user));
|
assert_cc(ELEMENTSOF(paths_system) == ELEMENTSOF(paths_user));
|
||||||
paths = arg_user ? paths_user : paths_system;
|
paths = arg_user ? paths_user : paths_system;
|
||||||
@ -271,7 +272,22 @@ static int specifier_directory(char specifier, const void *data, const void *use
|
|||||||
i = PTR_TO_UINT(data);
|
i = PTR_TO_UINT(data);
|
||||||
assert(i < ELEMENTSOF(paths_system));
|
assert(i < ELEMENTSOF(paths_system));
|
||||||
|
|
||||||
return sd_path_lookup(paths[i].type, paths[i].suffix, ret);
|
r = sd_path_lookup(paths[i].type, paths[i].suffix, &p);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (arg_root) {
|
||||||
|
_cleanup_free_ char *j = NULL;
|
||||||
|
|
||||||
|
j = path_join(arg_root, p);
|
||||||
|
if (!j)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(j);
|
||||||
|
} else
|
||||||
|
*ret = TAKE_PTR(p);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int log_unresolvable_specifier(const char *filename, unsigned line) {
|
static int log_unresolvable_specifier(const char *filename, unsigned line) {
|
||||||
@ -2778,7 +2794,7 @@ static int specifier_expansion_from_arg(Item *i) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to unescape parameter to write: %s", i->argument);
|
return log_error_errno(r, "Failed to unescape parameter to write: %s", i->argument);
|
||||||
|
|
||||||
r = specifier_printf(unescaped, PATH_MAX-1, specifier_table, NULL, &resolved);
|
r = specifier_printf(unescaped, PATH_MAX-1, specifier_table, arg_root, NULL, &resolved);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -2788,7 +2804,7 @@ static int specifier_expansion_from_arg(Item *i) {
|
|||||||
case SET_XATTR:
|
case SET_XATTR:
|
||||||
case RECURSIVE_SET_XATTR:
|
case RECURSIVE_SET_XATTR:
|
||||||
STRV_FOREACH(xattr, i->xattrs) {
|
STRV_FOREACH(xattr, i->xattrs) {
|
||||||
r = specifier_printf(*xattr, SIZE_MAX, specifier_table, NULL, &resolved);
|
r = specifier_printf(*xattr, SIZE_MAX, specifier_table, arg_root, NULL, &resolved);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -3021,7 +3037,7 @@ static int parse_line(
|
|||||||
i.allow_failure = allow_failure;
|
i.allow_failure = allow_failure;
|
||||||
i.try_replace = try_replace;
|
i.try_replace = try_replace;
|
||||||
|
|
||||||
r = specifier_printf(path, PATH_MAX-1, specifier_table, NULL, &i.path);
|
r = specifier_printf(path, PATH_MAX-1, specifier_table, arg_root, NULL, &i.path);
|
||||||
if (r == -ENXIO)
|
if (r == -ENXIO)
|
||||||
return log_unresolvable_specifier(fname, line);
|
return log_unresolvable_specifier(fname, line);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user