From: Karl Fleischmann Date: Tue, 23 Jan 2024 17:17:10 +0000 (+0100) Subject: lib: var-expand - Add os and os-version to system: key X-Git-Tag: 2.4.1~1047 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f7814bcd8203f78eced5a69448db2fb635458e53;p=thirdparty%2Fdovecot%2Fcore.git lib: var-expand - Add os and os-version to system: key --- diff --git a/src/lib/test-var-expand.c b/src/lib/test-var-expand.c index 3cbe22b5ba..77d29d9717 100644 --- a/src/lib/test-var-expand.c +++ b/src/lib/test-var-expand.c @@ -570,6 +570,20 @@ static void test_var_expand_system() test_assert_cmp_idx(ret, ==, test->ret, i); test_assert_strcmp_idx(str_c(dest), test->out, i); } + + /* Check the expansion of os/os-version depending on whether uname() + succeeds. */ + struct utsname utsname_result; + if (uname(&utsname_result) == 0) { + str_truncate(dest, 0); + test_assert(var_expand(dest, "%{system:os}", table, &error) == 1); + test_assert(strcmp(utsname_result.sysname, str_c(dest)) == 0); + + str_truncate(dest, 0); + test_assert(var_expand(dest, "%{system:os-version}", table, &error) == 1); + test_assert(strcmp(utsname_result.release, str_c(dest)) == 0); + } + test_end(); } diff --git a/src/lib/var-expand.c b/src/lib/var-expand.c index 41aa533d28..883bb3bff0 100644 --- a/src/lib/var-expand.c +++ b/src/lib/var-expand.c @@ -20,6 +20,10 @@ #include #include +#ifdef HAVE_SYS_UTSNAME_H +# include +#endif + #define ENV_CPU_COUNT "NCPU" #define TABLE_LAST(t) \ @@ -32,6 +36,11 @@ struct var_expand_modifier { static ARRAY(struct var_expand_extension_func_table) var_expand_extensions; +enum os_default_type { + OS_DEFAULT_TYPE_SYSNAME, + OS_DEFAULT_TYPE_RELEASE, +}; + static const char * m_str_lcase(const char *str, struct var_expand_context *ctx ATTR_UNUSED) { @@ -401,6 +410,37 @@ var_expand_process(struct var_expand_context *ctx ATTR_UNUSED, return 1; } +static struct utsname utsname_result; +static bool utsname_set = FALSE; + +static int +var_expand_system_os(enum os_default_type type, + const char **value_r, const char **error_r) +{ + if (!utsname_set) { + utsname_set = TRUE; + + if (uname(&utsname_result) < 0) { + *error_r = t_strdup_printf("uname() failed: %m"); + i_zero(&utsname_result); + return -1; + } + } + + switch (type) { + case OS_DEFAULT_TYPE_SYSNAME: + *value_r = utsname_result.sysname; + return 1; + case OS_DEFAULT_TYPE_RELEASE: + *value_r = utsname_result.release; + return 1; + default: + break; + } + + i_unreached(); +} + static int var_expand_system(struct var_expand_context *ctx ATTR_UNUSED, const char *key, const char *field, @@ -421,7 +461,12 @@ var_expand_system(struct var_expand_context *ctx ATTR_UNUSED, } else if (strcmp(field, "hostname") == 0) { *result_r = my_hostname; return 1; - } + } else if (strcmp(field, "os") == 0) + return var_expand_system_os(OS_DEFAULT_TYPE_SYSNAME, result_r, + error_r); + else if (strcmp(field, "os-version") == 0) + return var_expand_system_os(OS_DEFAULT_TYPE_RELEASE, result_r, + error_r); *error_r = t_strdup_printf("Unsupported system key '%s'", field); return 0; }