/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#include "httpd.h"
#include "apr_thread_proc.h"
#include "apr_strings.h"
#include "apr_portable.h"
#include "apr_pools.h"
#include "util_script.h"
#include "mod_core.h"
#include "mod_cgi.h"
#include "apr_tables.h"
#include "fcgid_proc.h"
#include "fcgid_proctbl.h"
#include "fcgid_protocol.h"
#include "fcgid_conf.h"
#include "fcgid_pm.h"
#include "fcgid_spawn_ctl.h"
#define SHUTDOWN_EVENT_NAME "_FCGI_SHUTDOWN_EVENT_"
#define FINISH_EVENT_DATA_NAME "finish_event"
#ifndef SIGKILL
#define SIGKILL 9
#endif

/* It's tested on WinNT ONLY, if it work on the other MS platform, let me know */
#if WINVER < 0x0400
#error It is tested on WinNT only
#endif

typedef struct {
    HANDLE handle_pipe;
    OVERLAPPED overlap_read;
    OVERLAPPED overlap_write;
} fcgid_namedpipe_handle;

static int g_process_counter = 0;

static apr_status_t close_finish_event(void *finishevent)
{
    HANDLE *finish_event = finishevent;

    CloseHandle(*finish_event);
    return APR_SUCCESS;
}

apr_status_t proc_spawn_process(const char *cmdline, fcgid_proc_info *procinfo,
                                fcgid_procnode *procnode)
{
    HANDLE *finish_event, listen_handle;
    SECURITY_ATTRIBUTES SecurityAttributes;
    fcgid_server_conf *sconf;
    apr_procattr_t *proc_attr;
    apr_status_t rv;
    apr_file_t *file;
    const char * const *proc_environ;
    char sock_path[FCGID_PATH_MAX];
    const char **wargv;

    /* Build wrapper args */
    apr_tokenize_to_argv(cmdline, (char ***)&wargv, procnode->proc_pool);

    memset(&SecurityAttributes, 0, sizeof(SecurityAttributes));

    /* Prepare finish event */
    finish_event = apr_palloc(procnode->proc_pool, sizeof(HANDLE));
    *finish_event = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (*finish_event == NULL
        || !SetHandleInformation(*finish_event, HANDLE_FLAG_INHERIT, TRUE))
    {
        ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(),
                     procinfo->main_server,
                     "mod_fcgid: can't create mutex for subprocess");
        return APR_ENOLOCK;
    }
    apr_pool_cleanup_register(procnode->proc_pool, finish_event,
                              close_finish_event, apr_pool_cleanup_null);

    /* For proc_kill_gracefully() */
    apr_pool_userdata_set(finish_event, FINISH_EVENT_DATA_NAME,
                          NULL, procnode->proc_pool);

    /* Pass the finish event id to subprocess */
    apr_table_setn(procinfo->proc_environ, SHUTDOWN_EVENT_NAME,
                   apr_ltoa(procnode->proc_pool, (long) *finish_event));

    /* Prepare the listen namedpipe file name (no check for truncation) */
    apr_snprintf(sock_path, sizeof sock_path,
                 "\\\\.\\pipe\\fcgidpipe-%lu.%d",
                 GetCurrentProcessId(), g_process_counter++);

    /* Prepare the listen namedpipe handle */
    SecurityAttributes.bInheritHandle = TRUE;
    SecurityAttributes.nLength = sizeof(SecurityAttributes);
    SecurityAttributes.lpSecurityDescriptor = NULL;
    listen_handle = CreateNamedPipe(sock_path,
                                    PIPE_ACCESS_DUPLEX,
                                    PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
                                    PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,
                                    8192, 8192, 0, &SecurityAttributes);
    if (listen_handle == INVALID_HANDLE_VALUE) {
        ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(),
                     procinfo->main_server,
                     "mod_fcgid: can't create namedpipe for subprocess");
        return APR_ENOSOCKET;
    }
    apr_cpystrn(procnode->socket_path, sock_path, sizeof(procnode->socket_path));
    apr_cpystrn(procnode->executable_path, wargv[0],
                sizeof(procnode->executable_path));

    /* Build environment variables */
    proc_environ = (const char * const *)
                   ap_create_environment(procnode->proc_pool,
                                         procinfo->proc_environ);
    if (!proc_environ) {
        ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(),
                     procinfo->main_server,
                     "mod_fcgid: can't build environment variables");
        return APR_ENOMEM;
    }

    /* Create process now */
    if ((rv = apr_procattr_create(&proc_attr, procnode->proc_pool))
               != APR_SUCCESS
        || (rv = apr_procattr_dir_set(proc_attr,
                     ap_make_dirstr_parent(procnode->proc_pool,
                                           wargv[0]))) != APR_SUCCESS
        || (rv = apr_procattr_cmdtype_set(proc_attr, APR_PROGRAM))
               != APR_SUCCESS
        || (rv = apr_procattr_detach_set(proc_attr, 1)) != APR_SUCCESS
        || (rv = apr_procattr_io_set(proc_attr, APR_NO_PIPE,
                                     APR_NO_FILE, APR_NO_FILE)) != APR_SUCCESS
        || (rv = apr_os_file_put(&file, &listen_handle, 0,
                                 procnode->proc_pool)) != APR_SUCCESS
        || (rv = apr_procattr_child_in_set(proc_attr, file, NULL))
               != APR_SUCCESS)
    {
        ap_log_error(APLOG_MARK, APLOG_WARNING, rv, procinfo->main_server,
                     "mod_fcgid: can't create FastCGI process attribute");
        CloseHandle(listen_handle);
        return APR_ENOPROC;
    }

    /* fork and exec now */
    rv = apr_proc_create(&(procnode->proc_id), wargv[0], wargv,
                         proc_environ,
                         proc_attr, procnode->proc_pool);

    /* OK, I created the process, now put it back to idle list */
    CloseHandle(listen_handle);

    if (rv != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, procinfo->main_server,
                     "mod_fcgid: can't run %s", wargv[0]);
        return rv;
    }

    /* FcgidWin32PreventOrphans feature */
    sconf = ap_get_module_config(procinfo->main_server->module_config,
                                 &fcgid_module);

    if (sconf->hJobObjectForAutoCleanup != NULL) {
        /* Associate cgi process to current process */
        if (AssignProcessToJobObject(sconf->hJobObjectForAutoCleanup,
                                     procnode->proc_id.hproc) == 0) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_os_error(),
                         procinfo->main_server,
                         "mod_fcgid: unable to assign child process to "
                         "job object");
        }
    }

    return APR_SUCCESS;
}

apr_status_t proc_kill_gracefully(fcgid_procnode *procnode,
                                  server_rec *main_server)
{
    HANDLE *finish_event = NULL;

    apr_pool_userdata_get((void **) &finish_event,
                          FINISH_EVENT_DATA_NAME, procnode->proc_pool);

    if (finish_event != NULL)
        SetEvent(*finish_event);
    return APR_SUCCESS;
}

apr_status_t proc_kill_force(fcgid_procnode *procnode,
                             server_rec *main_server)
{
    return apr_proc_kill(&(procnode->proc_id), SIGKILL);
}

apr_status_t proc_wait_process(server_rec *main_server,
                               fcgid_procnode *procnode)
{
    apr_status_t rv;
    int exitcode;
    apr_exit_why_e exitwhy;

    if ((rv = apr_proc_wait(&(procnode->proc_id), &exitcode, &exitwhy,
                            APR_NOWAIT)) == APR_CHILD_DONE) {
        /* Log why and how it die */
        proc_print_exit_info(procnode, exitcode, exitwhy, main_server);

        /* Register the death */
        register_termination(main_server, procnode);

        /* Destroy pool */
        apr_pool_destroy(procnode->proc_pool);
        procnode->proc_pool = NULL;
    }

    return rv;
}

static apr_status_t ipc_handle_cleanup(void *thehandle)
{
    fcgid_namedpipe_handle *handle = thehandle;

    /* Sanity check */
    if (handle) {
        if (handle->handle_pipe != INVALID_HANDLE_VALUE)
            CloseHandle(handle->handle_pipe);
        if (handle->overlap_read.hEvent != NULL)
            CloseHandle(handle->overlap_read.hEvent);
        if (handle->overlap_write.hEvent != NULL)
            CloseHandle(handle->overlap_write.hEvent);
        handle->handle_pipe = INVALID_HANDLE_VALUE;
        handle->overlap_read.hEvent = NULL;
        handle->overlap_write.hEvent = NULL;
    }

    return APR_SUCCESS;
}

apr_status_t proc_connect_ipc(fcgid_procnode *procnode, fcgid_ipc *ipc_handle)
{
    /* Prepare the ipc struct */
    fcgid_namedpipe_handle *handle_info;

    ipc_handle->ipc_handle_info =
        (fcgid_namedpipe_handle *) apr_pcalloc(ipc_handle->request->pool,
                                               sizeof
                                               (fcgid_namedpipe_handle));
    handle_info = (fcgid_namedpipe_handle *) ipc_handle->ipc_handle_info;

    /* Prepare OVERLAPPED struct for non-block I/O */
    handle_info->overlap_read.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    handle_info->overlap_write.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    handle_info->handle_pipe = INVALID_HANDLE_VALUE;

    apr_pool_cleanup_register(ipc_handle->request->pool,
                              handle_info,
                              ipc_handle_cleanup, apr_pool_cleanup_null);

    if (handle_info->overlap_read.hEvent == NULL
            || handle_info->overlap_write.hEvent == NULL)
        return APR_ENOMEM;

    /* Connect to name pipe */
    handle_info->handle_pipe = CreateFile(procnode->socket_path,
                                          GENERIC_READ | GENERIC_WRITE,
                                          0, NULL, OPEN_EXISTING,
                                          FILE_FLAG_OVERLAPPED, NULL);

    if (handle_info->handle_pipe == INVALID_HANDLE_VALUE
        && ipc_handle->connect_timeout != 0
        && GetLastError() == ERROR_PIPE_BUSY)
    {
        /* XXX - there appears to be a race, here
         * Wait for pipe to be ready for connect, and try again
         */
        if (WaitNamedPipe(procnode->socket_path, ipc_handle->connect_timeout))
        {
            handle_info->handle_pipe = CreateFile(procnode->socket_path,
                                                  GENERIC_READ | GENERIC_WRITE,
                                                  0, NULL, OPEN_EXISTING,
                                                  FILE_FLAG_OVERLAPPED, NULL);
        }
    }

    if (handle_info->handle_pipe == INVALID_HANDLE_VALUE)
    {
        if (GetLastError() == ERROR_FILE_NOT_FOUND) /* The process has exited */
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, ipc_handle->request,
                          "mod_fcgid: can't connect to named pipe, FastCGI"
                          " server %" APR_PID_T_FMT " has been terminated",
                          procnode->proc_id.pid);
        else
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, apr_get_os_error(),
                          ipc_handle->request,
                          "mod_fcgid: can't connect to named pipe, FastCGI"
                          " server pid %" APR_PID_T_FMT,
                          procnode->proc_id.pid);
        return APR_ESPIPE;
    }

    /* Now named pipe connected */
    return APR_SUCCESS;
}

apr_status_t proc_close_ipc(fcgid_ipc * ipc_handle)
{
    apr_status_t rv;

    rv = apr_pool_cleanup_run(ipc_handle->request->pool,
                              ipc_handle->ipc_handle_info,
                              ipc_handle_cleanup);
    ipc_handle->ipc_handle_info = NULL;
    return rv;
}

apr_status_t proc_read_ipc(fcgid_ipc * ipc_handle, const char *buffer,
                           apr_size_t * size)
{
    apr_status_t rv;
    fcgid_namedpipe_handle *handle_info;
    DWORD bytesread;

    handle_info = (fcgid_namedpipe_handle *) ipc_handle->ipc_handle_info;

    if (ReadFile(handle_info->handle_pipe, (LPVOID) buffer,
                 *size, &bytesread, &handle_info->overlap_read)) {
        *size = bytesread;
        return APR_SUCCESS;
    } else if ((rv = GetLastError()) != ERROR_IO_PENDING) {
        ap_log_rerror(APLOG_MARK, APLOG_WARNING, APR_FROM_OS_ERROR(rv),
                      ipc_handle->request,
                      "mod_fcgid: can't read from pipe");
        return rv;
    } else {
        /* it's ERROR_IO_PENDING */
        DWORD transferred;
        DWORD dwWaitResult
            = WaitForSingleObject(handle_info->overlap_read.hEvent,
                                  ipc_handle->communation_timeout * 1000);

        if (dwWaitResult == WAIT_OBJECT_0) {
            if (!GetOverlappedResult(handle_info->handle_pipe,
                                     &handle_info->overlap_read,
                                     &transferred, FALSE /* don't wait */ )
                || transferred == 0) {
                rv = apr_get_os_error();
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv,
                              ipc_handle->request,
                              "mod_fcgid: get overlap result error");
                return rv;
            }

            *size = transferred;
            return APR_SUCCESS;
        } else {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, ipc_handle->request,
                          "mod_fcgid: read timeout from pipe");
            return APR_ETIMEDOUT;
        }
    }
}

apr_status_t proc_write_ipc(fcgid_ipc * ipc_handle,
                            apr_bucket_brigade * birgade_send)
{
    fcgid_namedpipe_handle *handle_info;
    apr_bucket *bucket_request;
    apr_status_t rv;
    DWORD transferred;

    handle_info = (fcgid_namedpipe_handle *) ipc_handle->ipc_handle_info;

    for (bucket_request = APR_BRIGADE_FIRST(birgade_send);
         bucket_request != APR_BRIGADE_SENTINEL(birgade_send);
         bucket_request = APR_BUCKET_NEXT(bucket_request))
    {
        const char *write_buf;
        apr_size_t write_buf_len;
        apr_size_t has_write;

        if (APR_BUCKET_IS_METADATA(bucket_request))
            continue;

        if ((rv = apr_bucket_read(bucket_request, &write_buf, &write_buf_len,
                                  APR_BLOCK_READ)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, ipc_handle->request,
                          "mod_fcgid: can't read request from bucket");
            return rv;
        }

        /* Write the buffer to fastcgi server */
        has_write = 0;
        while (has_write < write_buf_len) {
            DWORD byteswrite;

            if (WriteFile(handle_info->handle_pipe,
                          write_buf + has_write,
                          write_buf_len - has_write,
                          &byteswrite, &handle_info->overlap_write)) {
                has_write += byteswrite;
                continue;
            } else if ((rv = GetLastError()) != ERROR_IO_PENDING) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING,
                              APR_FROM_OS_ERROR(rv), ipc_handle->request,
                              "mod_fcgid: can't write to pipe");
                return rv;
            } else {
                /*
                   it's ERROR_IO_PENDING on write
                 */
                DWORD dwWaitResult =
                    WaitForSingleObject(handle_info->overlap_write.hEvent,
                                        ipc_handle->communation_timeout * 1000);
                if (dwWaitResult == WAIT_OBJECT_0) {
                    if (!GetOverlappedResult(handle_info->handle_pipe,
                                             &handle_info->overlap_write,
                                             &transferred,
                                             FALSE /* don't wait */ )
                        || transferred == 0)
                    {
                        ap_log_rerror(APLOG_MARK, APLOG_WARNING,
                                      apr_get_os_error(), ipc_handle->request,
                                      "mod_fcgid: get overlap result error");
                        return APR_ESPIPE;
                    }
                    has_write += transferred;
                    continue;
                } else {
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0,
                                  ipc_handle->request,
                                  "mod_fcgid: write timeout to pipe");
                    return APR_ESPIPE;
                }
            }
        }
    }

    return APR_SUCCESS;
}

void proc_print_exit_info(fcgid_procnode * procnode, int exitcode,
                          apr_exit_why_e exitwhy, server_rec * main_server)
{
    char *diewhy = NULL;

    /* Reasons to exit */
    switch (procnode->diewhy) {
    case FCGID_DIE_KILLSELF:
        if (exitwhy == APR_PROC_EXIT)
            diewhy = "normal exit";
        else
            diewhy = "access violation";
        break;
    case FCGID_DIE_IDLE_TIMEOUT:
        diewhy = "idle timeout";
        break;
    case FCGID_DIE_LIFETIME_EXPIRED:
        diewhy = "lifetime expired";
        break;
    case FCGID_DIE_BUSY_TIMEOUT:
        diewhy = "busy timeout";
        break;
    case FCGID_DIE_CONNECT_ERROR:
        diewhy = "connect error, server may has exited";
        break;
    case FCGID_DIE_COMM_ERROR:
        diewhy = "communication error";
        break;
    case FCGID_DIE_SHUTDOWN:
        diewhy = "shutting down";
        break;
    default:
        diewhy = "unknown";
    }

    /* Print log now */
    ap_log_error(APLOG_MARK, APLOG_INFO, 0, main_server,
                     "mod_fcgid: process %s(%" APR_PID_T_FMT ") exit(%s), return code %d",
                     procnode->executable_path, procnode->proc_id.pid, diewhy, exitcode);
}
