/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/vt.h>

#include "sd-device.h"

#include "alloc-util.h"
#include "bus-error.h"
#include "bus-util.h"
#include "cgroup-util.h"
#include "conf-parser.h"
#include "device-util.h"
#include "efi-loader.h"
#include "errno-util.h"
#include "fd-util.h"
#include "limits-util.h"
#include "logind.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
#include "stdio-util.h"
#include "strv.h"
#include "terminal-util.h"
#include "udev-util.h"
#include "user-util.h"
#include "userdb.h"
#include "utmp-wtmp.h"

void manager_reset_config(Manager *m) {
        assert(m);

        m->n_autovts = 6;
        m->reserve_vt = 6;
        m->remove_ipc = true;
        m->inhibit_delay_max = 5 * USEC_PER_SEC;
        m->user_stop_delay = 10 * USEC_PER_SEC;

        m->handle_power_key = HANDLE_POWEROFF;
        m->handle_suspend_key = HANDLE_SUSPEND;
        m->handle_hibernate_key = HANDLE_HIBERNATE;
        m->handle_lid_switch = HANDLE_SUSPEND;
        m->handle_lid_switch_ep = _HANDLE_ACTION_INVALID;
        m->handle_lid_switch_docked = HANDLE_IGNORE;
        m->handle_reboot_key = HANDLE_REBOOT;
        m->power_key_ignore_inhibited = false;
        m->suspend_key_ignore_inhibited = false;
        m->hibernate_key_ignore_inhibited = false;
        m->lid_switch_ignore_inhibited = true;
        m->reboot_key_ignore_inhibited = false;

        m->holdoff_timeout_usec = 30 * USEC_PER_SEC;

        m->idle_action_usec = 30 * USEC_PER_MINUTE;
        m->idle_action = HANDLE_IGNORE;

        m->runtime_dir_size = physical_memory_scale(10U, 100U); /* 10% */
        m->runtime_dir_inodes = DIV_ROUND_UP(m->runtime_dir_size, 4096); /* 4k per inode */
        m->sessions_max = 8192;
        m->inhibitors_max = 8192;

        m->kill_user_processes = KILL_USER_PROCESSES;

        m->kill_only_users = strv_free(m->kill_only_users);
        m->kill_exclude_users = strv_free(m->kill_exclude_users);
}

int manager_parse_config_file(Manager *m) {
        assert(m);

        return config_parse_many_nulstr(
                        PKGSYSCONFDIR "/logind.conf",
                        CONF_PATHS_NULSTR("systemd/logind.conf.d"),
                        "Login\0",
                        config_item_perf_lookup, logind_gperf_lookup,
                        CONFIG_PARSE_WARN, m,
                        NULL);
}

int manager_add_device(Manager *m, const char *sysfs, bool master, Device **ret_device) {
        Device *d;

        assert(m);
        assert(sysfs);

        d = hashmap_get(m->devices, sysfs);
        if (d)
                /* we support adding master-flags, but not removing them */
                d->master = d->master || master;
        else {
                d = device_new(m, sysfs, master);
                if (!d)
                        return -ENOMEM;
        }

        if (ret_device)
                *ret_device = d;

        return 0;
}

int manager_add_seat(Manager *m, const char *id, Seat **ret_seat) {
        Seat *s;
        int r;

        assert(m);
        assert(id);

        s = hashmap_get(m->seats, id);
        if (!s) {
                r = seat_new(&s, m, id);
                if (r < 0)
                        return r;
        }

        if (ret_seat)
                *ret_seat = s;

        return 0;
}

int manager_add_session(Manager *m, const char *id, Session **ret_session) {
        Session *s;
        int r;

        assert(m);
        assert(id);

        s = hashmap_get(m->sessions, id);
        if (!s) {
                r = session_new(&s, m, id);
                if (r < 0)
                        return r;
        }

        if (ret_session)
                *ret_session = s;

        return 0;
}

int manager_add_user(
                Manager *m,
                UserRecord *ur,
                User **ret_user) {

        User *u;
        int r;

        assert(m);
        assert(ur);

        u = hashmap_get(m->users, UID_TO_PTR(ur->uid));
        if (!u) {
                r = user_new(&u, m, ur);
                if (r < 0)
                        return r;
        }

        if (ret_user)
                *ret_user = u;

        return 0;
}

int manager_add_user_by_name(
                Manager *m,
                const char *name,
                User **ret_user) {

        _cleanup_(user_record_unrefp) UserRecord *ur = NULL;
        int r;

        assert(m);
        assert(name);

        r = userdb_by_name(name, USERDB_SUPPRESS_SHADOW, &ur);
        if (r < 0)
                return r;

        return manager_add_user(m, ur, ret_user);
}

int manager_add_user_by_uid(
                Manager *m,
                uid_t uid,
                User **ret_user) {

        _cleanup_(user_record_unrefp) UserRecord *ur = NULL;
        int r;

        assert(m);
        assert(uid_is_valid(uid));

        r = userdb_by_uid(uid, USERDB_SUPPRESS_SHADOW, &ur);
        if (r < 0)
                return r;

        return manager_add_user(m, ur, ret_user);
}

int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **ret) {
        Inhibitor *i;
        int r;

        assert(m);
        assert(id);

        i = hashmap_get(m->inhibitors, id);
        if (!i) {
                r = inhibitor_new(&i, m, id);
                if (r < 0)
                        return r;
        }

        if (ret)
                *ret = i;

        return 0;
}

int manager_add_button(Manager *m, const char *name, Button **ret_button) {
        Button *b;

        assert(m);
        assert(name);

        b = hashmap_get(m->buttons, name);
        if (!b) {
                b = button_new(m, name);
                if (!b)
                        return -ENOMEM;
        }

        if (ret_button)
                *ret_button = b;

        return 0;
}

int manager_process_seat_device(Manager *m, sd_device *d) {
        Device *device;
        int r;

        assert(m);

        if (device_for_action(d, SD_DEVICE_REMOVE) ||
            sd_device_has_current_tag(d, "seat") <= 0) {
                const char *syspath;

                r = sd_device_get_syspath(d, &syspath);
                if (r < 0)
                        return 0;

                device = hashmap_get(m->devices, syspath);
                if (!device)
                        return 0;

                seat_add_to_gc_queue(device->seat);
                device_free(device);

        } else {
                const char *sn, *syspath;
                bool master;
                Seat *seat;

                if (sd_device_get_property_value(d, "ID_SEAT", &sn) < 0 || isempty(sn))
                        sn = "seat0";

                if (!seat_name_is_valid(sn)) {
                        log_device_warning(d, "Device with invalid seat name %s found, ignoring.", sn);
                        return 0;
                }

                seat = hashmap_get(m->seats, sn);
                master = sd_device_has_current_tag(d, "master-of-seat") > 0;

                /* Ignore non-master devices for unknown seats */
                if (!master && !seat)
                        return 0;

                r = sd_device_get_syspath(d, &syspath);
                if (r < 0)
                        return r;

                r = manager_add_device(m, syspath, master, &device);
                if (r < 0)
                        return r;

                if (!seat) {
                        r = manager_add_seat(m, sn, &seat);
                        if (r < 0) {
                                if (!device->seat)
                                        device_free(device);

                                return r;
                        }
                }

                device_attach(device, seat);
                seat_start(seat);
        }

        return 0;
}

int manager_process_button_device(Manager *m, sd_device *d) {
        const char *sysname;
        Button *b;
        int r;

        assert(m);

        r = sd_device_get_sysname(d, &sysname);
        if (r < 0)
                return r;

        if (device_for_action(d, SD_DEVICE_REMOVE) ||
            sd_device_has_current_tag(d, "power-switch") <= 0) {

                b = hashmap_get(m->buttons, sysname);
                if (!b)
                        return 0;

                button_free(b);

        } else {
                const char *sn;

                r = manager_add_button(m, sysname, &b);
                if (r < 0)
                        return r;

                if (sd_device_get_property_value(d, "ID_SEAT", &sn) < 0 || isempty(sn))
                        sn = "seat0";

                button_set_seat(b, sn);

                r = button_open(b);
                if (r < 0) /* event device doesn't have any keys or switches relevant to us? (or any other error
                            * opening the device?) let's close the button again. */
                        button_free(b);
        }

        return 0;
}

int manager_get_session_by_pid(Manager *m, pid_t pid, Session **ret) {
        _cleanup_free_ char *unit = NULL;
        Session *s;
        int r;

        assert(m);

        if (!pid_is_valid(pid))
                return -EINVAL;

        s = hashmap_get(m->sessions_by_leader, PID_TO_PTR(pid));
        if (!s) {
                r = cg_pid_get_unit(pid, &unit);
                if (r >= 0)
                        s = hashmap_get(m->session_units, unit);
        }

        if (ret)
                *ret = s;

        return !!s;
}

int manager_get_user_by_pid(Manager *m, pid_t pid, User **ret) {
        _cleanup_free_ char *unit = NULL;
        User *u = NULL;
        int r;

        assert(m);

        if (!pid_is_valid(pid))
                return -EINVAL;

        r = cg_pid_get_slice(pid, &unit);
        if (r >= 0)
                u = hashmap_get(m->user_units, unit);

        if (ret)
                *ret = u;

        return !!u;
}

int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
        Session *s;
        bool idle_hint;
        dual_timestamp ts = DUAL_TIMESTAMP_NULL;

        assert(m);

        idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0, NULL);

        HASHMAP_FOREACH(s, m->sessions) {
                dual_timestamp k;
                int ih;

                ih = session_get_idle_hint(s, &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;
}

bool manager_shall_kill(Manager *m, const char *user) {
        assert(m);
        assert(user);

        if (!m->kill_exclude_users && streq(user, "root"))
                return false;

        if (strv_contains(m->kill_exclude_users, user))
                return false;

        if (!strv_isempty(m->kill_only_users))
                return strv_contains(m->kill_only_users, user);

        return m->kill_user_processes;
}

int config_parse_n_autovts(
                const char *unit,
                const char *filename,
                unsigned line,
                const char *section,
                unsigned section_line,
                const char *lvalue,
                int ltype,
                const char *rvalue,
                void *data,
                void *userdata) {

        unsigned *n = data;
        unsigned o;
        int r;

        assert(filename);
        assert(lvalue);
        assert(rvalue);
        assert(data);

        r = safe_atou(rvalue, &o);
        if (r < 0) {
                log_syntax(unit, LOG_WARNING, filename, line, r,
                           "Failed to parse number of autovts, ignoring: %s", rvalue);
                return 0;
        }

        if (o > 15) {
                log_syntax(unit, LOG_WARNING, filename, line, 0,
                           "A maximum of 15 autovts are supported, ignoring: %s", rvalue);
                return 0;
        }

        *n = o;
        return 0;
}

static int vt_is_busy(unsigned vtnr) {
        struct vt_stat vt_stat;
        int r;
        _cleanup_close_ int fd = -1;

        assert(vtnr >= 1);

        /* VT_GETSTATE "cannot return state for more than 16 VTs, since v_state is short" */
        assert(vtnr <= 15);

        /* We explicitly open /dev/tty1 here instead of /dev/tty0. If
         * we'd open the latter we'd open the foreground tty which
         * hence would be unconditionally busy. By opening /dev/tty1
         * we avoid this. Since tty1 is special and needs to be an
         * explicitly loaded getty or DM this is safe. */

        fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC);
        if (fd < 0)
                return -errno;

        if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
                r = -errno;
        else
                r = !!(vt_stat.v_state & (1 << vtnr));

        return r;
}

int manager_spawn_autovt(Manager *m, unsigned vtnr) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        char name[sizeof("autovt@tty.service") + DECIMAL_STR_MAX(unsigned)];
        int r;

        assert(m);
        assert(vtnr >= 1);

        if (vtnr > m->n_autovts &&
            vtnr != m->reserve_vt)
                return 0;

        if (vtnr != m->reserve_vt) {
                /* If this is the reserved TTY, we'll start the getty
                 * on it in any case, but otherwise only if it is not
                 * busy. */

                r = vt_is_busy(vtnr);
                if (r < 0)
                        return r;
                else if (r > 0)
                        return -EBUSY;
        }

        xsprintf(name, "autovt@tty%u.service", vtnr);
        r = sd_bus_call_method(
                        m->bus,
                        "org.freedesktop.systemd1",
                        "/org/freedesktop/systemd1",
                        "org.freedesktop.systemd1.Manager",
                        "StartUnit",
                        &error,
                        NULL,
                        "ss", name, "fail");
        if (r < 0)
                return log_error_errno(r, "Failed to start %s: %s", name, bus_error_message(&error, r));

        return 0;
}

bool manager_is_lid_closed(Manager *m) {
        Button *b;

        HASHMAP_FOREACH(b, m->buttons)
                if (b->lid_closed)
                        return true;

        return false;
}

static bool manager_is_docked(Manager *m) {
        Button *b;

        HASHMAP_FOREACH(b, m->buttons)
                if (b->docked)
                        return true;

        return false;
}

static int manager_count_external_displays(Manager *m) {
        _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
        sd_device *d;
        int r, n = 0;

        r = sd_device_enumerator_new(&e);
        if (r < 0)
                return r;

        r = sd_device_enumerator_allow_uninitialized(e);
        if (r < 0)
                return r;

        r = sd_device_enumerator_add_match_subsystem(e, "drm", true);
        if (r < 0)
                return r;

        FOREACH_DEVICE(e, d) {
                const char *status, *enabled, *dash, *nn, *subsys;
                sd_device *p;

                if (sd_device_get_parent(d, &p) < 0)
                        continue;

                /* If the parent shares the same subsystem as the
                 * device we are looking at then it is a connector,
                 * which is what we are interested in. */
                if (sd_device_get_subsystem(p, &subsys) < 0 || !streq(subsys, "drm"))
                        continue;

                if (sd_device_get_sysname(d, &nn) < 0)
                        continue;

                /* Ignore internal displays: the type is encoded in the sysfs name, as the second dash
                 * separated item (the first is the card name, the last the connector number). We implement a
                 * deny list of external displays here, rather than an allow list of internal ones, to ensure
                 * we don't block suspends too eagerly. */
                dash = strchr(nn, '-');
                if (!dash)
                        continue;

                dash++;
                if (!STARTSWITH_SET(dash,
                                    "VGA-", "DVI-I-", "DVI-D-", "DVI-A-"
                                    "Composite-", "SVIDEO-", "Component-",
                                    "DIN-", "DP-", "HDMI-A-", "HDMI-B-", "TV-"))
                        continue;

                /* Ignore ports that are not enabled */
                if (sd_device_get_sysattr_value(d, "enabled", &enabled) < 0 || !streq(enabled, "enabled"))
                        continue;

                /* We count any connector which is not explicitly
                 * "disconnected" as connected. */
                if (sd_device_get_sysattr_value(d, "status", &status) < 0 || !streq(status, "disconnected"))
                        n++;
        }

        return n;
}

bool manager_is_docked_or_external_displays(Manager *m) {
        int n;

        /* If we are docked don't react to lid closing */
        if (manager_is_docked(m)) {
                log_debug("System is docked.");
                return true;
        }

        /* If we have more than one display connected,
         * assume that we are docked. */
        n = manager_count_external_displays(m);
        if (n < 0)
                log_warning_errno(n, "Display counting failed: %m");
        else if (n >= 1) {
                log_debug("External (%i) displays connected.", n);
                return true;
        }

        return false;
}

bool manager_is_on_external_power(void) {
        int r;

        /* For now we only check for AC power, but 'external power' can apply to anything that isn't an internal
         * battery */
        r = on_ac_power();
        if (r < 0)
                log_warning_errno(r, "Failed to read AC power status: %m");

        return r != 0; /* Treat failure as 'on AC' */
}

bool manager_all_buttons_ignored(Manager *m) {
        assert(m);

        if (m->handle_power_key != HANDLE_IGNORE)
                return false;
        if (m->handle_suspend_key != HANDLE_IGNORE)
                return false;
        if (m->handle_hibernate_key != HANDLE_IGNORE)
                return false;
        if (m->handle_lid_switch != HANDLE_IGNORE)
                return false;
        if (!IN_SET(m->handle_lid_switch_ep, _HANDLE_ACTION_INVALID, HANDLE_IGNORE))
                return false;
        if (m->handle_lid_switch_docked != HANDLE_IGNORE)
                return false;
        if (m->handle_reboot_key != HANDLE_IGNORE)
                return false;

        return true;
}

int manager_read_utmp(Manager *m) {
#if ENABLE_UTMP
        int r;
        _unused_ _cleanup_(utxent_cleanup) bool utmpx = false;

        assert(m);

        if (utmpxname(_PATH_UTMPX) < 0)
                return log_error_errno(errno, "Failed to set utmp path to " _PATH_UTMPX ": %m");

        utmpx = utxent_start();

        for (;;) {
                _cleanup_free_ char *t = NULL;
                struct utmpx *u;
                const char *c;
                Session *s;

                errno = 0;
                u = getutxent();
                if (!u) {
                        if (errno == ENOENT)
                                log_debug_errno(errno, _PATH_UTMPX " does not exist, ignoring.");
                        else if (errno != 0)
                                log_warning_errno(errno, "Failed to read " _PATH_UTMPX ", ignoring: %m");
                        return 0;
                }

                if (u->ut_type != USER_PROCESS)
                        continue;

                if (!pid_is_valid(u->ut_pid))
                        continue;

                t = strndup(u->ut_line, sizeof(u->ut_line));
                if (!t)
                        return log_oom();

                c = path_startswith(t, "/dev/");
                if (c) {
                        r = free_and_strdup(&t, c);
                        if (r < 0)
                                return log_oom();
                }

                if (isempty(t))
                        continue;

                s = hashmap_get(m->sessions_by_leader, PID_TO_PTR(u->ut_pid));
                if (!s)
                        continue;

                if (s->tty_validity == TTY_FROM_UTMP && !streq_ptr(s->tty, t)) {
                        /* This may happen on multiplexed SSH connection (i.e. 'SSH connection sharing'). In
                         * this case PAM and utmp sessions don't match. In such a case let's invalidate the TTY
                         * information and never acquire it again. */

                        s->tty = mfree(s->tty);
                        s->tty_validity = TTY_UTMP_INCONSISTENT;
                        log_debug("Session '%s' has inconsistent TTY information, dropping TTY information.", s->id);
                        continue;
                }

                /* Never override what we figured out once */
                if (s->tty || s->tty_validity >= 0)
                        continue;

                s->tty = TAKE_PTR(t);
                s->tty_validity = TTY_FROM_UTMP;
                log_debug("Acquired TTY information '%s' from utmp for session '%s'.", s->tty, s->id);
        }

#else
        return 0;
#endif
}

#if ENABLE_UTMP
static int manager_dispatch_utmp(sd_event_source *s, const struct inotify_event *event, void *userdata) {
        Manager *m = userdata;

        assert(m);

        /* If there's indication the file itself might have been removed or became otherwise unavailable, then let's
         * reestablish the watch on whatever there's now. */
        if ((event->mask & (IN_ATTRIB|IN_DELETE_SELF|IN_MOVE_SELF|IN_Q_OVERFLOW|IN_UNMOUNT)) != 0)
                manager_connect_utmp(m);

        (void) manager_read_utmp(m);
        return 0;
}
#endif

void manager_connect_utmp(Manager *m) {
#if ENABLE_UTMP
        sd_event_source *s = NULL;
        int r;

        assert(m);

        /* Watch utmp for changes via inotify. We do this to deal with tools such as ssh, which will register the PAM
         * session early, and acquire a TTY only much later for the connection. Thus during PAM the TTY won't be known
         * yet. ssh will register itself with utmp when it finally acquired the TTY. Hence, let's make use of this, and
         * watch utmp for the TTY asynchronously. We use the PAM session's leader PID as key, to find the right entry.
         *
         * Yes, relying on utmp is pretty ugly, but it's good enough for informational purposes, as well as idle
         * detection (which, for tty sessions, relies on the TTY used) */

        r = sd_event_add_inotify(m->event, &s, _PATH_UTMPX, IN_MODIFY|IN_MOVE_SELF|IN_DELETE_SELF|IN_ATTRIB, manager_dispatch_utmp, m);
        if (r < 0)
                log_full_errno(r == -ENOENT ? LOG_DEBUG: LOG_WARNING, r, "Failed to create inotify watch on " _PATH_UTMPX ", ignoring: %m");
        else {
                r = sd_event_source_set_priority(s, SD_EVENT_PRIORITY_IDLE);
                if (r < 0)
                        log_warning_errno(r, "Failed to adjust utmp event source priority, ignoring: %m");

                (void) sd_event_source_set_description(s, "utmp");
        }

        sd_event_source_unref(m->utmp_event_source);
        m->utmp_event_source = s;
#endif
}

void manager_reconnect_utmp(Manager *m) {
#if ENABLE_UTMP
        assert(m);

        if (m->utmp_event_source)
                return;

        manager_connect_utmp(m);
#endif
}

int manager_read_efi_boot_loader_entries(Manager *m) {
#if ENABLE_EFI
        int r;

        assert(m);
        if (m->efi_boot_loader_entries_set)
                return 0;

        r = efi_loader_get_entries(&m->efi_boot_loader_entries);
        if (r == -ENOENT || ERRNO_IS_NOT_SUPPORTED(r)) {
                log_debug_errno(r, "Boot loader reported no entries.");
                m->efi_boot_loader_entries_set = true;
                return 0;
        }
        if (r < 0)
                return log_error_errno(r, "Failed to determine entries reported by boot loader: %m");

        m->efi_boot_loader_entries_set = true;
        return 1;
#else
        return 0;
#endif
}
