chiark / gitweb /
bus: move ssh support into public API of libsystem-bus
[elogind.git] / src / libsystemd-bus / sd-bus.c
index 665f1e6c8bae11c7035eed493f168389ac0bb0a9..383b035b7e99cec269c7d02e3294de3f168811eb 100644 (file)
@@ -1033,6 +1033,42 @@ fail:
         return r;
 }
 
+int sd_bus_open_system_remote(const char *host, sd_bus **ret) {
+        _cleanup_free_ char *e = NULL;
+        char *p = NULL;
+        sd_bus *bus;
+        int r;
+
+        assert_return(host, -EINVAL);
+        assert_return(ret, -EINVAL);
+
+        e = bus_address_escape(host);
+        if (!e)
+                return -ENOMEM;
+
+        p = strjoin("unixexec:path=ssh,argv1=-xT,argv2=", e, ",argv3=systemd-stdio-bridge", NULL);
+        if (!p)
+                return -ENOMEM;
+
+        r = sd_bus_new(&bus);
+        if (r < 0) {
+                free(p);
+                return r;
+        }
+
+        bus->address = p;
+        bus->bus_client = true;
+
+        r = sd_bus_start(bus);
+        if (r < 0) {
+                bus_free(bus);
+                return r;
+        }
+
+        *ret = bus;
+        return 0;
+}
+
 void sd_bus_close(sd_bus *bus) {
         if (!bus)
                 return;
@@ -2208,6 +2244,16 @@ static int prepare_callback(sd_event_source *s, void *userdata) {
         return 1;
 }
 
+static int quit_callback(sd_event_source *event, void *userdata) {
+        sd_bus *bus = userdata;
+
+        assert(event);
+
+        sd_bus_flush(bus);
+
+        return 1;
+}
+
 int sd_bus_attach_event(sd_bus *bus, sd_event *event, int priority) {
         int r;
 
@@ -2251,6 +2297,10 @@ int sd_bus_attach_event(sd_bus *bus, sd_event *event, int priority) {
         if (r < 0)
                 goto fail;
 
+        r = sd_event_add_quit(event, quit_callback, bus, &bus->quit_event_source);
+        if (r < 0)
+                goto fail;
+
         return 0;
 
 fail:
@@ -2271,6 +2321,9 @@ int sd_bus_detach_event(sd_bus *bus) {
         if (bus->time_event_source)
                 bus->time_event_source = sd_event_source_unref(bus->time_event_source);
 
+        if (bus->quit_event_source)
+                bus->quit_event_source = sd_event_source_unref(bus->quit_event_source);
+
         if (bus->event)
                 bus->event = sd_event_unref(bus->event);