/*
 * 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.
 */

/* For DEFAULT_PATH */
#define CORE_PRIVATE
#include "httpd.h"
#include "http_config.h"

#include "fcgid_pm.h"
#include "fcgid_pm_main.h"
#include "fcgid_conf.h"
#include "fcgid_proctbl.h"
#include "fcgid_proc.h"
#include "fcgid_spawn_ctl.h"

#define HAS_GRACEFUL_KILL "Gracefulkill"

static void
link_node_to_list(server_rec * main_server,
                  fcgid_procnode * header,
                  fcgid_procnode * node, fcgid_procnode * table_array)
{
    safe_lock(main_server);
    node->next_index = header->next_index;
    header->next_index = node - table_array;
    safe_unlock(main_server);
}

static apr_time_t lastidlescan = 0;
static void scan_idlelist(server_rec * main_server)
{
    /* 
       Scan the idle list 
       1. move all processes idle timeout to error list
       2. move all processes lifetime expired to error list
     */
    fcgid_procnode *previous_node, *current_node, *next_node;
    fcgid_procnode *error_list_header;
    fcgid_procnode *proc_table;
    apr_time_t last_active_time, start_time;
    apr_time_t now = apr_time_now();
    int idle_timeout, proc_lifetime;
    fcgid_server_conf *sconf = ap_get_module_config(main_server->module_config,
                                                    &fcgid_module);

    /* Should I check the idle list now? */
    if (procmgr_must_exit()
        || apr_time_sec(now) - apr_time_sec(lastidlescan) <=
        sconf->idle_scan_interval)
        return;
    lastidlescan = now;

    /* Check the list */
    proc_table = proctable_get_table_array();
    previous_node = proctable_get_idle_list();
    error_list_header = proctable_get_error_list();

    safe_lock(main_server);
    current_node = &proc_table[previous_node->next_index];
    while (current_node != proc_table) {
        next_node = &proc_table[current_node->next_index];
        last_active_time = current_node->last_active_time;
        start_time = current_node->start_time;
        idle_timeout = current_node->cmdopts.idle_timeout;
        proc_lifetime = current_node->cmdopts.proc_lifetime;
        if (((idle_timeout && 
              (apr_time_sec(now) - apr_time_sec(last_active_time) > idle_timeout))
             || (proc_lifetime && 
              (apr_time_sec(now) - apr_time_sec(start_time) > proc_lifetime)))
            && is_kill_allowed(main_server, current_node)) {
            /* Set die reason for log */
            if (idle_timeout &&
                (apr_time_sec(now) - apr_time_sec(last_active_time) > idle_timeout))
                current_node->diewhy = FCGID_DIE_IDLE_TIMEOUT;
            else if (proc_lifetime && 
                     (apr_time_sec(now) - apr_time_sec(start_time) > proc_lifetime))
                current_node->diewhy = FCGID_DIE_LIFETIME_EXPIRED;

            /* Unlink from idle list */
            previous_node->next_index = current_node->next_index;

            /* Link to error list */
            current_node->next_index = error_list_header->next_index;
            error_list_header->next_index = current_node - proc_table;
        } else
            previous_node = current_node;

        current_node = next_node;
    }
    safe_unlock(main_server);
}

static apr_time_t lastbusyscan = 0;
static void scan_busylist(server_rec * main_server)
{
    /*
       Scan the busy list
       1. move all expired node to error list
     */
    fcgid_procnode *previous_node, *current_node, *next_node;
    fcgid_procnode *error_list_header;
    fcgid_procnode *proc_table;
    apr_time_t last_active_time;
    apr_time_t now = apr_time_now();
    fcgid_server_conf *sconf = ap_get_module_config(main_server->module_config,
                                                    &fcgid_module);

    /* Should I check the busy list? */
    if (procmgr_must_exit()
        || apr_time_sec(now) - apr_time_sec(lastbusyscan) <=
        sconf->busy_scan_interval)
        return;
    lastbusyscan = now;

    /* Check the list */
    proc_table = proctable_get_table_array();
    previous_node = proctable_get_busy_list();
    error_list_header = proctable_get_error_list();

    safe_lock(main_server);
    current_node = &proc_table[previous_node->next_index];
    while (current_node != proc_table) {
        next_node = &proc_table[current_node->next_index];

        last_active_time = current_node->last_active_time;
        /* FIXME See BZ #47483 */
        if (apr_time_sec(now) - apr_time_sec(last_active_time) >
            (current_node->cmdopts.busy_timeout + 10)) {
            /* Set dir reason for log */
            current_node->diewhy = FCGID_DIE_BUSY_TIMEOUT;

            /* Unlink from busy list */
            previous_node->next_index = current_node->next_index;

            /* Link to error list */
            current_node->next_index = error_list_header->next_index;
            error_list_header->next_index = current_node - proc_table;
        } else
            previous_node = current_node;

        current_node = next_node;
    }
    safe_unlock(main_server);
}

static apr_time_t lastzombiescan = 0;
static void scan_idlelist_zombie(server_rec * main_server)
{
    /* 
       Scan the idle list 
       1. pick up the node for scan(now-last_activ>g_zombie_scan_interval)
       2. check if it's zombie process
       3. if it's zombie process, wait() and return to free list
       4. return to idle list if it's not zombie process
     */
    pid_t thepid;
    fcgid_procnode *previous_node, *current_node, *next_node;
    fcgid_procnode *error_list_header, *check_list_header;
    fcgid_procnode *proc_table;
    apr_time_t last_active_time;
    apr_time_t now = apr_time_now();
    fcgid_procnode temp_header;
    fcgid_server_conf *sconf = ap_get_module_config(main_server->module_config,
                                                    &fcgid_module);

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

    /* Should I check zombie processes in idle list now? */
    if (procmgr_must_exit()
        || apr_time_sec(now) - apr_time_sec(lastzombiescan) <=
        sconf->zombie_scan_interval)
        return;
    lastzombiescan = now;

    /* 
       Check the list 
     */
    proc_table = proctable_get_table_array();
    previous_node = proctable_get_idle_list();
    error_list_header = proctable_get_error_list();
    check_list_header = &temp_header;

    safe_lock(main_server);
    current_node = &proc_table[previous_node->next_index];
    while (current_node != proc_table) {
        next_node = &proc_table[current_node->next_index];

        /* Is it time for zombie check? */
        last_active_time = current_node->last_active_time;
        if (apr_time_sec(now) - apr_time_sec(last_active_time) >
            sconf->zombie_scan_interval) {
            /* Unlink from idle list */
            previous_node->next_index = current_node->next_index;

            /* Link to check list */
            current_node->next_index = check_list_header->next_index;
            check_list_header->next_index = current_node - proc_table;
        } else
            previous_node = current_node;

        current_node = next_node;
    }
    safe_unlock(main_server);

    /* 
       Now check every node in check list
       1) If it's zombie process, wait() and return to free list
       2) If it's not zombie process, link it to the tail of idle list
     */
    previous_node = check_list_header;
    current_node = &proc_table[previous_node->next_index];
    while (current_node != proc_table) {
        next_node = &proc_table[current_node->next_index];

        /* Is it zombie process? */
        thepid = current_node->proc_id->pid;
        if (proc_wait_process(main_server, current_node) == APR_CHILD_DONE) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, main_server,
                         "mod_fcgid: cleanup zombie process %"
                         APR_PID_T_FMT, thepid);

            /* Unlink from check list */
            previous_node->next_index = current_node->next_index;

            /* Link to free list */
            link_node_to_list(main_server, proctable_get_free_list(),
                              current_node, proc_table);
        } else
            previous_node = current_node;

        current_node = next_node;
    }

    /* 
       Now link the check list back to the tail of idle list 
     */
    if (check_list_header->next_index) {
        safe_lock(main_server);
        previous_node = proctable_get_idle_list();
        current_node = &proc_table[previous_node->next_index];

        /* Find the tail of idle list */
        while (current_node != proc_table) {
            previous_node = current_node;
            current_node = &proc_table[current_node->next_index];
        }

        /* Link check list to the tail of idle list */
        previous_node->next_index = check_list_header->next_index;
        safe_unlock(main_server);
    }
}

static apr_time_t lasterrorscan = 0;
static void scan_errorlist(server_rec * main_server)
{
    /* 
       kill() and wait() every node in error list
       put them back to free list after that
     */
    void *dummy;
    fcgid_procnode *previous_node, *current_node, *next_node;
    apr_time_t now = apr_time_now();
    fcgid_procnode *error_list_header = proctable_get_error_list();
    fcgid_procnode *free_list_header = proctable_get_free_list();
    fcgid_procnode *proc_table = proctable_get_table_array();
    fcgid_procnode temp_error_header;
    fcgid_server_conf *sconf = ap_get_module_config(main_server->module_config,
                                                    &fcgid_module);

    /* Should I check the busy list? */
    if (procmgr_must_exit()
        || apr_time_sec(now) - apr_time_sec(lasterrorscan) <=
        sconf->error_scan_interval)
        return;
    lasterrorscan = now = apr_time_now();

    /* Try wait dead processes, restore to free list */
    /* Note: I can't keep the lock during the scan */
    safe_lock(main_server);
    temp_error_header.next_index = error_list_header->next_index;
    error_list_header->next_index = 0;
    safe_unlock(main_server);

    previous_node = &temp_error_header;
    current_node = &proc_table[previous_node->next_index];
    while (current_node != proc_table) {
        next_node = &proc_table[current_node->next_index];

        if (proc_wait_process(main_server, current_node) !=
            APR_CHILD_NOTDONE) {
            /* Unlink from error list */
            previous_node->next_index = current_node->next_index;

            /* Link to free list */
            current_node->next_index = free_list_header->next_index;
            free_list_header->next_index = current_node - proc_table;
        } else
            previous_node = current_node;

        current_node = next_node;
    }

    /* Kill the left processes, wait() them in the next round */
    for (current_node = &proc_table[temp_error_header.next_index];
         current_node != proc_table;
         current_node = &proc_table[current_node->next_index]) {
        /* Try gracefully first */
        dummy = NULL;
        apr_pool_userdata_get(&dummy, HAS_GRACEFUL_KILL,
                              current_node->proc_pool);
        if (!dummy) {
            proc_kill_gracefully(current_node, main_server);
            apr_pool_userdata_set("set", HAS_GRACEFUL_KILL,
                                  apr_pool_cleanup_null,
                                  current_node->proc_pool);
        } else {
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, main_server,
                         "mod_fcgid: process %" APR_PID_T_FMT
                         " graceful kill fail, sending SIGKILL",
                         current_node->proc_id->pid);
            proc_kill_force(current_node, main_server);
        }
    }

    /* Link the temp error list back */
    safe_lock(main_server);
    /* Find the tail of error list */
    previous_node = error_list_header;
    current_node = &proc_table[previous_node->next_index];
    while (current_node != proc_table) {
        previous_node = current_node;
        current_node = &proc_table[current_node->next_index];
    }
    previous_node->next_index = temp_error_header.next_index;
    safe_unlock(main_server);
}

static void kill_all_subprocess(server_rec * main_server)
{
    size_t i;
    int exitcode;
    apr_exit_why_e exitwhy;
    fcgid_procnode *proc_table = proctable_get_table_array();

    /* Kill gracefully */
    for (i = 0; i < proctable_get_table_size(); i++) {
        if (proc_table[i].proc_pool)
            proc_kill_gracefully(&proc_table[i], main_server);
    }
    apr_sleep(apr_time_from_sec(1));

    /* Kill with SIGKILL if it doesn't work */
    for (i = 0; i < proctable_get_table_size(); i++) {
        if (proc_table[i].proc_pool) {
            if (apr_proc_wait(proc_table[i].proc_id, &exitcode, &exitwhy,
                              APR_NOWAIT) != APR_CHILD_NOTDONE) {
                proc_table[i].diewhy = FCGID_DIE_SHUTDOWN;
                proc_print_exit_info(&proc_table[i], exitcode, exitwhy,
                                     main_server);
                apr_pool_destroy(proc_table[i].proc_pool);
                proc_table[i].proc_pool = NULL;
            } else
                proc_kill_force(&proc_table[i], main_server);
        }
    }

    /* Wait again */
    for (i = 0; i < proctable_get_table_size(); i++) {
        if (proc_table[i].proc_pool) {
            if (apr_proc_wait(proc_table[i].proc_id, &exitcode, &exitwhy,
                              APR_WAIT) != APR_CHILD_NOTDONE) {
                proc_table[i].diewhy = FCGID_DIE_SHUTDOWN;
                proc_print_exit_info(&proc_table[i], exitcode, exitwhy,
                                     main_server);
                apr_pool_destroy(proc_table[i].proc_pool);
                proc_table[i].proc_pool = NULL;
            }
        }
    }
}

/* This should be proposed as a stand-alone improvement to the httpd module,
 * either in the arch/ platform-specific modules or util_script.c from whence
 * it came.
 */
static void default_proc_env(apr_table_t *e)
{
    const char *env_temp;

    if (!(env_temp = getenv("PATH"))) {
        env_temp = DEFAULT_PATH;
    }
    apr_table_addn(e, "PATH", env_temp);

#ifdef WIN32
    if ((env_temp = getenv("SYSTEMROOT"))) {
        apr_table_addn(e, "SYSTEMROOT", env_temp);
    }
    if ((env_temp = getenv("COMSPEC"))) {
        apr_table_addn(e, "COMSPEC", env_temp);
    }
    if ((env_temp = getenv("PATHEXT"))) {
        apr_table_addn(e, "PATHEXT", env_temp);
    }
    if ((env_temp = getenv("WINDIR"))) {
        apr_table_addn(e, "WINDIR", env_temp);
    }
#elif defined(OS2)
    if ((env_temp = getenv("COMSPEC")) != NULL) {
        apr_table_addn(e, "COMSPEC", env_temp);
    }
    if ((env_temp = getenv("ETC")) != NULL) {
        apr_table_addn(e, "ETC", env_temp);
    }
    if ((env_temp = getenv("DPATH")) != NULL) {
        apr_table_addn(e, "DPATH", env_temp);
    }
    if ((env_temp = getenv("PERLLIB_PREFIX")) != NULL) {
        apr_table_addn(e, "PERLLIB_PREFIX", env_temp);
    }
#elif defined(BEOS)
    if ((env_temp = getenv("LIBRARY_PATH")) != NULL) {
        apr_table_addn(e, "LIBRARY_PATH", env_temp);
    }
#elif defined (AIX)
    if ((env_temp = getenv("LIBPATH"))) {
        apr_table_addn(e, "LIBPATH", env_temp);
    }
#else
/* DARWIN, HPUX vary depending on circumstance */
#if defined (DARWIN)
    if ((env_temp = getenv("DYLD_LIBRARY_PATH"))) {
        apr_table_addn(e, "DYLD_LIBRARY_PATH", env_temp);
    }
#elif defined (HPUX11) || defined (HPUX10) || defined (HPUX)
    if ((env_temp = getenv("SHLIB_PATH"))) {
        apr_table_addn(e, "SHLIB_PATH", env_temp);
    }
#endif
    if ((env_temp = getenv("LD_LIBRARY_PATH"))) {
        apr_table_addn(e, "LD_LIBRARY_PATH", env_temp);
    }
#endif
}
/* End of common to util_script.c */

static void
fastcgi_spawn(fcgid_command * command, server_rec * main_server,
              apr_pool_t * configpool)
{
    fcgid_procnode *free_list_header, *proctable_array,
        *procnode, *idle_list_header;
    fcgid_proc_info procinfo;
    apr_status_t rv;
    int i;

    free_list_header = proctable_get_free_list();
    idle_list_header = proctable_get_idle_list();
    proctable_array = proctable_get_table_array();

    /* Apply a slot from free list */
    safe_lock(main_server);
    if (free_list_header->next_index == 0) {
        safe_unlock(main_server);
        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, main_server,
                     "mod_fcgid: too much processes, please increase FCGID_MAX_APPLICATION");
        return;
    }
    procnode = &proctable_array[free_list_header->next_index];
    free_list_header->next_index = procnode->next_index;
    procnode->next_index = 0;
    safe_unlock(main_server);

    /* Prepare to spawn */
    procnode->deviceid = command->deviceid;
    procnode->inode = command->inode;
    procnode->share_grp_id = command->share_grp_id;
    procnode->virtualhost = command->virtualhost;
    procnode->uid = command->uid;
    procnode->gid = command->gid;
    procnode->start_time = procnode->last_active_time = apr_time_now();
    procnode->requests_handled = 0;
    procnode->diewhy = FCGID_DIE_KILLSELF;
    procnode->proc_pool = NULL;
    procnode->cmdopts = command->cmdopts;

    procinfo.cgipath = command->cgipath;
    procinfo.configpool = configpool;
    procinfo.main_server = main_server;
    procinfo.uid = command->uid;
    procinfo.gid = command->gid;
    procinfo.userdir = command->userdir;
    if ((rv = apr_pool_create(&procnode->proc_pool, configpool)) != APR_SUCCESS
        || (procinfo.proc_environ =
            apr_table_make(procnode->proc_pool, INITENV_CNT)) == NULL) {
        /* Link the node back to free list in this case */
        if (procnode->proc_pool)
            apr_pool_destroy(procnode->proc_pool);
        link_node_to_list(main_server, free_list_header, procnode,
                          proctable_array);

        ap_log_error(APLOG_MARK, APLOG_WARNING, rv, main_server,
                     "mod_fcgid: can't create pool for process");
        return;
    }
    /* Set up longer, system defaults before falling into parsing fixed-limit
     * request-by-request variables, so if any are overriden, they preempt
     * any system default assumptions
     */
    default_proc_env(procinfo.proc_environ);        
    for (i = 0; i < INITENV_CNT; i++) {
        if (command->cmdopts.initenv_key[i][0] == '\0')
            break;
        apr_table_set(procinfo.proc_environ, command->cmdopts.initenv_key[i],
                      command->cmdopts.initenv_val[i]);
    }

    /* Spawn the process now */
    /* XXX Spawn uses wrapperpath, but log uses cgipath ? */
    if ((rv =
        proc_spawn_process(command->wrapperpath, &procinfo,
                           procnode)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_WARNING, rv, main_server,
                     "mod_fcgid: spawn process %s error",
                     command->cgipath);

        apr_pool_destroy(procnode->proc_pool);
        link_node_to_list(main_server, free_list_header,
                          procnode, proctable_array);
        return;
    } else {
        /* The job done */
        link_node_to_list(main_server, idle_list_header,
                          procnode, proctable_array);
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, main_server,
                     "mod_fcgid: server %s:%s(%" APR_PID_T_FMT ") started",
                     command->virtualhost, command->cgipath, procnode->proc_id->pid);
        register_spawn(main_server, procnode);
    }
}

apr_status_t pm_main(server_rec * main_server, apr_pool_t * configpool)
{
    fcgid_command command;

    while (1) {
        if (procmgr_must_exit())
            break;

        /* Wait for command */
        if (procmgr_peek_cmd(&command, main_server) == APR_SUCCESS) {
            if (is_spawn_allowed(main_server, &command))
                fastcgi_spawn(&command, main_server, configpool);

            procmgr_finish_notify(main_server);
        }

        /* Move matched node to error list */
        scan_idlelist_zombie(main_server);
        scan_idlelist(main_server);
        scan_busylist(main_server);

        /* Kill() and wait() nodes in error list */
        scan_errorlist(main_server);
    }

    /* Stop all processes */
    kill_all_subprocess(main_server);

    return APR_SUCCESS;
}
