bus-util: introduce bus_message_print_all_properties()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 19 Mar 2018 15:37:00 +0000 (00:37 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 19 Mar 2018 15:44:37 +0000 (00:44 +0900)
Then, use it where applicable.

src/login/loginctl.c
src/machine/machinectl.c
src/shared/bus-util.c
src/shared/bus-util.h
src/systemctl/systemctl.c

index 403ba40..7554fae 100644 (file)
@@ -688,40 +688,41 @@ static int print_seat_status_info(sd_bus *bus, const char *path, bool *new_line)
 
 #define property(name, fmt, ...)                                        \
         do {                                                            \
-                if (arg_value)                                          \
+                if (value)                                              \
                         printf(fmt "\n", __VA_ARGS__);                  \
                 else                                                    \
                         printf("%s=" fmt "\n", name, __VA_ARGS__);      \
         } while (0)
 
-static int print_property(const char *name, sd_bus_message *m, const char *contents) {
+static int print_property(const char *name, sd_bus_message *m, bool value, bool all) {
+        char type;
+        const char *contents;
         int r;
 
         assert(name);
         assert(m);
-        assert(contents);
 
-        if (arg_property && !strv_find(arg_property, name))
-                /* skip what we didn't read */
-                return sd_bus_message_skip(m, contents);
+        r = sd_bus_message_peek_type(m, &type, &contents);
+        if (r < 0)
+                return r;
 
-        switch (contents[0]) {
+        switch (type) {
 
-        case SD_BUS_TYPE_STRUCT_BEGIN:
+        case SD_BUS_TYPE_STRUCT:
 
-                if (contents[1] == SD_BUS_TYPE_STRING && STR_IN_SET(name, "Display", "Seat", "ActiveSession")) {
+                if (contents[0] == SD_BUS_TYPE_STRING && STR_IN_SET(name, "Display", "Seat", "ActiveSession")) {
                         const char *s;
 
                         r = sd_bus_message_read(m, "(so)", &s, NULL);
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        if (arg_all || !isempty(s))
+                        if (all || !isempty(s))
                                 property(name, "%s", s);
 
-                        return 0;
+                        return 1;
 
-                } else if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "User")) {
+                } else if (contents[0] == SD_BUS_TYPE_UINT32 && streq(name, "User")) {
                         uint32_t uid;
 
                         r = sd_bus_message_read(m, "(uo)", &uid, NULL);
@@ -734,14 +735,13 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
                         }
 
                         property(name, UID_FMT, uid);
-                        return 0;
+                        return 1;
                 }
-
                 break;
 
         case SD_BUS_TYPE_ARRAY:
 
-                if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Sessions")) {
+                if (contents[0] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Sessions")) {
                         const char *s;
                         bool space = false;
 
@@ -749,7 +749,7 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        if (!arg_value)
+                        if (!value)
                                 printf("%s=", name);
 
                         while ((r = sd_bus_message_read(m, "(so)", &s, NULL)) > 0) {
@@ -757,7 +757,7 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
                                 space = true;
                         }
 
-                        if (space || !arg_value)
+                        if (space || !value)
                                 printf("\n");
 
                         if (r < 0)
@@ -767,25 +767,11 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        return 0;
+                        return 1;
                 }
-
                 break;
         }
 
-        r = bus_print_property(name, m, arg_value, arg_all);
-        if (r < 0)
-                return bus_log_parse_error(r);
-
-        if (r == 0) {
-                r = sd_bus_message_skip(m, contents);
-                if (r < 0)
-                        return bus_log_parse_error(r);
-
-                if (arg_all)
-                        printf("%s=[unprintable]\n", name);
-        }
-
         return 0;
 }
 
@@ -798,58 +784,12 @@ static int show_properties(sd_bus *bus, const char *path, bool *new_line) {
         assert(path);
         assert(new_line);
 
-        r = sd_bus_call_method(
-                        bus,
-                        "org.freedesktop.login1",
-                        path,
-                        "org.freedesktop.DBus.Properties",
-                        "GetAll",
-                        &error,
-                        &reply,
-                        "s", "");
-        if (r < 0)
-                return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r));
-
-        r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
-        if (r < 0)
-                return bus_log_parse_error(r);
-
         if (*new_line)
                 printf("\n");
 
         *new_line = true;
 
-        while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
-                const char *name, *contents;
-
-                r = sd_bus_message_read(reply, "s", &name);
-                if (r < 0)
-                        return bus_log_parse_error(r);
-
-                r = sd_bus_message_peek_type(reply, NULL, &contents);
-                if (r < 0)
-                        return bus_log_parse_error(r);
-
-                r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
-                if (r < 0)
-                        return bus_log_parse_error(r);
-
-                r = print_property(name, reply, contents);
-                if (r < 0)
-                        return r;
-
-                r = sd_bus_message_exit_container(reply);
-                if (r < 0)
-                        return bus_log_parse_error(r);
-
-                r = sd_bus_message_exit_container(reply);
-                if (r < 0)
-                        return bus_log_parse_error(r);
-        }
-        if (r < 0)
-                return bus_log_parse_error(r);
-
-        r = sd_bus_message_exit_container(reply);
+        r = bus_print_all_properties(bus, "org.freedesktop.login1", path, print_property, arg_property, arg_value, arg_all, NULL);
         if (r < 0)
                 return bus_log_parse_error(r);
 
index d4b8c15..78a7ce2 100644 (file)
@@ -838,7 +838,7 @@ static int show_machine_properties(sd_bus *bus, const char *path, bool *new_line
 
         *new_line = true;
 
-        r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, arg_property, arg_value, arg_all);
+        r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, NULL, arg_property, arg_value, arg_all, NULL);
         if (r < 0)
                 log_error_errno(r, "Could not get properties: %m");
 
@@ -1176,7 +1176,7 @@ static int show_image_properties(sd_bus *bus, const char *path, bool *new_line)
 
         *new_line = true;
 
-        r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, arg_property, arg_value, arg_all);
+        r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, NULL, arg_property, arg_value, arg_all, NULL);
         if (r < 0)
                 log_error_errno(r, "Could not get properties: %m");
 
index 2336338..8061af1 100644 (file)
@@ -656,15 +656,15 @@ int bus_connect_user_systemd(sd_bus **_bus) {
                         printf("%s=" fmt "\n", name, __VA_ARGS__);      \
         } while (0)
 
-int bus_print_property(const char *name, sd_bus_message *property, bool value, bool all) {
+int bus_print_property(const char *name, sd_bus_message *m, bool value, bool all) {
         char type;
         const char *contents;
         int r;
 
         assert(name);
-        assert(property);
+        assert(m);
 
-        r = sd_bus_message_peek_type(property, &type, &contents);
+        r = sd_bus_message_peek_type(m, &type, &contents);
         if (r < 0)
                 return r;
 
@@ -673,7 +673,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b
         case SD_BUS_TYPE_STRING: {
                 const char *s;
 
-                r = sd_bus_message_read_basic(property, type, &s);
+                r = sd_bus_message_read_basic(m, type, &s);
                 if (r < 0)
                         return r;
 
@@ -692,7 +692,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b
         case SD_BUS_TYPE_BOOLEAN: {
                 int b;
 
-                r = sd_bus_message_read_basic(property, type, &b);
+                r = sd_bus_message_read_basic(m, type, &b);
                 if (r < 0)
                         return r;
 
@@ -704,7 +704,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b
         case SD_BUS_TYPE_UINT64: {
                 uint64_t u;
 
-                r = sd_bus_message_read_basic(property, type, &u);
+                r = sd_bus_message_read_basic(m, type, &u);
                 if (r < 0)
                         return r;
 
@@ -781,7 +781,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b
         case SD_BUS_TYPE_INT64: {
                 int64_t i;
 
-                r = sd_bus_message_read_basic(property, type, &i);
+                r = sd_bus_message_read_basic(m, type, &i);
                 if (r < 0)
                         return r;
 
@@ -793,7 +793,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b
         case SD_BUS_TYPE_UINT32: {
                 uint32_t u;
 
-                r = sd_bus_message_read_basic(property, type, &u);
+                r = sd_bus_message_read_basic(m, type, &u);
                 if (r < 0)
                         return r;
 
@@ -818,7 +818,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b
         case SD_BUS_TYPE_INT32: {
                 int32_t i;
 
-                r = sd_bus_message_read_basic(property, type, &i);
+                r = sd_bus_message_read_basic(m, type, &i);
                 if (r < 0)
                         return r;
 
@@ -829,7 +829,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b
         case SD_BUS_TYPE_DOUBLE: {
                 double d;
 
-                r = sd_bus_message_read_basic(property, type, &d);
+                r = sd_bus_message_read_basic(m, type, &d);
                 if (r < 0)
                         return r;
 
@@ -842,11 +842,11 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b
                         bool first = true;
                         const char *str;
 
-                        r = sd_bus_message_enter_container(property, SD_BUS_TYPE_ARRAY, contents);
+                        r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, contents);
                         if (r < 0)
                                 return r;
 
-                        while ((r = sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str)) > 0) {
+                        while ((r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &str)) > 0) {
                                 bool good;
 
                                 if (first && !value)
@@ -868,7 +868,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b
                         if (!first || all)
                                 puts("");
 
-                        r = sd_bus_message_exit_container(property);
+                        r = sd_bus_message_exit_container(m);
                         if (r < 0)
                                 return r;
 
@@ -878,7 +878,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b
                         const uint8_t *u;
                         size_t n;
 
-                        r = sd_bus_message_read_array(property, SD_BUS_TYPE_BYTE, (const void**) &u, &n);
+                        r = sd_bus_message_read_array(m, SD_BUS_TYPE_BYTE, (const void**) &u, &n);
                         if (r < 0)
                                 return r;
 
@@ -900,7 +900,7 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b
                         uint32_t *u;
                         size_t n;
 
-                        r = sd_bus_message_read_array(property, SD_BUS_TYPE_UINT32, (const void**) &u, &n);
+                        r = sd_bus_message_read_array(m, SD_BUS_TYPE_UINT32, (const void**) &u, &n);
                         if (r < 0)
                                 return r;
 
@@ -925,81 +925,118 @@ int bus_print_property(const char *name, sd_bus_message *property, bool value, b
         return 0;
 }
 
-int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool value, bool all) {
-        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
-        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-        int r;
+int bus_message_print_all_properties(
+                sd_bus_message *m,
+                bus_message_print_t func,
+                char **filter,
+                bool value,
+                bool all,
+                Set **found_properties) {
 
-        assert(bus);
-        assert(path);
+        int r;
 
-        r = sd_bus_call_method(bus,
-                        dest,
-                        path,
-                        "org.freedesktop.DBus.Properties",
-                        "GetAll",
-                        &error,
-                        &reply,
-                        "s", "");
-        if (r < 0)
-                return r;
+        assert(m);
 
-        r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
+        r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
         if (r < 0)
                 return r;
 
-        while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
+        while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
                 const char *name;
                 const char *contents;
 
-                r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &name);
+                r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &name);
                 if (r < 0)
                         return r;
 
+                if (found_properties) {
+                        r = set_ensure_allocated(found_properties, &string_hash_ops);
+                        if (r < 0)
+                                return log_oom();
+
+                        r = set_put(*found_properties, name);
+                        if (r < 0 && r != EEXIST)
+                                return log_oom();
+                }
+
                 if (!filter || strv_find(filter, name)) {
-                        r = sd_bus_message_peek_type(reply, NULL, &contents);
+                        r = sd_bus_message_peek_type(m, NULL, &contents);
                         if (r < 0)
                                 return r;
 
-                        r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
+                        r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
                         if (r < 0)
                                 return r;
 
-                        r = bus_print_property(name, reply, value, all);
+                        if (func)
+                                r = func(name, m, value, all);
+                        if (!func || r == 0)
+                                r = bus_print_property(name, m, value, all);
                         if (r < 0)
                                 return r;
                         if (r == 0) {
                                 if (all)
                                         printf("%s=[unprintable]\n", name);
                                 /* skip what we didn't read */
-                                r = sd_bus_message_skip(reply, contents);
+                                r = sd_bus_message_skip(m, contents);
                                 if (r < 0)
                                         return r;
                         }
 
-                        r = sd_bus_message_exit_container(reply);
+                        r = sd_bus_message_exit_container(m);
                         if (r < 0)
                                 return r;
                 } else {
-                        r = sd_bus_message_skip(reply, "v");
+                        r = sd_bus_message_skip(m, "v");
                         if (r < 0)
                                 return r;
                 }
 
-                r = sd_bus_message_exit_container(reply);
+                r = sd_bus_message_exit_container(m);
                 if (r < 0)
                         return r;
         }
         if (r < 0)
                 return r;
 
-        r = sd_bus_message_exit_container(reply);
+        r = sd_bus_message_exit_container(m);
         if (r < 0)
                 return r;
 
         return 0;
 }
 
+int bus_print_all_properties(
+                sd_bus *bus,
+                const char *dest,
+                const char *path,
+                bus_message_print_t func,
+                char **filter,
+                bool value,
+                bool all,
+                Set **found_properties) {
+
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        int r;
+
+        assert(bus);
+        assert(path);
+
+        r = sd_bus_call_method(bus,
+                        dest,
+                        path,
+                        "org.freedesktop.DBus.Properties",
+                        "GetAll",
+                        &error,
+                        &reply,
+                        "s", "");
+        if (r < 0)
+                return r;
+
+        return bus_message_print_all_properties(reply, func, filter, value, all, found_properties);
+}
+
 int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
         sd_id128_t *p = userdata;
         const void *v;
index 5e1fe89..e42198f 100644 (file)
@@ -76,8 +76,11 @@ int bus_connect_user_systemd(sd_bus **_bus);
 int bus_connect_transport(BusTransport transport, const char *host, bool user, sd_bus **bus);
 int bus_connect_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus);
 
+typedef int (*bus_message_print_t) (const char *name, sd_bus_message *m, bool value, bool all);
+
 int bus_print_property(const char *name, sd_bus_message *property, bool value, bool all);
-int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool value, bool all);
+int bus_message_print_all_properties(sd_bus_message *m, bus_message_print_t func, char **filter, bool value, bool all, Set **found_properties);
+int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, bus_message_print_t func, char **filter, bool value, bool all, Set **found_properties);
 
 int bus_property_get_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
 int bus_property_set_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *error);
index c90cf0a..cae4ff0 100644 (file)
@@ -4564,7 +4564,9 @@ static int map_exec(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_e
                         printf("%s=" fmt "\n", name, __VA_ARGS__);      \
         } while (0)
 
-static int print_property(const char *name, sd_bus_message *m, const char *contents) {
+static int print_property(const char *name, sd_bus_message *m, bool value, bool all) {
+        char bus_type;
+        const char *contents;
         int r;
 
         assert(name);
@@ -4573,17 +4575,15 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
         /* This is a low-level property printer, see
          * print_status_info() for the nicer output */
 
-        if (arg_properties && !strv_find(arg_properties, name)) {
-                /* skip what we didn't read */
-                r = sd_bus_message_skip(m, contents);
+        r = sd_bus_message_peek_type(m, &bus_type, &contents);
+        if (r < 0)
                 return r;
-        }
 
-        switch (contents[0]) {
+        switch (bus_type) {
 
-        case SD_BUS_TYPE_STRUCT_BEGIN:
+        case SD_BUS_TYPE_STRUCT:
 
-                if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
+                if (contents[0] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
                         uint32_t u;
 
                         r = sd_bus_message_read(m, "(uo)", &u, NULL);
@@ -4592,34 +4592,34 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
 
                         if (u > 0)
                                 print_prop(name, "%"PRIu32, u);
-                        else if (arg_all)
+                        else if (all)
                                 print_prop(name, "%s", "");
 
-                        return 0;
+                        return 1;
 
-                } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
+                } else if (contents[0] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
                         const char *s;
 
                         r = sd_bus_message_read(m, "(so)", &s, NULL);
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        if (arg_all || !isempty(s))
+                        if (all || !isempty(s))
                                 print_prop(name, "%s", s);
 
-                        return 0;
+                        return 1;
 
-                } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
+                } else if (contents[0] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
                         const char *a = NULL, *b = NULL;
 
                         r = sd_bus_message_read(m, "(ss)", &a, &b);
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        if (arg_all || !isempty(a) || !isempty(b))
+                        if (all || !isempty(a) || !isempty(b))
                                 print_prop(name, "%s \"%s\"", strempty(a), strempty(b));
 
-                        return 0;
+                        return 1;
                 } else if (streq_ptr(name, "SystemCallFilter")) {
                         _cleanup_strv_free_ char **l = NULL;
                         int whitelist;
@@ -4640,11 +4640,11 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        if (arg_all || whitelist || !strv_isempty(l)) {
+                        if (all || whitelist || !strv_isempty(l)) {
                                 bool first = true;
                                 char **i;
 
-                                if (!arg_value) {
+                                if (!value) {
                                         fputs(name, stdout);
                                         fputc('=', stdout);
                                 }
@@ -4663,14 +4663,14 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
                                 fputc('\n', stdout);
                         }
 
-                        return 0;
+                        return 1;
                 }
 
                 break;
 
         case SD_BUS_TYPE_ARRAY:
 
-                if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
+                if (contents[0] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
                         const char *path;
                         int ignore;
 
@@ -4688,9 +4688,9 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        return 0;
+                        return 1;
 
-                } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
+                } else if (contents[0] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
                         const char *type, *path;
 
                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
@@ -4706,9 +4706,9 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        return 0;
+                        return 1;
 
-                } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
+                } else if (contents[0] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
                         const char *type, *path;
 
                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
@@ -4724,21 +4724,21 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        return 0;
+                        return 1;
 
-                } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "TimersMonotonic")) {
+                } else if (contents[0] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "TimersMonotonic")) {
                         const char *base;
-                        uint64_t value, next_elapse;
+                        uint64_t v, next_elapse;
 
                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
+                        while ((r = sd_bus_message_read(m, "(stt)", &base, &v, &next_elapse)) > 0) {
                                 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
 
                                 print_prop(name, "{ %s=%s ; next_elapse=%s }", base,
-                                           format_timespan(timespan1, sizeof(timespan1), value, 0),
+                                           format_timespan(timespan1, sizeof(timespan1), v, 0),
                                            format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
                         }
                         if (r < 0)
@@ -4748,9 +4748,9 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        return 0;
+                        return 1;
 
-                } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "TimersCalendar")) {
+                } else if (contents[0] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "TimersCalendar")) {
                         const char *base, *spec;
                         uint64_t next_elapse;
 
@@ -4771,9 +4771,9 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        return 0;
+                        return 1;
 
-                } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
+                } else if (contents[0] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
                         ExecStatusInfo info = {};
 
                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
@@ -4808,9 +4808,9 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        return 0;
+                        return 1;
 
-                } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
+                } else if (contents[0] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
                         const char *path, *rwm;
 
                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
@@ -4826,9 +4826,9 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        return 0;
+                        return 1;
 
-                } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN &&
+                } else if (contents[0] == SD_BUS_TYPE_STRUCT_BEGIN &&
                            STR_IN_SET(name, "IODeviceWeight", "BlockIODeviceWeight")) {
                         const char *path;
                         uint64_t weight;
@@ -4846,9 +4846,9 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        return 0;
+                        return 1;
 
-                } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN &&
+                } else if (contents[0] == SD_BUS_TYPE_STRUCT_BEGIN &&
                            (cgroup_io_limit_type_from_string(name) >= 0 ||
                             STR_IN_SET(name, "BlockIOReadBandwidth", "BlockIOWriteBandwidth"))) {
                         const char *path;
@@ -4867,9 +4867,9 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        return 0;
+                        return 1;
 
-                } else if (contents[1] == SD_BUS_TYPE_BYTE && streq(name, "StandardInputData")) {
+                } else if (contents[0] == SD_BUS_TYPE_BYTE && streq(name, "StandardInputData")) {
                         _cleanup_free_ char *h = NULL;
                         const void *p;
                         size_t sz;
@@ -4885,25 +4885,12 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
 
                         print_prop(name, "%s", h);
 
-                        return 0;
+                        return 1;
                 }
 
                 break;
         }
 
-        r = bus_print_property(name, m, arg_value, arg_all);
-        if (r < 0)
-                return bus_log_parse_error(r);
-
-        if (r == 0) {
-                r = sd_bus_message_skip(m, contents);
-                if (r < 0)
-                        return bus_log_parse_error(r);
-
-                if (arg_all)
-                        printf("%s=[unprintable]\n", name);
-        }
-
         return 0;
 }
 
@@ -5071,49 +5058,7 @@ static int show_one(
         if (r < 0)
                 return log_error_errno(r, "Failed to rewind: %s", bus_error_message(&error, r));
 
-        r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
-        if (r < 0)
-                return bus_log_parse_error(r);
-
-        while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
-                const char *name, *contents;
-
-                r = sd_bus_message_read(reply, "s", &name);
-                if (r < 0)
-                        return bus_log_parse_error(r);
-
-                r = sd_bus_message_peek_type(reply, NULL, &contents);
-                if (r < 0)
-                        return bus_log_parse_error(r);
-
-                r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
-                if (r < 0)
-                        return bus_log_parse_error(r);
-
-                r = set_ensure_allocated(&found_properties, &string_hash_ops);
-                if (r < 0)
-                        return log_oom();
-
-                r = set_put(found_properties, name);
-                if (r < 0 && r != EEXIST)
-                        return log_oom();
-
-                r = print_property(name, reply, contents);
-                if (r < 0)
-                        return r;
-
-                r = sd_bus_message_exit_container(reply);
-                if (r < 0)
-                        return bus_log_parse_error(r);
-
-                r = sd_bus_message_exit_container(reply);
-                if (r < 0)
-                        return bus_log_parse_error(r);
-        }
-        if (r < 0)
-                return bus_log_parse_error(r);
-
-        r = sd_bus_message_exit_container(reply);
+        r = bus_message_print_all_properties(reply, print_property, arg_properties, arg_value, arg_all, &found_properties);
         if (r < 0)
                 return bus_log_parse_error(r);