X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fsystemctl.c;h=799f57d006d3b0b6b0883e7eba18cbcad1418cbe;hp=76f6b84aa59e2f8589d1808333afde9d85a01db7;hb=c6c18be35bb1d300d0b62a568783cc1c477f7151;hpb=c59760eedae9d9de3be1572b9b612dfd8cc37547 diff --git a/src/systemctl.c b/src/systemctl.c index 76f6b84aa..799f57d00 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -41,6 +41,10 @@ #include "special.h" #include "initreq.h" #include "strv.h" +#include "dbus-common.h" +#include "cgroup-show.h" +#include "cgroup-util.h" +#include "list.h" static const char *arg_type = NULL; static const char *arg_property = NULL; @@ -74,6 +78,8 @@ enum action { _ACTION_MAX } arg_action = ACTION_SYSTEMCTL; +static bool private_bus = false; + static bool error_is_no_service(DBusError *error) { assert(error); @@ -106,57 +112,6 @@ static int bus_iter_get_basic_and_next(DBusMessageIter *iter, int type, void *da return 0; } -static int bus_check_peercred(DBusConnection *c) { - int fd; - struct ucred ucred; - socklen_t l; - - assert(c); - - assert_se(dbus_connection_get_unix_fd(c, &fd)); - - l = sizeof(struct ucred); - if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0) { - log_error("SO_PEERCRED failed: %m"); - return -errno; - } - - if (l != sizeof(struct ucred)) { - log_error("SO_PEERCRED returned wrong size."); - return -E2BIG; - } - - if (ucred.uid != 0) - return -EPERM; - - return 1; -} - -static int columns(void) { - static int parsed_columns = 0; - const char *e; - - if (parsed_columns > 0) - return parsed_columns; - - if ((e = getenv("COLUMNS"))) - parsed_columns = atoi(e); - - if (parsed_columns <= 0) { - struct winsize ws; - zero(ws); - - if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0) - parsed_columns = ws.ws_col; - } - - if (parsed_columns <= 0) - parsed_columns = 80; - - return parsed_columns; - -} - static void warn_wall(enum action action) { static const char *table[_ACTION_MAX] = { [ACTION_HALT] = "The system is going down for system halt NOW!", @@ -262,6 +217,9 @@ static int list_units(DBusConnection *bus, char **args, unsigned n) { int a = 0, b = 0; + if (streq(active_state, "maintenance")) + fputs(ANSI_HIGHLIGHT_ON, stdout); + printf("%-45s %-6s %-12s %-12s%n", id, load_state, active_state, sub_state, &a); if (job_id != 0) @@ -273,9 +231,12 @@ static int list_units(DBusConnection *bus, char **args, unsigned n) { if (job_id == 0) printf(" "); - printf("%.*s", columns() - a - b - 2, description); + printf(" %.*s", columns() - a - b - 2, description); } + if (streq(active_state, "maintenance")) + fputs(ANSI_HIGHLIGHT_OFF, stdout); + fputs("\n", stdout); k++; } @@ -546,10 +507,10 @@ static DBusHandlerResult wait_filter(DBusConnection *connection, DBusMessage *me dbus_error_init(&error); - /* log_debug("Got D-Bus request: %s.%s() on %s", */ - /* dbus_message_get_interface(message), */ - /* dbus_message_get_member(message), */ - /* dbus_message_get_path(message)); */ + log_debug("Got D-Bus request: %s.%s() on %s", + dbus_message_get_interface(message), + dbus_message_get_member(message), + dbus_message_get_path(message)); if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) { log_error("Warning! D-Bus connection terminated."); @@ -586,6 +547,9 @@ static int enable_wait_for_jobs(DBusConnection *bus) { assert(bus); + if (private_bus) + return 0; + dbus_error_init(&error); dbus_bus_add_match(bus, "type='signal'," @@ -881,6 +845,7 @@ static int check_unit(DBusConnection *bus, char **args, unsigned n) { if (!arg_quiet) puts("unknown"); + dbus_error_free(&error); continue; } @@ -959,41 +924,93 @@ finish: return r; } -static void show_cgroup(const char *name) { - char *fn, *pids; - int r; - char *p; +typedef struct ExecStatusInfo { + char *path; + char **argv; - if (!startswith(name, "name=systemd:")) - return; + usec_t start_timestamp; + usec_t exit_timestamp; + pid_t pid; + int code; + int status; - if (asprintf(&fn, "/cgroup/systemd/%s/tasks", name + 13) < 0) - return; + LIST_FIELDS(struct ExecStatusInfo, exec); +} ExecStatusInfo; + +static void exec_status_info_free(ExecStatusInfo *i) { + assert(i); - r = read_one_line_file(fn, &pids); - free(fn); + free(i->path); + strv_free(i->argv); + free(i); +} - if (r < 0) - return; +static int exec_status_info_deserialize(DBusMessageIter *sub, ExecStatusInfo *i) { + uint64_t start_timestamp, exit_timestamp; + DBusMessageIter sub2, sub3; + const char*path; + unsigned n; + uint32_t pid; + int32_t code, status; - p = pids; - while (p[0]) { - unsigned long ul; - char *t = NULL; + assert(i); + assert(i); - p += strspn(p, WHITESPACE); + if (dbus_message_iter_get_arg_type(sub) != DBUS_TYPE_STRUCT) + return -EIO; - errno = 0; - ul = strtoul(p, &p, 0); - if (errno != 0 || ul <= 0) - break; + dbus_message_iter_recurse(sub, &sub2); - get_process_cmdline((pid_t) ul, 60, &t); - printf("\t\t%lu %s\n", ul, strna(t)); - free(t); + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) < 0) + return -EIO; + + if (!(i->path = strdup(path))) + return -ENOMEM; + + if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&sub2) != DBUS_TYPE_STRING) + return -EIO; + + n = 0; + dbus_message_iter_recurse(&sub2, &sub3); + while (dbus_message_iter_get_arg_type(&sub3) != DBUS_TYPE_INVALID) { + assert(dbus_message_iter_get_arg_type(&sub3) == DBUS_TYPE_STRING); + dbus_message_iter_next(&sub3); + n++; + } + + + if (!(i->argv = new0(char*, n+1))) + return -ENOMEM; + + n = 0; + dbus_message_iter_recurse(&sub2, &sub3); + while (dbus_message_iter_get_arg_type(&sub3) != DBUS_TYPE_INVALID) { + const char *s; + + assert(dbus_message_iter_get_arg_type(&sub3) == DBUS_TYPE_STRING); + dbus_message_iter_get_basic(&sub3, &s); + dbus_message_iter_next(&sub3); + + if (!(i->argv[n++] = strdup(s))) + return -ENOMEM; } - free(pids); + if (!dbus_message_iter_next(&sub2) || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &start_timestamp, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &exit_timestamp, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &pid, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &code, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &status, false) < 0) + return -EIO; + + i->start_timestamp = (usec_t) start_timestamp; + i->exit_timestamp = (usec_t) exit_timestamp; + i->pid = (pid_t) pid; + i->code = code; + i->status = status; + + return 0; } typedef struct UnitStatusInfo { @@ -1021,6 +1038,7 @@ typedef struct UnitStatusInfo { /* Socket */ unsigned n_accepted; unsigned n_connections; + bool accept; /* Device */ const char *sysfs_path; @@ -1030,9 +1048,14 @@ typedef struct UnitStatusInfo { /* Swap */ const char *what; + + LIST_HEAD(ExecStatusInfo, exec); } UnitStatusInfo; static void print_status_info(UnitStatusInfo *i) { + ExecStatusInfo *p; + int r; + assert(i); /* This shows pretty information about a unit. See @@ -1052,14 +1075,23 @@ static void print_status_info(UnitStatusInfo *i) { else printf("\t Loaded: %s\n", strna(i->load_state)); - if (streq_ptr(i->active_state, "maintenance")) - printf("\t Active: " ANSI_HIGHLIGHT_ON "%s (%s)" ANSI_HIGHLIGHT_OFF "\n", - strna(i->active_state), - strna(i->sub_state)); - else - printf("\t Active: %s (%s)\n", - strna(i->active_state), - strna(i->sub_state)); + if (streq_ptr(i->active_state, "maintenance")) { + if (streq_ptr(i->active_state, i->sub_state)) + printf("\t Active: " ANSI_HIGHLIGHT_ON "%s" ANSI_HIGHLIGHT_OFF "\n", + strna(i->active_state)); + else + printf("\t Active: " ANSI_HIGHLIGHT_ON "%s (%s)" ANSI_HIGHLIGHT_OFF "\n", + strna(i->active_state), + strna(i->sub_state)); + } else { + if (streq_ptr(i->active_state, i->sub_state)) + printf("\t Active: %s\n", + strna(i->active_state)); + else + printf("\t Active: %s (%s)\n", + strna(i->active_state), + strna(i->sub_state)); + } if (i->sysfs_path) printf("\t Device: %s\n", i->sysfs_path); @@ -1071,14 +1103,41 @@ static void print_status_info(UnitStatusInfo *i) { if (i->status_text) printf("\t Status: \"%s\"\n", i->status_text); - if (i->id && endswith(i->id, ".socket")) + if (i->accept) printf("\tAccepted: %u; Connected: %u\n", i->n_accepted, i->n_connections); + LIST_FOREACH(exec, p, i->exec) { + char *t; + + /* Only show exited processes here */ + if (p->code == 0) + continue; + + t = strv_join(p->argv, " "); + printf("\t Exited: %u (%s, code=%s, ", p->pid, strna(t), sigchld_code_to_string(p->code)); + free(t); + + if (p->code == CLD_EXITED) + printf("status=%i", p->status); + else + printf("signal=%s", signal_to_string(p->status)); + printf(")\n"); + + if (i->main_pid == p->pid && + i->start_timestamp == p->start_timestamp && + i->exit_timestamp == p->start_timestamp) + /* Let's not show this twice */ + i->main_pid = 0; + + if (p->pid == i->control_pid) + i->control_pid = 0; + } + if (i->main_pid > 0 || i->control_pid > 0) { printf("\t"); if (i->main_pid > 0) { - printf(" Process: %u", (unsigned) i->main_pid); + printf(" Main: %u", (unsigned) i->main_pid); if (i->running) { char *t = NULL; @@ -1093,7 +1152,7 @@ static void print_status_info(UnitStatusInfo *i) { if (i->exit_code == CLD_EXITED) printf("status=%i", i->exit_status); else - printf("signal=%s", strsignal(i->exit_status)); + printf("signal=%s", signal_to_string(i->exit_status)); printf(")"); } } @@ -1117,8 +1176,19 @@ static void print_status_info(UnitStatusInfo *i) { } if (i->default_control_group) { + unsigned c; + printf("\t CGroup: %s\n", i->default_control_group); - show_cgroup(i->default_control_group); + + if ((c = columns()) > 18) + c -= 18; + else + c = 0; + + if ((r = cg_init()) < 0) + log_error("Failed to initialize libcg: %s", strerror(-r)); + else + show_cgroup_recursive(i->default_control_group, "\t\t ", c); } } @@ -1159,6 +1229,17 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn break; } + case DBUS_TYPE_BOOLEAN: { + dbus_bool_t b; + + dbus_message_iter_get_basic(iter, &b); + + if (streq(name, "Accept")) + i->accept = b; + + break; + } + case DBUS_TYPE_UINT32: { uint32_t u; @@ -1207,6 +1288,34 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn break; } + + case DBUS_TYPE_ARRAY: { + + if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && + startswith(name, "Exec")) { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + ExecStatusInfo *info; + int r; + + if (!(info = new0(ExecStatusInfo, 1))) + return -ENOMEM; + + if ((r = exec_status_info_deserialize(&sub, info)) < 0) { + free(info); + return r; + } + + LIST_PREPEND(ExecStatusInfo, exec, i->exec, info); + + dbus_message_iter_next(&sub); + } + } + + break; + } } return 0; @@ -1320,7 +1429,6 @@ static int print_property(const char *name, DBusMessageIter *iter) { bool space = false; dbus_message_iter_recurse(iter, &sub); - if (arg_all || dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { printf("%s=", name); @@ -1340,11 +1448,11 @@ static int print_property(const char *name, DBusMessageIter *iter) { } return 0; + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_BYTE) { DBusMessageIter sub; dbus_message_iter_recurse(iter, &sub); - if (arg_all || dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { printf("%s=", name); @@ -1363,11 +1471,11 @@ static int print_property(const char *name, DBusMessageIter *iter) { } return 0; + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Paths")) { DBusMessageIter sub, sub2; dbus_message_iter_recurse(iter, &sub); - while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { const char *type, *path; @@ -1381,11 +1489,11 @@ static int print_property(const char *name, DBusMessageIter *iter) { } return 0; + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Timers")) { DBusMessageIter sub, sub2; dbus_message_iter_recurse(iter, &sub); - while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { const char *base; uint64_t value, next_elapse; @@ -1407,59 +1515,38 @@ static int print_property(const char *name, DBusMessageIter *iter) { } return 0; - } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && startswith(name, "Exec")) { - DBusMessageIter sub, sub2, sub3; + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && startswith(name, "Exec")) { + DBusMessageIter sub; dbus_message_iter_recurse(iter, &sub); - while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { - const char *path; - uint64_t start_time, exit_time; - uint32_t pid; - int32_t code, status; - - dbus_message_iter_recurse(&sub, &sub2); - - if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) < 0) - continue; - - if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_ARRAY || - dbus_message_iter_get_element_type(&sub2) != DBUS_TYPE_STRING) - continue; - - printf("%s={ path=%s ; argv[]=", name, path); - - dbus_message_iter_recurse(&sub2, &sub3); - - while (dbus_message_iter_get_arg_type(&sub3) != DBUS_TYPE_INVALID) { - const char *s; - - assert(dbus_message_iter_get_arg_type(&sub3) == DBUS_TYPE_STRING); - dbus_message_iter_get_basic(&sub3, &s); - printf("%s ", s); - dbus_message_iter_next(&sub3); - } - - if (dbus_message_iter_next(&sub2) && - bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &start_time, true) >= 0 && - bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &exit_time, true) >= 0 && - bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &pid, true) >= 0 && - bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &code, true) >= 0 && - bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &status, false) >= 0) { + ExecStatusInfo info; + zero(info); + if (exec_status_info_deserialize(&sub, &info) >= 0) { char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX]; + char *t; + + t = strv_join(info.argv, " "); + + printf("%s={ path=%s ; argv[]=%s; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n", + name, + strna(info.path), + strna(t), + strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)), + strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)), + (unsigned) info. pid, + sigchld_code_to_string(info.code), + info.status, + info.code == CLD_EXITED ? "" : "/", + strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status))); - printf("; start=%s ; stop=%s ; pid=%u ; code=%s ; status=%i/%s", - strna(format_timestamp(timestamp1, sizeof(timestamp1), start_time)), - strna(format_timestamp(timestamp2, sizeof(timestamp2), exit_time)), - (unsigned) pid, - sigchld_code_to_string(code), - status, - strempty(code == CLD_EXITED ? NULL : strsignal(status))); + free(t); } - printf(" }\n"); + free(info.path); + strv_free(info.argv); dbus_message_iter_next(&sub); } @@ -1483,6 +1570,7 @@ static int show_one(DBusConnection *bus, const char *path, bool show_properties, DBusError error; DBusMessageIter iter, sub, sub2, sub3; UnitStatusInfo info; + ExecStatusInfo *p; assert(bus); assert(path); @@ -1572,6 +1660,11 @@ static int show_one(DBusConnection *bus, const char *path, bool show_properties, if (!show_properties) print_status_info(&info); + while ((p = info.exec)) { + LIST_REMOVE(ExecStatusInfo, exec, info.exec, p); + exec_status_info_free(p); + } + r = 0; finish: @@ -1632,6 +1725,42 @@ static int show(DBusConnection *bus, char **args, unsigned n) { goto finish; } + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + + if (!dbus_error_has_name(&error, DBUS_ERROR_ACCESS_DENIED)) { + log_error("Failed to issue method call: %s", error.message); + r = -EIO; + goto finish; + } + + dbus_error_free(&error); + + dbus_message_unref(m); + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnit"))) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", error.message); + r = -EIO; + goto finish; + } + } + } else { if (!(m = dbus_message_new_method_call( @@ -1651,12 +1780,12 @@ static int show(DBusConnection *bus, char **args, unsigned n) { r = -ENOMEM; goto finish; } - } - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { - log_error("Failed to issue method call: %s", error.message); - r = -EIO; - goto finish; + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", error.message); + r = -EIO; + goto finish; + } } if (!dbus_message_get_args(reply, &error, @@ -1698,10 +1827,10 @@ static DBusHandlerResult monitor_filter(DBusConnection *connection, DBusMessage dbus_error_init(&error); - /* log_debug("Got D-Bus request: %s.%s() on %s", */ - /* dbus_message_get_interface(message), */ - /* dbus_message_get_member(message), */ - /* dbus_message_get_path(message)); */ + log_debug("Got D-Bus request: %s.%s() on %s", + dbus_message_get_interface(message), + dbus_message_get_member(message), + dbus_message_get_path(message)); if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) { log_error("Warning! D-Bus connection terminated."); @@ -1827,43 +1956,45 @@ static int monitor(DBusConnection *bus, char **args, unsigned n) { dbus_error_init(&error); - dbus_bus_add_match(bus, - "type='signal'," - "sender='org.freedesktop.systemd1'," - "interface='org.freedesktop.systemd1.Manager'," - "path='/org/freedesktop/systemd1'", - &error); + if (!private_bus) { + dbus_bus_add_match(bus, + "type='signal'," + "sender='org.freedesktop.systemd1'," + "interface='org.freedesktop.systemd1.Manager'," + "path='/org/freedesktop/systemd1'", + &error); - if (dbus_error_is_set(&error)) { - log_error("Failed to add match: %s", error.message); - r = -EIO; - goto finish; - } + if (dbus_error_is_set(&error)) { + log_error("Failed to add match: %s", error.message); + r = -EIO; + goto finish; + } - dbus_bus_add_match(bus, - "type='signal'," - "sender='org.freedesktop.systemd1'," - "interface='org.freedesktop.systemd1.Unit'," - "member='Changed'", - &error); + dbus_bus_add_match(bus, + "type='signal'," + "sender='org.freedesktop.systemd1'," + "interface='org.freedesktop.systemd1.Unit'," + "member='Changed'", + &error); - if (dbus_error_is_set(&error)) { - log_error("Failed to add match: %s", error.message); - r = -EIO; - goto finish; - } + if (dbus_error_is_set(&error)) { + log_error("Failed to add match: %s", error.message); + r = -EIO; + goto finish; + } - dbus_bus_add_match(bus, - "type='signal'," - "sender='org.freedesktop.systemd1'," - "interface='org.freedesktop.systemd1.Job'," - "member='Changed'", - &error); + dbus_bus_add_match(bus, + "type='signal'," + "sender='org.freedesktop.systemd1'," + "interface='org.freedesktop.systemd1.Job'," + "member='Changed'", + &error); - if (dbus_error_is_set(&error)) { - log_error("Failed to add match: %s", error.message); - r = -EIO; - goto finish; + if (dbus_error_is_set(&error)) { + log_error("Failed to add match: %s", error.message); + r = -EIO; + goto finish; + } } if (!dbus_connection_add_filter(bus, monitor_filter, NULL, NULL)) { @@ -3072,7 +3203,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[]) { { "reboot", EQUAL, 1, start_special }, { "default", EQUAL, 1, start_special }, { "rescue", EQUAL, 1, start_special }, - { "emergency", EQUAL, 1, start_special }, + { "emergency", EQUAL, 1, start_special } }; int left; @@ -3184,7 +3315,12 @@ static int start_with_fallback(DBusConnection *bus) { static int halt_main(DBusConnection *bus) { int r; - if (!arg_immediate) + if (geteuid() != 0) { + log_error("Must to be root."); + return -EPERM; + } + + if (!arg_dry && !arg_immediate) return start_with_fallback(bus); if (!arg_no_wtmp) @@ -3264,19 +3400,7 @@ int main(int argc, char*argv[]) { goto finish; } - /* If we are root, then let's not go via the bus */ - if (geteuid() == 0 && !arg_session) { - bus = dbus_connection_open("unix:abstract=/org/freedesktop/systemd1/private", &error); - - if (bus && bus_check_peercred(bus) < 0) { - log_error("Failed to verify owner of bus."); - goto finish; - } - } else - bus = dbus_bus_get(arg_session ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &error); - - if (bus) - dbus_connection_set_exit_on_disconnect(bus, FALSE); + bus_connect(arg_session ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &bus, &private_bus, &error); switch (arg_action) {