]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
condition: allow fnmatch() matches in ConditionKernelVersion=
authorLennart Poettering <lennart@poettering.net>
Mon, 29 Aug 2022 09:10:18 +0000 (11:10 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 1 Sep 2022 21:16:13 +0000 (23:16 +0200)
This is mostly to make things systematic, and brings no new
functionality, as not specifying any operator is identical to prefixing
with =$ anyway.

man/systemd.unit.xml
src/shared/condition.c

index c5ba817579f79e78c79cb552385522f470b121e0..9dd02c3060413a8b84137f0df2fedbd315892776 100644 (file)
           <listitem><para><varname>ConditionKernelVersion=</varname> may be used to check whether the kernel
           version (as reported by <command>uname -r</command>) matches a certain expression (or if prefixed
           with the exclamation mark does not match it). The argument must be a list of (potentially quoted)
-          expressions.  For each of the expressions, if it starts with one of <literal>&lt;</literal>,
-          <literal>&lt;=</literal>, <literal>=</literal> (or <literal>==</literal>), <literal>!=</literal>
-          (or <literal>&lt;&gt;</literal>), <literal>&gt;=</literal>, <literal>&gt;</literal> a relative
-          version comparison is done, otherwise the specified string is matched with shell-style
-          globs.</para>
+          expressions.  Each expression starts with one of <literal>&lt;</literal>, <literal>&lt;=</literal>,
+          <literal>=</literal> (or <literal>==</literal>), <literal>!=</literal> (or
+          <literal>&lt;&gt;</literal>), <literal>&gt;=</literal>, <literal>&gt;</literal> for a relative
+          version comparison, or <literal>=$</literal>, <literal>!=$</literal> for a shell-style glob
+          match. If no operator is specified <literal>=$</literal> is implied.</para>
 
           <para>Note that using the kernel version string is an unreliable way to determine which features
           are supported by a kernel, because of the widespread practice of backporting drivers, features, and
index 2d9979b9c45ff0809ae30045fe125d63ddf334e8..f893937156fa25d05c29f5716716d42ce97b2dc7 100644 (file)
@@ -206,30 +206,30 @@ static int condition_test_kernel_version(Condition *c, char **env) {
                         break;
 
                 s = strstrip(word);
-                operator = parse_compare_operator(&s, 0);
-                if (operator >= 0) {
-                        s += strspn(s, WHITESPACE);
-                        if (isempty(s)) {
-                                if (first) {
-                                        /* For backwards compatibility, allow whitespace between the operator and
-                                         * value, without quoting, but only in the first expression. */
-                                        word = mfree(word);
-                                        r = extract_first_word(&p, &word, NULL, 0);
-                                        if (r < 0)
-                                                return log_debug_errno(r, "Failed to parse condition string \"%s\": %m", p);
-                                        if (r == 0)
-                                                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unexpected end of expression: %s", p);
-                                        s = word;
-                                } else
+                operator = parse_compare_operator(&s, COMPARE_ALLOW_FNMATCH);
+                if (operator < 0) /* No prefix? Then treat as glob string */
+                        operator = COMPARE_FNMATCH_EQUAL;
+
+                s += strspn(s, WHITESPACE);
+                if (isempty(s)) {
+                        if (first) {
+                                /* For backwards compatibility, allow whitespace between the operator and
+                                 * value, without quoting, but only in the first expression. */
+                                word = mfree(word);
+                                r = extract_first_word(&p, &word, NULL, 0);
+                                if (r < 0)
+                                        return log_debug_errno(r, "Failed to parse condition string \"%s\": %m", p);
+                                if (r == 0)
                                         return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unexpected end of expression: %s", p);
-                        }
-
-                        r = test_order(strverscmp_improved(u.release, s), operator);
-                } else
-                        /* No prefix? Then treat as glob string */
-                        r = fnmatch(s, u.release, 0) == 0;
+                                s = word;
+                        } else
+                                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unexpected end of expression: %s", p);
+                }
 
-                if (r == 0)
+                r = version_or_fnmatch_compare(operator, u.release, s);
+                if (r < 0)
+                        return r;
+                if (!r)
                         return false;
 
                 first = false;