X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fdbus.c;h=7916817629914569e6ae4bfa107b83769406d701;hp=f5bbc5815a364693874eb26f0ef40686ad97c763;hb=0034c15c60ba5c30cf2786c5693c71f99dfffbc3;hpb=9a9a438596e6f57cda87fc7045971197fd2b3078 diff --git a/src/dbus.c b/src/dbus.c index f5bbc5815..791681762 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -65,6 +65,8 @@ const char *const bus_interface_table[] = { NULL }; +static const char *error_to_dbus(int error); + static void api_bus_dispatch_status(DBusConnection *bus, DBusDispatchStatus status, void *data) { Manager *m = data; @@ -333,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); @@ -340,10 +343,10 @@ static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBu 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! API D-Bus connection terminated."); @@ -370,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) { @@ -642,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"'," @@ -656,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;