From 4c163bf1f4451d64e40b39e520655c7185e88810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 24 May 2020 12:30:55 +0200 Subject: [PATCH 1/7] busctl: use set_put_strdup() --- src/busctl/busctl.c | 36 +++++++++--------------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c index 7aceb1796f1..eab418d2192 100644 --- a/src/busctl/busctl.c +++ b/src/busctl/busctl.c @@ -496,33 +496,22 @@ static int find_nodes(sd_bus *bus, const char *service, const char *path, Set *p } static int tree_one(sd_bus *bus, const char *service, const char *prefix, bool many) { - _cleanup_set_free_free_ Set *paths = NULL, *done = NULL, *failed = NULL; + _cleanup_set_free_ Set *paths = NULL, *done = NULL, *failed = NULL; _cleanup_free_ char **l = NULL; - char *m; int r; - paths = set_new(&string_hash_ops); - if (!paths) + r = set_put_strdup(&paths, "/"); + if (r < 0) return log_oom(); - done = set_new(&string_hash_ops); + done = set_new(&string_hash_ops_free); if (!done) return log_oom(); - failed = set_new(&string_hash_ops); + failed = set_new(&string_hash_ops_free); if (!failed) return log_oom(); - m = strdup("/"); - if (!m) - return log_oom(); - - r = set_put(paths, m); - if (r < 0) { - free(m); - return log_oom(); - } - for (;;) { _cleanup_free_ char *p = NULL; int q; @@ -536,19 +525,13 @@ static int tree_one(sd_bus *bus, const char *service, const char *prefix, bool m continue; q = find_nodes(bus, service, p, paths, many); - if (q < 0) { - if (r >= 0) - r = q; - - q = set_put(failed, p); - } else - q = set_put(done, p); + if (q < 0 && r >= 0) + r = q; + q = set_consume(q < 0 ? failed : done, TAKE_PTR(p)); + assert(q != 0); if (q < 0) return log_oom(); - - assert(q != 0); - p = NULL; } (void) pager_open(arg_pager_flags); @@ -2608,7 +2591,6 @@ static int parse_argv(int argc, char *argv[]) { } static int busctl_main(int argc, char *argv[]) { - static const Verb verbs[] = { { "list", VERB_ANY, 1, VERB_DEFAULT, list_bus_names }, { "status", VERB_ANY, 2, 0, status }, From d2916409edb7bea9963c71052375a9919df28dc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 24 May 2020 12:51:51 +0200 Subject: [PATCH 2/7] sd-bus: make name validation functions public Those are fairly trivial to reimplement, but any non-trivial user of sd-bus is likely to need them. So let's expose them to save everyone the trouble. I'm keeping the internal functions and making the public ones thin wrappers, because for the internal uses we don't need the additional asserts, and also we can't expose _pure_ annotation easily, and dropping it would likely make the compiled code a bit less efficient. --- src/libsystemd/libsystemd.sym | 6 ++++++ src/libsystemd/sd-bus/bus-internal.h | 1 + src/libsystemd/sd-bus/bus-type.c | 25 +++++++++++++++++++++++++ src/systemd/sd-bus.h | 7 +++++++ 4 files changed, 39 insertions(+) diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 1cfe3550896..cc396780ce8 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -700,6 +700,11 @@ global: LIBSYSTEMD_246 { global: + sd_bus_interface_name_is_valid; + sd_bus_service_name_is_valid; + sd_bus_member_name_is_valid; + sd_bus_object_path_is_valid; + sd_bus_call_methodv; sd_bus_call_method_asyncv; sd_bus_emit_signalv; @@ -707,6 +712,7 @@ global: sd_bus_reply_method_errorfv; sd_bus_reply_method_returnv; sd_bus_set_propertyv; + sd_path_lookup; sd_path_lookup_strv; } LIBSYSTEMD_245; diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h index 352a419e25d..7e13f4f73ba 100644 --- a/src/libsystemd/sd-bus/bus-internal.h +++ b/src/libsystemd/sd-bus/bus-internal.h @@ -354,6 +354,7 @@ bool interface_name_is_valid(const char *p) _pure_; bool service_name_is_valid(const char *p) _pure_; bool member_name_is_valid(const char *p) _pure_; bool object_path_is_valid(const char *p) _pure_; + char *object_path_startswith(const char *a, const char *b) _pure_; bool namespace_complex_pattern(const char *pattern, const char *value) _pure_; diff --git a/src/libsystemd/sd-bus/bus-type.c b/src/libsystemd/sd-bus/bus-type.c index 18564a53834..585f8424b3f 100644 --- a/src/libsystemd/sd-bus/bus-type.c +++ b/src/libsystemd/sd-bus/bus-type.c @@ -4,6 +4,7 @@ #include "sd-bus.h" +#include "bus-internal.h" #include "bus-type.h" bool bus_type_is_valid(char c) { @@ -135,3 +136,27 @@ int bus_type_get_size(char c) { return -EINVAL; } + +_public_ int sd_bus_interface_name_is_valid(const char *p) { + assert_return(p, -EINVAL); + + return interface_name_is_valid(p); +} + +_public_ int sd_bus_service_name_is_valid(const char *p) { + assert_return(p, -EINVAL); + + return service_name_is_valid(p); +} + +_public_ int sd_bus_member_name_is_valid(const char *p) { + assert_return(p, -EINVAL); + + return member_name_is_valid(p); +} + +_public_ int sd_bus_object_path_is_valid(const char *p) { + assert_return(p, -EINVAL); + + return object_path_is_valid(p); +} diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h index 61b5a493c7c..d4b6befc8cb 100644 --- a/src/systemd/sd-bus.h +++ b/src/systemd/sd-bus.h @@ -124,6 +124,13 @@ typedef _sd_destroy_t sd_bus_destroy_t; #include "sd-bus-protocol.h" #include "sd-bus-vtable.h" +/* Naming */ + +int sd_bus_interface_name_is_valid(const char *p); +int sd_bus_service_name_is_valid(const char *p); +int sd_bus_member_name_is_valid(const char *p); +int sd_bus_object_path_is_valid(const char *p); + /* Connections */ int sd_bus_default(sd_bus **ret); From 5453a4b1a85fbe2029798e0ab990702626510333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 24 May 2020 13:39:25 +0200 Subject: [PATCH 3/7] tree-wide: use public sd-bus functions in more places --- src/busctl/busctl.c | 2 +- src/core/dbus-scope.c | 3 +-- src/core/dbus-service.c | 3 +-- src/core/load-fragment.c | 2 +- src/shared/bus-util.c | 8 ++++---- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c index eab418d2192..068e847170f 100644 --- a/src/busctl/busctl.c +++ b/src/busctl/busctl.c @@ -1274,7 +1274,7 @@ static int monitor(int argc, char **argv, int (*dump)(sd_bus_message *m, FILE *f STRV_FOREACH(i, argv+1) { _cleanup_free_ char *m = NULL; - if (!service_name_is_valid(*i)) + if (!sd_bus_service_name_is_valid(*i)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid service name '%s'", *i); m = strjoin("sender='", *i, "'"); diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c index 84d91dcfa35..2d877a8c55f 100644 --- a/src/core/dbus-scope.c +++ b/src/core/dbus-scope.c @@ -2,7 +2,6 @@ #include "alloc-util.h" #include "bus-common-errors.h" -#include "bus-internal.h" #include "bus-util.h" #include "dbus-cgroup.h" #include "dbus-kill.h" @@ -140,7 +139,7 @@ static int bus_scope_set_transient_property( if (r < 0) return r; - if (!isempty(controller) && !service_name_is_valid(controller)) + if (!isempty(controller) && !sd_bus_service_name_is_valid(controller)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Controller '%s' is not a valid bus name.", controller); if (!UNIT_WRITE_FLAGS_NOOP(flags)) { diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index 5cf9b21890e..984ef2459ef 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -4,7 +4,6 @@ #include "alloc-util.h" #include "async.h" -#include "bus-internal.h" #include "bus-util.h" #include "dbus-cgroup.h" #include "dbus-execute.h" @@ -258,7 +257,7 @@ static BUS_DEFINE_SET_TRANSIENT_PARSE(notify_access, NotifyAccess, notify_access static BUS_DEFINE_SET_TRANSIENT_PARSE(service_type, ServiceType, service_type_from_string); static BUS_DEFINE_SET_TRANSIENT_PARSE(service_restart, ServiceRestart, service_restart_from_string); static BUS_DEFINE_SET_TRANSIENT_PARSE(oom_policy, OOMPolicy, oom_policy_from_string); -static BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(bus_name, service_name_is_valid); +static BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(bus_name, sd_bus_service_name_is_valid); static int bus_service_set_transient_property( Service *s, diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index e420239e157..352798fd6ac 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -1948,7 +1948,7 @@ int config_parse_bus_name( return 0; } - if (!service_name_is_valid(k)) { + if (!sd_bus_service_name_is_valid(k)) { log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid bus name, ignoring: %s", k); return 0; } diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 379aecf7307..a61f8e70da0 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -1156,7 +1156,7 @@ int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, int r; assert_return(b || (sender_id && external_id), -EINVAL); - assert_return(object_path_is_valid(prefix), -EINVAL); + assert_return(sd_bus_object_path_is_valid(prefix), -EINVAL); assert_return(ret_path, -EINVAL); if (!sender_id) { @@ -1208,8 +1208,8 @@ int bus_path_decode_unique(const char *path, const char *prefix, char **ret_send const char *p, *q; char *sender, *external; - assert(object_path_is_valid(path)); - assert(object_path_is_valid(prefix)); + assert(sd_bus_object_path_is_valid(path)); + assert(sd_bus_object_path_is_valid(prefix)); assert(ret_sender); assert(ret_external); @@ -1670,7 +1670,7 @@ int bus_introspect_implementations( } struct introspect intro = {}; - bool is_interface = interface_name_is_valid(pattern); + bool is_interface = sd_bus_interface_name_is_valid(pattern); impl = find_implementation(pattern, bus_objects); if (!impl) From 0406d1a843ba38334b8d4d9926cffd11ce4d5586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 24 May 2020 14:13:24 +0200 Subject: [PATCH 4/7] man: add docs for the new functions --- man/rules/meson.build | 6 ++ man/sd-bus.xml | 1 + man/sd_bus_interface_name_is_valid.xml | 98 ++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 man/sd_bus_interface_name_is_valid.xml diff --git a/man/rules/meson.build b/man/rules/meson.build index 941e248d72a..78440e6e91c 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -267,6 +267,12 @@ manpages = [ ['sd_bus_get_n_queued_read', '3', ['sd_bus_get_n_queued_write'], ''], ['sd_bus_get_name_creds', '3', ['sd_bus_get_owner_creds'], ''], ['sd_bus_get_name_machine_id', '3', [], ''], + ['sd_bus_interface_name_is_valid', + '3', + ['sd_bus_member_name_is_valid', + 'sd_bus_object_path_is_valid', + 'sd_bus_service_name_is_valid'], + ''], ['sd_bus_is_open', '3', ['sd_bus_is_ready'], ''], ['sd_bus_list_names', '3', [], ''], ['sd_bus_message_append', '3', ['sd_bus_message_appendv'], ''], diff --git a/man/sd-bus.xml b/man/sd-bus.xml index 24999337c8f..0938255d5c0 100644 --- a/man/sd-bus.xml +++ b/man/sd-bus.xml @@ -89,6 +89,7 @@ sd_bus_get_scope3, sd_bus_get_tid3, sd_bus_get_unique_name3, +sd_bus_interface_name_is_valid3, sd_bus_is_monitor3, sd_bus_is_bus_client3, sd_bus_is_server3, diff --git a/man/sd_bus_interface_name_is_valid.xml b/man/sd_bus_interface_name_is_valid.xml new file mode 100644 index 00000000000..73c0ba1bf1f --- /dev/null +++ b/man/sd_bus_interface_name_is_valid.xml @@ -0,0 +1,98 @@ + + + + + + + sd_bus_interface_name_is_valid + systemd + + + + sd_bus_interface_name_is_valid + 3 + + + + sd_bus_interface_name_is_valid + sd_bus_service_name_is_valid + sd_bus_member_name_is_valid + sd_bus_object_path_is_valid + + Check if a string is a valid bus name or object path + + + + + #include <systemd/sd-bus.h> + + + int sd_bus_interface_name_is_valid + const char* p + + + + int sd_bus_service_name_is_valid + const char* p + + + + int sd_bus_member_name_is_valid + const char* p + + + + int sd_bus_object_path_is_valid + const char* p + + + + + + Description + + sd_bus_interface_name_is_valid() checks if a given string + p is a syntactically valid bus interface name. Similarly, + sd_bus_service_name_is_valid() checks if the argument is a valid bus service name, + sd_bus_member_name_is_valid() checks if the argument is a valid bus interface member + name, and sd_bus_object_path_is_valid() checks if the argument is a valid bus object + path. Those functions generally check that only allowed characters are used and that the length of the + string is within limits. + + + + Return Value + + Those functions return 1 if the argument is a valid interface / service / member name or object + path, and 0 if it is not. If the argument is NULL, an error is returned. + + + Errors + + Returned errors may indicate the following problems: + + + + -EINVAL + + The p parameter is + NULL. + + + + + + + + + See Also + + + systemd1, + sd-bus3, + sd_bus_message_call_method3 + + + + From 062ac2ea85e466105c6aca4ea95e1d9a17422cea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 24 May 2020 13:04:24 +0200 Subject: [PATCH 5/7] sd-bus: internalize setting of bus is_system/is_user Each of bus_set_address_{user,system} had two users, and each of the two users would set the internal flag manually. We should do that internally in the functions instead. While at it, only set the flag when setting the address is actually successful. This doesn't change anything for current users, but it seems more correct. --- src/busctl/busctl.c | 7 ++----- src/libsystemd/sd-bus/sd-bus.c | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c index 068e847170f..a4132b3345f 100644 --- a/src/busctl/busctl.c +++ b/src/busctl/busctl.c @@ -110,13 +110,10 @@ static int acquire_bus(bool set_monitor, sd_bus **ret) { switch (arg_transport) { case BUS_TRANSPORT_LOCAL: - if (arg_user) { - bus->is_user = true; + if (arg_user) r = bus_set_address_user(bus); - } else { - bus->is_system = true; + else r = bus_set_address_system(bus); - } break; case BUS_TRANSPORT_REMOTE: diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 366f36645a1..cd1a79a256d 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -1266,10 +1266,16 @@ _public_ int sd_bus_open(sd_bus **ret) { int bus_set_address_system(sd_bus *b) { const char *e; + int r; + assert(b); e = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS"); - return sd_bus_set_address(b, e ?: DEFAULT_SYSTEM_BUS_ADDRESS); + + r = sd_bus_set_address(b, e ?: DEFAULT_SYSTEM_BUS_ADDRESS); + if (r >= 0) + b->is_system = true; + return r; } _public_ int sd_bus_open_system_with_description(sd_bus **ret, const char *description) { @@ -1293,7 +1299,6 @@ _public_ int sd_bus_open_system_with_description(sd_bus **ret, const char *descr return r; b->bus_client = true; - b->is_system = true; /* Let's do per-method access control on the system bus. We * need the caller's UID and capability set for that. */ @@ -1316,6 +1321,7 @@ _public_ int sd_bus_open_system(sd_bus **ret) { int bus_set_address_user(sd_bus *b) { const char *a; _cleanup_free_ char *_a = NULL; + int r; assert(b); @@ -1337,7 +1343,10 @@ int bus_set_address_user(sd_bus *b) { a = _a; } - return sd_bus_set_address(b, a); + r = sd_bus_set_address(b, a); + if (r >= 0) + b->is_user = true; + return r; } _public_ int sd_bus_open_user_with_description(sd_bus **ret, const char *description) { @@ -1361,7 +1370,6 @@ _public_ int sd_bus_open_user_with_description(sd_bus **ret, const char *descrip return r; b->bus_client = true; - b->is_user = true; /* We don't do any per-method access control on the user bus. */ b->trusted = true; From 50f20d1bc2211a0e769278471aac108aa79ab26e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 24 May 2020 13:47:53 +0200 Subject: [PATCH 6/7] busctl: verify args early and always print results to stdout We would print the error sometimes to stdout and sometimes to stderr. It *is* useful to get the message if one of the names is not found on the bus to stdout, so that this shows out in the pager. So let's do verification of args early to catch invalid arguments, and then if we receive an error over the bus (most likely that the name is not activatable), let's print to stdout so it gets paged. E.g. 'busctl tree org.freedesktop.systemd1 org.freedesktop.systemd2' gives a nicely usable output. --- TODO | 3 --- src/busctl/busctl.c | 31 +++++++++++++++++-------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/TODO b/TODO index e4182588fe8..e962db26ca6 100644 --- a/TODO +++ b/TODO @@ -4,9 +4,6 @@ Bugfixes: manager or system manager can be always set. It would be better to reject them when parsing config. -* busctl prints errors to stdout: - busctl tree org.freedesktop.systemd1 /org/freedesktop/systemd1 - External: * Fedora: add an rpmlint check that verifies that all unit files in the RPM are listed in %systemd_post macros. diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c index a4132b3345f..4879b466e30 100644 --- a/src/busctl/busctl.c +++ b/src/busctl/busctl.c @@ -462,7 +462,7 @@ static int on_path(const char *path, void *userdata) { return 0; } -static int find_nodes(sd_bus *bus, const char *service, const char *path, Set *paths, bool many) { +static int find_nodes(sd_bus *bus, const char *service, const char *path, Set *paths) { static const XMLIntrospectOps ops = { .on_path = on_path, }; @@ -476,12 +476,10 @@ static int find_nodes(sd_bus *bus, const char *service, const char *path, Set *p "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, ""); if (r < 0) { - if (many) - printf("Failed to introspect object %s of service %s: %s\n", - path, service, bus_error_message(&error, r)); - else - log_error_errno(r, "Failed to introspect object %s of service %s: %s", - path, service, bus_error_message(&error, r)); + printf("%sFailed to introspect object %s of service %s: %s%s\n", + ansi_highlight_red(), + path, service, bus_error_message(&error, r), + ansi_normal()); return r; } @@ -492,7 +490,7 @@ static int find_nodes(sd_bus *bus, const char *service, const char *path, Set *p return parse_xml_introspect(path, xml, &ops, paths); } -static int tree_one(sd_bus *bus, const char *service, const char *prefix, bool many) { +static int tree_one(sd_bus *bus, const char *service, const char *prefix) { _cleanup_set_free_ Set *paths = NULL, *done = NULL, *failed = NULL; _cleanup_free_ char **l = NULL; int r; @@ -521,7 +519,7 @@ static int tree_one(sd_bus *bus, const char *service, const char *prefix, bool m set_contains(failed, p)) continue; - q = find_nodes(bus, service, p, paths, many); + q = find_nodes(bus, service, p, paths); if (q < 0 && r >= 0) r = q; @@ -550,6 +548,12 @@ static int tree(int argc, char **argv, void *userdata) { char **i; int r = 0; + /* Do superficial verification of arguments before even opening the bus */ + STRV_FOREACH(i, strv_skip(argv, 1)) + if (!sd_bus_service_name_is_valid(*i)) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Invalid bus service name: %s", *i); + if (!arg_unique && !arg_acquired) arg_acquired = true; @@ -581,14 +585,14 @@ static int tree(int argc, char **argv, void *userdata) { printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_normal()); - q = tree_one(bus, *i, NULL, true); + q = tree_one(bus, *i, NULL); if (q < 0 && r >= 0) r = q; not_first = true; } - } else { - STRV_FOREACH(i, argv+1) { + } else + STRV_FOREACH(i, strv_skip(argv, 1)) { int q; if (i > argv+1) @@ -599,11 +603,10 @@ static int tree(int argc, char **argv, void *userdata) { printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_normal()); } - q = tree_one(bus, *i, NULL, !!argv[2]); + q = tree_one(bus, *i, NULL); if (q < 0 && r >= 0) r = q; } - } return r; } From 445bd57e397ac77bc0f6ca0165bbc70397341c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 26 May 2020 09:13:39 +0200 Subject: [PATCH 7/7] busctl: drop unneeded param --- src/busctl/busctl.c | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c index 4879b466e30..8e000ee1196 100644 --- a/src/busctl/busctl.c +++ b/src/busctl/busctl.c @@ -424,29 +424,15 @@ static void print_subtree(const char *prefix, const char *path, char **l) { } } -static void print_tree(const char *prefix, char **l) { - - prefix = strempty(prefix); - - if (arg_list) { - char **i; - - STRV_FOREACH(i, l) - printf("%s%s\n", prefix, *i); - return; - } - - if (strv_isempty(l)) { +static void print_tree(char **l) { + if (arg_list) + strv_print(l); + else if (strv_isempty(l)) printf("No objects discovered.\n"); - return; - } - - if (streq(l[0], "/") && !l[1]) { + else if (streq(l[0], "/") && !l[1]) printf("Only root object discovered.\n"); - return; - } - - print_subtree(prefix, "/", l); + else + print_subtree("", "/", l); } static int on_path(const char *path, void *userdata) { @@ -490,7 +476,7 @@ static int find_nodes(sd_bus *bus, const char *service, const char *path, Set *p return parse_xml_introspect(path, xml, &ops, paths); } -static int tree_one(sd_bus *bus, const char *service, const char *prefix) { +static int tree_one(sd_bus *bus, const char *service) { _cleanup_set_free_ Set *paths = NULL, *done = NULL, *failed = NULL; _cleanup_free_ char **l = NULL; int r; @@ -536,7 +522,7 @@ static int tree_one(sd_bus *bus, const char *service, const char *prefix) { return log_oom(); strv_sort(l); - print_tree(prefix, l); + print_tree(l); fflush(stdout); @@ -585,7 +571,7 @@ static int tree(int argc, char **argv, void *userdata) { printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_normal()); - q = tree_one(bus, *i, NULL); + q = tree_one(bus, *i); if (q < 0 && r >= 0) r = q; @@ -603,7 +589,7 @@ static int tree(int argc, char **argv, void *userdata) { printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_normal()); } - q = tree_one(bus, *i, NULL); + q = tree_one(bus, *i); if (q < 0 && r >= 0) r = q; }