X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-bus%2Fbusctl.c;h=c0d51e06a3b2a068dba479ac7cc51d0742b5c27d;hp=0795472c8be02c6ccd303fb9a3ea3162befaf806;hb=92d66625794057081046f051f7564e0789de0ace;hpb=40ed1a4574152337479f7f9c01763b84847ff09f diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c index 0795472c8..c0d51e06a 100644 --- a/src/libsystemd/sd-bus/busctl.c +++ b/src/libsystemd/sd-bus/busctl.c @@ -28,6 +28,7 @@ #include "pager.h" #include "xml.h" #include "path-util.h" +#include "set.h" #include "sd-bus.h" #include "bus-message.h" @@ -89,10 +90,8 @@ static int list_bus_names(sd_bus *bus, char **argv) { arg_unique = arg_acquired = arg_activatable = true; r = sd_bus_list_names(bus, (arg_acquired || arg_unique) ? &acquired : NULL, arg_activatable ? &activatable : NULL); - if (r < 0) { - log_error("Failed to list names: %s", strerror(-r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to list names: %m"); pager_open_if_enabled(); @@ -104,20 +103,16 @@ static int list_bus_names(sd_bus *bus, char **argv) { max_i = MAX(max_i, strlen(*i)); r = hashmap_put(names, *i, NAME_IS_ACQUIRED); - if (r < 0) { - log_error("Failed to add to hashmap: %s", strerror(-r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to add to hashmap: %m"); } STRV_FOREACH(i, activatable) { max_i = MAX(max_i, strlen(*i)); r = hashmap_put(names, *i, NAME_IS_ACTIVATABLE); - if (r < 0 && r != -EEXIST) { - log_error("Failed to add to hashmap: %s", strerror(-r)); - return r; - } + if (r < 0 && r != -EEXIST) + return log_error_errno(r, "Failed to add to hashmap: %m"); } merged = new(char*, hashmap_size(names) + 1); @@ -438,10 +433,8 @@ static int tree(sd_bus *bus, char **argv) { bool not_first = false; r = sd_bus_list_names(bus, &names, NULL); - if (r < 0) { - log_error("Failed to get name list: %s", strerror(-r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to get name list: %m"); pager_open_if_enabled(); @@ -546,7 +539,7 @@ static int format_cmdline(sd_bus_message *m, FILE *f, bool needs_space) { fprintf(f, "%s", contents); } - r = format_cmdline(m, f, true); + r = format_cmdline(m, f, needs_space || IN_SET(type, SD_BUS_TYPE_ARRAY, SD_BUS_TYPE_VARIANT)); if (r < 0) return r; @@ -622,6 +615,7 @@ static int format_cmdline(sd_bus_message *m, FILE *f, bool needs_space) { assert_not_reached("Unknown basic type."); } + needs_space = true; } } @@ -889,13 +883,19 @@ static int introspect(sd_bus *bus, char **argv) { int r; unsigned name_width, type_width, signature_width, result_width; Member **sorted = NULL; - unsigned k = 0, j; + unsigned k = 0, j, n_args; - if (strv_length(argv) != 3) { + n_args = strv_length(argv); + if (n_args < 3) { log_error("Requires service and object path argument."); return -EINVAL; } + if (n_args > 4) { + log_error("Too many arguments."); + return -EINVAL; + } + members = set_new(&member_hash_ops); if (!members) return log_oom(); @@ -924,6 +924,9 @@ static int introspect(sd_bus *bus, char **argv) { if (m->value) continue; + if (argv[3] && !streq(argv[3], m->interface)) + continue; + r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Properties", "GetAll", &error, &reply, "s", m->interface); if (r < 0) { log_error("%s", bus_error_message(&error, r)); @@ -1001,6 +1004,10 @@ static int introspect(sd_bus *bus, char **argv) { sorted = newa(Member*, set_size(members)); SET_FOREACH(m, members, i) { + + if (argv[3] && !streq(argv[3], m->interface)) + continue; + if (m->interface) name_width = MAX(name_width, strlen(m->interface)); if (m->name) @@ -1020,7 +1027,6 @@ static int introspect(sd_bus *bus, char **argv) { if (result_width > 40) result_width = 40; - assert(k == set_size(members)); qsort(sorted, k, sizeof(Member*), member_compare_funcp); if (arg_legend) { @@ -1039,8 +1045,14 @@ static int introspect(sd_bus *bus, char **argv) { m = sorted[j]; + if (argv[3] && !streq(argv[3], m->interface)) + continue; + is_interface = streq(m->type, "interface"); + if (argv[3] && is_interface) + continue; + if (m->value) { ellipsized = ellipsize(m->value, result_width, 100); if (!ellipsized) @@ -1095,43 +1107,43 @@ static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FIL return log_oom(); r = sd_bus_add_match(bus, NULL, m, NULL, NULL); - if (r < 0) { - log_error("Failed to add match: %s", strerror(-r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to add match: %m"); added_something = true; } STRV_FOREACH(i, arg_matches) { r = sd_bus_add_match(bus, NULL, *i, NULL, NULL); - if (r < 0) { - log_error("Failed to add match: %s", strerror(-r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to add match: %m"); added_something = true; } if (!added_something) { r = sd_bus_add_match(bus, NULL, "", NULL, NULL); - if (r < 0) { - log_error("Failed to add match: %s", strerror(-r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to add match: %m"); } + log_info("Monitoring bus message stream."); + for (;;) { _cleanup_bus_message_unref_ sd_bus_message *m = NULL; r = sd_bus_process(bus, &m); - if (r < 0) { - log_error("Failed to process bus: %s", strerror(-r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to process bus: %m"); if (m) { dump(m, stdout); + + if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected") > 0) { + log_info("Connection terminated, exiting."); + return 0; + } + continue; } @@ -1139,10 +1151,8 @@ static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FIL continue; r = sd_bus_wait(bus, (uint64_t) -1); - if (r < 0) { - log_error("Failed to wait for bus: %s", strerror(-r)); - return r; - } + if (r < 0) + return log_error_errno(r, "Failed to wait for bus: %m"); } } @@ -1175,26 +1185,49 @@ static int status(sd_bus *bus, char *argv[]) { assert(bus); - if (strv_length(argv) != 2) { - log_error("Expects one argument."); + if (strv_length(argv) > 2) { + log_error("Expects no or one argument."); return -EINVAL; } - r = parse_pid(argv[1], &pid); - if (r < 0) - r = sd_bus_get_name_creds( + if (argv[1]) { + r = parse_pid(argv[1], &pid); + if (r < 0) + r = sd_bus_get_name_creds( + bus, + argv[1], + (arg_augment_creds ? SD_BUS_CREDS_AUGMENT : 0) | _SD_BUS_CREDS_ALL, + &creds); + else + r = sd_bus_creds_new_from_pid( + &creds, + pid, + _SD_BUS_CREDS_ALL); + } else { + const char *scope, *address; + sd_id128_t bus_id; + + r = sd_bus_get_address(bus, &address); + if (r >= 0) + printf("BusAddress=%s%s%s\n", ansi_highlight(), address, ansi_highlight_off()); + + r = sd_bus_get_scope(bus, &scope); + if (r >= 0) + printf("BusScope=%s%s%s\n", ansi_highlight(), scope, ansi_highlight_off()); + + r = sd_bus_get_bus_id(bus, &bus_id); + if (r >= 0) + printf("BusID=%s" SD_ID128_FORMAT_STR "%s\n", ansi_highlight(), SD_ID128_FORMAT_VAL(bus_id), ansi_highlight_off()); + + r = sd_bus_get_owner_creds( bus, - argv[1], (arg_augment_creds ? SD_BUS_CREDS_AUGMENT : 0) | _SD_BUS_CREDS_ALL, &creds); - else - r = sd_bus_creds_new_from_pid(&creds, pid, _SD_BUS_CREDS_ALL); - - if (r < 0) { - log_error("Failed to get credentials: %s", strerror(-r)); - return r; } + if (r < 0) + return log_error_errno(r, "Failed to get credentials: %m"); + bus_creds_dump(creds, NULL, false); return 0; } @@ -1675,11 +1708,11 @@ static int help(void) { " --augment-creds=BOOL Extend credential data with data read from /proc/$PID\n\n" "Commands:\n" " list List bus names\n" - " status SERVICE Show service name status\n" + " status [SERVICE] Show bus service, process or bus owner credentials\n" " monitor [SERVICE...] Show bus traffic\n" " capture [SERVICE...] Capture bus traffic as pcap\n" " tree [SERVICE...] Show object tree of service\n" - " introspect SERVICE OBJECT\n" + " introspect SERVICE OBJECT [INTERFACE]\n" " call SERVICE OBJECT INTERFACE METHOD [SIGNATURE [ARGUMENT...]]\n" " Call a method\n" " get-property SERVICE OBJECT INTERFACE PROPERTY...\n" @@ -1829,7 +1862,7 @@ static int parse_argv(int argc, char *argv[]) { break; case 'M': - arg_transport = BUS_TRANSPORT_CONTAINER; + arg_transport = BUS_TRANSPORT_MACHINE; arg_host = optarg; break; @@ -1953,7 +1986,7 @@ int main(int argc, char *argv[]) { r = sd_bus_new(&bus); if (r < 0) { - log_error("Failed to allocate bus: %s", strerror(-r)); + log_error_errno(r, "Failed to allocate bus: %m"); goto finish; } @@ -1962,25 +1995,25 @@ int main(int argc, char *argv[]) { r = sd_bus_set_monitor(bus, true); if (r < 0) { - log_error("Failed to set monitor mode: %s", strerror(-r)); + log_error_errno(r, "Failed to set monitor mode: %m"); goto finish; } - r = sd_bus_negotiate_creds(bus, _SD_BUS_CREDS_ALL); + r = sd_bus_negotiate_creds(bus, true, _SD_BUS_CREDS_ALL); if (r < 0) { - log_error("Failed to enable credentials: %s", strerror(-r)); + log_error_errno(r, "Failed to enable credentials: %m"); goto finish; } r = sd_bus_negotiate_timestamp(bus, true); if (r < 0) { - log_error("Failed to enable timestamps: %s", strerror(-r)); + log_error_errno(r, "Failed to enable timestamps: %m"); goto finish; } r = sd_bus_negotiate_fds(bus, true); if (r < 0) { - log_error("Failed to enable fds: %s", strerror(-r)); + log_error_errno(r, "Failed to enable fds: %m"); goto finish; } } @@ -1990,25 +2023,28 @@ int main(int argc, char *argv[]) { else { r = sd_bus_set_bus_client(bus, true); if (r < 0) { - log_error("Failed to set bus client: %s", strerror(-r)); + log_error_errno(r, "Failed to set bus client: %m"); goto finish; } switch (arg_transport) { case BUS_TRANSPORT_LOCAL: - if (arg_user) + if (arg_user) { + bus->is_user = true; r = bus_set_address_user(bus); - else + } else { + bus->is_system = true; r = bus_set_address_system(bus); + } break; case BUS_TRANSPORT_REMOTE: r = bus_set_address_system_remote(bus, arg_host); break; - case BUS_TRANSPORT_CONTAINER: - r = bus_set_address_system_container(bus, arg_host); + case BUS_TRANSPORT_MACHINE: + r = bus_set_address_system_machine(bus, arg_host); break; default: @@ -2016,13 +2052,13 @@ int main(int argc, char *argv[]) { } } if (r < 0) { - log_error("Failed to set address: %s", strerror(-r)); + log_error_errno(r, "Failed to set address: %m"); goto finish; } r = sd_bus_start(bus); if (r < 0) { - log_error("Failed to connect to bus: %s", strerror(-r)); + log_error_errno(r, "Failed to connect to bus: %m"); goto finish; }