]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: var-expand - Add os and os-version to system: key
authorKarl Fleischmann <karl.fleischmann@open-xchange.com>
Tue, 23 Jan 2024 17:17:10 +0000 (18:17 +0100)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 12 Feb 2025 10:34:12 +0000 (12:34 +0200)
src/lib/test-var-expand.c
src/lib/var-expand.c

index 3cbe22b5ba4689d632be0ba142e26453a9d71a37..77d29d9717ecc50d726ab1ab11b4c469fe9bfb36 100644 (file)
@@ -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();
 }
 
index 41aa533d282c6472db01ec6bd9e43047b3be5293..883bb3bff0ecc5e99dab3acd3f62e2a2f965e3c7 100644 (file)
 #include <unistd.h>
 #include <ctype.h>
 
+#ifdef HAVE_SYS_UTSNAME_H
+#  include <sys/utsname.h>
+#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;
 }