chiark / gitweb /
logind: move logind into its own subdirectory
[elogind.git] / src / logind-seat.c
diff --git a/src/logind-seat.c b/src/logind-seat.c
deleted file mode 100644 (file)
index 3cf3958..0000000
+++ /dev/null
@@ -1,499 +0,0 @@
-/*-*- 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 <http://www.gnu.org/licenses/>.
-***/
-
-#include <assert.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <linux/vt.h>
-#include <string.h>
-
-#include "logind-seat.h"
-#include "logind-acl.h"
-#include "util.h"
-
-Seat *seat_new(Manager *m, const char *id) {
-        Seat *s;
-
-        assert(m);
-        assert(id);
-
-        s = new0(Seat, 1);
-        if (!s)
-                return NULL;
-
-        s->state_file = strappend("/run/systemd/seats/", id);
-        if (!s->state_file) {
-                free(s);
-                return NULL;
-        }
-
-        s->id = file_name_from_path(s->state_file);
-        s->manager = m;
-
-        if (hashmap_put(m->seats, s->id, s) < 0) {
-                free(s->state_file);
-                free(s);
-                return NULL;
-        }
-
-        return s;
-}
-
-void seat_free(Seat *s) {
-        assert(s);
-
-        if (s->in_gc_queue)
-                LIST_REMOVE(Seat, gc_queue, s->manager->seat_gc_queue, s);
-
-        while (s->sessions)
-                session_free(s->sessions);
-
-        assert(!s->active);
-
-        while (s->devices)
-                device_free(s->devices);
-
-        hashmap_remove(s->manager->seats, s->id);
-
-        free(s->state_file);
-        free(s);
-}
-
-int seat_save(Seat *s) {
-        int r;
-        FILE *f;
-        char *temp_path;
-
-        assert(s);
-
-        if (!s->started)
-                return 0;
-
-        r = safe_mkdir("/run/systemd/seats", 0755, 0, 0);
-        if (r < 0)
-                goto finish;
-
-        r = fopen_temporary(s->state_file, &f, &temp_path);
-        if (r < 0)
-                goto finish;
-
-        fchmod(fileno(f), 0644);
-
-        fprintf(f,
-                "# This is private data. Do not parse.\n"
-                "IS_VTCONSOLE=%i\n",
-                seat_is_vtconsole(s));
-
-        if (s->active) {
-                assert(s->active->user);
-
-                fprintf(f,
-                        "ACTIVE=%s\n"
-                        "ACTIVE_UID=%lu\n",
-                        s->active->id,
-                        (unsigned long) s->active->user->uid);
-        }
-
-        if (s->sessions) {
-                Session *i;
-
-                fputs("SESSIONS=", f);
-                LIST_FOREACH(sessions_by_seat, i, s->sessions) {
-                        fprintf(f,
-                                "%s%c",
-                                i->id,
-                                i->sessions_by_seat_next ? ' ' : '\n');
-                }
-
-                fputs("UIDS=", f);
-                LIST_FOREACH(sessions_by_seat, i, s->sessions)
-                        fprintf(f,
-                                "%lu%c",
-                                (unsigned long) i->user->uid,
-                                i->sessions_by_seat_next ? ' ' : '\n');
-        }
-
-        fflush(f);
-
-        if (ferror(f) || rename(temp_path, s->state_file) < 0) {
-                r = -errno;
-                unlink(s->state_file);
-                unlink(temp_path);
-        }
-
-        fclose(f);
-        free(temp_path);
-
-finish:
-        if (r < 0)
-                log_error("Failed to save seat data for %s: %s", s->id, strerror(-r));
-
-        return r;
-}
-
-int seat_load(Seat *s) {
-        assert(s);
-
-        /* There isn't actually anything to read here ... */
-
-        return 0;
-}
-
-static int vt_allocate(int vtnr) {
-        int fd, r;
-        char *p;
-
-        assert(vtnr >= 1);
-
-        if (asprintf(&p, "/dev/tty%i", vtnr) < 0)
-                return -ENOMEM;
-
-        fd = open_terminal(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
-        free(p);
-
-        r = fd < 0 ? -errno : 0;
-
-        if (fd >= 0)
-                close_nointr_nofail(fd);
-
-        return r;
-}
-
-int seat_preallocate_vts(Seat *s) {
-        int r = 0;
-        unsigned i;
-
-        assert(s);
-        assert(s->manager);
-
-        log_debug("Preallocating VTs...");
-
-        if (s->manager->n_autovts <= 0)
-                return 0;
-
-        if (!seat_is_vtconsole(s))
-                return 0;
-
-        for (i = 1; i <= s->manager->n_autovts; i++) {
-                int q;
-
-                q = vt_allocate(i);
-                if (q < 0) {
-                        log_error("Failed to preallocate VT %i: %s", i, strerror(-q));
-                        r = q;
-                }
-        }
-
-        return r;
-}
-
-int seat_apply_acls(Seat *s, Session *old_active) {
-        int r;
-
-        assert(s);
-
-        r = devnode_acl_all(s->manager->udev,
-                            s->id,
-                            false,
-                            !!old_active, old_active ? old_active->user->uid : 0,
-                            !!s->active, s->active ? s->active->user->uid : 0);
-
-        if (r < 0)
-                log_error("Failed to apply ACLs: %s", strerror(-r));
-
-        return r;
-}
-
-int seat_set_active(Seat *s, Session *session) {
-        Session *old_active;
-
-        assert(s);
-        assert(!session || session->seat == s);
-
-        if (session == s->active)
-                return 0;
-
-        old_active = s->active;
-        s->active = session;
-
-        seat_apply_acls(s, old_active);
-
-        if (session && session->started)
-                session_send_changed(session, "Active\0");
-
-        if (!session || session->started)
-                seat_send_changed(s, "ActiveSession\0");
-
-        seat_save(s);
-
-        if (session) {
-                session_save(session);
-                user_save(session->user);
-        }
-
-        if (old_active) {
-                session_save(old_active);
-                user_save(old_active->user);
-        }
-
-        return 0;
-}
-
-int seat_active_vt_changed(Seat *s, int vtnr) {
-        Session *i, *new_active = NULL;
-        int r;
-
-        assert(s);
-        assert(vtnr >= 1);
-
-        if (!seat_is_vtconsole(s))
-                return -EINVAL;
-
-        log_debug("VT changed to %i", vtnr);
-
-        LIST_FOREACH(sessions_by_seat, i, s->sessions)
-                if (i->vtnr == vtnr) {
-                        new_active = i;
-                        break;
-                }
-
-        r = seat_set_active(s, new_active);
-        manager_spawn_autovt(s->manager, vtnr);
-
-        return r;
-}
-
-int seat_read_active_vt(Seat *s) {
-        char t[64];
-        ssize_t k;
-        int r, vtnr;
-
-        assert(s);
-
-        if (!seat_is_vtconsole(s))
-                return 0;
-
-        lseek(s->manager->console_active_fd, SEEK_SET, 0);
-
-        k = read(s->manager->console_active_fd, t, sizeof(t)-1);
-        if (k <= 0) {
-                log_error("Failed to read current console: %s", k < 0 ? strerror(-errno) : "EOF");
-                return k < 0 ? -errno : -EIO;
-        }
-
-        t[k] = 0;
-        truncate_nl(t);
-
-        if (!startswith(t, "tty")) {
-                log_error("Hm, /sys/class/tty/tty0/active is badly formatted.");
-                return -EIO;
-        }
-
-        r = safe_atoi(t+3, &vtnr);
-        if (r < 0) {
-                log_error("Failed to parse VT number %s", t+3);
-                return r;
-        }
-
-        if (vtnr <= 0) {
-                log_error("VT number invalid: %s", t+3);
-                return -EIO;
-        }
-
-        return seat_active_vt_changed(s, vtnr);
-}
-
-int seat_start(Seat *s) {
-        assert(s);
-
-        if (s->started)
-                return 0;
-
-        log_info("New seat %s.", s->id);
-
-        /* Initialize VT magic stuff */
-        seat_preallocate_vts(s);
-
-        /* Read current VT */
-        seat_read_active_vt(s);
-
-        s->started = true;
-
-        /* Save seat data */
-        seat_save(s);
-
-        seat_send_signal(s, true);
-
-        return 0;
-}
-
-int seat_stop(Seat *s) {
-        int r = 0;
-
-        assert(s);
-
-        if (s->started)
-                log_info("Removed seat %s.", s->id);
-
-        seat_stop_sessions(s);
-
-        unlink(s->state_file);
-        seat_add_to_gc_queue(s);
-
-        if (s->started)
-                seat_send_signal(s, false);
-
-        s->started = false;
-
-        return r;
-}
-
-int seat_stop_sessions(Seat *s) {
-        Session *session;
-        int r = 0, k;
-
-        assert(s);
-
-        LIST_FOREACH(sessions_by_seat, session, s->sessions) {
-                k = session_stop(session);
-                if (k < 0)
-                        r = k;
-        }
-
-        return r;
-}
-
-int seat_attach_session(Seat *s, Session *session) {
-        assert(s);
-        assert(session);
-        assert(!session->seat);
-
-        if (!seat_is_vtconsole(s) && s->sessions)
-                return -EEXIST;
-
-        session->seat = s;
-        LIST_PREPEND(Session, sessions_by_seat, s->sessions, session);
-
-        seat_send_changed(s, "Sessions\0");
-
-        if (!seat_is_vtconsole(s)) {
-                assert(!s->active);
-                seat_set_active(s, session);
-        }
-
-        return 0;
-}
-
-bool seat_is_vtconsole(Seat *s) {
-        assert(s);
-
-        return s->manager->vtconsole == s;
-}
-
-int seat_get_idle_hint(Seat *s, dual_timestamp *t) {
-        Session *session;
-        bool idle_hint = true;
-        dual_timestamp ts = { 0, 0 };
-
-        assert(s);
-
-        LIST_FOREACH(sessions_by_seat, session, s->sessions) {
-                dual_timestamp k;
-                int ih;
-
-                ih = session_get_idle_hint(session, &k);
-                if (ih < 0)
-                        return ih;
-
-                if (!ih) {
-                        if (!idle_hint) {
-                                if (k.monotonic < ts.monotonic)
-                                        ts = k;
-                        } else {
-                                idle_hint = false;
-                                ts = k;
-                        }
-                } else if (idle_hint) {
-
-                        if (k.monotonic > ts.monotonic)
-                                ts = k;
-                }
-        }
-
-        if (t)
-                *t = ts;
-
-        return idle_hint;
-}
-
-int seat_check_gc(Seat *s, bool drop_not_started) {
-        assert(s);
-
-        if (drop_not_started && !s->started)
-                return 0;
-
-        if (seat_is_vtconsole(s))
-                return 1;
-
-        return !!s->devices;
-}
-
-void seat_add_to_gc_queue(Seat *s) {
-        assert(s);
-
-        if (s->in_gc_queue)
-                return;
-
-        LIST_PREPEND(Seat, gc_queue, s->manager->seat_gc_queue, s);
-        s->in_gc_queue = true;
-}
-
-static bool seat_name_valid_char(char c) {
-        return
-                (c >= 'a' && c <= 'z') ||
-                (c >= 'A' && c <= 'Z') ||
-                (c >= '0' && c <= '9') ||
-                c == '-' ||
-                c == '_';
-}
-
-bool seat_name_is_valid(const char *name) {
-        const char *p;
-
-        assert(name);
-
-        if (!startswith(name, "seat"))
-                return false;
-
-        if (!name[4])
-                return false;
-
-        for (p = name; *p; p++)
-                if (!seat_name_valid_char(*p))
-                        return false;
-
-        if (strlen(name) > 255)
-                return false;
-
-        return true;
-}