chiark / gitweb /
execute: fix parsing of StandardError= setting
[elogind.git] / src / dbus.c
index 6ed659a2393e870786035e71f22b05b193f85c36..65e4daa01cb55ddd570b843c7dc92d45968b1691 100644 (file)
 #include "dbus-unit.h"
 #include "dbus-job.h"
 #include "dbus-manager.h"
+#include "dbus-service.h"
+#include "dbus-socket.h"
+#include "dbus-target.h"
+#include "dbus-device.h"
+#include "dbus-mount.h"
+#include "dbus-automount.h"
+#include "dbus-snapshot.h"
+#include "dbus-swap.h"
+#include "dbus-timer.h"
+#include "dbus-path.h"
+
+static const char bus_properties_interface[] = BUS_PROPERTIES_INTERFACE;
+static const char bus_introspectable_interface[] = BUS_INTROSPECTABLE_INTERFACE;
+
+const char *const bus_interface_table[] = {
+        "org.freedesktop.DBus.Properties",     bus_properties_interface,
+        "org.freedesktop.DBus.Introspectable", bus_introspectable_interface,
+        "org.freedesktop.systemd1.Manager",    bus_manager_interface,
+        "org.freedesktop.systemd1.Job",        bus_job_interface,
+        "org.freedesktop.systemd1.Unit",       bus_unit_interface,
+        "org.freedesktop.systemd1.Service",    bus_service_interface,
+        "org.freedesktop.systemd1.Socket",     bus_socket_interface,
+        "org.freedesktop.systemd1.Target",     bus_target_interface,
+        "org.freedesktop.systemd1.Device",     bus_device_interface,
+        "org.freedesktop.systemd1.Mount",      bus_mount_interface,
+        "org.freedesktop.systemd1.Automount",  bus_automount_interface,
+        "org.freedesktop.systemd1.Snapshot",   bus_snapshot_interface,
+        "org.freedesktop.systemd1.Swap",       bus_swap_interface,
+        "org.freedesktop.systemd1.Timer",      bus_timer_interface,
+        "org.freedesktop.systemd1.Path",       bus_path_interface,
+        NULL
+};
+
+static const char *error_to_dbus(int error);
 
 static void api_bus_dispatch_status(DBusConnection *bus, DBusDispatchStatus status, void *data)  {
         Manager *m = data;
@@ -301,6 +335,7 @@ static void bus_toggle_timeout(DBusTimeout *timeout, void *data) {
 static DBusHandlerResult api_bus_message_filter(DBusConnection  *connection, DBusMessage  *message, void *data) {
         Manager *m = data;
         DBusError error;
+        DBusMessage *reply = NULL;
 
         assert(connection);
         assert(message);
@@ -338,10 +373,65 @@ static DBusHandlerResult api_bus_message_filter(DBusConnection  *connection, DBu
 
                         manager_dispatch_bus_name_owner_changed(m, name, old_owner, new_owner);
                 }
+        } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Activator", "ActivationRequest")) {
+                const char *name;
+
+                if (!dbus_message_get_args(message, &error,
+                                           DBUS_TYPE_STRING, &name,
+                                           DBUS_TYPE_INVALID))
+                        log_error("Failed to parse ActivationRequest message: %s", error.message);
+                else  {
+                        int r;
+                        Unit *u;
+
+                        r = manager_load_unit(m, name, NULL, &u);
+
+                        if (r >= 0 && u->meta.only_by_dependency)
+                                r = -EPERM;
+
+                        if (r >= 0)
+                                r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, NULL);
+
+                        if (r < 0) {
+                                const char *id, *text;
+
+                                if (!(reply = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure")))
+                                        goto oom;
+
+                                id = error_to_dbus(r);
+                                text = strerror(-r);
+
+                                if (!dbus_message_set_destination(reply, DBUS_SERVICE_DBUS) ||
+                                    !dbus_message_append_args(reply,
+                                                              DBUS_TYPE_STRING, &name,
+                                                              DBUS_TYPE_STRING, &id,
+                                                              DBUS_TYPE_STRING, &text,
+                                                              DBUS_TYPE_INVALID))
+                                        goto oom;
+                        }
+
+                        /* On success we don't do anything, the service will be spwaned now */
+                }
         }
 
         dbus_error_free(&error);
+
+        if (reply) {
+                if (!dbus_connection_send(connection, reply, NULL))
+                        goto oom;
+
+                dbus_message_unref(reply);
+        }
+
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+oom:
+        if (reply)
+                dbus_message_unref(reply);
+
+        dbus_error_free(&error);
+
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
 }
 
 static DBusHandlerResult system_bus_message_filter(DBusConnection  *connection, DBusMessage  *message, void *data) {
@@ -610,6 +700,7 @@ int bus_init_api(Manager *m) {
                 return -ENOMEM;
         }
 
+        /* Get NameOwnerChange messages */
         dbus_bus_add_match(m->api_bus,
                            "type='signal',"
                            "sender='"DBUS_SERVICE_DBUS"',"
@@ -624,6 +715,21 @@ int bus_init_api(Manager *m) {
                 return -ENOMEM;
         }
 
+        /* Get activation requests */
+        dbus_bus_add_match(m->api_bus,
+                           "type='signal',"
+                           "sender='"DBUS_SERVICE_DBUS"',"
+                           "interface='org.freedesktop.systemd1.Activator',"
+                           "path='"DBUS_PATH_DBUS"'",
+                           &error);
+
+        if (dbus_error_is_set(&error)) {
+                log_error("Failed to register match: %s", error.message);
+                dbus_error_free(&error);
+                bus_done_api(m);
+                return -ENOMEM;
+        }
+
         if ((r = request_name(m)) < 0) {
                 bus_done_api(m);
                 return r;