summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--src/libsystemd-bus/bus-util.c75
-rw-r--r--src/libsystemd-bus/bus-util.h2
-rw-r--r--src/systemctl/systemctl.c18
4 files changed, 86 insertions, 11 deletions
diff --git a/TODO b/TODO
index 9b8df458b7..e08e11e2d7 100644
--- a/TODO
+++ b/TODO
@@ -48,7 +48,7 @@ Features:
* add field to transient units that indicate whether systemd or somebody else saves/restores its settings, for integration with libvirt
-* direct connections to PID 1/XDG_RUNTIME_DIR, wait filter, reboot() filter unification, unify dispatch table in systemctl_main() and friends, convert all to bus_log_create_error()
+* wait filter, reboot() filter unification, unify dispatch table in systemctl_main() and friends, convert all to bus_log_create_error()
* bus: access policy as vtable flag
diff --git a/src/libsystemd-bus/bus-util.c b/src/libsystemd-bus/bus-util.c
index 2cf718b096..3dd208d0c1 100644
--- a/src/libsystemd-bus/bus-util.c
+++ b/src/libsystemd-bus/bus-util.c
@@ -440,6 +440,46 @@ int bus_open_system_systemd(sd_bus **_bus) {
return 0;
}
+int bus_open_user_systemd(sd_bus **_bus) {
+ _cleanup_bus_unref_ sd_bus *bus = NULL;
+ _cleanup_free_ char *p = NULL;
+ const char *e;
+ int r;
+
+ /* If we are supposed to talk to the instance, try via
+ * XDG_RUNTIME_DIR first, then fallback to normal bus
+ * access */
+
+ assert(_bus);
+
+ e = secure_getenv("XDG_RUNTIME_DIR");
+ if (e) {
+ if (asprintf(&p, "unix:path=%s/systemd/private", e) < 0)
+ return -ENOMEM;
+ }
+
+ r = sd_bus_new(&bus);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_set_address(bus, p);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_start(bus);
+ if (r < 0)
+ return r;
+
+ r = bus_check_peercred(bus);
+ if (r < 0)
+ return r;
+
+ *_bus = bus;
+ bus = NULL;
+
+ return 0;
+}
+
int bus_print_property(const char *name, sd_bus_message *property, bool all) {
char type;
const char *contents;
@@ -924,6 +964,41 @@ int bus_open_transport(BusTransport transport, const char *host, bool user, sd_b
return r;
}
+int bus_open_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) {
+ int r;
+
+ assert(transport >= 0);
+ assert(transport < _BUS_TRANSPORT_MAX);
+ assert(bus);
+
+ assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
+ assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -ENOTSUP);
+
+ switch (transport) {
+
+ case BUS_TRANSPORT_LOCAL:
+ if (user)
+ r = bus_open_user_systemd(bus);
+ else
+ r = bus_open_system_systemd(bus);
+
+ break;
+
+ case BUS_TRANSPORT_REMOTE:
+ r = sd_bus_open_system_remote(host, bus);
+ break;
+
+ case BUS_TRANSPORT_CONTAINER:
+ r = sd_bus_open_system_container(host, bus);
+ break;
+
+ default:
+ assert_not_reached("Hmm, unknown transport type.");
+ }
+
+ return r;
+}
+
int bus_property_get_bool(
sd_bus *bus,
const char *path,
diff --git a/src/libsystemd-bus/bus-util.h b/src/libsystemd-bus/bus-util.h
index 21a483fb01..314c2f7867 100644
--- a/src/libsystemd-bus/bus-util.h
+++ b/src/libsystemd-bus/bus-util.h
@@ -63,8 +63,10 @@ int bus_verify_polkit_async(sd_bus *bus, Hashmap **registry, sd_bus_message *m,
void bus_verify_polkit_async_registry_free(sd_bus *bus, Hashmap *registry);
int bus_open_system_systemd(sd_bus **_bus);
+int bus_open_user_systemd(sd_bus **_bus);
int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus);
+int bus_open_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus);
int bus_print_property(const char *name, sd_bus_message *property, bool all);
int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all);
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 7a2431986d..73fdbdbed6 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -5354,7 +5354,7 @@ static int talk_initctl(void) {
return 1;
}
-static int systemctl_main(sd_bus *bus, int argc, char *argv[], const int r) {
+static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
static const struct {
const char* verb;
@@ -5505,14 +5505,14 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], const int r) {
if (((!streq(verbs[i].verb, "reboot") &&
!streq(verbs[i].verb, "halt") &&
!streq(verbs[i].verb, "poweroff")) || arg_force <= 0) && !bus) {
- log_error("Failed to get D-Bus connection: %s", strerror (-r));
+ log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
return -EIO;
}
} else {
if (!bus && !avoid_bus()) {
- log_error("Failed to get D-Bus connection: %s", strerror (-r));
+ log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
return -EIO;
}
}
@@ -5764,13 +5764,11 @@ int main(int argc, char*argv[]) {
goto finish;
}
- if (!avoid_bus()) {
- r = bus_open_transport(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
- if (r < 0) {
- log_error("Failed to create bus connection: %s", strerror(-r));
- goto finish;
- }
- }
+ if (!avoid_bus())
+ r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
+
+ /* systemctl_main() will print an error message for the bus
+ * connection, but only if it needs to */
switch (arg_action) {