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

#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include <unistd.h>

#include "sd-login.h"

#include "copy.h"
#include "env-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "io-util.h"
#include "locale-util.h"
#include "log.h"
#include "macro.h"
#include "pager.h"
#include "process-util.h"
#include "rlimit-util.h"
#include "signal-util.h"
#include "string-util.h"
#include "strv.h"
#include "terminal-util.h"
#include "util.h"

static pid_t pager_pid = 0;

static int stored_stdout = -1;
static int stored_stderr = -1;
static bool stdout_redirected = false;
static bool stderr_redirected = false;

_noreturn_ static void pager_fallback(void) {
        int r;

        r = copy_bytes(STDIN_FILENO, STDOUT_FILENO, UINT64_MAX, 0);
        if (r < 0) {
                log_error_errno(r, "Internal pager failed: %m");
                _exit(EXIT_FAILURE);
        }

        _exit(EXIT_SUCCESS);
}

static int no_quit_on_interrupt(int exe_name_fd, const char *less_opts) {
        _cleanup_fclose_ FILE *file = NULL;
        _cleanup_free_ char *line = NULL;
        int r;

        assert(exe_name_fd >= 0);
        assert(less_opts);

        /* This takes ownership of exe_name_fd */
        file = fdopen(exe_name_fd, "r");
        if (!file) {
                safe_close(exe_name_fd);
                return log_error_errno(errno, "Failed to create FILE object: %m");
        }

        /* Find the last line */
        for (;;) {
                _cleanup_free_ char *t = NULL;

                r = read_line(file, LONG_LINE_MAX, &t);
                if (r < 0)
                        return log_error_errno(r, "Failed to read from socket: %m");
                if (r == 0)
                        break;

                free_and_replace(line, t);
        }

        /* We only treat "less" specially.
         * Return true whenever option K is *not* set. */
        r = streq_ptr(line, "less") && !strchr(less_opts, 'K');

        log_debug("Pager executable is \"%s\", options \"%s\", quit_on_interrupt: %s",
                  strnull(line), less_opts, yes_no(!r));
        return r;
}

int pager_open(PagerFlags flags) {
        _cleanup_close_pair_ int fd[2] = { -1, -1 }, exe_name_pipe[2] = { -1, -1 };
        _cleanup_strv_free_ char **pager_args = NULL;
        const char *pager, *less_opts;
        int r;

        if (flags & PAGER_DISABLE)
                return 0;

        if (pager_pid > 0)
                return 1;

        if (terminal_is_dumb())
                return 0;

        if (!is_main_thread())
                return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Pager invoked from wrong thread.");

        pager = getenv("SYSTEMD_PAGER");
        if (!pager)
                pager = getenv("PAGER");

        if (pager) {
                pager_args = strv_split(pager, WHITESPACE);
                if (!pager_args)
                        return log_oom();

                /* If the pager is explicitly turned off, honour it */
                if (strv_isempty(pager_args) || strv_equal(pager_args, STRV_MAKE("cat")))
                        return 0;
        }

        /* Determine and cache number of columns/lines before we spawn the pager so that we get the value from the
         * actual tty */
        (void) columns();
        (void) lines();

        if (pipe2(fd, O_CLOEXEC) < 0)
                return log_error_errno(errno, "Failed to create pager pipe: %m");

        /* This is a pipe to feed the name of the executed pager binary into the parent */
        if (pipe2(exe_name_pipe, O_CLOEXEC) < 0)
                return log_error_errno(errno, "Failed to create exe_name pipe: %m");

        /* Initialize a good set of less options */
        less_opts = getenv("SYSTEMD_LESS");
        if (!less_opts)
                less_opts = "FRSXMK";
        if (flags & PAGER_JUMP_TO_END)
                less_opts = strjoina(less_opts, " +G");

        /* We set SIGINT as PR_DEATHSIG signal here, to match the "K" parameter we set in $LESS, which enables SIGINT behaviour. */
        r = safe_fork("(pager)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGINT|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pager_pid);
        if (r < 0)
                return r;
        if (r == 0) {
                const char *less_charset, *exe;

                /* In the child start the pager */

                if (dup2(fd[0], STDIN_FILENO) < 0) {
                        log_error_errno(errno, "Failed to duplicate file descriptor to STDIN: %m");
                        _exit(EXIT_FAILURE);
                }

                safe_close_pair(fd);

                if (setenv("LESS", less_opts, 1) < 0) {
                        log_error_errno(errno, "Failed to set environment variable LESS: %m");
                        _exit(EXIT_FAILURE);
                }

                /* Initialize a good charset for less. This is particularly important if we output UTF-8
                 * characters. */
                less_charset = getenv("SYSTEMD_LESSCHARSET");
                if (!less_charset && is_locale_utf8())
                        less_charset = "utf-8";
                if (less_charset &&
                    setenv("LESSCHARSET", less_charset, 1) < 0) {
                        log_error_errno(errno, "Failed to set environment variable LESSCHARSET: %m");
                        _exit(EXIT_FAILURE);
                }

                /* People might invoke us from sudo, don't needlessly allow less to be a way to shell out
                 * privileged stuff. If the user set $SYSTEMD_PAGERSECURE, trust their configuration of the
                 * pager. If they didn't, use secure mode when under euid is changed. If $SYSTEMD_PAGERSECURE
                 * wasn't explicitly set, and we autodetect the need for secure mode, only use the pager we
                 * know to be good. */
                int use_secure_mode = getenv_bool_secure("SYSTEMD_PAGERSECURE");
                bool trust_pager = use_secure_mode >= 0;
                if (use_secure_mode == -ENXIO) {
                        uid_t uid;

                        r = sd_pid_get_owner_uid(0, &uid);
                        if (r < 0)
                                log_debug_errno(r, "sd_pid_get_owner_uid() failed, enabling pager secure mode: %m");

                        use_secure_mode = r < 0 || uid != geteuid();

                } else if (use_secure_mode < 0) {
                        log_warning_errno(use_secure_mode, "Unable to parse $SYSTEMD_PAGERSECURE, assuming true: %m");
                        use_secure_mode = true;
                }

                /* We generally always set variables used by less, even if we end up using a different pager.
                 * They shouldn't hurt in any case, and ideally other pagers would look at them too. */
                r = set_unset_env("LESSSECURE", use_secure_mode ? "1" : NULL, true);
                if (r < 0) {
                        log_error_errno(r, "Failed to adjust environment variable LESSSECURE: %m");
                        _exit(EXIT_FAILURE);
                }

                if (trust_pager && pager_args) { /* The pager config might be set globally, and we cannot
                                                  * know if the user adjusted it to be appropriate for the
                                                  * secure mode. Thus, start the pager specified through
                                                  * envvars only when $SYSTEMD_PAGERSECURE was explicitly set
                                                  * as well. */
                        r = loop_write(exe_name_pipe[1], pager_args[0], strlen(pager_args[0]) + 1, false);
                        if (r < 0) {
                                log_error_errno(r, "Failed to write pager name to socket: %m");
                                _exit(EXIT_FAILURE);
                        }

                        execvp(pager_args[0], pager_args);
                        log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
                                       "Failed to execute '%s', using fallback pagers: %m", pager_args[0]);
                }

                /* Debian's alternatives command for pagers is called 'pager'. Note that we do not call
                 * sensible-pagers here, since that is just a shell script that implements a logic that is
                 * similar to this one anyway, but is Debian-specific. */
                FOREACH_STRING(exe, "pager", "less", "more") {
                        /* Only less implements secure mode right now. */
                        if (use_secure_mode && !streq(exe, "less"))
                                continue;

                        r = loop_write(exe_name_pipe[1], exe, strlen(exe) + 1, false);
                        if (r  < 0) {
                                log_error_errno(r, "Failed to write pager name to socket: %m");
                                _exit(EXIT_FAILURE);
                        }
                        execlp(exe, exe, NULL);
                        log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
                                       "Failed to execute '%s', using next fallback pager: %m", exe);
                }

                /* Our builtin is also very secure. */
                r = loop_write(exe_name_pipe[1], "(built-in)", strlen("(built-in)") + 1, false);
                if (r < 0) {
                        log_error_errno(r, "Failed to write pager name to socket: %m");
                        _exit(EXIT_FAILURE);
                }
                /* Close pipe to signal the parent to start sending data */
                safe_close_pair(exe_name_pipe);
                pager_fallback();
                /* not reached */
        }

        /* Return in the parent */
        stored_stdout = fcntl(STDOUT_FILENO, F_DUPFD_CLOEXEC, 3);
        if (dup2(fd[1], STDOUT_FILENO) < 0) {
                stored_stdout = safe_close(stored_stdout);
                return log_error_errno(errno, "Failed to duplicate pager pipe: %m");
        }
        stdout_redirected = true;

        stored_stderr = fcntl(STDERR_FILENO, F_DUPFD_CLOEXEC, 3);
        if (dup2(fd[1], STDERR_FILENO) < 0) {
                stored_stderr = safe_close(stored_stderr);
                return log_error_errno(errno, "Failed to duplicate pager pipe: %m");
        }
        stderr_redirected = true;

        exe_name_pipe[1] = safe_close(exe_name_pipe[1]);

        r = no_quit_on_interrupt(TAKE_FD(exe_name_pipe[0]), less_opts);
        if (r < 0)
                return r;
        if (r > 0)
                (void) ignore_signals(SIGINT);

        return 1;
}

void pager_close(void) {

        if (pager_pid <= 0)
                return;

        /* Inform pager that we are done */
        (void) fflush(stdout);
        if (stdout_redirected)
                if (stored_stdout < 0 || dup2(stored_stdout, STDOUT_FILENO) < 0)
                        (void) close(STDOUT_FILENO);
        stored_stdout = safe_close(stored_stdout);
        (void) fflush(stderr);
        if (stderr_redirected)
                if (stored_stderr < 0 || dup2(stored_stderr, STDERR_FILENO) < 0)
                        (void) close(STDERR_FILENO);
        stored_stderr = safe_close(stored_stderr);
        stdout_redirected = stderr_redirected = false;

        (void) kill(pager_pid, SIGCONT);
        (void) wait_for_terminate(pager_pid, NULL);
        pager_pid = 0;
}

bool pager_have(void) {
        return pager_pid > 0;
}

int show_man_page(const char *desc, bool null_stdio) {
        const char *args[4] = { "man", NULL, NULL, NULL };
        char *e = NULL;
        pid_t pid;
        size_t k;
        int r;

        k = strlen(desc);

        if (desc[k-1] == ')')
                e = strrchr(desc, '(');

        if (e) {
                char *page = NULL, *section = NULL;

                page = strndupa(desc, e - desc);
                section = strndupa(e + 1, desc + k - e - 2);

                args[1] = section;
                args[2] = page;
        } else
                args[1] = desc;

        r = safe_fork("(man)", FORK_RESET_SIGNALS|FORK_DEATHSIG|(null_stdio ? FORK_NULL_STDIO : 0)|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
        if (r < 0)
                return r;
        if (r == 0) {
                /* Child */
                execvp(args[0], (char**) args);
                log_error_errno(errno, "Failed to execute man: %m");
                _exit(EXIT_FAILURE);
        }

        return wait_for_terminate_and_check(NULL, pid, 0);
}
