/*
 * Copyright (C) Tildeslash Ltd. All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License version 3.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 *
 * You must obey the GNU Affero General Public License in all respects
 * for all of the code used other than OpenSSL.  
 */


#include "Config.h"

#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>

#include "Str.h"
#include "Dir.h"
#include "File.h"
#include "List.h"
#include "system/Net.h"

#include "system/System.h"
#include "system/Command.h"


/**
 * Implementation of the Command and Process interfaces.
 *
 * @see http://www.mmonit.com/
 * @file
 */



/* ----------------------------------------------------------- Definitions */


#define T Command_T
struct T {
        uid_t uid;
        gid_t gid;
        List_T env;
        List_T args;
        char *working_directory;
};
struct Process_T {
        pid_t pid;
        uid_t uid;
        gid_t gid;
        char **env; 
        char **args;
        int status;
        int stdin_pipe[2];
        int stdout_pipe[2];
        int stderr_pipe[2];
        InputStream_T in;
        InputStream_T err;
        OutputStream_T out;
        char *working_directory;
};
const char *Command_Path = "PATH=/bin:/usr/bin:/usr/local/bin:/opt/csw/bin:/usr/sfw/bin";


/* --------------------------------------------------------------- Private */


/* Search the env list and return the pointer to the name (in the list)
 if found, otherwise NULL */
static inline char *findEnv(T C, const char *name) {
        for (list_t p = C->env->head; p; p = p->next)
                if (Str_startsWith(p->e, name))
                        return p->e;
        return NULL;
}


/* Remove env variable and value identified by name */
static inline void removeEnv(T C, const char *name) {
        char *e = findEnv(C, name);
        if (e) {
                List_remove(C->env, e);
                FREE(e);
        }
}


/* Free each string in a list of strings */
static void freeStrings(List_T l) {
        while (List_length(l) > 0) {
                char *s = List_pop(l);
                FREE(s);
        }
}


/* Build the Command args list. The list represent the array sent
 to execv and the List contains the following entries: args[0]
 is the path to the program, the rest are arguments to the program */
static void buildArgs(T C, const char *path, const char *x, va_list ap) {
        freeStrings(C->args);
        List_append(C->args, Str_dup(path));
        va_list ap_copy;
        va_copy(ap_copy, ap);
        for (; x; x = va_arg(ap_copy, char *))
                List_append(C->args, Str_dup(x));
        va_end(ap_copy);
}


/* Create stdio pipes for communication between parent and child process */
static void createPipes(Process_T P) {
        if (pipe(P->stdin_pipe) < 0 
            || pipe(P->stdout_pipe) < 0 
            || pipe(P->stderr_pipe) < 0) {
                ERROR("Command pipe(2): Bad file descriptors -- %s", System_getLastError());
        }
}


/* Setup stdio pipes in subprocess */
static void setupChildPipes(Process_T P) {
        close(P->stdin_pipe[1]);   // close write end
        if (P->stdin_pipe[0] != STDIN_FILENO) {
                if (dup2(P->stdin_pipe[0],  STDIN_FILENO) != STDIN_FILENO)
                        ERROR("Command: dup2(stdin) -- %s\n", System_getLastError());
                close(P->stdin_pipe[0]);
        }
        close(P->stdout_pipe[0]);  // close read end
        if (P->stdout_pipe[1] != STDOUT_FILENO) {
                if (dup2(P->stdout_pipe[1], STDOUT_FILENO) != STDOUT_FILENO)
                        ERROR("Command: dup2(stdout) -- %s\n", System_getLastError());
                close(P->stdout_pipe[1]);
        }
        close(P->stderr_pipe[0]);  // close read end
        if (P->stderr_pipe[1] != STDERR_FILENO) {
                if (dup2(P->stderr_pipe[1], STDERR_FILENO) != STDERR_FILENO)
                        ERROR("Command: dup2(stderr) -- %s\n", System_getLastError());
                close(P->stderr_pipe[1]);
        }
}


/* Setup stdio pipes in parent process for communication with the subprocess */
static void setupParentPipes(Process_T P) {
        close(P->stdin_pipe[0]);    // close read end
        Net_setNonBlocking(P->stdin_pipe[1]);
        close(P->stdout_pipe[1]);   // close write end
        Net_setNonBlocking(P->stdout_pipe[0]);
        close(P->stderr_pipe[1]);   // close write end
        Net_setNonBlocking(P->stderr_pipe[0]);
}


/* Close stdio pipes in parent process */
static void closeParentPipes(Process_T P) {
        close(P->stdin_pipe[1]);    // close write end
        close(P->stdout_pipe[0]);   // close read end
        close(P->stderr_pipe[0]);   // close read end
}


/* Close and destroy opened stdio streams */
static void closeStreams(Process_T P) {
        if (P->in) InputStream_free(&P->in);
        if (P->err) InputStream_free(&P->err);
        if (P->out) OutputStream_free(&P->out);
}


/* -------------------------------------------------------------- Process_T */


static inline void setstatus(Process_T P) {
        if (WIFEXITED(P->status))
                P->status = WEXITSTATUS(P->status);
        else if (WIFSIGNALED(P->status))
                P->status = WTERMSIG(P->status);
        else if (WIFSTOPPED(P->status))
                P->status = WSTOPSIG(P->status);
}


static Process_T Process_new(void) {
        Process_T P;
        NEW(P);
        P->status = -1;
        return P;
}


void Process_free(Process_T *P) {
        assert(P && *P);
        FREE((*P)->args);
        FREE((*P)->env);
        FREE((*P)->working_directory);
        if (Process_isRunning(*P)) 
                Process_kill(*P);
        closeParentPipes(*P);
        closeStreams(*P);
        FREE(*P);
}


uid_t Process_getUid(Process_T P) {
        assert(P);
        return P->uid;
}


gid_t Process_getGid(Process_T P) {
        assert(P);
        return P->gid;
}


const char *Process_getDir(Process_T P) {
        assert(P);
        if (! P->working_directory) {
                char t[STRLEN];
                P->working_directory = Str_dup(Dir_cwd(t, STRLEN));
        }
        return P->working_directory;
}


pid_t Process_getPid(Process_T P) {
        assert(P);
        return P->pid;
}


int Process_waitFor(Process_T P) {
        assert(P);
        if (P->status < 0) {
                int r;
                do
                        r = waitpid(P->pid, &P->status, 0); // Wait blocking
                while (r == -1 && errno == EINTR);
                if (r != P->pid) 
                        P->status = -1;
                else 
                        setstatus(P);
        }
        return P->status;
}


int Process_exitStatus(Process_T P) {
        assert(P);
        if (P->status < 0) {
                int r;
                do
                        r = waitpid(P->pid, &P->status, WNOHANG); // Wait non-blocking
                while (r == -1 && errno == EINTR); 
                if (r == 0) // Process is still running
                        P->status = -1;
                else 
                        setstatus(P);
        }
        return P->status;
}


int Process_isRunning(Process_T P) {
        assert(P);
        errno = 0;
        return ((getpgid(P->pid) > -1) || (errno == EPERM));
}


OutputStream_T Process_getOutputStream(Process_T P) {
        assert(P);
        if (! P->out)
                P->out = OutputStream_new(P->stdin_pipe[1]);
        return P->out;
}


InputStream_T Process_getInputStream(Process_T P) {
        assert(P);
        if (! P->in)
                P->in = InputStream_new(P->stdout_pipe[0]);
        return P->in;
}


InputStream_T Process_getErrorStream(Process_T P) {
        assert(P);
        if (! P->err)
                P->err = InputStream_new(P->stderr_pipe[0]);
        return P->err;
}


void Process_terminate(Process_T P) {
        assert(P);
        kill(P->pid, SIGTERM);
}


void Process_kill(Process_T P) {
        assert(P);
        kill(P->pid, SIGKILL);
}


/* ---------------------------------------------------------------- Public */


T Command_new(const char *path, const char *arg0, ...) {
        T C;
        if (! File_exist(path))
                THROW(AssertException, "File '%s' does not exist", path ? path : "null");
        NEW(C);
        C->env = List_new();
        C->args = List_new();
        List_append(C->env, Str_dup(Command_Path));
        va_list ap;
        va_start(ap, arg0);
        buildArgs(C, path, arg0, ap);
        va_end(ap);
        return C;
}


void Command_free(T *C) {
        assert(C && *C);
        freeStrings((*C)->args);
        List_free(&(*C)->args);
        freeStrings((*C)->env);
        List_free(&(*C)->env);
        FREE((*C)->working_directory);
        FREE(*C);
}


void Command_setUid(T C, uid_t uid) {
        assert(C);
        C->uid = uid;
}


uid_t Command_getUid(T C) {
        assert(C);
        return C->uid;
}


void Command_setGid(T C, gid_t gid) {
        assert(C);
        C->gid = gid;
}


gid_t Command_getGid(T C) {
        assert(C);
        return C->gid;
}


void Command_setDir(T C, const char *dir) {
        assert(C);
        if (dir) { // Allow to set a NULL directory, meaning the calling process's current directory
                if (! File_isDirectory(dir))
                        THROW(AssertException, "The working directory '%s' is not a directory", dir);
                if (! File_isExecutable(dir))
                        THROW(AssertException, "The working directory '%s' is not accessible", dir);
        }
        FREE(C->working_directory);
        C->working_directory = Str_dup(dir);
        File_removeTrailingSeparator(C->working_directory);
}


const char *Command_getDir(Command_T C) {
        assert(C);
        return C->working_directory;
}


/* Env variables are stored in the environment list as "name=value" strings */
void Command_setEnv(Command_T C, const char *name, const char *value) {
        assert(C);
        assert(name);
        removeEnv(C, name);
        List_append(C->env, Str_cat("%s=%s", name, value ? value : ""));
}


void Command_vSetEnv(T C, const char *env, ...) {
        assert(C);
        if (STR_DEF(env)) {
                va_list ap;
                char *s, *n, *v, *t;
                va_start(ap, env);
                n = s = Str_vcat(env, ap);
                va_end(ap);
                while ((v = strchr(n, '='))) {
                        *(v++) = 0;
                        t = strchr(v, ';');
                        if (t)
                                *(t++) = 0;
                        Command_setEnv(C, Str_trim(n), Str_trim(v));
                        if (t)
                                n = t;
                        else
                                break;
                }
                FREE(s);
        }
}


/* Returns the value part from a "name=value" environment string */
const char *Command_getEnv(Command_T C, const char *name) {
        assert(C);
        assert(name);
        char *e = findEnv(C, name);
        if (e) {
                char *v = strchr(e, '=');
                if (v)
                        return ++v;   
        }
        return NULL;
}


List_T Command_getCommand(T C) {
        assert(C);
        return C->args;
}


/* The Execute function. Note that we use vfork() rather than fork. Vfork has
 a special semantic in that the child process runs in the parent address space
 until exec is called in the child. The child also run first and suspend the
 parent process until exec or exit is called */
Process_T Command_execute(T C) {
        assert(C);
        volatile int exec_error = 0;
        Process_T P = Process_new();
        P->env = (char**)List_toArray(C->env);
        P->args = (char**)List_toArray(C->args);
        createPipes(P);
        if ((P->pid = vfork()) < 0) {
                ERROR("Command: fork failed -- %s\n", System_getLastError());
                Process_free(&P);
                return NULL;
        }
        // Child
        else if (P->pid == 0) { 
                if (C->working_directory) {
                        if (! Dir_chdir(C->working_directory)) {
                                exec_error = errno;
                                ERROR("Command: sub-process cannot change working directory to '%s' -- %s\n", C->working_directory, System_getLastError());
                                _exit(errno);
                        }
                }
                if (C->uid)
                        P->uid = (setuid(C->uid) != 0) ? ERROR("Command: Cannot change process uid to '%d' -- %s\n", C->uid, System_getLastError()), getuid() : C->uid;
                else
                        P->uid = getuid();
                if (C->gid)
                        P->gid = (setgid(C->gid) != 0) ? ERROR("Command: Cannot change process gid to '%d' -- %s\n", C->gid, System_getLastError()), getgid() : C->gid;
                else
                        P->gid = getgid();
                setsid(); // Loose controlling terminal
                setupChildPipes(P);
                // Close all descriptors except stdio
                int descriptors = getdtablesize();
                for (int i = 3; i < descriptors; i++)
                        close(i);
                // Unblock any signals and reset signal handlers
                sigset_t mask;
                sigemptyset(&mask);
                pthread_sigmask(SIG_SETMASK, &mask, NULL);
                signal(SIGINT, SIG_DFL);
                signal(SIGQUIT, SIG_DFL);
                signal(SIGABRT, SIG_DFL);
                signal(SIGTERM, SIG_DFL);
                signal(SIGPIPE, SIG_DFL);
                signal(SIGCHLD, SIG_DFL); 
                signal(SIGHUP, SIG_IGN);  // Ensure future opens won't allocate controlling TTYs
                // Execute the program
                execve(P->args[0], P->args, P->env);
                exec_error = errno;
                _exit(errno);
        }
        // Parent
        if (exec_error != 0)
                Process_free(&P);
        else 
                setupParentPipes(P);
        errno = exec_error;
        return P;
}
