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

#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "alloc-util.h"
#include "env-file.h"
#include "errno-list.h"
#include "errno-util.h"
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
#include "format-util.h"
#include "io-util.h"
#include "logind-dbus.h"
#include "logind-inhibit.h"
#include "missing_threads.h"
#include "mkdir-label.h"
#include "parse-util.h"
#include "path-util.h"
#include "string-table.h"
#include "string-util.h"
#include "tmpfile-util.h"
#include "user-util.h"

static void inhibitor_remove_fifo(Inhibitor *i);

int inhibitor_new(Inhibitor **ret, Manager *m, const char* id) {
        _cleanup_(inhibitor_freep) Inhibitor *i = NULL;
        int r;

        assert(ret);
        assert(m);
        assert(id);

        i = new(Inhibitor, 1);
        if (!i)
                return -ENOMEM;

        *i = (Inhibitor) {
                .manager = m,
                .what = _INHIBIT_WHAT_INVALID,
                .mode = _INHIBIT_MODE_INVALID,
                .uid = UID_INVALID,
                .fifo_fd = -EBADF,
        };

        i->state_file = path_join("/run/systemd/inhibit", id);
        if (!i->state_file)
                return -ENOMEM;

        i->id = basename(i->state_file);

        r = hashmap_put(m->inhibitors, i->id, i);
        if (r < 0)
                return r;

        *ret = TAKE_PTR(i);
        return 0;
}

Inhibitor* inhibitor_free(Inhibitor *i) {

        if (!i)
                return NULL;

        free(i->who);
        free(i->why);

        sd_event_source_unref(i->event_source);
        safe_close(i->fifo_fd);

        hashmap_remove(i->manager->inhibitors, i->id);

        /* Note that we don't remove neither the state file nor the fifo path here, since we want both to
         * survive daemon restarts */
        free(i->state_file);
        free(i->fifo_path);

        return mfree(i);
}

static int inhibitor_save(Inhibitor *i) {
        _cleanup_free_ char *temp_path = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        int r;

        assert(i);

        r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0, MKDIR_WARN_MODE);
        if (r < 0)
                goto fail;

        r = fopen_temporary(i->state_file, &f, &temp_path);
        if (r < 0)
                goto fail;

        (void) fchmod(fileno(f), 0644);

        fprintf(f,
                "# This is private data. Do not parse.\n"
                "WHAT=%s\n"
                "MODE=%s\n"
                "UID="UID_FMT"\n"
                "PID="PID_FMT"\n",
                inhibit_what_to_string(i->what),
                inhibit_mode_to_string(i->mode),
                i->uid,
                i->pid);

        if (i->who) {
                _cleanup_free_ char *cc = NULL;

                cc = cescape(i->who);
                if (!cc) {
                        r = -ENOMEM;
                        goto fail;
                }

                fprintf(f, "WHO=%s\n", cc);
        }

        if (i->why) {
                _cleanup_free_ char *cc = NULL;

                cc = cescape(i->why);
                if (!cc) {
                        r = -ENOMEM;
                        goto fail;
                }

                fprintf(f, "WHY=%s\n", cc);
        }

        if (i->fifo_path)
                fprintf(f, "FIFO=%s\n", i->fifo_path);

        r = fflush_and_check(f);
        if (r < 0)
                goto fail;

        if (rename(temp_path, i->state_file) < 0) {
                r = -errno;
                goto fail;
        }

        return 0;

fail:
        (void) unlink(i->state_file);

        if (temp_path)
                (void) unlink(temp_path);

        return log_error_errno(r, "Failed to save inhibit data %s: %m", i->state_file);
}

static int bus_manager_send_inhibited_change(Inhibitor *i) {
        const char *property;

        assert(i);

        property = i->mode == INHIBIT_BLOCK ? "BlockInhibited" : "DelayInhibited";

        return manager_send_changed(i->manager, property, NULL);
}

int inhibitor_start(Inhibitor *i) {
        assert(i);

        if (i->started)
                return 0;

        dual_timestamp_get(&i->since);

        log_debug("Inhibitor %s (%s) pid="PID_FMT" uid="UID_FMT" mode=%s started.",
                  strna(i->who), strna(i->why),
                  i->pid, i->uid,
                  inhibit_mode_to_string(i->mode));

        i->started = true;

        inhibitor_save(i);

        bus_manager_send_inhibited_change(i);

        return 0;
}

void inhibitor_stop(Inhibitor *i) {
        assert(i);

        if (i->started)
                log_debug("Inhibitor %s (%s) pid="PID_FMT" uid="UID_FMT" mode=%s stopped.",
                          strna(i->who), strna(i->why),
                          i->pid, i->uid,
                          inhibit_mode_to_string(i->mode));

        inhibitor_remove_fifo(i);

        if (i->state_file)
                (void) unlink(i->state_file);

        i->started = false;

        bus_manager_send_inhibited_change(i);
}

int inhibitor_load(Inhibitor *i) {
        _cleanup_free_ char *what = NULL, *uid = NULL, *pid = NULL, *who = NULL, *why = NULL, *mode = NULL;
        InhibitWhat w;
        InhibitMode mm;
        char *cc;
        ssize_t l;
        int r;

        r = parse_env_file(NULL, i->state_file,
                           "WHAT", &what,
                           "UID", &uid,
                           "PID", &pid,
                           "WHO", &who,
                           "WHY", &why,
                           "MODE", &mode,
                           "FIFO", &i->fifo_path);
        if (r < 0)
                return log_error_errno(r, "Failed to read %s: %m", i->state_file);

        w = what ? inhibit_what_from_string(what) : 0;
        if (w >= 0)
                i->what = w;

        mm = mode ? inhibit_mode_from_string(mode) : INHIBIT_BLOCK;
        if  (mm >= 0)
                i->mode = mm;

        if (uid) {
                r = parse_uid(uid, &i->uid);
                if (r < 0)
                        log_debug_errno(r, "Failed to parse UID of inhibitor: %s", uid);
        }

        if (pid) {
                r = parse_pid(pid, &i->pid);
                if (r < 0)
                        log_debug_errno(r, "Failed to parse PID of inhibitor: %s", pid);
        }

        if (who) {
                l = cunescape(who, 0, &cc);
                if (l < 0)
                        return log_debug_errno(l, "Failed to unescape \"who\" of inhibitor: %m");

                free_and_replace(i->who, cc);
        }

        if (why) {
                l = cunescape(why, 0, &cc);
                if (l < 0)
                        return log_debug_errno(l, "Failed to unescape \"why\" of inhibitor: %m");

                free_and_replace(i->why, cc);
        }

        if (i->fifo_path) {
                _cleanup_close_ int fd = -EBADF;

                /* Let's re-open the FIFO on both sides, and close the writing side right away */
                fd = inhibitor_create_fifo(i);
                if (fd < 0)
                        return log_error_errno(fd, "Failed to reopen FIFO: %m");
        }

        return 0;
}

static int inhibitor_dispatch_fifo(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
        Inhibitor *i = ASSERT_PTR(userdata);

        assert(s);
        assert(fd == i->fifo_fd);

        inhibitor_stop(i);
        inhibitor_free(i);

        return 0;
}

int inhibitor_create_fifo(Inhibitor *i) {
        int r;

        assert(i);

        /* Create FIFO */
        if (!i->fifo_path) {
                r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0, MKDIR_WARN_MODE);
                if (r < 0)
                        return r;

                i->fifo_path = strjoin("/run/systemd/inhibit/", i->id, ".ref");
                if (!i->fifo_path)
                        return -ENOMEM;

                if (mkfifo(i->fifo_path, 0600) < 0 && errno != EEXIST)
                        return -errno;
        }

        /* Open reading side */
        if (i->fifo_fd < 0) {
                i->fifo_fd = open(i->fifo_path, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
                if (i->fifo_fd < 0)
                        return -errno;
        }

        if (!i->event_source) {
                r = sd_event_add_io(i->manager->event, &i->event_source, i->fifo_fd, 0, inhibitor_dispatch_fifo, i);
                if (r < 0)
                        return r;

                r = sd_event_source_set_priority(i->event_source, SD_EVENT_PRIORITY_IDLE-10);
                if (r < 0)
                        return r;

                (void) sd_event_source_set_description(i->event_source, "inhibitor-ref");
        }

        /* Open writing side */
        return RET_NERRNO(open(i->fifo_path, O_WRONLY|O_CLOEXEC|O_NONBLOCK));
}

static void inhibitor_remove_fifo(Inhibitor *i) {
        assert(i);

        i->event_source = sd_event_source_unref(i->event_source);
        i->fifo_fd = safe_close(i->fifo_fd);

        if (i->fifo_path) {
                (void) unlink(i->fifo_path);
                i->fifo_path = mfree(i->fifo_path);
        }
}

bool inhibitor_is_orphan(Inhibitor *i) {
        assert(i);

        if (!i->started)
                return true;

        if (!i->fifo_path)
                return true;

        if (i->fifo_fd < 0)
                return true;

        if (pipe_eof(i->fifo_fd) != 0)
                return true;

        return false;
}

InhibitWhat manager_inhibit_what(Manager *m, InhibitMode mm) {
        Inhibitor *i;
        InhibitWhat what = 0;

        assert(m);

        HASHMAP_FOREACH(i, m->inhibitors)
                if (i->mode == mm && i->started)
                        what |= i->what;

        return what;
}

static int pid_is_active(Manager *m, pid_t pid) {
        Session *s;
        int r;

        /* Get client session.  This is not what you are looking for these days.
         * FIXME #6852 */
        r = manager_get_session_by_pid(m, pid, &s);
        if (r < 0)
                return r;

        /* If there's no session assigned to it, then it's globally
         * active on all ttys */
        if (r == 0)
                return 1;

        return session_is_active(s);
}

bool manager_is_inhibited(
                Manager *m,
                InhibitWhat w,
                InhibitMode mm,
                dual_timestamp *since,
                bool ignore_inactive,
                bool ignore_uid,
                uid_t uid,
                Inhibitor **offending) {

        Inhibitor *i;
        struct dual_timestamp ts = DUAL_TIMESTAMP_NULL;
        bool inhibited = false;

        assert(m);
        assert(w > 0 && w < _INHIBIT_WHAT_MAX);

        HASHMAP_FOREACH(i, m->inhibitors) {
                if (!i->started)
                        continue;

                if (!(i->what & w))
                        continue;

                if (i->mode != mm)
                        continue;

                if (ignore_inactive && pid_is_active(m, i->pid) <= 0)
                        continue;

                if (ignore_uid && i->uid == uid)
                        continue;

                if (!inhibited ||
                    i->since.monotonic < ts.monotonic)
                        ts = i->since;

                inhibited = true;

                if (offending)
                        *offending = i;
        }

        if (since)
                *since = ts;

        return inhibited;
}

const char *inhibit_what_to_string(InhibitWhat w) {
        static thread_local char buffer[STRLEN(
            "shutdown:"
            "sleep:"
            "idle:"
            "handle-power-key:"
            "handle-suspend-key:"
            "handle-hibernate-key:"
            "handle-lid-switch:"
            "handle-reboot-key")+1];
        char *p;

        if (w < 0 || w >= _INHIBIT_WHAT_MAX)
                return NULL;

        p = buffer;
        if (w & INHIBIT_SHUTDOWN)
                p = stpcpy(p, "shutdown:");
        if (w & INHIBIT_SLEEP)
                p = stpcpy(p, "sleep:");
        if (w & INHIBIT_IDLE)
                p = stpcpy(p, "idle:");
        if (w & INHIBIT_HANDLE_POWER_KEY)
                p = stpcpy(p, "handle-power-key:");
        if (w & INHIBIT_HANDLE_SUSPEND_KEY)
                p = stpcpy(p, "handle-suspend-key:");
        if (w & INHIBIT_HANDLE_HIBERNATE_KEY)
                p = stpcpy(p, "handle-hibernate-key:");
        if (w & INHIBIT_HANDLE_LID_SWITCH)
                p = stpcpy(p, "handle-lid-switch:");
        if (w & INHIBIT_HANDLE_REBOOT_KEY)
                p = stpcpy(p, "handle-reboot-key:");

        if (p > buffer)
                *(p-1) = 0;
        else
                *p = 0;

        return buffer;
}

int inhibit_what_from_string(const char *s) {
        InhibitWhat what = 0;

        for (const char *p = s;;) {
                _cleanup_free_ char *word = NULL;
                int r;

                /* A sanity check that our return values fit in an int */
                assert_cc((int) _INHIBIT_WHAT_MAX == _INHIBIT_WHAT_MAX);

                r = extract_first_word(&p, &word, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
                if (r < 0)
                        return r;
                if (r == 0)
                        return what;

                if (streq(word, "shutdown"))
                        what |= INHIBIT_SHUTDOWN;
                else if (streq(word, "sleep"))
                        what |= INHIBIT_SLEEP;
                else if (streq(word, "idle"))
                        what |= INHIBIT_IDLE;
                else if (streq(word, "handle-power-key"))
                        what |= INHIBIT_HANDLE_POWER_KEY;
                else if (streq(word, "handle-suspend-key"))
                        what |= INHIBIT_HANDLE_SUSPEND_KEY;
                else if (streq(word, "handle-hibernate-key"))
                        what |= INHIBIT_HANDLE_HIBERNATE_KEY;
                else if (streq(word, "handle-lid-switch"))
                        what |= INHIBIT_HANDLE_LID_SWITCH;
                else if (streq(word, "handle-reboot-key"))
                        what |= INHIBIT_HANDLE_REBOOT_KEY;
                else
                        return _INHIBIT_WHAT_INVALID;
        }
}

static const char* const inhibit_mode_table[_INHIBIT_MODE_MAX] = {
        [INHIBIT_BLOCK] = "block",
        [INHIBIT_DELAY] = "delay"
};

DEFINE_STRING_TABLE_LOOKUP(inhibit_mode, InhibitMode);
