]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
cap-list: add capability_set_to_string_negative()
authorLennart Poettering <lennart@poettering.net>
Wed, 22 Feb 2023 12:05:07 +0000 (13:05 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 22 Feb 2023 22:45:40 +0000 (23:45 +0100)
src/basic/cap-list.c
src/basic/cap-list.h
src/test/test-cap-list.c

index b95b9b140eedda1df9619d678656f85b0f792a3e..80d48c142e3bb14ded03589159d3563e35a2fe2b 100644 (file)
@@ -103,6 +103,37 @@ int capability_set_to_string(uint64_t set, char **ret) {
         return 0;
 }
 
+int capability_set_to_string_negative(uint64_t set, char **ret) {
+        _cleanup_free_ char *a = NULL, *b = NULL;
+        int r;
+
+        assert(ret);
+
+        /* Format the specified capability mask both in positive way (i.e. just listing caps) and in negative
+         * way (i.e. listing only caps that are missing from the full set) and return the shorter version of
+         * the two. */
+
+        r = capability_set_to_string(set, &a);
+        if (r < 0)
+                return r;
+
+        r = capability_set_to_string(~set & all_capabilities(), &b);
+        if (r < 0)
+                return r;
+
+        if (strlen(a) <= 1 + strlen(b))
+                *ret = TAKE_PTR(a);
+        else {
+                char *c = strjoin("~", b);
+                if (!c)
+                        return -ENOMEM;
+
+                *ret = c;
+        }
+
+        return 0;
+}
+
 int capability_set_to_strv(uint64_t set, char ***ret) {
         _cleanup_strv_free_ char **l = NULL;
         int r;
index fdf4366de0e11e6d7b3298d91369fd5c08b04172..3028197b56a8066bc7e09346af08cfc7fa2f70ff 100644 (file)
@@ -16,5 +16,6 @@ int capability_from_name(const char *name);
 int capability_list_length(void);
 
 int capability_set_to_string(uint64_t set, char **ret);
+int capability_set_to_string_negative(uint64_t set, char **ret);
 int capability_set_to_strv(uint64_t set, char ***ret);
 int capability_set_from_string(const char *s, uint64_t *ret);
index 42503d294c6a2086745e7b2ff480007aafa65094..a9cbf695b9012299880d2fb69fe21e2ee89d8ea8 100644 (file)
@@ -7,6 +7,7 @@
 #include "cap-list.h"
 #include "capability-util.h"
 #include "parse-util.h"
+#include "random-util.h"
 #include "string-util.h"
 #include "strv.h"
 #include "tests.h"
@@ -151,4 +152,26 @@ TEST(capability_set_to_string) {
                 test_capability_set_to_string_invalid(all_capabilities() + 1);
 }
 
+TEST(capability_set_to_string_negative) {
+
+        for (unsigned i = 0; i < 150; i++) {
+                _cleanup_free_ char *a = NULL, *b = NULL;
+
+                uint64_t m =
+                        random_u64() % (UINT64_C(1) << (cap_last_cap() + 1));
+
+                assert_se(capability_set_to_string(m, &a) >= 0);
+                assert_se(capability_set_to_string_negative(m, &b) >= 0);
+
+                printf("%s (%zu) → ", a, strlen(a));
+
+                if (streq(a, b))
+                        printf("same\n");
+                else
+                        printf("%s (%zu)\n", b, strlen(b));
+
+                assert_se(strlen(b) <= strlen(a));
+        }
+}
+
 DEFINE_TEST_MAIN(LOG_INFO);