chiark / gitweb /
loginctl: add missing header file
authorLennart Poettering <lennart@poettering.net>
Fri, 8 Jul 2011 22:04:27 +0000 (00:04 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 8 Jul 2011 22:04:27 +0000 (00:04 +0200)
src/loginctl.c
src/sysfs-show.c [new file with mode: 0644]
src/sysfs-show.h [new file with mode: 0644]

index 12787ce..23c998c 100644 (file)
@@ -1151,7 +1151,58 @@ finish:
 }
 
 static int activate(DBusConnection *bus, char **args, unsigned n) {
-        return 0;
+        DBusMessage *m = NULL, *reply = NULL;
+        int ret = 0;
+        DBusError error;
+        unsigned i;
+
+        assert(bus);
+        assert(args);
+
+        dbus_error_init(&error);
+
+        for (i = 1; i < n; i++) {
+                m = dbus_message_new_method_call(
+                                "org.freedesktop.login1",
+                                "/org/freedesktop/login1",
+                                "org.freedesktop.login1.Manager",
+                                "ActivateSession");
+                if (!m) {
+                        log_error("Could not allocate message.");
+                        ret = -ENOMEM;
+                        goto finish;
+                }
+
+                if (!dbus_message_append_args(m,
+                                              DBUS_TYPE_STRING, &args[i],
+                                              DBUS_TYPE_INVALID)) {
+                        log_error("Could not append arguments to message.");
+                        ret = -ENOMEM;
+                        goto finish;
+                }
+
+                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+                if (!reply) {
+                        log_error("Failed to issue method call: %s", bus_error_message(&error));
+                        ret = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_unref(m);
+                dbus_message_unref(reply);
+                m = reply = NULL;
+        }
+
+finish:
+        if (m)
+                dbus_message_unref(m);
+
+        if (reply)
+                dbus_message_unref(reply);
+
+        dbus_error_free(&error);
+
+        return ret;
 }
 
 static int kill_session(DBusConnection *bus, char **args, unsigned n) {
@@ -1327,21 +1378,21 @@ static int loginctl_main(DBusConnection *bus, int argc, char *argv[], DBusError
         } verbs[] = {
                 { "list-sessions",         LESS,   1, list_sessions    },
                 { "session-status",        MORE,   2, show             },
-                { "show-session",          MORE,   2, show             },
+                { "show-session",          MORE,   1, show             },
                 { "activate",              EQUAL,  2, activate         },
                 { "lock-session",          MORE,   2, activate         },
                 { "terminate-session",     MORE,   2, activate         },
                 { "kill-session",          MORE,   2, kill_session     },
                 { "list-users",            EQUAL,  1, list_users       },
                 { "user-status",           MORE,   2, show             },
-                { "show-user",             MORE,   2, show             },
+                { "show-user",             MORE,   1, show             },
                 { "enable-linger",         MORE,   2, enable_linger    },
                 { "disable-linger",        MORE,   2, enable_linger    },
                 { "terminate-user",        MORE,   2, enable_linger    },
                 { "kill-user",             MORE,   2, kill_session     },
                 { "list-seats",            EQUAL,  1, list_seats       },
                 { "seat-status",           MORE,   2, show             },
-                { "show-seat",             MORE,   2, show             },
+                { "show-seat",             MORE,   1, show             },
                 { "attach",                MORE,   3, attach           },
                 { "flush-devices",         EQUAL,  1, flush_devices    },
                 { "terminate-seat",        MORE,   2, terminate_seat   },
diff --git a/src/sysfs-show.c b/src/sysfs-show.c
new file mode 100644 (file)
index 0000000..d12d3cc
--- /dev/null
@@ -0,0 +1,191 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 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 <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <string.h>
+#include <libudev.h>
+
+#include "util.h"
+#include "sysfs-show.h"
+
+static bool device_has_tag(struct udev_device *d, const char *tag) {
+        struct udev_list_entry *first, *item;
+
+        assert(d);
+        assert(tag);
+
+        /* FIXME */
+        udev_device_get_is_initialized(d);
+
+        first = udev_device_get_tags_list_entry(d);
+        udev_list_entry_foreach(item, first)
+                if (streq(udev_list_entry_get_name(item), tag))
+                        return true;
+
+        return false;
+}
+
+static int show_sysfs_one(
+                struct udev *udev,
+                const char *seat,
+                struct udev_list_entry **item,
+                const char *sub,
+                const char *prefix,
+                unsigned n_columns) {
+
+        assert(udev);
+        assert(seat);
+        assert(item);
+        assert(prefix);
+
+        while (*item) {
+                struct udev_list_entry *next, *lookahead;
+                struct udev_device *d;
+                const char *sn, *id, *name, *sysfs, *subsystem, *sysname;
+
+                sysfs = udev_list_entry_get_name(*item);
+                if (!path_startswith(sysfs, sub))
+                        return 0;
+
+                d = udev_device_new_from_syspath(udev, sysfs);
+                if (!d) {
+                        *item = udev_list_entry_get_next(*item);
+                        continue;
+                }
+
+                sn = udev_device_get_property_value(d, "ID_SEAT");
+                if (isempty(sn))
+                        sn = "seat0";
+
+                /* fixme, also check for tag 'seat' here */
+                if (!streq(seat, sn) || !device_has_tag(d, "seat")) {
+                        udev_device_unref(d);
+                        *item = udev_list_entry_get_next(*item);
+                        continue;
+                }
+
+                id = udev_device_get_property_value(d, "ID_FOR_SEAT");
+                name = udev_device_get_sysattr_value(d, "name");
+                if (!name)
+                        name = udev_device_get_sysattr_value(d, "id");
+                subsystem = udev_device_get_subsystem(d);
+                sysname = udev_device_get_sysname(d);
+
+                /* Look if there's more coming after this */
+                lookahead = next = udev_list_entry_get_next(*item);
+                while (lookahead) {
+                        const char *lookahead_sysfs;
+
+                        lookahead_sysfs = udev_list_entry_get_name(lookahead);
+
+                        if (path_startswith(lookahead_sysfs, sub) &&
+                            !path_startswith(lookahead_sysfs, sysfs)) {
+                                struct udev_device *lookahead_d;
+
+                                lookahead_d = udev_device_new_from_syspath(udev, lookahead_sysfs);
+                                if (lookahead_d) {
+                                        const char *lookahead_sn;
+                                        bool found;
+
+                                        lookahead_sn = udev_device_get_property_value(d, "ID_SEAT");
+                                        if (isempty(lookahead_sn))
+                                                lookahead_sn = "seat0";
+
+                                        found = streq(seat, lookahead_sn) && device_has_tag(d, "seat");
+                                        udev_device_unref(lookahead_d);
+
+                                        if (found)
+                                                break;
+                                }
+                        }
+
+                        lookahead = udev_list_entry_get_next(lookahead);
+                }
+
+                printf("%s%s %s (%s:%s)", prefix, lookahead ? "\342\224\234" : "\342\224\224", id ? id : sysfs, subsystem, sysname);
+
+                if (name)
+                        printf(" \"%s\"\n", name);
+                else
+                        printf("\n");
+
+                *item = next;
+                if (*item) {
+                        char *p;
+
+                        p = strappend(prefix, lookahead ? "\342\224\202 " : "  ");
+                        show_sysfs_one(udev, seat, item, sysfs, p, n_columns - 2);
+                        free(p);
+                }
+
+                udev_device_unref(d);
+        }
+
+        return 0;
+}
+
+int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) {
+        struct udev *udev;
+        struct udev_list_entry *first = NULL;
+        struct udev_enumerate *e;
+        int r;
+
+        if (n_columns <= 0)
+                n_columns = columns();
+
+        if (!prefix)
+                prefix = "";
+
+        if (isempty(seat))
+                seat = "seat0";
+
+        udev = udev_new();
+        if (!udev)
+                return -ENOMEM;
+
+        e = udev_enumerate_new(udev);
+        if (!e) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        if (!streq(seat, "seat0"))
+                r = udev_enumerate_add_match_tag(e, seat);
+        else
+                r = udev_enumerate_add_match_tag(e, "seat");
+
+        r = udev_enumerate_scan_devices(e);
+        if (r < 0)
+                goto finish;
+
+        first = udev_enumerate_get_list_entry(e);
+        if (first)
+                show_sysfs_one(udev, seat, &first, "/", prefix, n_columns);
+
+finish:
+        if (e)
+                udev_enumerate_unref(e);
+
+        if (udev)
+                udev_unref(udev);
+
+        return r;
+}
diff --git a/src/sysfs-show.h b/src/sysfs-show.h
new file mode 100644 (file)
index 0000000..9939e8b
--- /dev/null
@@ -0,0 +1,27 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foosysfsshowhfoo
+#define foosysfsshowhfoo
+
+/***
+  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 <http://www.gnu.org/licenses/>.
+***/
+
+int show_sysfs(const char *seat, const char *prefix, unsigned columns);
+
+#endif