/*
 * Copyright 2014 Cloud Linux Zug GmbH
 *
 * Licensed under CLOUD LINUX LICENSE AGREEMENT
 * http://cloudlinux.com/docs/LICENSE.TXT
 *
 * author Alexander Demeshko <ademeshko@cloudlinux.com>
 *
 */

#include <lscapi_util.h>
#include <unixd.h>
#include <apr_strings.h>
#include <apr_signal.h>
#include <mpm_common.h>

#define PREFIX "mod_lsapi: "
#define MOD_LSAPI_VERSION MOD_LSAPI_VERSION_MAJOR "." MOD_LSAPI_VERSION_MINOR "-" MOD_LSAPI_VERSION_RELEASE

module AP_MODULE_DECLARE_DATA lsapi_module;

APLOG_USE_MODULE(lsapi);

static void* alloc_by_pool(size_t sz, void *user_data) 
{
    return apr_palloc((apr_pool_t*)user_data, sz);
}


static apr_status_t lsapi_handler(request_rec * r)
{
    apr_status_t status;
    lsapi_svr_conf_t *svrcfg = ap_get_module_config(r->server->module_config, &lsapi_module);

    const char *backend_path = lscapi_get_backend(r->handler);
    if(!backend_path)
    {
        return DECLINED;
    }

    unsigned flags = 0;
    char errbuf[256];
    lsapi_conn_t *conn = lscapi_create_connection(r, backend_path, 
                                                  &flags, &status,
                                                  errbuf, sizeof errbuf,
                                                  &lsapi_module);
    if(!conn) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, LSCAPI_APLOGNO
                      PREFIX "[host %s] %s", r->hostname, errbuf);
#ifdef WITH_LSAPI_LVE_ENABLED
        if(flags & LSCAPI_OUT_ALREADY_INSIDE_LVE) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, LSCAPI_APLOGNO
                            PREFIX "Already inside LVE");
            return DECLINED;
            
        } else if(flags & LSCAPI_OUT_RESOURCE_LIMIT_LVE) {
        /*
            lsapi_dir_conf_t* cfg = (lsapi_dir_conf_t*) ap_get_module_config(r->per_dir_config, &lsapi_module);
            return process_lve_error(r, cfg);
        */
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, LSCAPI_APLOGNO
                            PREFIX "LVE resouce limit");
            return DECLINED;
        }
#endif
        return status;
    }

    status = lscapi_do_request(conn, svrcfg);

    lscapi_close_connection(conn);
    return status;
}

static void lsapi_child_init(apr_pool_t *configpool, server_rec *s) {
    lsapi_svr_conf_t *cfg = ap_get_module_config(s->module_config, &lsapi_module);
    
    apr_signal_unblock(SIGCHLD);
    apr_signal(SIGCHLD, SIG_IGN);
    lscapi_child_init(alloc_by_pool, s->process->pool);

    if(!lscapi_is_lve_loaded())
        cfg->lve_enabled = 0;
    
    //ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, LSCAPI_APLOGNO
    //                  "in lsapi_child_init: lveEnabled:%d",
    //                  cfg->lveEnabled );

    return;
}

static apr_status_t lsapi_cleanup(void *data)
{
    lsapi_svr_conf_t *cfg = ap_get_module_config(((server_rec*)data)->module_config,
                                                    &lsapi_module);
    if(cfg->debug_enabled) {
        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, (server_rec*)data, PREFIX "Cleanup");
    }
    if(cfg->terminate_backends_on_exit) {
        lscapi_terminate_backends();
    }

    return APR_SUCCESS;
}


static int lsapi_init(apr_pool_t * config_pool, apr_pool_t * plog, apr_pool_t * ptemp,
                      server_rec * main_server)
{
    char errbuf[256];
    int rc = lscapi_init(errbuf, sizeof errbuf);

    if(rc) {
        ap_log_error (APLOG_MARK, APLOG_ERR, 0, main_server,
		    PREFIX " version " MOD_LSAPI_VERSION ": initialization error: %s", errbuf );
        return HTTP_INTERNAL_SERVER_ERROR;
    }

#ifdef WITH_LSAPI_LVE_ENABLED
    lsapi_svr_conf_t *cfg = ap_get_module_config(main_server->module_config,
                                                    &lsapi_module);

    int lve_available = lscapi_is_lve_loaded();
    const char *lve_status = cfg->lve_enabled ? 
                                    (lve_available ? "available" : "not available") 
                                  : "disabled";
    ap_log_error (APLOG_MARK, APLOG_NOTICE, 0, main_server,
		    PREFIX " version " MOD_LSAPI_VERSION
		    ". LVE mechanism is %s", lve_status);
#else
    ap_log_error (APLOG_MARK, APLOG_NOTICE, 0, main_server,
		    PREFIX " version " MOD_LSAPI_VERSION );
#endif

    apr_pool_cleanup_register(config_pool, main_server, 
                              lsapi_cleanup, apr_pool_cleanup_null);
    return APR_SUCCESS;
}

static void register_cleanup_by_pool(void* user_data, void *data, int (*fn)() )
{
    apr_pool_cleanup_register(((request_rec*)user_data)->pool, data, fn, apr_pool_cleanup_null);
}

static void register_hooks(apr_pool_t * p)
{
    char errbuf[256];
    lscapi_load_lve(alloc_by_pool, register_cleanup_by_pool, p, 
                    errbuf, sizeof errbuf);
    
    ap_hook_post_config(lsapi_init, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_child_init(lsapi_child_init, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_handler(lsapi_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

/*
static const char *lsapi_secret_file_handler(cmd_parms *cmd, void *dummy, const char *value) {
    lsapi_svr_conf_t *cfg = ap_get_module_config(cmd->server->module_config, &lsapi_module);
    return lscapi_secret_file_handler(cmd, cfg, value);
}
*/

#ifdef WITH_LSAPI_LVE_ENABLED
static const char *lsapi_lve_enabled_handler(cmd_parms *cmd, void *dummy, const char *value) {
    lsapi_svr_conf_t *cfg = ap_get_module_config(cmd->server->module_config, &lsapi_module);
    cfg->lve_enabled = !strcasecmp(value, "yes");
    return NULL;
}
#endif

static const char *lsapi_debug_handler(cmd_parms *cmd, void *dummy, const char *value) {
    lsapi_svr_conf_t *cfg = ap_get_module_config(cmd->server->module_config, &lsapi_module);
    cfg->debug_enabled = !strcasecmp(value, "on");
    cfg->debug_enabled_was_set = 1;
    return NULL;
}



static const char *lsapi_terminate_backends_on_exit_handler(cmd_parms *cmd, void *dummy, const char *value) {
    lsapi_svr_conf_t *cfg = ap_get_module_config(cmd->server->module_config, &lsapi_module);
    cfg->terminate_backends_on_exit = strcasecmp(value, "off");
    cfg->terminate_backends_was_set = 1;
    return NULL;
}

static const char *lsapi_socket_path_handler(cmd_parms *cmd, void *dummy, const char *value) {
    lsapi_svr_conf_t *cfg = ap_get_module_config(cmd->server->module_config, &lsapi_module);
    cfg->socket_path = apr_pstrdup(cmd->pool, value);
    return NULL;
}

static const char *lsapi_backend_connect_timeout_handler(cmd_parms *cmd, void *dummy, const char *value) {
    lsapi_svr_conf_t *cfg = ap_get_module_config(cmd->server->module_config, &lsapi_module);
    uint32_t ival = (uint32_t) apr_atoi64 (value);
    if(ival > 0) {
        cfg->backend_info.connect_timeout = ival;
    }
    return NULL;
}

static const char *lsapi_backend_pgrp_max_idle_handler(cmd_parms *cmd, void *dummy, const char *value) {
    lsapi_svr_conf_t *cfg = ap_get_module_config(cmd->server->module_config, &lsapi_module);
    uint32_t ival = (uint32_t) apr_atoi64 (value);
    if(ival >= 0) {
        cfg->backend_info.backend_pgrp_max_idle = ival;
    }
    return NULL;
}

static const char *lsapi_backend_max_process_time_handler(cmd_parms *cmd, void *dummy, const char *value) {
    lsapi_svr_conf_t *cfg = ap_get_module_config(cmd->server->module_config, &lsapi_module);
    uint32_t ival = (uint32_t) apr_atoi64 (value);
    if(ival > 0) {
        cfg->backend_info.backend_max_process_time = ival;
    }
    return NULL;
}


static const char *lsapi_backend_connect_tries_handler(cmd_parms *cmd, void *dummy, const char *value) {
    lsapi_svr_conf_t *cfg = ap_get_module_config(cmd->server->module_config, &lsapi_module);
    uint32_t ival = (uint32_t) apr_atoi64 (value);
    if(ival > 0) {
        cfg->backend_info.connect_tries = ival;
    }
    return NULL;
}


static const char *lsapi_backend_children_handler(cmd_parms *cmd, void *dummy, const char *value) {
    lsapi_svr_conf_t *cfg = ap_get_module_config(cmd->server->module_config, &lsapi_module);
    uint32_t ival = (uint32_t) apr_atoi64 (value);
    if(ival > 1) {
        cfg->backend_info.backend_children = ival;
    }
    return NULL;
}

static const char *lsapi_suphp_usergroup_handler(cmd_parms *cmd, void* dummy,
                                           const char *arg1, const char *arg2)
{
    lsapi_svr_conf_t *cfg = ap_get_module_config(cmd->server->module_config, &lsapi_module);
    cfg->suphp_uid = ap_uname2id(arg1);
    cfg->suphp_gid = ap_gname2id(arg2);
    
    return NULL;
}


static const char *lsapi_ruidgid_handler(cmd_parms *cmd, void* dummy,
                                           const char *arg1, const char *arg2)
{
    lsapi_svr_conf_t *cfg = ap_get_module_config(cmd->server->module_config, &lsapi_module);
    cfg->ruid = ap_uname2id(arg1);
    cfg->rgid = ap_gname2id(arg2);
    
    return NULL;
}

static const char *lsapi_assign_user_id(cmd_parms *cmd, void* dummy,
                                           const char *arg1, const char *arg2)
{
    lsapi_svr_conf_t *cfg = ap_get_module_config(cmd->server->module_config, &lsapi_module);
    cfg->itk_uid = ap_uname2id(arg1);
    cfg->itk_gid = ap_gname2id(arg2);
    
    return NULL;
}


static const char *php_value_handler(cmd_parms *cmd, void *cfg,
                                    const char *name, const char *value) {
    return lscapi_php_value_handler(cmd, cfg, name, value, 0);
}

static const char *php_admin_value_handler(cmd_parms *cmd, void *cfg,
                                    const char *name, const char *value) {
    return lscapi_php_value_handler(cmd, cfg, name, value, 1);
}

static const char *php_flag_handler(cmd_parms *cmd, void *cfg,
                                    const char *name, const char *value) {
    return lscapi_php_flag_handler(cmd, cfg, name, value, 0);
}

static const char *php_admin_flag_handler(cmd_parms *cmd, void *cfg,
                                    const char *name, const char *value) {
    return lscapi_php_flag_handler(cmd, cfg, name, value, 1);
}

static const char *fake_TAKE1_handler(cmd_parms *cmd, void *dummy, const char *args) {
    return NULL;
}

static const char *fake_FLAG_handler(cmd_parms *cmd, void *dummy, int arg) {
    return NULL;
}

static const char *fake_TAKE2_handler(cmd_parms * cmd, void *dummy,
                                       const char *arg1, const char *arg2)
{
    return NULL;
}

static const char *fake_TAKE3_handler(cmd_parms * cmd, void *dummy,
                                       const char *arg1, const char *arg2, const char *arg3)
{
    return NULL;
}

static const command_rec config_directives[] = {
    AP_INIT_TAKE2("php_value", php_value_handler, NULL, OR_OPTIONS, "PHP Value"),
    AP_INIT_TAKE2("php_admin_value", php_admin_value_handler, NULL, ACCESS_CONF|RSRC_CONF, "PHP Admin Value"),
    AP_INIT_TAKE2("php_flag", php_flag_handler, NULL, OR_OPTIONS, "PHP Flag"),
    AP_INIT_TAKE2("php_admin_flag", php_admin_flag_handler, NULL, ACCESS_CONF|RSRC_CONF, "PHP Admin Flag"),
    //AP_INIT_TAKE1("PHPINIDir", LSCAPI_PhpIniDirSetHandler, NULL, RSRC_CONF, "Directory with php.ini"),

    //AP_INIT_TAKE1("lsapi_secret_file", lsapi_secret_file_handler, NULL, RSRC_CONF, "Path to file with secret"),
#ifdef WITH_LSAPI_LVE_ENABLED
    AP_INIT_TAKE1("lsapi_lve_enabled", lsapi_lve_enabled_handler, NULL, RSRC_CONF, "LVE mode"),
#endif
    AP_INIT_TAKE1("lsapi_backend_connect_timeout", lsapi_backend_connect_timeout_handler, NULL, RSRC_CONF, "Backend connect timeout"),
    AP_INIT_TAKE1("lsapi_backend_connect_tries", lsapi_backend_connect_tries_handler, NULL, RSRC_CONF, "Backend connect try number"),
    AP_INIT_TAKE1("lsapi_backend_children", lsapi_backend_children_handler, NULL, RSRC_CONF, "LSAPI_CHILDREN"),
    AP_INIT_TAKE1("lsapi_backend_pgrp_max_idle", lsapi_backend_pgrp_max_idle_handler, NULL, RSRC_CONF, "LSAPI_PGRP_MAX_IDLE"),
    AP_INIT_TAKE1("lsapi_backend_max_process_time", lsapi_backend_max_process_time_handler, NULL, RSRC_CONF, "LSAPI_MAX_PROCESS_TIME"),
    AP_INIT_TAKE1("lsapi_debug", lsapi_debug_handler, NULL, RSRC_CONF, "Extended Debug"),
    AP_INIT_TAKE1("lsapi_terminate_backends_on_exit", lsapi_terminate_backends_on_exit_handler, NULL, RSRC_CONF, "Terminate backends processes on server stop/restart"),
    AP_INIT_TAKE1("lsapi_socket_path", lsapi_socket_path_handler, NULL, RSRC_CONF, "Path for backend sockets"),

    /*
     * SU PHP param will be used too as fallback
     */
    AP_INIT_TAKE2("suPHP_UserGroup", lsapi_suphp_usergroup_handler, NULL, RSRC_CONF | ACCESS_CONF,
                  "User and group scripts shall be run as"),

    /*
     * RUidGid param will be used too as fallback
     */
	AP_INIT_TAKE2 ("RUidGid", lsapi_ruidgid_handler, NULL, RSRC_CONF | ACCESS_CONF, 
                "ruid2: Minimal uid or gid file/dir, else set[ug]id to default (User,Group)"),

    /*
     * AssignUserID param of itk module will be used too as fallback
     */
    AP_INIT_TAKE2("AssignUserID", lsapi_assign_user_id, NULL, RSRC_CONF|ACCESS_CONF,
                    "Tie a virtual host to a specific child process."),


    /* 
     * Fake config directives to make fcgid-related configs compatible with mod_lsapi
     */
    AP_INIT_TAKE1("FcgidAccessChecker", fake_TAKE1_handler, NULL,
                  ACCESS_CONF | OR_FILEINFO,
                  "fcgid fake: a absolute access checker file path"),
    AP_INIT_FLAG("FcgidAccessCheckerAuthoritative",
                 fake_FLAG_handler, NULL, ACCESS_CONF | OR_FILEINFO,
                 "fcgid fake: Set to 'off' to allow access control to be passed along to lower modules upon failure"),
    AP_INIT_TAKE1("FcgidAuthenticator", fake_TAKE1_handler, NULL,
                  ACCESS_CONF | OR_FILEINFO, "fcgid fake: a absolute authenticator file path"),
    AP_INIT_FLAG("FcgidAuthenticatorAuthoritative",
                 fake_FLAG_handler, NULL,
                 ACCESS_CONF | OR_FILEINFO,
                 "fcgid fake: Set to 'off' to allow authentication to be passed along to lower modules upon failure"),
    AP_INIT_TAKE1("FcgidAuthorizer", fake_TAKE1_handler, NULL,
                  ACCESS_CONF | OR_FILEINFO,
                  "fcgid fake: a absolute authorizer file path"),
    AP_INIT_FLAG("FcgidAuthorizerAuthoritative",
                 fake_FLAG_handler, NULL,
                 ACCESS_CONF | OR_FILEINFO,
                 "fcgid fake: Set to 'off' to allow authorization to be passed along to lower modules upon failure"),
    AP_INIT_TAKE1("FcgidBusyScanInterval", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: scan interval for busy timeout process"),
    AP_INIT_TAKE1("FcgidBusyTimeout", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: a fastcgi application will be killed after handling a request for BusyTimeout"),
    AP_INIT_RAW_ARGS("FcgidCmdOptions", fake_TAKE1_handler, NULL, RSRC_CONF,
                     "set processing options for a FastCGI command"),
    AP_INIT_TAKE12("FcgidInitialEnv", fake_TAKE2_handler, NULL, RSRC_CONF,
                   "fcgid fake: an environment variable name and optional value to pass to FastCGI."),
    AP_INIT_TAKE1("FcgidMaxProcessesPerClass",
                  fake_TAKE1_handler,
                  NULL, RSRC_CONF,
                  "fcgid fake: Max process count of one class of fastcgi application"),
    AP_INIT_TAKE1("FcgidMinProcessesPerClass",
                  fake_TAKE1_handler,
                  NULL, RSRC_CONF,
                  "fcgid fake: Min process count of one class of fastcgi application"),
    AP_INIT_TAKE1("FcgidErrorScanInterval", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: scan interval for exited process"),
    AP_INIT_TAKE1("FcgidIdleScanInterval", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: scan interval for idle timeout process"),
    AP_INIT_TAKE1("FcgidIdleTimeout", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: an idle fastcgi application will be killed after IdleTimeout"),
    AP_INIT_TAKE1("FcgidIOTimeout", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: Communication timeout to fastcgi server"),
    AP_INIT_TAKE1("FcgidConnectTimeout", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: Connect timeout to fastcgi server"),
    AP_INIT_TAKE1("FcgidMaxProcesses", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: Max total process count"),
    AP_INIT_TAKE1("FcgidMaxRequestInMem", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: The part of HTTP request which greater than this limit will swap to disk"),
    AP_INIT_TAKE1("FcgidMaxRequestLen", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: Max HTTP request length in byte"),
    AP_INIT_TAKE1("FcgidMaxRequestsPerProcess", fake_TAKE1_handler,
                  NULL, RSRC_CONF,
                  "fcgid fake: Max requests handled by each fastcgi application"),
    AP_INIT_TAKE1("FcgidOutputBufferSize", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: CGI output buffer size"),
    AP_INIT_TAKE1("FcgidPassHeader", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: Header name which will be passed to FastCGI as environment variable."),
    AP_INIT_TAKE1("FcgidFixPathinfo",
                  fake_TAKE1_handler,
                  NULL, RSRC_CONF,
                  "fcgid fake: Set 1, if cgi.fix_pathinfo=1 in php.ini"),
    AP_INIT_TAKE1("FcgidProcessLifeTime", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: fastcgi application lifetime"),
    AP_INIT_TAKE1("FcgidProcessTableFile", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: fastcgi shared memory file path"),
    AP_INIT_TAKE1("FcgidIPCDir", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: fastcgi socket file path"),
    AP_INIT_TAKE1("FcgidSpawnScore", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: Score of spawn"),
    AP_INIT_TAKE1("FcgidSpawnScoreUpLimit", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: Spawn score up limit"),
    AP_INIT_TAKE1("FcgidTerminationScore", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: Score of termination"),
    AP_INIT_TAKE1("FcgidTimeScore", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: Score of passage of time (in seconds)"),
    AP_INIT_TAKE123("FcgidWrapper", fake_TAKE3_handler, NULL,
                    RSRC_CONF | ACCESS_CONF | OR_FILEINFO,
                    "fcgid fake: The CGI wrapper file an optional URL suffix and an optional flag"),
    AP_INIT_TAKE1("FcgidZombieScanInterval", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: scan interval for zombie process"),
    /* 
     * Fake of deprecated fcgid config directives.
     */
    AP_INIT_TAKE1("BusyScanInterval", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidBusyScanInterval' instead"),
    AP_INIT_TAKE1("BusyTimeout", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidBusyTimeout' instead"),
    AP_INIT_TAKE12("DefaultInitEnv", fake_TAKE2_handler, NULL, RSRC_CONF,
                   "fcgid fake: Deprecated - Use 'FcgidInitialEnv' instead"),
    AP_INIT_TAKE1("DefaultMaxClassProcessCount",
                  fake_TAKE1_handler,
                  NULL, RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidMaxProcessesPerClass' instead"),
    AP_INIT_TAKE1("DefaultMinClassProcessCount",
                  fake_TAKE1_handler,
                  NULL, RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidMinProcessesPerClass' instead"),
    AP_INIT_TAKE1("ErrorScanInterval", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidErrorScanInterval' instead"),
    AP_INIT_TAKE1("FastCgiAccessChecker", fake_TAKE1_handler, NULL,
                  ACCESS_CONF | OR_FILEINFO,
                  "fcgid fake: Deprecated - Use 'FcgidAccessChecker' instead"),
    AP_INIT_FLAG("FastCgiAccessCheckerAuthoritative",
                 fake_FLAG_handler, NULL, ACCESS_CONF | OR_FILEINFO,
                 "fcgid fake: Deprecated - Use 'FcgidAccessCheckerAuthoritative' instead"),
    AP_INIT_TAKE1("FastCgiAuthenticator", fake_TAKE1_handler, NULL,
                  ACCESS_CONF | OR_FILEINFO,
                  "fcgid fake: Deprecated - Use 'FcgidAuthenticator' instead"),
    AP_INIT_FLAG("FastCgiAuthenticatorAuthoritative",
                 fake_FLAG_handler, NULL,
                 ACCESS_CONF | OR_FILEINFO,
                 "fcgid fake: Deprecated - Use 'FcgidAuthenticatorAuthoritative' instead"),
    AP_INIT_TAKE1("FastCgiAuthorizer", fake_TAKE1_handler, NULL,
                  ACCESS_CONF | OR_FILEINFO,
                  "fcgid fake: Deprecated - Use 'FcgidAuthorizer' instead"),
    AP_INIT_FLAG("FastCgiAuthorizerAuthoritative",
                 fake_FLAG_handler, NULL,
                 ACCESS_CONF | OR_FILEINFO,
                 "fcgid fake: Deprecated - Use 'FcgidAuthorizerAuthoritative' instead"),
    AP_INIT_TAKE123("FCGIWrapper", fake_TAKE3_handler, NULL,
                    RSRC_CONF | ACCESS_CONF | OR_FILEINFO,
                    "fcgid fake: Deprecated - Use 'FcgidWrapper' instead"),
    AP_INIT_TAKE1("IdleScanInterval", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidIdleScanInterval' instead"),
    AP_INIT_TAKE1("IdleTimeout", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidIdleTimeout' instead"),
    AP_INIT_TAKE1("IPCCommTimeout", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidIOTimeout' instead"),
    AP_INIT_TAKE1("IPCConnectTimeout", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidConnectTimeout' instead"),
    AP_INIT_TAKE1("MaxProcessCount", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidMaxProcesses' instead"),
    AP_INIT_TAKE1("MaxRequestInMem", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidMaxRequestInMem' instead"),
    AP_INIT_TAKE1("MaxRequestLen", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidMaxRequestLen' instead"),
    AP_INIT_TAKE1("MaxRequestsPerProcess", fake_TAKE1_handler,
                  NULL, RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidMaxRequestsPerProcess' instead"),
    AP_INIT_TAKE1("OutputBufferSize", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidOutputBufferSize' instead"),
    AP_INIT_TAKE1("PassHeader", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidPassHeader' instead"),
    AP_INIT_TAKE1("PHP_Fix_Pathinfo_Enable",
                  fake_TAKE1_handler,
                  NULL, RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidFixPathinfo' instead"),
    AP_INIT_TAKE1("ProcessLifeTime", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidProcessLifeTime' instead"),
    AP_INIT_TAKE1("SharememPath", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidProcessTableFile' instead"),
    AP_INIT_TAKE1("SocketPath", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidIPCDir' instead"),
    AP_INIT_TAKE1("SpawnScore", fake_TAKE1_handler, NULL, RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidSpawnScore' instead"),
    AP_INIT_TAKE1("SpawnScoreUpLimit", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidSpawnScoreUpLimit' instead"),
    AP_INIT_TAKE1("TerminationScore", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidTerminationScore' instead"),
    AP_INIT_TAKE1("TimeScore", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidTimeScore' instead"),
    AP_INIT_TAKE1("ZombieScanInterval", fake_TAKE1_handler, NULL,
                  RSRC_CONF,
                  "fcgid fake: Deprecated - Use 'FcgidZombieScanInterval' instead"),

    /* 
     * Fake config directives to make suphp configs compatible with mod_lsapi
     */
    AP_INIT_FLAG("suPHP_Engine", fake_FLAG_handler, NULL, RSRC_CONF | ACCESS_CONF,
                 "suPHP fake: Whether suPHP is on or off, default is off"),
    AP_INIT_TAKE1("suPHP_ConfigPath", fake_TAKE1_handler, NULL, OR_OPTIONS,
                  "suPHP fake: Wheres the php.ini resides, default is the PHP default"),
    AP_INIT_ITERATE("suPHP_AddHandler", fake_TAKE1_handler, NULL, RSRC_CONF | ACCESS_CONF, "suPHP fake: Tells mod_suphp to handle these MIME-types"),
    AP_INIT_ITERATE("suPHP_RemoveHandler", fake_TAKE1_handler, NULL, RSRC_CONF | ACCESS_CONF, "suPHP fake: Tells mod_suphp not to handle these MIME-types"),
    AP_INIT_TAKE1("suPHP_PHPPath", fake_TAKE1_handler, NULL, RSRC_CONF, "suPHP fake: Path to the PHP binary used to render source view"),

    /* 
     * Fake config directives to make ruid2 configs compatible with mod_lsapi
     */
	AP_INIT_TAKE1 ("RMode", fake_TAKE1_handler, NULL, RSRC_CONF | ACCESS_CONF, "ruid2 fake: Set mode to config or stat (default: config)"),
	AP_INIT_ITERATE ("RGroups", fake_TAKE1_handler, NULL, RSRC_CONF | ACCESS_CONF, "ruid2 fake: Set additional groups"),
	AP_INIT_TAKE2 ("RDefaultUidGid", fake_TAKE2_handler, NULL, RSRC_CONF, "ruid2 fake: If uid or gid is < than RMinUidGid set[ug]id to this uid gid"),
	AP_INIT_TAKE2 ("RMinUidGid", fake_TAKE2_handler, NULL, RSRC_CONF, "ruid2 fake: Minimal uid or gid file/dir, else set[ug]id to default (RDefaultUidGid)"),
	AP_INIT_TAKE2 ("RDocumentChRoot", fake_TAKE2_handler, NULL, RSRC_CONF, "ruid2 fake: Set chroot directory and the document root inside"),

    {NULL}
};

module AP_MODULE_DECLARE_DATA lsapi_module = {
    STANDARD20_MODULE_STUFF,
    lscapi_create_dir_config,     /* create per-directory config structure */
    lscapi_merge_dir_config,      /* merge per-directory config structures */
    lscapi_create_svr_config,     /* create per-server config structure */
    lscapi_merge_svr_config,      /* merge per-server config structures */
    config_directives,            /* command apr_table_t */
    register_hooks                /* register hooks */
};
