#include "pager.h"
#include "xml.h"
#include "path-util.h"
+#include "set.h"
#include "sd-bus.h"
#include "bus-message.h"
static bool arg_expect_reply = true;
static bool arg_auto_start = true;
static bool arg_allow_interactive_authorization = true;
+static bool arg_augment_creds = true;
static usec_t arg_timeout = 0;
static void pager_open_if_enabled(void) {
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();
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);
printf("%-*s", (int) max_i, *i);
- r = sd_bus_get_name_creds(bus, *i,
- SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|
- SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_SESSION|
- SD_BUS_CREDS_DESCRIPTION, &creds);
+ r = sd_bus_get_name_creds(
+ bus, *i,
+ (arg_augment_creds ? SD_BUS_CREDS_AUGMENT : 0) |
+ SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|
+ SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_SESSION|
+ SD_BUS_CREDS_DESCRIPTION, &creds);
if (r >= 0) {
const char *unique, *session, *unit, *cn;
pid_t pid;
} else
fputs(" - - ", stdout);
- r = sd_bus_creds_get_uid(creds, &uid);
+ r = sd_bus_creds_get_euid(creds, &uid);
if (r >= 0) {
_cleanup_free_ char *u = NULL;
l++;
}
- vertical = strappenda(prefix, draw_special_char(DRAW_TREE_VERTICAL));
- space = strappenda(prefix, draw_special_char(DRAW_TREE_SPACE));
+ vertical = strjoina(prefix, draw_special_char(DRAW_TREE_VERTICAL));
+ space = strjoina(prefix, draw_special_char(DRAW_TREE_SPACE));
for (;;) {
bool has_more = false;
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();
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;
assert_not_reached("Unknown basic type.");
}
+ needs_space = true;
}
}
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();
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));
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)
if (result_width > 40)
result_width = 40;
- assert(k == set_size(members));
qsort(sorted, k, sizeof(Member*), member_compare_funcp);
if (arg_legend) {
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)
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;
}
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");
}
}
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(bus, argv[1], _SD_BUS_CREDS_ALL, &creds);
- else
- r = sd_bus_creds_new_from_pid(&creds, pid, _SD_BUS_CREDS_ALL);
+ 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;
- if (r < 0) {
- log_error("Failed to get credentials: %s", strerror(-r));
- return r;
+ 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,
+ (arg_augment_creds ? SD_BUS_CREDS_AUGMENT : 0) | _SD_BUS_CREDS_ALL,
+ &creds);
}
+ if (r < 0)
+ return log_error_errno(r, "Failed to get credentials: %m");
+
bus_creds_dump(creds, NULL, false);
return 0;
}
" --auto-start=BOOL Auto-start destination service\n"
" --allow-interactive-authorization=BOOL\n"
" Allow interactive authorization for operation\n"
- " --timeout=SECS Maximum time to wait for method call completion\n\n"
+ " --timeout=SECS Maximum time to wait for method call completion\n"
+ " --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"
ARG_AUTO_START,
ARG_ALLOW_INTERACTIVE_AUTHORIZATION,
ARG_TIMEOUT,
+ ARG_AUGMENT_CREDS,
};
static const struct option options[] = {
{ "auto-start", required_argument, NULL, ARG_AUTO_START },
{ "allow-interactive-authorization", required_argument, NULL, ARG_ALLOW_INTERACTIVE_AUTHORIZATION },
{ "timeout", required_argument, NULL, ARG_TIMEOUT },
+ { "augment-creds",required_argument, NULL, ARG_AUGMENT_CREDS},
{},
};
break;
case 'M':
- arg_transport = BUS_TRANSPORT_CONTAINER;
+ arg_transport = BUS_TRANSPORT_MACHINE;
arg_host = optarg;
break;
break;
+ case ARG_AUGMENT_CREDS:
+ r = parse_boolean(optarg);
+ if (r < 0) {
+ log_error("Failed to parse --augment-creds= parameter.");
+ return r;
+ }
+
+ arg_augment_creds = !!r;
+ break;
+
case '?':
return -EINVAL;
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;
}
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;
}
}
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:
}
}
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;
}