return false;
}
-static int condition_test_kernel_version(Condition *c) {
- enum {
- /* Listed in order of checking. Note that some comparators are prefixes of others, hence the longest
- * should be listed first. */
- LOWER_OR_EQUAL,
- GREATER_OR_EQUAL,
- LOWER,
- GREATER,
- EQUAL,
- _ORDER_MAX,
- };
+typedef enum {
+ /* Listed in order of checking. Note that some comparators are prefixes of others, hence the longest
+ * should be listed first. */
+ ORDER_LOWER_OR_EQUAL,
+ ORDER_GREATER_OR_EQUAL,
+ ORDER_LOWER,
+ ORDER_GREATER,
+ ORDER_EQUAL,
+ _ORDER_MAX,
+ _ORDER_INVALID = -1
+} OrderOperator;
+
+static OrderOperator parse_order(const char **s) {
static const char *const prefix[_ORDER_MAX] = {
- [LOWER_OR_EQUAL] = "<=",
- [GREATER_OR_EQUAL] = ">=",
- [LOWER] = "<",
- [GREATER] = ">",
- [EQUAL] = "=",
+ [ORDER_LOWER_OR_EQUAL] = "<=",
+ [ORDER_GREATER_OR_EQUAL] = ">=",
+ [ORDER_LOWER] = "<",
+ [ORDER_GREATER] = ">",
+ [ORDER_EQUAL] = "=",
};
- const char *p = NULL;
- struct utsname u;
- size_t i;
- int k;
-
- assert(c);
- assert(c->parameter);
- assert(c->type == CONDITION_KERNEL_VERSION);
- assert_se(uname(&u) >= 0);
+ OrderOperator i;
for (i = 0; i < _ORDER_MAX; i++) {
- p = startswith(c->parameter, prefix[i]);
- if (p)
- break;
+ const char *e;
+
+ e = startswith(*s, prefix[i]);
+ if (e) {
+ *s = e;
+ return i;
+ }
}
- /* No prefix? Then treat as glob string */
- if (!p)
- return fnmatch(skip_leading_chars(c->parameter, NULL), u.release, 0) == 0;
+ return _ORDER_INVALID;
+}
- k = str_verscmp(u.release, skip_leading_chars(p, NULL));
+static bool test_order(int k, OrderOperator p) {
- switch (i) {
+ switch (p) {
- case LOWER:
+ case ORDER_LOWER:
return k < 0;
- case LOWER_OR_EQUAL:
+ case ORDER_LOWER_OR_EQUAL:
return k <= 0;
- case EQUAL:
+ case ORDER_EQUAL:
return k == 0;
- case GREATER_OR_EQUAL:
+ case ORDER_GREATER_OR_EQUAL:
return k >= 0;
- case GREATER:
+ case ORDER_GREATER:
return k > 0;
default:
- assert_not_reached("Can't compare");
+ assert_not_reached("unknown order");
+
}
}
+static int condition_test_kernel_version(Condition *c) {
+ OrderOperator order;
+ struct utsname u;
+ const char *p;
+
+ assert(c);
+ assert(c->parameter);
+ assert(c->type == CONDITION_KERNEL_VERSION);
+
+ assert_se(uname(&u) >= 0);
+
+ p = c->parameter;
+ order = parse_order(&p);
+
+ /* No prefix? Then treat as glob string */
+ if (order < 0)
+ return fnmatch(skip_leading_chars(c->parameter, NULL), u.release, 0) == 0;
+
+ return test_order(str_verscmp(u.release, skip_leading_chars(p, NULL)), order);
+}
+
static int condition_test_user(Condition *c) {
uid_t id;
int r;