]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
compare: add flag for parse_compare_operator() to do equality/inequality comparison...
authorLennart Poettering <lennart@poettering.net>
Fri, 26 Aug 2022 14:56:04 +0000 (16:56 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 1 Sep 2022 21:15:14 +0000 (23:15 +0200)
This allows us to switch condition_test_osrelease() to use generic
version_or_fnmatch_compare() for executing the comparison.

src/shared/compare-operator.c
src/shared/compare-operator.h
src/shared/condition.c

index 1a19e4219d88bcdb6a09f61bce3ca227749356da..2bd64add7f5c899ebe212956630c810498c085cb 100644 (file)
@@ -27,12 +27,23 @@ CompareOperator parse_compare_operator(const char **s, CompareOperatorParseFlags
         for (CompareOperator i = 0; i < _COMPARE_OPERATOR_MAX; i++) {
                 const char *e;
 
+                if (!prefix[i])
+                        continue;
+
                 e = startswith(*s, prefix[i]);
                 if (e) {
                         if (!FLAGS_SET(flags, COMPARE_ALLOW_FNMATCH) && COMPARE_OPERATOR_IS_FNMATCH(i))
                                 return _COMPARE_OPERATOR_INVALID;
 
                         *s = e;
+
+                        if (FLAGS_SET(flags, COMPARE_EQUAL_BY_STRING)) {
+                                if (i == COMPARE_EQUAL)
+                                        return COMPARE_STRING_EQUAL;
+                                if (i == COMPARE_UNEQUAL)
+                                        return COMPARE_STRING_UNEQUAL;
+                        }
+
                         return i;
                 }
         }
@@ -74,6 +85,12 @@ int version_or_fnmatch_compare(
 
         switch (op) {
 
+        case COMPARE_STRING_EQUAL:
+                return streq_ptr(a, b);
+
+        case COMPARE_STRING_UNEQUAL:
+                return !streq_ptr(a, b);
+
         case COMPARE_FNMATCH_EQUAL:
                 return fnmatch(b, a, 0) != FNM_NOMATCH;
 
index f7137bba1af18f534f10928665e12f551423495d..363b4bdc759f3c82443a2d3e6ccb04811b570e8b 100644 (file)
@@ -8,6 +8,12 @@ typedef enum CompareOperator {
         /* Listed in order of checking. Note that some comparators are prefixes of others, hence the longest
          * should be listed first. */
 
+        /* Simple string compare operators */
+        _COMPARE_OPERATOR_STRING_FIRST,
+        COMPARE_STRING_EQUAL = _COMPARE_OPERATOR_STRING_FIRST,
+        COMPARE_STRING_UNEQUAL,
+        _COMPARE_OPERATOR_STRING_LAST = COMPARE_STRING_UNEQUAL,
+
         /* fnmatch() compare operators */
         _COMPARE_OPERATOR_FNMATCH_FIRST,
         COMPARE_FNMATCH_EQUAL = _COMPARE_OPERATOR_FNMATCH_FIRST,
@@ -28,6 +34,10 @@ typedef enum CompareOperator {
         _COMPARE_OPERATOR_INVALID = -EINVAL,
 } CompareOperator;
 
+static inline bool COMPARE_OPERATOR_IS_STRING(CompareOperator c) {
+        return c >= _COMPARE_OPERATOR_STRING_FIRST && c <= _COMPARE_OPERATOR_STRING_LAST;
+}
+
 static inline bool COMPARE_OPERATOR_IS_FNMATCH(CompareOperator c) {
         return c >= _COMPARE_OPERATOR_FNMATCH_FIRST && c <= _COMPARE_OPERATOR_FNMATCH_LAST;
 }
@@ -38,6 +48,7 @@ static inline bool COMPARE_OPERATOR_IS_ORDER(CompareOperator c) {
 
 typedef enum CompareOperatorParseFlags {
         COMPARE_ALLOW_FNMATCH   = 1 << 0,
+        COMPARE_EQUAL_BY_STRING = 1 << 1,
 } CompareOperatorParseFlags;
 
 CompareOperator parse_compare_operator(const char **s, CompareOperatorParseFlags flags);
index 1f9e6d221f2bbe3945d657c51e7937b37da8b68f..db7a02db7d71b6f8f5d0c66c0a70a5d76fe548cc 100644 (file)
@@ -248,7 +248,6 @@ static int condition_test_osrelease(Condition *c, char **env) {
                 _cleanup_free_ char *key = NULL, *condition = NULL, *actual_value = NULL;
                 CompareOperator operator;
                 const char *word;
-                bool matches;
 
                 r = extract_first_word(&parameter, &condition, NULL, EXTRACT_UNQUOTE);
                 if (r < 0)
@@ -267,7 +266,7 @@ static int condition_test_osrelease(Condition *c, char **env) {
                                         "Failed to parse parameter, key/value format expected: %m");
 
                 /* Do not allow whitespace after the separator, as that's not a valid os-release format */
-                operator = parse_compare_operator(&word, 0);
+                operator = parse_compare_operator(&word, COMPARE_EQUAL_BY_STRING);
                 if (operator < 0 || isempty(word) || strchr(WHITESPACE, *word) != NULL)
                         return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
                                         "Failed to parse parameter, key/value format expected: %m");
@@ -276,15 +275,10 @@ static int condition_test_osrelease(Condition *c, char **env) {
                 if (r < 0)
                         return log_debug_errno(r, "Failed to parse os-release: %m");
 
-                /* Might not be comparing versions, so do exact string matching */
-                if (operator == COMPARE_EQUAL)
-                        matches = streq_ptr(actual_value, word);
-                else if (operator == COMPARE_UNEQUAL)
-                        matches = !streq_ptr(actual_value, word);
-                else
-                        matches = test_order(strverscmp_improved(actual_value, word), operator);
-
-                if (!matches)
+                r = version_or_fnmatch_compare(operator, actual_value, word);
+                if (r < 0)
+                        return r;
+                if (!r)
                         return false;
         }