/***
  This file is part of libdaemon.

  Copyright 2003-2008 Lennart Poettering

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.

***/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#include <limits.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>

#include "dlog.h"
#include "dsignal.h"
#include "dfork.h"
#include "dexec.h"

#define MAX_ARGS 64

int daemon_execv(const char *dir, int *ret, const char *prog, va_list ap) {
    pid_t pid;
    int p[2];
    unsigned n = 0;
    static char buf[256];
    int sigfd, r;
    fd_set fds;
    int saved_errno;

    assert(daemon_signal_fd() >= 0);

    if (pipe(p) < 0) {
        daemon_log(LOG_ERR, "pipe() failed: %s", strerror(errno));
        return -1;
    }

    if ((pid = fork()) < 0) {
        daemon_log(LOG_ERR, "fork() failed: %s", strerror(errno));

        saved_errno = errno;
        close(p[0]);
        close(p[1]);
        errno = saved_errno;

        return -1;

    } else if (pid == 0) {
        char *args[MAX_ARGS];
        int i;

        if (p[1] != 1)
            if (dup2(p[1], 1) < 0) {
                daemon_log(LOG_ERR, "dup2: %s", strerror(errno));
                goto fail;
            }

        if (p[1] != 2)
            if (dup2(p[1], 2) < 0) {
                daemon_log(LOG_ERR, "dup2: %s", strerror(errno));
                goto fail;
            }


        if (p[0] > 2)
            close(p[0]);

        if (p[1] > 2)
            close(p[1]);

        close(0);

        if (open("/dev/null", O_RDONLY) != 0) {
            daemon_log(LOG_ERR, "Unable to open /dev/null as STDIN");
            goto fail;
        }

        daemon_close_all(-1);
        daemon_reset_sigs(-1);
        daemon_unblock_sigs(-1);

        umask(0022); /* Set up a sane umask */

        if (dir && chdir(dir) < 0) {
            daemon_log(LOG_WARNING, "Failed to change to directory '%s'", dir);
            chdir("/");
        }

        for (i = 0; i < MAX_ARGS-1; i++)
            if (!(args[i] = va_arg(ap, char*)))
                break;
        args[i] = NULL;

        execv(prog, args);

        daemon_log(LOG_ERR, "execv(%s) failed: %s", prog, strerror(errno));

    fail:

        _exit(EXIT_FAILURE);
    }

    close(p[1]);

    FD_ZERO(&fds);
    FD_SET(p[0], &fds);
    sigfd = daemon_signal_fd();
    FD_SET(sigfd, &fds);

    n = 0;

    for (;;) {
        fd_set qfds = fds;

        if (select(FD_SETSIZE, &qfds, NULL, NULL, NULL) < 0) {

            if (errno == EINTR)
                continue;

            daemon_log(LOG_ERR, "select() failed: %s", strerror(errno));

            saved_errno = errno;
            close(p[0]);
            errno = saved_errno;
            return -1;
        }

        if (FD_ISSET(p[0], &qfds)) {
            char c;

            if (read(p[0], &c, 1) != 1)
                break;

            buf[n] = c;

            if (c == '\n' || n >= sizeof(buf) - 2) {
                if (c != '\n') n++;
                buf[n] = 0;

                if (buf[0])
                    daemon_log(LOG_INFO, "client: %s", buf);

                n = 0;
            } else
                n++;
        }

        if (FD_ISSET(sigfd, &qfds)) {
            int sig;

            if ((sig = daemon_signal_next()) < 0) {
                saved_errno = errno;
                close(p[0]);
                errno = saved_errno;
                return -1;
            }

            if (sig != SIGCHLD) {
                daemon_log(LOG_WARNING, "Killing child.");
                kill(pid, SIGTERM);
            }
        }
    }

    if (n > 0) {
        buf[n] = 0;
        daemon_log(LOG_WARNING, "client: %s", buf);
    }

    close(p[0]);

    for (;;) {
        if (waitpid(pid, &r, 0) < 0) {

            if (errno == EINTR)
                continue;

            daemon_log(LOG_ERR, "waitpid(): %s", strerror(errno));
            return -1;
        } else {
            if (!WIFEXITED(r)) {
                errno = ECANCELED;
                return -1;
            }

            if (ret)
                *ret = WEXITSTATUS(r);

            return 0;
        }
    }
}

int daemon_exec(const char *dir, int *ret, const char *prog, ...) {
    va_list ap;
    int r;

    va_start(ap, prog);
    r = daemon_execv(dir, ret, prog, ap);
    va_end(ap);

    return r;
}
