From e97708fa3e029902c02676bba6e6c2f54f1eba3a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 7 May 2020 16:16:19 +0200 Subject: [PATCH] Add %l as specifier for the hostname without any domain component As described in #15603, it is a fairly common setup to use a fqdn as the configured hostname. But it is often convenient to use just the actual hostname, i.e. until the first dot. This adds support in tmpfiles, sysusers, and unit files for %l which expands to that. Fixes #15603. --- man/standard-specifiers.xml | 5 +++++ man/systemd.unit.xml | 5 +++++ man/sysusers.d.xml | 1 + man/tmpfiles.d.xml | 1 + src/basic/hostname-util.c | 25 ++++++++++++++++++++++--- src/basic/hostname-util.h | 1 + src/core/unit-printf.c | 1 + src/shared/specifier.c | 11 +++++++++++ src/shared/specifier.h | 1 + src/sysusers/sysusers.c | 23 ++++++++++++----------- src/test/test-hostname-util.c | 11 +++++++++++ src/tmpfiles/tmpfiles.c | 1 + 12 files changed, 72 insertions(+), 14 deletions(-) diff --git a/man/standard-specifiers.xml b/man/standard-specifiers.xml index 0c258241df..3efbb6db00 100644 --- a/man/standard-specifiers.xml +++ b/man/standard-specifiers.xml @@ -24,6 +24,11 @@ Host name The hostname of the running system. + + %l + Short host name + The hostname of the running system, truncated at the first dot to remove any domain component. + %m Machine ID diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index dd6d6af21d..b451c53020 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -1747,6 +1747,11 @@ Note that this setting is not influenced by the Us Host name The hostname of the running system at the point in time the unit configuration is loaded. + + %l + Short host name + The hostname of the running system at the point in time the unit configuration is loaded, truncated at the first dot to remove any domain component. + %i Instance name diff --git a/man/sysusers.d.xml b/man/sysusers.d.xml index f7db34ae90..38a95d6e1f 100644 --- a/man/sysusers.d.xml +++ b/man/sysusers.d.xml @@ -257,6 +257,7 @@ r - 500-900 + diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index 2e9ba5fe90..90234c3d43 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -646,6 +646,7 @@ w- /proc/sys/vm/swappiness - - - - 10 This is the home directory of the user running the command. In case of the system instance this resolves to /root. + %L System or user log directory diff --git a/src/basic/hostname-util.c b/src/basic/hostname-util.c index 5a2d60f21d..90a3dfc864 100644 --- a/src/basic/hostname-util.c +++ b/src/basic/hostname-util.c @@ -31,6 +31,7 @@ bool hostname_is_set(void) { char* gethostname_malloc(void) { struct utsname u; + const char *s; /* This call tries to return something useful, either the actual hostname * or it makes something up. The only reason it might fail is OOM. @@ -38,10 +39,28 @@ char* gethostname_malloc(void) { assert_se(uname(&u) >= 0); - if (isempty(u.nodename) || streq(u.nodename, "(none)")) - return strdup(FALLBACK_HOSTNAME); + s = u.nodename; + if (isempty(s) || streq(s, "(none)")) + s = FALLBACK_HOSTNAME; - return strdup(u.nodename); + return strdup(s); +} + +char* gethostname_short_malloc(void) { + struct utsname u; + const char *s; + + /* Like above, but kills the FQDN part if present. */ + + assert_se(uname(&u) >= 0); + + s = u.nodename; + if (isempty(s) || streq(s, "(none)") || s[0] == '.') { + s = FALLBACK_HOSTNAME; + assert(s[0] != '.'); + } + + return strndup(s, strcspn(s, ".")); } int gethostname_strict(char **ret) { diff --git a/src/basic/hostname-util.h b/src/basic/hostname-util.h index 7ba386a0fd..cafd6f020b 100644 --- a/src/basic/hostname-util.h +++ b/src/basic/hostname-util.h @@ -9,6 +9,7 @@ bool hostname_is_set(void); char* gethostname_malloc(void); +char* gethostname_short_malloc(void); int gethostname_strict(char **ret); bool valid_ldh_char(char c) _const_; diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c index 049a2f5596..4fee5dc6dc 100644 --- a/src/core/unit-printf.c +++ b/src/core/unit-printf.c @@ -291,6 +291,7 @@ int unit_full_printf(const Unit *u, const char *format, char **ret) { { 'm', specifier_machine_id, NULL }, { 'H', specifier_host_name, NULL }, + { 'l', specifier_short_host_name, NULL }, { 'b', specifier_boot_id, NULL }, { 'v', specifier_kernel_release, NULL }, {} diff --git a/src/shared/specifier.c b/src/shared/specifier.c index c784222be6..112cf6f8fb 100644 --- a/src/shared/specifier.c +++ b/src/shared/specifier.c @@ -160,6 +160,17 @@ int specifier_host_name(char specifier, const void *data, const void *userdata, return 0; } +int specifier_short_host_name(char specifier, const void *data, const void *userdata, char **ret) { + char *n; + + n = gethostname_short_malloc(); + if (!n) + return -ENOMEM; + + *ret = n; + return 0; +} + int specifier_kernel_release(char specifier, const void *data, const void *userdata, char **ret) { struct utsname uts; char *n; diff --git a/src/shared/specifier.h b/src/shared/specifier.h index 33c17eae67..50c6cbd6ab 100644 --- a/src/shared/specifier.h +++ b/src/shared/specifier.h @@ -18,6 +18,7 @@ int specifier_string(char specifier, const void *data, const void *userdata, cha int specifier_machine_id(char specifier, const void *data, const void *userdata, char **ret); 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_short_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); diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 73a710bee7..a13c35b648 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -1389,17 +1389,18 @@ static bool item_equal(Item *a, Item *b) { static int parse_line(const char *fname, unsigned line, const char *buffer) { static const Specifier specifier_table[] = { - { '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 }, - { 'T', specifier_tmp_dir, NULL }, - { 'V', specifier_var_tmp_dir, NULL }, + { 'm', specifier_machine_id, NULL }, + { 'b', specifier_boot_id, NULL }, + { 'H', specifier_host_name, NULL }, + { 'l', specifier_short_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 }, {} }; diff --git a/src/test/test-hostname-util.c b/src/test/test-hostname-util.c index fe1b23e1bb..5ab82bba61 100644 --- a/src/test/test-hostname-util.c +++ b/src/test/test-hostname-util.c @@ -140,6 +140,16 @@ static void test_read_etc_hostname(void) { unlink(path); } +static void test_hostname_malloc(void) { + _cleanup_free_ char *h = NULL, *l = NULL; + + assert_se(h = gethostname_malloc()); + log_info("hostname_malloc: \"%s\"", h); + + assert_se(l = gethostname_short_malloc()); + log_info("hostname_short_malloc: \"%s\"", l); +} + static void test_fallback_hostname(void) { if (!hostname_is_valid(FALLBACK_HOSTNAME, false)) { log_error("Configured fallback hostname \"%s\" is not valid.", FALLBACK_HOSTNAME); @@ -154,6 +164,7 @@ int main(int argc, char *argv[]) { test_hostname_is_valid(); test_hostname_cleanup(); test_read_etc_hostname(); + test_hostname_malloc(); test_fallback_hostname(); diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 7137e9fbd7..2702b36bdd 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -184,6 +184,7 @@ static const Specifier specifier_table[] = { { 'm', specifier_machine_id_safe, NULL }, { 'b', specifier_boot_id, NULL }, { 'H', specifier_host_name, NULL }, + { 'l', specifier_short_host_name, NULL }, { 'v', specifier_kernel_release, NULL }, { 'a', specifier_architecture, NULL }, { 'o', specifier_os_id, NULL }, -- 2.25.1