chiark / gitweb /
mac: also rename use_{smack,selinux,apparmor}() calls so that they share the new...
[elogind.git] / src / core / condition.c
index 658e8d6a4c000e47d9f6b769d9d3ec559ec6c44f..ec78169fc309355b2cf5ce4677e12e733e07daf1 100644 (file)
@@ -27,7 +27,7 @@
 #include <sys/statvfs.h>
 #include <fnmatch.h>
 
-#include <systemd/sd-id128.h>
+#include "sd-id128.h"
 #include "util.h"
 #include "condition.h"
 #include "virt.h"
@@ -45,21 +45,22 @@ static bool condition_test_security(Condition *c) {
         assert(c->type == CONDITION_SECURITY);
 
         if (streq(c->parameter, "selinux"))
-                return use_selinux() == !c->negate;
+                return mac_selinux_use() == !c->negate;
+        if (streq(c->parameter, "smack"))
+                return mac_smack_use() == !c->negate;
         if (streq(c->parameter, "apparmor"))
-                return use_apparmor() == !c->negate;
+                return mac_apparmor_use() == !c->negate;
         if (streq(c->parameter, "ima"))
                 return use_ima() == !c->negate;
-        if (streq(c->parameter, "smack"))
-                return use_smack() == !c->negate;
+
         return c->negate;
 }
 
 static bool condition_test_capability(Condition *c) {
+        _cleanup_fclose_ FILE *f = NULL;
         cap_value_t value;
-        FILE *f;
         char line[LINE_MAX];
-        unsigned long long capabilities = (unsigned long long) -1;
+        unsigned long long capabilities = -1;
 
         assert(c);
         assert(c->parameter);
@@ -86,11 +87,53 @@ static bool condition_test_capability(Condition *c) {
                 }
         }
 
-        fclose(f);
-
         return !!(capabilities & (1ULL << value)) == !c->negate;
 }
 
+static bool condition_test_needs_update(Condition *c) {
+        const char *p;
+        struct stat usr, other;
+
+        assert(c);
+        assert(c->parameter);
+        assert(c->type == CONDITION_NEEDS_UPDATE);
+
+        /* If the file system is read-only we shouldn't suggest an update */
+        if (path_is_read_only_fs(c->parameter) > 0)
+                return c->negate;
+
+        /* Any other failure means we should allow the condition to be true,
+         * so that we rather invoke too many update tools then too
+         * few. */
+
+        if (!path_is_absolute(c->parameter))
+                return !c->negate;
+
+        p = strappenda(c->parameter, "/.updated");
+        if (lstat(p, &other) < 0)
+                return !c->negate;
+
+        if (lstat("/usr/", &usr) < 0)
+                return !c->negate;
+
+        return (usr.st_mtim.tv_sec > other.st_mtim.tv_sec ||
+                (usr.st_mtim.tv_sec == other.st_mtim.tv_sec && usr.st_mtim.tv_nsec > other.st_mtim.tv_nsec)) == !c->negate;
+}
+
+static bool condition_test_first_boot(Condition *c) {
+        int r;
+
+        assert(c);
+        assert(c->parameter);
+        assert(c->type == CONDITION_FIRST_BOOT);
+
+        r = parse_boolean(c->parameter);
+        if (r < 0)
+                return c->negate;
+
+        return ((access("/run/systemd/first-boot", F_OK) >= 0) == !!r) == !c->negate;
+}
+
 static bool condition_test(Condition *c) {
         assert(c);
 
@@ -167,6 +210,15 @@ static bool condition_test(Condition *c) {
         case CONDITION_AC_POWER:
                 return condition_test_ac_power(c);
 
+        case CONDITION_ARCHITECTURE:
+                return condition_test_architecture(c);
+
+        case CONDITION_NEEDS_UPDATE:
+                return condition_test_needs_update(c);
+
+        case CONDITION_FIRST_BOOT:
+                return condition_test_first_boot(c);
+
         case CONDITION_NULL:
                 return !c->negate;