X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flogind-user-dbus.c;h=7263d1b757265ecc2504224a94524625b0a71a3f;hp=7c8bb27c6d3ee44fd20af2a77d812814b7045d6e;hb=82e487c56d0947796793b6fd2836264328defe9f;hpb=3f49d45a45c6c585098590174c3245d2d9bdde0a diff --git a/src/logind-user-dbus.c b/src/logind-user-dbus.c index 7c8bb27c6..7263d1b75 100644 --- a/src/logind-user-dbus.c +++ b/src/logind-user-dbus.c @@ -20,6 +20,7 @@ ***/ #include +#include #include "logind.h" #include "logind-user.h" @@ -31,12 +32,17 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ " \n" \ - " \n" \ " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ #define INTROSPECTION \ @@ -115,7 +121,7 @@ static int bus_user_append_sessions(DBusMessageIter *i, const char *property, vo assert(property); assert(u); - if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "so", &sub)) + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(so)", &sub)) return -ENOMEM; LIST_FOREACH(sessions_by_user, session, u->sessions) { @@ -146,6 +152,40 @@ static int bus_user_append_sessions(DBusMessageIter *i, const char *property, vo return 0; } +static int bus_user_append_idle_hint(DBusMessageIter *i, const char *property, void *data) { + User *u = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(u); + + b = user_get_idle_hint(u, NULL) > 0; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_user_append_idle_hint_since(DBusMessageIter *i, const char *property, void *data) { + User *u = data; + dual_timestamp t; + uint64_t k; + + assert(i); + assert(property); + assert(u); + + user_get_idle_hint(u, &t); + k = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &k)) + return -ENOMEM; + + return 0; +} + static int get_user_for_path(Manager *m, const char *path, User **_u) { User *u; unsigned long lu; @@ -176,23 +216,59 @@ static DBusHandlerResult user_message_dispatch( DBusMessage *message) { const BusProperty properties[] = { - { "org.freedesktop.login1.User", "UID", bus_property_append_uid, "u", &u->uid }, - { "org.freedesktop.login1.User", "GID", bus_property_append_gid, "u", &u->gid }, - { "org.freedesktop.login1.User", "Name", bus_property_append_string, "s", u->name }, - { "org.freedesktop.login1.User", "RuntimePath", bus_property_append_string, "s", u->runtime_path }, - { "org.freedesktop.login1.User", "ControlGroupPath", bus_property_append_string, "s", u->cgroup_path }, - { "org.freedesktop.login1.User", "Service", bus_property_append_string, "s", u->service }, - { "org.freedesktop.login1.User", "Display", bus_user_append_display, "(so)", u }, - { "org.freedesktop.login1.User", "State", bus_user_append_state, "s", u }, - { "org.freedesktop.login1.User", "Sessions", bus_user_append_sessions, "a(so)", u }, + { "org.freedesktop.login1.User", "UID", bus_property_append_uid, "u", &u->uid }, + { "org.freedesktop.login1.User", "GID", bus_property_append_gid, "u", &u->gid }, + { "org.freedesktop.login1.User", "Name", bus_property_append_string, "s", u->name }, + { "org.freedesktop.login1.User", "Timestamp", bus_property_append_usec, "t", &u->timestamp.realtime }, + { "org.freedesktop.login1.User", "TimestampMonotonic", bus_property_append_usec, "t", &u->timestamp.monotonic }, + { "org.freedesktop.login1.User", "RuntimePath", bus_property_append_string, "s", u->runtime_path }, + { "org.freedesktop.login1.User", "ControlGroupPath", bus_property_append_string, "s", u->cgroup_path }, + { "org.freedesktop.login1.User", "Service", bus_property_append_string, "s", u->service }, + { "org.freedesktop.login1.User", "Display", bus_user_append_display, "(so)", u }, + { "org.freedesktop.login1.User", "State", bus_user_append_state, "s", u }, + { "org.freedesktop.login1.User", "Sessions", bus_user_append_sessions, "a(so)", u }, + { "org.freedesktop.login1.User", "IdleHint", bus_user_append_idle_hint, "b", u }, + { "org.freedesktop.login1.User", "IdleSinceHint", bus_user_append_idle_hint_since, "t", u }, + { "org.freedesktop.login1.User", "IdleSinceHintMonotonic", bus_user_append_idle_hint_since, "t", u }, { NULL, NULL, NULL, NULL, NULL } }; + DBusError error; + DBusMessage *reply = NULL; + int r; + assert(u); assert(connection); assert(message); - return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, properties); + if (dbus_message_is_method_call(message, "org.freedesktop.login1.User", "Terminate")) { + + r = user_stop(u); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + } else + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, properties); + + if (reply) { + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; } static DBusHandlerResult user_message_handler( @@ -238,3 +314,74 @@ char *user_bus_path(User *u) { return s; } + +int user_send_signal(User *u, bool new_user) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + uint32_t uid; + + assert(u); + + m = dbus_message_new_signal("/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + new_user ? "UserNew" : "UserRemoved"); + + if (!m) + return -ENOMEM; + + p = user_bus_path(u); + if (!p) + goto finish; + + uid = u->uid; + + if (!dbus_message_append_args( + m, + DBUS_TYPE_UINT32, &uid, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID)) + goto finish; + + if (!dbus_connection_send(u->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + dbus_message_unref(m); + free(p); + + return r; +} + +int user_send_changed(User *u, const char *properties) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + + assert(u); + + if (!u->started) + return 0; + + p = user_bus_path(u); + if (!p) + return -ENOMEM; + + m = bus_properties_changed_new(p, "org.freedesktop.login1.User", properties); + if (!m) + goto finish; + + if (!dbus_connection_send(u->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + free(p); + + return r; +}