chiark / gitweb /
condition: rewrite condition_test_kernel_command_line() based on unquote_first_word()
[elogind.git] / src / shared / condition-util.c
index d31c4bf5b17958e276303c2832ddd9e6640cf18f..026b6a8712593e972ca0166d61ec1fc84bc31244 100644 (file)
 #include <sys/statvfs.h>
 #include <fnmatch.h>
 
-#include <systemd/sd-id128.h>
+#include "systemd/sd-id128.h"
 #include "util.h"
 #include "condition-util.h"
 #include "virt.h"
 #include "path-util.h"
 #include "fileio.h"
 #include "unit.h"
+#include "architecture.h"
 
 Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) {
         Condition *c;
@@ -73,11 +74,10 @@ void condition_free_list(Condition *first) {
 }
 
 bool condition_test_kernel_command_line(Condition *c) {
-        char *line, *w, *state, *word = NULL;
+        _cleanup_free_ char *line = NULL;
+        const char *p;
         bool equal;
         int r;
-        size_t l, pl;
-        bool found = false;
 
         assert(c);
         assert(c->parameter);
@@ -90,38 +90,34 @@ bool condition_test_kernel_command_line(Condition *c) {
                 return c->negate;
 
         equal = !!strchr(c->parameter, '=');
-        pl = strlen(c->parameter);
-
-        FOREACH_WORD_QUOTED(w, l, line, state) {
-
-                free(word);
-                word = strndup(w, l);
-                if (!word)
-                        break;
-
-                if (equal) {
-                        if (streq(word, c->parameter)) {
-                                found = true;
-                                break;
-                        }
-                } else {
-                        if (startswith(word, c->parameter) && (word[pl] == '=' || word[pl] == 0)) {
-                                found = true;
-                                break;
-                        }
+        p = line;
+
+        for (;;) {
+                _cleanup_free_ char *word = NULL;
+                bool found;
+
+                r = unquote_first_word(&p, &word);
+                if (r <= 0)
+                        return c->negate;
+
+                if (equal)
+                        found = streq(word, c->parameter);
+                else {
+                        const char *f;
+
+                        f = startswith(word, c->parameter);
+                        found = f && (*f == '=' || *f == 0);
                 }
 
+                if (found)
+                        return !c->negate;
         }
 
-        free(word);
-        free(line);
-
-        return found == !c->negate;
+        return c->negate;
 }
 
 bool condition_test_virtualization(Condition *c) {
-        int b;
-        Virtualization v;
+        int b, v;
         const char *id;
 
         assert(c);
@@ -154,11 +150,32 @@ bool condition_test_virtualization(Condition *c) {
         return (v > 0 && streq(c->parameter, id)) == !c->negate;
 }
 
+bool condition_test_architecture(Condition *c) {
+        Architecture a, b;
+
+        assert(c);
+        assert(c->parameter);
+        assert(c->type == CONDITION_ARCHITECTURE);
+
+        a = uname_architecture();
+        if (a < 0)
+                return c->negate;
+
+        if (streq(c->parameter, "native"))
+                b = native_architecture();
+        else
+                b = architecture_from_string(c->parameter);
+
+        if (b < 0)
+                return c->negate;
+
+        return (a == b) == !c->negate;
+}
+
 bool condition_test_host(Condition *c) {
+        _cleanup_free_ char *h = NULL;
         sd_id128_t x, y;
-        char *h;
         int r;
-        bool b;
 
         assert(c);
         assert(c->parameter);
@@ -170,17 +187,14 @@ bool condition_test_host(Condition *c) {
                 if (r < 0)
                         return c->negate;
 
-                return sd_id128_equal(x, y);
+                return sd_id128_equal(x, y) == !c->negate;
         }
 
         h = gethostname_malloc();
         if (!h)
                 return c->negate;
 
-        b = fnmatch(c->parameter, h, FNM_CASEFOLD) == 0;
-        free(h);
-
-        return b == !c->negate;
+        return (fnmatch(c->parameter, h, FNM_CASEFOLD) == 0) == !c->negate;
 }
 
 bool condition_test_ac_power(Condition *c) {
@@ -237,6 +251,9 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
         [CONDITION_CAPABILITY] = "ConditionCapability",
         [CONDITION_HOST] = "ConditionHost",
         [CONDITION_AC_POWER] = "ConditionACPower",
+        [CONDITION_ARCHITECTURE] = "ConditionArchitecture",
+        [CONDITION_NEEDS_UPDATE] = "ConditionNeedsUpdate",
+        [CONDITION_FIRST_BOOT] = "ConditionFirstBoot",
         [CONDITION_NULL] = "ConditionNull"
 };