diff options
author | Lennart Poettering <lennart@poettering.net> | 2020-06-28 16:17:46 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2020-06-30 15:09:56 +0200 |
commit | 9176326ba2f2167076269acf7573a4a99da82a2d (patch) | |
tree | 80726803dcb77e7d402e7619f7c5a3830f3ec94e /src | |
parent | shared: split out code that maps properties to local structs (diff) | |
download | systemd-9176326ba2f2167076269acf7573a4a99da82a2d.tar.xz systemd-9176326ba2f2167076269acf7573a4a99da82a2d.zip |
shared: split out code for printing properties
No code changes, just some refactoring.
Diffstat (limited to 'src')
-rw-r--r-- | src/login/loginctl.c | 1 | ||||
-rw-r--r-- | src/machine/machinectl.c | 1 | ||||
-rw-r--r-- | src/shared/bus-print-properties.c | 462 | ||||
-rw-r--r-- | src/shared/bus-print-properties.h | 16 | ||||
-rw-r--r-- | src/shared/bus-util.c | 457 | ||||
-rw-r--r-- | src/shared/bus-util.h | 8 | ||||
-rw-r--r-- | src/shared/meson.build | 2 | ||||
-rw-r--r-- | src/systemctl/systemctl.c | 1 | ||||
-rw-r--r-- | src/timedate/timedatectl.c | 1 |
9 files changed, 484 insertions, 465 deletions
diff --git a/src/login/loginctl.c b/src/login/loginctl.c index 6302589a48..ee617929ff 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -11,6 +11,7 @@ #include "bus-error.h" #include "bus-locator.h" #include "bus-map-properties.h" +#include "bus-print-properties.h" #include "bus-unit-procs.h" #include "cgroup-show.h" #include "cgroup-util.h" diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index 6d124b418c..f41cf464b1 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -18,6 +18,7 @@ #include "bus-error.h" #include "bus-locator.h" #include "bus-map-properties.h" +#include "bus-print-properties.h" #include "bus-unit-procs.h" #include "bus-unit-util.h" #include "bus-wait-for-jobs.h" diff --git a/src/shared/bus-print-properties.c b/src/shared/bus-print-properties.c new file mode 100644 index 0000000000..bf7d050fa3 --- /dev/null +++ b/src/shared/bus-print-properties.c @@ -0,0 +1,462 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "bus-print-properties.h" +#include "cap-list.h" +#include "cgroup-util.h" +#include "escape.h" +#include "mountpoint-util.h" +#include "nsflags.h" +#include "parse-util.h" +#include "stdio-util.h" +#include "string-util.h" +#include "strv.h" +#include "time-util.h" +#include "user-util.h" + +int bus_print_property_value(const char *name, const char *expected_value, bool only_value, const char *value) { + assert(name); + + if (expected_value && !streq_ptr(expected_value, value)) + return 0; + + if (only_value) + puts(value); + else + printf("%s=%s\n", name, value); + + return 0; +} + +int bus_print_property_valuef(const char *name, const char *expected_value, bool only_value, const char *fmt, ...) { + va_list ap; + int r; + + assert(name); + assert(fmt); + + if (expected_value) { + _cleanup_free_ char *s = NULL; + + va_start(ap, fmt); + r = vasprintf(&s, fmt, ap); + va_end(ap); + if (r < 0) + return -ENOMEM; + + if (streq_ptr(expected_value, s)) { + if (only_value) + puts(s); + else + printf("%s=%s\n", name, s); + } + + return 0; + } + + if (!only_value) + printf("%s=", name); + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + puts(""); + + return 0; +} + +static int bus_print_property(const char *name, const char *expected_value, sd_bus_message *m, bool value, bool all) { + char type; + const char *contents; + int r; + + assert(name); + assert(m); + + r = sd_bus_message_peek_type(m, &type, &contents); + if (r < 0) + return r; + + switch (type) { + + case SD_BUS_TYPE_STRING: { + const char *s; + + r = sd_bus_message_read_basic(m, type, &s); + if (r < 0) + return r; + + if (all || !isempty(s)) { + bool good; + + /* This property has a single value, so we need to take + * care not to print a new line, everything else is OK. */ + good = !strchr(s, '\n'); + bus_print_property_value(name, expected_value, value, good ? s : "[unprintable]"); + } + + return 1; + } + + case SD_BUS_TYPE_BOOLEAN: { + int b; + + r = sd_bus_message_read_basic(m, type, &b); + if (r < 0) + return r; + + if (expected_value && parse_boolean(expected_value) != b) + return 1; + + bus_print_property_value(name, NULL, value, yes_no(b)); + return 1; + } + + case SD_BUS_TYPE_UINT64: { + uint64_t u; + + r = sd_bus_message_read_basic(m, type, &u); + if (r < 0) + return r; + + /* Yes, heuristics! But we can change this check + * should it turn out to not be sufficient */ + + if (endswith(name, "Timestamp") || + STR_IN_SET(name, "NextElapseUSecRealtime", "LastTriggerUSec", "TimeUSec", "RTCTimeUSec")) { + char timestamp[FORMAT_TIMESTAMP_MAX]; + const char *t; + + t = format_timestamp(timestamp, sizeof(timestamp), u); + if (t || all) + bus_print_property_value(name, expected_value, value, strempty(t)); + + } else if (strstr(name, "USec")) { + char timespan[FORMAT_TIMESPAN_MAX]; + + (void) format_timespan(timespan, sizeof(timespan), u, 0); + bus_print_property_value(name, expected_value, value, timespan); + + } else if (streq(name, "CoredumpFilter")) { + char buf[STRLEN("0xFFFFFFFF")]; + + xsprintf(buf, "0x%"PRIx64, u); + bus_print_property_value(name, expected_value, value, buf); + + } else if (streq(name, "RestrictNamespaces")) { + _cleanup_free_ char *s = NULL; + const char *result; + + if ((u & NAMESPACE_FLAGS_ALL) == 0) + result = "yes"; + else if (FLAGS_SET(u, NAMESPACE_FLAGS_ALL)) + result = "no"; + else { + r = namespace_flags_to_string(u, &s); + if (r < 0) + return r; + + result = strempty(s); + } + + bus_print_property_value(name, expected_value, value, result); + + } else if (streq(name, "MountFlags")) { + const char *result; + + result = mount_propagation_flags_to_string(u); + if (!result) + return -EINVAL; + + bus_print_property_value(name, expected_value, value, result); + + } else if (STR_IN_SET(name, "CapabilityBoundingSet", "AmbientCapabilities")) { + _cleanup_free_ char *s = NULL; + + r = capability_set_to_string_alloc(u, &s); + if (r < 0) + return r; + + bus_print_property_value(name, expected_value, value, s); + + } else if ((STR_IN_SET(name, "CPUWeight", "StartupCPUWeight", "IOWeight", "StartupIOWeight") && u == CGROUP_WEIGHT_INVALID) || + (STR_IN_SET(name, "CPUShares", "StartupCPUShares") && u == CGROUP_CPU_SHARES_INVALID) || + (STR_IN_SET(name, "BlockIOWeight", "StartupBlockIOWeight") && u == CGROUP_BLKIO_WEIGHT_INVALID) || + (STR_IN_SET(name, "MemoryCurrent", "TasksCurrent") && u == (uint64_t) -1) || + (endswith(name, "NSec") && u == (uint64_t) -1)) + + bus_print_property_value(name, expected_value, value, "[not set]"); + + else if ((STR_IN_SET(name, "DefaultMemoryLow", "DefaultMemoryMin", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit") && u == CGROUP_LIMIT_MAX) || + (STR_IN_SET(name, "TasksMax", "DefaultTasksMax") && u == (uint64_t) -1) || + (startswith(name, "Limit") && u == (uint64_t) -1) || + (startswith(name, "DefaultLimit") && u == (uint64_t) -1)) + + bus_print_property_value(name, expected_value, value, "infinity"); + else if (STR_IN_SET(name, "IPIngressBytes", "IPIngressPackets", "IPEgressBytes", "IPEgressPackets") && u == (uint64_t) -1) + bus_print_property_value(name, expected_value, value, "[no data]"); + else + bus_print_property_valuef(name, expected_value, value, "%"PRIu64, u); + + return 1; + } + + case SD_BUS_TYPE_INT64: { + int64_t i; + + r = sd_bus_message_read_basic(m, type, &i); + if (r < 0) + return r; + + bus_print_property_valuef(name, expected_value, value, "%"PRIi64, i); + return 1; + } + + case SD_BUS_TYPE_UINT32: { + uint32_t u; + + r = sd_bus_message_read_basic(m, type, &u); + if (r < 0) + return r; + + if (strstr(name, "UMask") || strstr(name, "Mode")) + bus_print_property_valuef(name, expected_value, value, "%04o", u); + + else if (streq(name, "UID")) { + if (u == UID_INVALID) + bus_print_property_value(name, expected_value, value, "[not set]"); + else + bus_print_property_valuef(name, expected_value, value, "%"PRIu32, u); + } else if (streq(name, "GID")) { + if (u == GID_INVALID) + bus_print_property_value(name, expected_value, value, "[not set]"); + else + bus_print_property_valuef(name, expected_value, value, "%"PRIu32, u); + } else + bus_print_property_valuef(name, expected_value, value, "%"PRIu32, u); + + return 1; + } + + case SD_BUS_TYPE_INT32: { + int32_t i; + + r = sd_bus_message_read_basic(m, type, &i); + if (r < 0) + return r; + + bus_print_property_valuef(name, expected_value, value, "%"PRIi32, i); + return 1; + } + + case SD_BUS_TYPE_DOUBLE: { + double d; + + r = sd_bus_message_read_basic(m, type, &d); + if (r < 0) + return r; + + bus_print_property_valuef(name, expected_value, value, "%g", d); + return 1; + } + + case SD_BUS_TYPE_ARRAY: + if (streq(contents, "s")) { + bool first = true; + const char *str; + + r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, contents); + if (r < 0) + return r; + + while ((r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &str)) > 0) { + _cleanup_free_ char *e = NULL; + + e = shell_maybe_quote(str, ESCAPE_BACKSLASH_ONELINE); + if (!e) + return -ENOMEM; + + if (first) { + if (!value) + printf("%s=", name); + first = false; + } else + fputs(" ", stdout); + + fputs(e, stdout); + } + if (r < 0) + return r; + + if (first && all && !value) + printf("%s=", name); + if (!first || all) + puts(""); + + r = sd_bus_message_exit_container(m); + if (r < 0) + return r; + + return 1; + + } else if (streq(contents, "y")) { + const uint8_t *u; + size_t n; + + r = sd_bus_message_read_array(m, SD_BUS_TYPE_BYTE, (const void**) &u, &n); + if (r < 0) + return r; + + if (all || n > 0) { + unsigned i; + + if (!value) + printf("%s=", name); + + for (i = 0; i < n; i++) + printf("%02x", u[i]); + + puts(""); + } + + return 1; + + } else if (streq(contents, "u")) { + uint32_t *u; + size_t n; + + r = sd_bus_message_read_array(m, SD_BUS_TYPE_UINT32, (const void**) &u, &n); + if (r < 0) + return r; + + if (all || n > 0) { + unsigned i; + + if (!value) + printf("%s=", name); + + for (i = 0; i < n; i++) + printf("%08x", u[i]); + + puts(""); + } + + return 1; + } + + break; + } + + return 0; +} + +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 r; + + assert(m); + + r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}"); + if (r < 0) + return r; + + while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) { + _cleanup_free_ char *name_with_equal = NULL; + const char *name, *contents, *expected_value = NULL; + + r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &name); + if (r < 0) + return r; + + if (found_properties) { + r = set_ensure_put(found_properties, &string_hash_ops, name); + if (r < 0) + return log_oom(); + } + + name_with_equal = strjoin(name, "="); + if (!name_with_equal) + return log_oom(); + + if (!filter || strv_find(filter, name) || + (expected_value = strv_find_startswith(filter, name_with_equal))) { + r = sd_bus_message_peek_type(m, NULL, &contents); + if (r < 0) + return r; + + r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents); + if (r < 0) + return r; + + if (func) + r = func(name, expected_value, m, value, all); + if (!func || r == 0) + r = bus_print_property(name, expected_value, m, value, all); + if (r < 0) + return r; + if (r == 0) { + if (all && !expected_value) + printf("%s=[unprintable]\n", name); + /* skip what we didn't read */ + r = sd_bus_message_skip(m, contents); + if (r < 0) + return r; + } + + r = sd_bus_message_exit_container(m); + if (r < 0) + return r; + } else { + r = sd_bus_message_skip(m, "v"); + if (r < 0) + return r; + } + + r = sd_bus_message_exit_container(m); + if (r < 0) + return r; + } + if (r < 0) + return r; + + 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); +} diff --git a/src/shared/bus-print-properties.h b/src/shared/bus-print-properties.h new file mode 100644 index 0000000000..1c21dff2c8 --- /dev/null +++ b/src/shared/bus-print-properties.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +#include <stdbool.h> + +#include "sd-bus.h" + +#include "macro.h" +#include "set.h" + +typedef int (*bus_message_print_t) (const char *name, const char *expected_value, sd_bus_message *m, bool value, bool all); + +int bus_print_property_value(const char *name, const char *expected_value, bool only_value, const char *value); +int bus_print_property_valuef(const char *name, const char *expected_value, bool only_value, const char *fmt, ...) _printf_(4,5); +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); diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index fc5ac7a057..85b5bedbc0 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -17,21 +17,12 @@ #include "alloc-util.h" #include "bus-internal.h" #include "bus-label.h" -#include "bus-message.h" #include "bus-util.h" -#include "cap-list.h" -#include "cgroup-util.h" -#include "escape.h" -#include "mountpoint-util.h" -#include "nsflags.h" -#include "parse-util.h" #include "path-util.h" #include "rlimit-util.h" #include "socket-util.h" #include "stdio-util.h" #include "string-util.h" -#include "strv.h" -#include "user-util.h" static int name_owner_change_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { sd_event *e = userdata; @@ -253,454 +244,6 @@ int bus_connect_user_systemd(sd_bus **_bus) { return 0; } -int bus_print_property_value(const char *name, const char *expected_value, bool only_value, const char *value) { - assert(name); - - if (expected_value && !streq_ptr(expected_value, value)) - return 0; - - if (only_value) - puts(value); - else - printf("%s=%s\n", name, value); - - return 0; -} - -int bus_print_property_valuef(const char *name, const char *expected_value, bool only_value, const char *fmt, ...) { - va_list ap; - int r; - - assert(name); - assert(fmt); - - if (expected_value) { - _cleanup_free_ char *s = NULL; - - va_start(ap, fmt); - r = vasprintf(&s, fmt, ap); - va_end(ap); - if (r < 0) - return -ENOMEM; - - if (streq_ptr(expected_value, s)) { - if (only_value) - puts(s); - else - printf("%s=%s\n", name, s); - } - - return 0; - } - - if (!only_value) - printf("%s=", name); - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); - puts(""); - - return 0; -} - -static int bus_print_property(const char *name, const char *expected_value, sd_bus_message *m, bool value, bool all) { - char type; - const char *contents; - int r; - - assert(name); - assert(m); - - r = sd_bus_message_peek_type(m, &type, &contents); - if (r < 0) - return r; - - switch (type) { - - case SD_BUS_TYPE_STRING: { - const char *s; - - r = sd_bus_message_read_basic(m, type, &s); - if (r < 0) - return r; - - if (all || !isempty(s)) { - bool good; - - /* This property has a single value, so we need to take - * care not to print a new line, everything else is OK. */ - good = !strchr(s, '\n'); - bus_print_property_value(name, expected_value, value, good ? s : "[unprintable]"); - } - - return 1; - } - - case SD_BUS_TYPE_BOOLEAN: { - int b; - - r = sd_bus_message_read_basic(m, type, &b); - if (r < 0) - return r; - - if (expected_value && parse_boolean(expected_value) != b) - return 1; - - bus_print_property_value(name, NULL, value, yes_no(b)); - return 1; - } - - case SD_BUS_TYPE_UINT64: { - uint64_t u; - - r = sd_bus_message_read_basic(m, type, &u); - if (r < 0) - return r; - - /* Yes, heuristics! But we can change this check - * should it turn out to not be sufficient */ - - if (endswith(name, "Timestamp") || - STR_IN_SET(name, "NextElapseUSecRealtime", "LastTriggerUSec", "TimeUSec", "RTCTimeUSec")) { - char timestamp[FORMAT_TIMESTAMP_MAX]; - const char *t; - - t = format_timestamp(timestamp, sizeof(timestamp), u); - if (t || all) - bus_print_property_value(name, expected_value, value, strempty(t)); - - } else if (strstr(name, "USec")) { - char timespan[FORMAT_TIMESPAN_MAX]; - - (void) format_timespan(timespan, sizeof(timespan), u, 0); - bus_print_property_value(name, expected_value, value, timespan); - - } else if (streq(name, "CoredumpFilter")) { - char buf[STRLEN("0xFFFFFFFF")]; - - xsprintf(buf, "0x%"PRIx64, u); - bus_print_property_value(name, expected_value, value, buf); - - } else if (streq(name, "RestrictNamespaces")) { - _cleanup_free_ char *s = NULL; - const char *result; - - if ((u & NAMESPACE_FLAGS_ALL) == 0) - result = "yes"; - else if (FLAGS_SET(u, NAMESPACE_FLAGS_ALL)) - result = "no"; - else { - r = namespace_flags_to_string(u, &s); - if (r < 0) - return r; - - result = strempty(s); - } - - bus_print_property_value(name, expected_value, value, result); - - } else if (streq(name, "MountFlags")) { - const char *result; - - result = mount_propagation_flags_to_string(u); - if (!result) - return -EINVAL; - - bus_print_property_value(name, expected_value, value, result); - - } else if (STR_IN_SET(name, "CapabilityBoundingSet", "AmbientCapabilities")) { - _cleanup_free_ char *s = NULL; - - r = capability_set_to_string_alloc(u, &s); - if (r < 0) - return r; - - bus_print_property_value(name, expected_value, value, s); - - } else if ((STR_IN_SET(name, "CPUWeight", "StartupCPUWeight", "IOWeight", "StartupIOWeight") && u == CGROUP_WEIGHT_INVALID) || - (STR_IN_SET(name, "CPUShares", "StartupCPUShares") && u == CGROUP_CPU_SHARES_INVALID) || - (STR_IN_SET(name, "BlockIOWeight", "StartupBlockIOWeight") && u == CGROUP_BLKIO_WEIGHT_INVALID) || - (STR_IN_SET(name, "MemoryCurrent", "TasksCurrent") && u == (uint64_t) -1) || - (endswith(name, "NSec") && u == (uint64_t) -1)) - - bus_print_property_value(name, expected_value, value, "[not set]"); - - else if ((STR_IN_SET(name, "DefaultMemoryLow", "DefaultMemoryMin", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit") && u == CGROUP_LIMIT_MAX) || - (STR_IN_SET(name, "TasksMax", "DefaultTasksMax") && u == (uint64_t) -1) || - (startswith(name, "Limit") && u == (uint64_t) -1) || - (startswith(name, "DefaultLimit") && u == (uint64_t) -1)) - - bus_print_property_value(name, expected_value, value, "infinity"); - else if (STR_IN_SET(name, "IPIngressBytes", "IPIngressPackets", "IPEgressBytes", "IPEgressPackets") && u == (uint64_t) -1) - bus_print_property_value(name, expected_value, value, "[no data]"); - else - bus_print_property_valuef(name, expected_value, value, "%"PRIu64, u); - - return 1; - } - - case SD_BUS_TYPE_INT64: { - int64_t i; - - r = sd_bus_message_read_basic(m, type, &i); - if (r < 0) - return r; - - bus_print_property_valuef(name, expected_value, value, "%"PRIi64, i); - return 1; - } - - case SD_BUS_TYPE_UINT32: { - uint32_t u; - - r = sd_bus_message_read_basic(m, type, &u); - if (r < 0) - return r; - - if (strstr(name, "UMask") || strstr(name, "Mode")) - bus_print_property_valuef(name, expected_value, value, "%04o", u); - - else if (streq(name, "UID")) { - if (u == UID_INVALID) - bus_print_property_value(name, expected_value, value, "[not set]"); - else - bus_print_property_valuef(name, expected_value, value, "%"PRIu32, u); - } else if (streq(name, "GID")) { - if (u == GID_INVALID) - bus_print_property_value(name, expected_value, value, "[not set]"); - else - bus_print_property_valuef(name, expected_value, value, "%"PRIu32, u); - } else - bus_print_property_valuef(name, expected_value, value, "%"PRIu32, u); - - return 1; - } - - case SD_BUS_TYPE_INT32: { - int32_t i; - - r = sd_bus_message_read_basic(m, type, &i); - if (r < 0) - return r; - - bus_print_property_valuef(name, expected_value, value, "%"PRIi32, i); - return 1; - } - - case SD_BUS_TYPE_DOUBLE: { - double d; - - r = sd_bus_message_read_basic(m, type, &d); - if (r < 0) - return r; - - bus_print_property_valuef(name, expected_value, value, "%g", d); - return 1; - } - - case SD_BUS_TYPE_ARRAY: - if (streq(contents, "s")) { - bool first = true; - const char *str; - - r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, contents); - if (r < 0) - return r; - - while ((r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &str)) > 0) { - _cleanup_free_ char *e = NULL; - - e = shell_maybe_quote(str, ESCAPE_BACKSLASH_ONELINE); - if (!e) - return -ENOMEM; - - if (first) { - if (!value) - printf("%s=", name); - first = false; - } else - fputs(" ", stdout); - - fputs(e, stdout); - } - if (r < 0) - return r; - - if (first && all && !value) - printf("%s=", name); - if (!first || all) - puts(""); - - r = sd_bus_message_exit_container(m); - if (r < 0) - return r; - - return 1; - - } else if (streq(contents, "y")) { - const uint8_t *u; - size_t n; - - r = sd_bus_message_read_array(m, SD_BUS_TYPE_BYTE, (const void**) &u, &n); - if (r < 0) - return r; - - if (all || n > 0) { - unsigned i; - - if (!value) - printf("%s=", name); - - for (i = 0; i < n; i++) - printf("%02x", u[i]); - - puts(""); - } - - return 1; - - } else if (streq(contents, "u")) { - uint32_t *u; - size_t n; - - r = sd_bus_message_read_array(m, SD_BUS_TYPE_UINT32, (const void**) &u, &n); - if (r < 0) - return r; - - if (all || n > 0) { - unsigned i; - - if (!value) - printf("%s=", name); - - for (i = 0; i < n; i++) - printf("%08x", u[i]); - - puts(""); - } - - return 1; - } - - break; - } - - return 0; -} - -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 r; - - assert(m); - - r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}"); - if (r < 0) - return r; - - while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) { - _cleanup_free_ char *name_with_equal = NULL; - const char *name, *contents, *expected_value = NULL; - - r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &name); - if (r < 0) - return r; - - if (found_properties) { - r = set_ensure_put(found_properties, &string_hash_ops, name); - if (r < 0) - return log_oom(); - } - - name_with_equal = strjoin(name, "="); - if (!name_with_equal) - return log_oom(); - - if (!filter || strv_find(filter, name) || - (expected_value = strv_find_startswith(filter, name_with_equal))) { - r = sd_bus_message_peek_type(m, NULL, &contents); - if (r < 0) - return r; - - r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents); - if (r < 0) - return r; - - if (func) - r = func(name, expected_value, m, value, all); - if (!func || r == 0) - r = bus_print_property(name, expected_value, m, value, all); - if (r < 0) - return r; - if (r == 0) { - if (all && !expected_value) - printf("%s=[unprintable]\n", name); - /* skip what we didn't read */ - r = sd_bus_message_skip(m, contents); - if (r < 0) - return r; - } - - r = sd_bus_message_exit_container(m); - if (r < 0) - return r; - } else { - r = sd_bus_message_skip(m, "v"); - if (r < 0) - return r; - } - - r = sd_bus_message_exit_container(m); - if (r < 0) - return r; - } - if (r < 0) - return r; - - 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_connect_transport(BusTransport transport, const char *host, bool user, sd_bus **ret) { _cleanup_(sd_bus_close_unrefp) sd_bus *bus = NULL; int r; diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h index 8f700c3cfd..4dbf74fdf7 100644 --- a/src/shared/bus-util.h +++ b/src/shared/bus-util.h @@ -10,7 +10,6 @@ #include "sd-event.h" #include "macro.h" -#include "set.h" #include "string-util.h" #include "time-util.h" @@ -38,13 +37,6 @@ 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, const char *expected_value, sd_bus_message *m, bool value, bool all); - -int bus_print_property_value(const char *name, const char *expected_value, bool only_value, const char *value); -int bus_print_property_valuef(const char *name, const char *expected_value, bool only_value, const char *fmt, ...) _printf_(4,5); -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); int bus_property_get_id128(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); diff --git a/src/shared/meson.build b/src/shared/meson.build index 881e30835e..3bd680295c 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -37,6 +37,8 @@ shared_sources = files(''' bus-object.h bus-polkit.c bus-polkit.h + bus-print-properties.c + bus-print-properties.h bus-unit-procs.c bus-unit-procs.h bus-unit-util.c diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 3bc32065a5..954e5080ea 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -23,6 +23,7 @@ #include "bus-locator.h" #include "bus-map-properties.h" #include "bus-message.h" +#include "bus-print-properties.h" #include "bus-unit-procs.h" #include "bus-unit-util.h" #include "bus-wait-for-jobs.h" diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c index 9ee995802c..96be78746d 100644 --- a/src/timedate/timedatectl.c +++ b/src/timedate/timedatectl.c @@ -11,6 +11,7 @@ #include "bus-error.h" #include "bus-locator.h" #include "bus-map-properties.h" +#include "bus-print-properties.h" #include "format-table.h" #include "in-addr-util.h" #include "main-func.h" |