tree-wide: support a bunch of additional specifiers

This commit is contained in:
Lennart Poettering 2020-04-28 20:03:56 +02:00
parent 76410e9849
commit 268f5a5463
9 changed files with 112 additions and 12 deletions

View File

@ -186,8 +186,14 @@ int unit_name_printf(const Unit *u, const char* format, char **ret) {
* %u: the username of the running user
*
* %m: the machine ID of the running system
* %H: the hostname of the running system
* %b: the boot ID of the running system
* %H: the hostname of the running system
* %v: the kernel version
* %a: the native userspace architecture
* %o: the OS ID according to /etc/os-release
* %w: the OS version ID, according to /etc/os-release
* %B: the OS build ID, according to /etc/os-release
* %W: the OS variant ID, according to /etc/os-release
*/
const Specifier table[] = {
@ -203,8 +209,14 @@ int unit_name_printf(const Unit *u, const char* format, char **ret) {
{ 'u', specifier_user_name, NULL },
{ 'm', specifier_machine_id, NULL },
{ 'H', specifier_host_name, NULL },
{ 'b', specifier_boot_id, NULL },
{ 'H', specifier_host_name, NULL },
{ 'v', specifier_kernel_release, NULL },
{ 'a', specifier_architecture, NULL },
{ 'o', specifier_os_id, NULL },
{ 'w', specifier_os_version_id, NULL },
{ 'B', specifier_os_build_id, NULL },
{ 'W', specifier_os_variant_id, NULL },
{}
};

View File

@ -218,10 +218,15 @@ int config_parse_search_domains(
int config_parse_dnssd_service_name(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
static const Specifier specifier_table[] = {
{ 'm', specifier_machine_id, NULL },
{ 'b', specifier_boot_id, NULL },
{ 'H', specifier_host_name, NULL },
{ 'm', specifier_machine_id, NULL },
{ 'v', specifier_kernel_release, NULL },
{ 'a', specifier_architecture, NULL },
{ 'o', specifier_os_id, NULL },
{ 'w', specifier_os_version_id, NULL },
{ 'B', specifier_os_build_id, NULL },
{ 'W', specifier_os_variant_id, NULL },
{}
};
DnssdService *s = userdata;

View File

@ -153,10 +153,15 @@ static int specifier_dnssd_host_name(char specifier, const void *data, const voi
int dnssd_render_instance_name(DnssdService *s, char **ret_name) {
static const Specifier specifier_table[] = {
{ 'm', specifier_machine_id, NULL },
{ 'b', specifier_boot_id, NULL },
{ 'H', specifier_dnssd_host_name, NULL },
{ 'm', specifier_machine_id, NULL },
{ 'v', specifier_kernel_release, NULL },
{ 'a', specifier_architecture, NULL },
{ 'o', specifier_os_id, NULL },
{ 'w', specifier_os_version_id, NULL },
{ 'B', specifier_os_build_id, NULL },
{ 'W', specifier_os_variant_id, NULL },
{}
};
_cleanup_free_ char *name = NULL;

View File

@ -133,9 +133,14 @@ int install_full_printf(const UnitFileInstallInfo *i, const char *format, char *
{ 'u', specifier_user_name, NULL },
{ 'm', specifier_machine_id, NULL },
{ 'H', specifier_host_name, NULL },
{ 'b', specifier_boot_id, NULL },
{ 'H', specifier_host_name, NULL },
{ 'v', specifier_kernel_release, NULL },
{ 'a', specifier_architecture, NULL },
{ 'o', specifier_os_id, NULL },
{ 'w', specifier_os_version_id, NULL },
{ 'B', specifier_os_build_id, NULL },
{ 'W', specifier_os_variant_id, NULL },
{}
};

View File

@ -9,10 +9,12 @@
#include "sd-id128.h"
#include "alloc-util.h"
#include "architecture.h"
#include "format-util.h"
#include "fs-util.h"
#include "hostname-util.h"
#include "macro.h"
#include "os-util.h"
#include "specifier.h"
#include "string-util.h"
#include "strv.h"
@ -175,6 +177,52 @@ int specifier_kernel_release(char specifier, const void *data, const void *userd
return 0;
}
int specifier_architecture(char specifier, const void *data, const void *userdata, char **ret) {
char *t;
t = strdup(architecture_to_string(uname_architecture()));
if (!t)
return -ENOMEM;
*ret = t;
return 0;
}
static int specifier_os_release_common(const char *field, char **ret) {
char *t = NULL;
int r;
r = parse_os_release(NULL, field, &t, NULL);
if (r < 0)
return r;
if (!t) {
/* fields in /etc/os-release might quite possibly be missing, even if everything is entirely
* valid otherwise. Let's hence return "" in that case. */
t = strdup("");
if (!t)
return -ENOMEM;
}
*ret = t;
return 0;
}
int specifier_os_id(char specifier, const void *data, const void *userdata, char **ret) {
return specifier_os_release_common("ID", ret);
}
int specifier_os_version_id(char specifier, const void *data, const void *userdata, char **ret) {
return specifier_os_release_common("VERSION_ID", ret);
}
int specifier_os_build_id(char specifier, const void *data, const void *userdata, char **ret) {
return specifier_os_release_common("BUILD_ID", ret);
}
int specifier_os_variant_id(char specifier, const void *data, const void *userdata, char **ret) {
return specifier_os_release_common("VARIANT_ID", ret);
}
int specifier_group_name(char specifier, const void *data, const void *userdata, char **ret) {
char *t;

View File

@ -19,6 +19,11 @@ int specifier_machine_id(char specifier, const void *data, const void *userdata,
int specifier_boot_id(char specifier, const void *data, const void *userdata, char **ret);
int specifier_host_name(char specifier, const void *data, const void *userdata, char **ret);
int specifier_kernel_release(char specifier, const void *data, const void *userdata, char **ret);
int specifier_architecture(char specifier, const void *data, const void *userdata, char **ret);
int specifier_os_id(char specifier, const void *data, const void *userdata, char **ret);
int specifier_os_version_id(char specifier, const void *data, const void *userdata, char **ret);
int specifier_os_build_id(char specifier, const void *data, const void *userdata, char **ret);
int specifier_os_variant_id(char specifier, const void *data, const void *userdata, char **ret);
int specifier_group_name(char specifier, const void *data, const void *userdata, char **ret);
int specifier_group_id(char specifier, const void *data, const void *userdata, char **ret);

View File

@ -1393,6 +1393,11 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
{ 'b', specifier_boot_id, NULL },
{ 'H', specifier_host_name, NULL },
{ 'v', specifier_kernel_release, NULL },
{ 'a', specifier_architecture, NULL },
{ 'o', specifier_os_id, NULL },
{ 'w', specifier_os_version_id, NULL },
{ 'B', specifier_os_build_id, NULL },
{ 'W', specifier_os_variant_id, NULL },
{ 'T', specifier_tmp_dir, NULL },
{ 'V', specifier_var_tmp_dir, NULL },
{}

View File

@ -9,12 +9,17 @@
static void test_specifier_printf(void) {
static const Specifier table[] = {
{ 'a', specifier_string, (char*) "AAAA" },
{ 'b', specifier_string, (char*) "BBBB" },
{ 'm', specifier_machine_id, NULL },
{ 'B', specifier_boot_id, NULL },
{ 'H', specifier_host_name, NULL },
{ 'X', specifier_string, (char*) "AAAA" },
{ 'Y', specifier_string, (char*) "BBBB" },
{ 'm', specifier_machine_id, NULL },
{ 'b', specifier_boot_id, NULL },
{ 'H', specifier_host_name, NULL },
{ 'v', specifier_kernel_release, NULL },
{ 'a', specifier_architecture, NULL },
{ 'o', specifier_os_id, NULL },
{ 'w', specifier_os_version_id, NULL },
{ 'B', specifier_os_build_id, NULL },
{ 'W', specifier_os_variant_id, NULL },
{}
};
@ -23,7 +28,7 @@ static void test_specifier_printf(void) {
log_info("/* %s */", __func__);
r = specifier_printf("xxx a=%a b=%b yyy", table, NULL, &w);
r = specifier_printf("xxx a=%X b=%Y yyy", table, NULL, &w);
assert_se(r >= 0);
assert_se(w);
@ -31,10 +36,15 @@ static void test_specifier_printf(void) {
assert_se(streq(w, "xxx a=AAAA b=BBBB yyy"));
free(w);
r = specifier_printf("machine=%m, boot=%B, host=%H, version=%v", table, NULL, &w);
r = specifier_printf("machine=%m, boot=%b, host=%H, version=%v, arch=%a", table, NULL, &w);
assert_se(r >= 0);
assert_se(w);
puts(w);
w = mfree(w);
specifier_printf("os=%o, os-version=%w, build=%B, variant=%W", table, NULL, &w);
if (w)
puts(w);
}
static void test_str_in_set(void) {

View File

@ -185,6 +185,11 @@ static const Specifier specifier_table[] = {
{ 'b', specifier_boot_id, NULL },
{ 'H', specifier_host_name, NULL },
{ 'v', specifier_kernel_release, NULL },
{ 'a', specifier_architecture, NULL },
{ 'o', specifier_os_id, NULL },
{ 'w', specifier_os_version_id, NULL },
{ 'B', specifier_os_build_id, NULL },
{ 'W', specifier_os_variant_id, NULL },
{ 'g', specifier_group_name, NULL },
{ 'G', specifier_group_id, NULL },