From 3f49d45a45c6c585098590174c3245d2d9bdde0a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 May 2011 02:21:16 +0200 Subject: logind: implement D-Bus properties --- src/logind-dbus.c | 235 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 src/logind-dbus.c (limited to 'src/logind-dbus.c') diff --git a/src/logind-dbus.c b/src/logind-dbus.c new file mode 100644 index 0000000000..90db94184f --- /dev/null +++ b/src/logind-dbus.c @@ -0,0 +1,235 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include "logind.h" +#include "dbus-common.h" + +#define BUS_MANAGER_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION_BEGIN \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_MANAGER_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE + +#define INTROSPECTION_END \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.login1.Manager\0" + +static DBusHandlerResult manager_message_handler( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + Manager *m = userdata; + + const BusProperty properties[] = { + { "org.freedesktop.login1.Manager", "ControlGroupHierarchy", bus_property_append_string, "s", m->cgroup_path }, + { "org.freedesktop.login1.Manager", "Controllers", bus_property_append_strv, "as", m->controllers }, + { "org.freedesktop.login1.Manager", "ResetControllers", bus_property_append_strv, "as", m->reset_controllers }, + { "org.freedesktop.login1.Manager", "NAutoVTs", bus_property_append_unsigned, "u", &m->n_autovts }, + { "org.freedesktop.login1.Manager", "KillOnlyUsers", bus_property_append_strv, "as", m->kill_only_users }, + { "org.freedesktop.login1.Manager", "KillExcludeUsers", bus_property_append_strv, "as", m->kill_exclude_users }, + { "org.freedesktop.login1.Manager", "KillUserProcesses", bus_property_append_bool, "b", &m->kill_user_processes }, + { NULL, NULL, NULL, NULL, NULL } + }; + + DBusError error; + DBusMessage *reply = NULL; + + assert(connection); + assert(message); + assert(m); + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) { + char *introspection = NULL; + FILE *f; + Iterator i; + Session *session; + Seat *seat; + User *user; + size_t size; + char *p; + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + /* We roll our own introspection code here, instead of + * relying on bus_default_message_handler() because we + * need to generate our introspection string + * dynamically. */ + + if (!(f = open_memstream(&introspection, &size))) + goto oom; + + fputs(INTROSPECTION_BEGIN, f); + + HASHMAP_FOREACH(seat, m->seats, i) { + p = bus_path_escape(seat->id); + + if (p) { + fprintf(f, "", p); + free(p); + } + } + + HASHMAP_FOREACH(user, m->users, i) + fprintf(f, "", (unsigned long long) user->uid); + + HASHMAP_FOREACH(session, m->sessions, i) { + p = bus_path_escape(session->id); + + if (p) { + fprintf(f, "", p); + free(p); + } + } + + fputs(INTROSPECTION_END, f); + + if (ferror(f)) { + fclose(f); + free(introspection); + goto oom; + } + + fclose(f); + + if (!introspection) + goto oom; + + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) { + free(introspection); + goto oom; + } + + free(introspection); + } else + return bus_default_message_handler(connection, message, NULL, 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; +} + +const DBusObjectPathVTable bus_manager_vtable = { + .message_function = manager_message_handler +}; -- cgit v1.2.3-54-g00ecf