#include "ep.h"
#ifdef APACHE
#include <http_core.h>
#include "epdefault.c"
#if !defined(MOD_EMBPERL) && !defined(EMBPERL_SO)
#define MOD_EMBPERL
#define EMBPERL_SO
#endif
#undef getenv
#undef getpid
#if !defined(_GNU_SOURCE) || !defined(__GLIBC__) || __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 30)
#ifndef gettid
#ifdef WIN32
#define gettid GetCurrentThreadId
#else
int
gettid()
{
return
0 ;
}
#endif
#endif
#endif
#ifndef APACHE2
apr_pool_t * perl_get_startup_pool (
void
)
{
SV *sv ;
dTHX ;
sv = perl_get_sv(
"Apache::__POOL"
, FALSE);
if
(sv) {
IV tmp = SvIV((SV*)SvRV(sv));
return
(pool *)tmp;
}
return
NULL;
}
#endif
static
int
bApDebug = 0 ;
static
int
bApInit = 0 ;
static
apr_pool_t * unload_subpool ;
#define EPCFG_STR EPCFG
#define EPCFG_INT EPCFG
#define EPCFG_INTOPT EPCFG
#define EPCFG_BOOL EPCFG
#define EPCFG_CHAR EPCFG
#define EPCFG_EXPIRES EPCFG_STR
#define EPCFG_CV EPCFG_SAVE
#define EPCFG_SV EPCFG_SAVE
#define EPCFG_HV EPCFG_SAVE
#define EPCFG_REGEX EPCFG_SAVE
#define EPCFG_AV(STRUCT,TYPE,NAME,CFGNAME,SEPARATOR) EPCFG_SAVE(STRUCT,TYPE,NAME,CFGNAME)
#define EPCFG_APP
#define EPCFG_REQ
#define EPCFG_COMPONENT
#define EPCFG(STRUCT,TYPE,NAME,CFGNAME) int set_##STRUCT##NAME:1 ;
#define EPCFG_SAVE(STRUCT,TYPE,NAME,CFGNAME) \
int
set_##STRUCT##NAME:1 ; \
char
* save_##STRUCT##NAME ;
struct
tApacheDirConfig
{
tPerlInterpreter * pPerlTHX ;
tAppConfig AppConfig ;
tReqConfig ReqConfig ;
tComponentConfig ComponentConfig ;
int
bUseEnv ;
#include "epcfg.h"
} ;
#ifdef MOD_EMBPERL
#ifdef APACHE2
static
int
embperl_ApacheInit (apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) ;
static
int
embperl_ApachePostConfig (apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) ;
static
apr_status_t embperl_ApacheInitCleanup (
void
* p) ;
#else
static
void
embperl_ApacheInitCleanup (
void
* p) ;
static
void
embperl_ApacheInit (server_rec *s, apr_pool_t *p) ;
#endif
static
const
char
* embperl_Apache_Config_useenv (cmd_parms *cmd,
void
* pDirCfg,
int
arg) ;
static
void
*embperl_create_dir_config(apr_pool_t *p,
char
*d) ;
static
void
*embperl_create_server_config(apr_pool_t *p, server_rec *s) ;
static
void
*embperl_merge_dir_config (apr_pool_t *p,
void
*basev,
void
*addv) ;
#undef EPCFG_SAVE
#define EPCFG_SAVE EPCFG
#undef EPCFG
#define EPCFG(STRUCT,TYPE,NAME,CFGNAME) \
const
char
* embperl_Apache_Config_##STRUCT##NAME (cmd_parms *cmd,
void
* pDirCfg,
const
char
* arg) ;
#include "epcfg.h"
#ifndef AP_INIT_TAKE1
#define AP_INIT_TAKE1(name,func,foo,valid,comment) { name,func,foo,valid, TAKE1, comment }
#endif
#ifndef AP_INIT_FLAG
#define AP_INIT_FLAG(name,func,foo,valid,comment) { name,func,foo,valid, FLAG, comment }
#endif
#undef EPCFG
#undef EPCFG_SAVE
#define EPCFG_SAVE EPCFG
#define EPCFG(STRUCT,TYPE,NAME,CFGNAME) \
AP_INIT_TAKE1(
"EMBPERL_"
#CFGNAME, embperl_Apache_Config_##STRUCT##NAME, NULL, RSRC_CONF | OR_OPTIONS,
""
),
static
const
command_rec embperl_cmds[] =
{
#include "epcfg.h"
AP_INIT_FLAG(
"EMBPERL_USEENV"
, embperl_Apache_Config_useenv, NULL, RSRC_CONF,
"If set to 'on' Embperl will also scan the environment variable for configuration information"
),
{NULL}
};
#ifdef APACHE2
static
void
embperl_register_hooks (apr_pool_t * p)
{
ap_hook_open_logs(embperl_ApacheInit, NULL, NULL, APR_HOOK_LAST) ;
ap_hook_post_config(embperl_ApachePostConfig, NULL, NULL, APR_HOOK_FIRST) ;
}
module AP_MODULE_DECLARE_DATA embperl_module =
{
STANDARD20_MODULE_STUFF,
embperl_create_dir_config,
embperl_merge_dir_config,
embperl_create_server_config,
embperl_merge_dir_config,
embperl_cmds,
embperl_register_hooks
};
#else
static
module embperl_module = {
STANDARD_MODULE_STUFF,
embperl_ApacheInit,
embperl_create_dir_config,
embperl_merge_dir_config,
embperl_create_server_config,
embperl_merge_dir_config,
embperl_cmds,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
#endif
int
embperl_ApInitDone (
void
)
{
return
0 ;
}
static
int
embperl_ApacheInitUnload (apr_pool_t *p)
{
#ifdef APACHE2
if
(!unload_subpool && p)
{
apr_pool_create_ex(&unload_subpool, p, NULL, NULL);
apr_pool_cleanup_register(unload_subpool, NULL, embperl_ApacheInitCleanup, embperl_ApacheInitCleanup);
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: ApacheInitUnload [%d/%d]\n"
, getpid(), gettid()) ;
}
#else
if
(!unload_subpool && p)
{
unload_subpool = ap_make_sub_pool(p);
ap_register_cleanup(unload_subpool, NULL, embperl_ApacheInitCleanup, embperl_ApacheInitCleanup);
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: ApacheInitUnload [%d/%d]\n"
, getpid(), gettid()) ;
}
#endif
return
ok ;
}
void
embperl_ApacheAddModule (
void
)
{
bApDebug |= ap_exists_config_define(
"EMBPERL_APDEBUG"
) ;
#ifdef APACHE2
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Perl part initialization start [%d/%d]\n"
, getpid(), gettid()) ;
return
;
#else
if
(!ap_find_linked_module(
"mod_embperl.c"
))
{
apr_pool_t * pool ;
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: About to add mod_embperl.c as dynamic module [%d/%d]\n"
, getpid(), gettid()) ;
ap_add_module (&embperl_module) ;
pool = perl_get_startup_pool () ;
embperl_ApacheInitUnload (pool) ;
}
else
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: mod_embperl.c already added as dynamic module [%d/%d]\n"
, getpid(), gettid()) ;
#endif
}
#ifdef APACHE2
static
int
embperl_ApacheInit (apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
#else
static
void
embperl_ApacheInit (server_rec *s, apr_pool_t *p)
#endif
{
#ifndef APACHE2
int
rc;
#endif
dTHX ;
#ifndef APACHE2
embperl_ApacheInitUnload (p) ;
#endif
bApDebug |= ap_exists_config_define(
"EMBPERL_APDEBUG"
) ;
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: ApacheInit [%d/%d]\n"
, getpid(), gettid()) ;
#ifdef APACHE2
bApInit = 1 ;
return
APR_SUCCESS ;
#else
ap_add_version_component (
"Embperl/"
VERSION) ;
if
((rc = embperl_Init (aTHX_ NULL, NULL, s)) != ok)
{
ap_log_error (APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"Initialization of Embperl failed (#%d)\n"
, rc) ;
}
bApInit = 1 ;
#endif
}
#ifdef APACHE2
static
int
embperl_ApachePostConfig (apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
{
ap_add_version_component (p,
"Embperl/"
VERSION) ;
return
APR_SUCCESS ;
}
#endif
#ifdef APACHE2
static
apr_status_t embperl_ApacheInitCleanup (
void
* p)
#else
static
void
embperl_ApacheInitCleanup (
void
* p)
#endif
{
#ifdef APACHE2
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: embperl_ApacheInitCleanup [%d/%d]\n"
, getpid(), gettid()) ;
return
OK ;
#else
module * m ;
if
((m = ap_find_linked_module(
"mod_perl.c"
)))
{
if
(m -> dynamic_load_handle)
{
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: ApacheInitCleanup: mod_perl.c dynamicly loaded -> remove mod_embperl.c [%d/%d]\n"
, getpid(), gettid()) ;
ap_remove_module (&embperl_module) ;
}
else
{
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: ApacheInitCleanup: mod_perl.c not dynamic loaded [%d/%d]\n"
, getpid(), gettid()) ;
embperl_EndPass1 () ;
}
}
else
{
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: ApacheInitCleanup: mod_perl.c not found [%d/%d]\n"
, getpid(), gettid()) ;
embperl_EndPass1 () ;
}
#endif
}
#define EPCFG_APP
#define EPCFG_REQ
#define EPCFG_COMPONENT
#undef EPCFG_STR
#undef EPCFG_INT
#undef EPCFG_INTOPT
#undef EPCFG_BOOL
#undef EPCFG_CHAR
#undef EPCFG_CV
#undef EPCFG_SV
#undef EPCFG_HV
#undef EPCFG_AV
#undef EPCFG_REGEX
#define EPCFG_INT EPCFG
#define EPCFG_INTOPT EPCFG
#define EPCFG_BOOL EPCFG
#define EPCFG_CHAR EPCFG
#define EPCFG_STR EPCFG
#define EPCFG_CV EPCFG_DEC
#define EPCFG_SV EPCFG_DEC
#define EPCFG_HV EPCFG_DEC
#define EPCFG_REGEX EPCFG_DEC
#define EPCFG_AV(STRUCT,TYPE,NAME,CFGNAME,X) EPCFG_DEC(STRUCT,TYPE,NAME,CFGNAME)
#undef EPCFG
#define EPCFG(STRUCT,TYPE,NAME,CFGNAME)
#undef EPCFG_DEC
#define EPCFG_DEC(STRUCT,TYPE,NAME,CFGNAME) \
if
(cfg -> STRUCT.NAME) \
{ \
if
(bApDebug) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: ApacheConfigCleanup:SvREFCNT_dec "
#CFGNAME
" (name="
#NAME
" type="
#TYPE
" refcnt=%d) \n"
, (
int
)SvREFCNT ((SV *)(cfg -> STRUCT.NAME))) ; \
SvREFCNT_dec ((SV *)(cfg -> STRUCT.NAME)) ; \
cfg -> STRUCT.NAME = NULL ; \
}
#ifdef APACHE2
static
apr_status_t embperl_ApacheConfigCleanup (
void
* p)
#else
static
void
embperl_ApacheConfigCleanup (
void
* p)
#endif
{
tApacheDirConfig * cfg = (tApacheDirConfig *) p ;
dTHX ;
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: ApacheConfigCleanup [%d/%d]\n"
, getpid(), gettid()) ;
#include "epcfg.h"
#ifdef APACHE2
return
OK ;
#endif
}
int
embperl_GetApacheConfig (
tThreadData * pThread,
request_rec * r,
server_rec * s,
tApacheDirConfig * * ppConfig)
{
*ppConfig = NULL ;
if
(embperl_module.module_index >= 0)
{
if
(r && r->per_dir_config)
{
*ppConfig = (tApacheDirConfig *) ap_get_module_config(r->per_dir_config, &embperl_module);
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: GetApacheConfig for dir\n"
) ;
}
else
if
(s && s->lookup_defaults)
{
*ppConfig = (tApacheDirConfig *) ap_get_module_config(s->lookup_defaults
, &embperl_module);
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: GetApacheConfig for server\n"
) ;
}
else
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: GetApacheConfig -> no config available for %s\n"
,r && r->per_dir_config?
"dir"
:
"server"
) ;
}
else
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: GetApacheConfig -> no config available for %s; mod_embperl not loaded?\n"
,r && r->per_dir_config?
"dir"
:
"server"
) ;
return
ok ;
}
static
void
*embperl_create_dir_config(apr_pool_t * p,
char
*d)
{
tApacheDirConfig *cfg ;
apr_pool_t * subpool ;
embperl_ApacheInitUnload (p) ;
#ifdef APACHE2
apr_pool_create_ex(&subpool, p, NULL, NULL);
#else
subpool = ap_make_sub_pool(p);
#endif
cfg = (tApacheDirConfig *) apr_pcalloc(subpool,
sizeof
(tApacheDirConfig));
#if 0
#ifdef APACHE2
apr_pool_cleanup_register(subpool, cfg, embperl_ApacheConfigCleanup, embperl_ApacheConfigCleanup);
#else
ap_register_cleanup(subpool, cfg, embperl_ApacheConfigCleanup, embperl_ApacheConfigCleanup);
#endif
#endif
embperl_DefaultReqConfig (&cfg -> ReqConfig) ;
embperl_DefaultAppConfig (&cfg -> AppConfig) ;
embperl_DefaultComponentConfig (&cfg -> ComponentConfig) ;
cfg -> bUseEnv = -1 ;
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: create_dir_config %s (0x%p) [%d/%d]\n"
, cfg -> AppConfig.sAppName?cfg -> AppConfig.sAppName:
""
, cfg, getpid(), gettid()) ;
return
cfg;
}
static
void
*embperl_create_server_config(apr_pool_t * p, server_rec *s)
{
tApacheDirConfig *cfg = (tApacheDirConfig *) apr_pcalloc(p,
sizeof
(tApacheDirConfig));
bApDebug |= ap_exists_config_define(
"EMBPERL_APDEBUG"
) ;
embperl_ApacheInitUnload (p) ;
embperl_DefaultReqConfig (&cfg -> ReqConfig) ;
embperl_DefaultAppConfig (&cfg -> AppConfig) ;
embperl_DefaultComponentConfig (&cfg -> ComponentConfig) ;
cfg -> bUseEnv = -1 ;
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: create_server_config (0x%p) [%d/%d]\n"
, cfg, getpid(), gettid()) ;
return
cfg;
}
#define EPCFG_APP
#define EPCFG_REQ
#define EPCFG_COMPONENT
#undef EPCFG_STR
#undef EPCFG_INT
#undef EPCFG_INTOPT
#undef EPCFG_BOOL
#undef EPCFG_CHAR
#undef EPCFG_CV
#undef EPCFG_SV
#undef EPCFG_HV
#undef EPCFG_AV
#undef EPCFG_REGEX
#define EPCFG_INT EPCFG
#define EPCFG_INTOPT EPCFG
#define EPCFG_BOOL EPCFG
#define EPCFG_CHAR EPCFG
#define EPCFG_CV EPCFG_SAVE
#define EPCFG_SV EPCFG_SAVE
#define EPCFG_HV EPCFG_SAVE
#define EPCFG_REGEX EPCFG_SAVE
#define EPCFG_AV(STRUCT,TYPE,NAME,CFGNAME,SEPARATOR) EPCFG_SAVE(STRUCT,TYPE,NAME,CFGNAME)
#undef EPCFG
#define EPCFG(STRUCT,TYPE,NAME,CFGNAME) \
if
(add -> set_##STRUCT##NAME) \
{ \
mrg -> set_##STRUCT##NAME = 1 ; \
mrg -> STRUCT.NAME = add -> STRUCT.NAME ; \
if
(bApDebug) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Merge "
#CFGNAME
" (type="
#TYPE
") => %d\n"
, mrg -> STRUCT.NAME) ; \
} \
else
\
{ \
if
(bApDebug && mrg -> set_##STRUCT##NAME) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Merge "
#CFGNAME
" (type="
#TYPE
") stays %d\n"
, mrg -> STRUCT.NAME) ; \
}
#define EPCFG_STR(STRUCT,TYPE,NAME,CFGNAME) \
if
(add -> set_##STRUCT##NAME) \
{ \
mrg -> set_##STRUCT##NAME = 1 ; \
mrg -> STRUCT.NAME = add -> STRUCT.NAME ; \
if
(bApDebug) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Merge "
#CFGNAME
" (type="
#TYPE
") => %s\n"
, mrg -> STRUCT.NAME?mrg -> STRUCT.NAME:
"<null>"
) ; \
} \
else
\
{ \
if
(bApDebug && mrg -> set_##STRUCT##NAME) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Merge "
#CFGNAME
" (type="
#TYPE
") stays %s\n"
, mrg -> STRUCT.NAME?mrg -> STRUCT.NAME:
"<null>"
) ; \
}
#undef EPCFG_SAVE
#ifdef PERL_IMPLICIT_CONTEXT
#define dTHXCond if (!aTHX) aTHX = PERL_GET_THX ;
#else
#define dTHXCond
#endif
#define EPCFG_SAVE(STRUCT,TYPE,NAME,CFGNAME) \
if
(add -> set_##STRUCT##NAME) \
{ \
mrg -> set_##STRUCT##NAME = 1 ; \
mrg -> STRUCT.NAME = add -> STRUCT.NAME ; \
mrg -> save_##STRUCT##NAME = add -> save_##STRUCT##NAME ; \
if
(bApDebug) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Merge "
#CFGNAME
" (type="
#TYPE
") => %s\n"
, mrg -> save_##STRUCT##NAME?mrg -> save_##STRUCT##NAME:
"<null>"
) ; \
} \
else
\
{ \
if
(bApDebug && mrg -> set_##STRUCT##NAME) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Merge "
#CFGNAME
" (type="
#TYPE
") stays %s\n"
, mrg -> save_##STRUCT##NAME?mrg -> save_##STRUCT##NAME:
"<null>"
) ; \
} \
if
(mrg -> STRUCT.NAME) \
{ \
dTHXCond \
SvREFCNT_inc((SV *)mrg -> STRUCT.NAME) ; \
}
static
void
*embperl_merge_dir_config (apr_pool_t *p,
void
*basev,
void
*addv)
{
if
(!basev)
{
return
addv ;
}
else
{
tApacheDirConfig *mrg ;
tApacheDirConfig *base = (tApacheDirConfig *)basev;
tApacheDirConfig *add = (tApacheDirConfig *)addv;
apr_pool_t * subpool ;
#ifdef PERL_IMPLICIT_CONTEXT
pTHX ;
aTHX = NULL ;
#endif
#ifdef APACHE2
apr_pool_create_ex(&subpool, p, NULL, NULL);
#else
subpool = ap_make_sub_pool(p);
#endif
mrg = (tApacheDirConfig *)apr_palloc (subpool,
sizeof
(tApacheDirConfig));
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: merge_dir/server_config base=0x%p add=0x%p mrg=0x%p\n"
, basev, addv, mrg) ;
#ifdef APACHE2
apr_pool_cleanup_register(subpool, mrg, embperl_ApacheConfigCleanup, embperl_ApacheConfigCleanup);
#else
ap_register_cleanup(subpool, mrg, embperl_ApacheConfigCleanup, embperl_ApacheConfigCleanup);
#endif
memcpy
(mrg, base,
sizeof
(*mrg)) ;
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: merge_dir/server_config %s + %s\n"
, mrg -> AppConfig.sAppName, add -> AppConfig.sAppName) ;
if
(add -> AppConfig.sAppName)
mrg -> AppConfig.sAppName = add -> AppConfig.sAppName ;
#include "epcfg.h"
if
(add -> bUseEnv >= 0)
mrg -> bUseEnv = add -> bUseEnv ;
return
mrg ;
}
}
static
const
char
* embperl_Apache_Config_useenv (cmd_parms *cmd,
void
* pDirCfg,
int
arg)
{
((tApacheDirConfig *)pDirCfg) -> bUseEnv = arg ;
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Set UseEnv = %d\n"
, arg) ;
return
NULL;
}
#undef EPCFG
#undef EPCFG_INT
#define EPCFG_INT(STRUCT,TYPE,NAME,CFGNAME) \
const
char
* embperl_Apache_Config_##STRUCT##NAME (cmd_parms *cmd,
void
* pDirCfg,
const
char
* arg) \
{ \
((tApacheDirConfig *)pDirCfg) -> STRUCT.NAME = (TYPE)
strtol
(arg, NULL, 0) ; \
((tApacheDirConfig *)pDirCfg) -> set_##STRUCT##NAME = 1 ; \
if
(bApDebug) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Set "
#CFGNAME
" (type="
#TYPE
";INT) = %s\n"
, arg) ; \
return
NULL; \
}
#undef EPCFG_INTOPT
#define EPCFG_INTOPT(STRUCT,TYPE,NAME,CFGNAME) \
const
char
* embperl_Apache_Config_##STRUCT##NAME (cmd_parms *cmd,
void
* pDirCfg,
const
char
* arg) \
{ \
if
(
isdigit
(*arg)) \
((tApacheDirConfig *)pDirCfg) -> STRUCT.NAME = (TYPE)
strtol
(arg, NULL, 0) ; \
else
\
{ \
int
val ; \
if
(embperl_OptionListSearch(Options##CFGNAME,1,#CFGNAME,arg,&val)) \
return
"Unknown Option"
; \
((tApacheDirConfig *)pDirCfg) -> STRUCT.NAME = (TYPE)val ; \
} \
((tApacheDirConfig *)pDirCfg) -> set_##STRUCT##NAME = 1 ; \
if
(bApDebug) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Set "
#CFGNAME
" (type="
#TYPE
";INT) = %s\n"
, arg) ; \
return
NULL; \
}
#undef EPCFG_BOOL
#define EPCFG_BOOL(STRUCT,TYPE,NAME,CFGNAME) \
const
char
* embperl_Apache_Config_##STRUCT##NAME (cmd_parms *cmd,
void
* pDirCfg,
const
char
* arg) \
{ \
((tApacheDirConfig *)pDirCfg) -> STRUCT.NAME = (TYPE)(arg?1:0) ; \
((tApacheDirConfig *)pDirCfg) -> set_##STRUCT##NAME = 1 ; \
if
(bApDebug) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Set "
#CFGNAME
" (type="
#TYPE
";BOOL) = %s\n"
, arg) ; \
return
NULL; \
}
#undef EPCFG_STR
#define EPCFG_STR(STRUCT,TYPE,NAME,CFGNAME) \
const
char
* embperl_Apache_Config_##STRUCT##NAME (cmd_parms *cmd,
void
* pDirCfg,
const
char
* arg) \
{ \
apr_pool_t * p = cmd -> pool ; \
((tApacheDirConfig *)pDirCfg) -> STRUCT.NAME = apr_pstrdup(p, arg) ; \
((tApacheDirConfig *)pDirCfg) -> set_##STRUCT##NAME = 1 ; \
if
(bApDebug) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Set "
#CFGNAME
" (type="
#TYPE
";STR) = %s\n"
, arg) ; \
return
NULL; \
}
#undef EPCFG_EXPIRES
#define EPCFG_EXPIRES(STRUCT,TYPE,NAME,CFGNAME) \
const
char
* embperl_Apache_Config_##STRUCT##NAME (cmd_parms *cmd,
void
* pDirCfg,
const
char
* arg) \
{ \
apr_pool_t * p = cmd -> pool ; \
char
buf[256] ; \
if
(!embperl_CalcExpires(arg, buf, 0)) \
LogErrorParam (NULL, rcTimeFormatErr,
"EMBPERL_"
#CFGNAME, arg) ; \
else
\
((tApacheDirConfig *)pDirCfg) -> STRUCT.NAME = apr_pstrdup(p, arg) ; \
((tApacheDirConfig *)pDirCfg) -> set_##STRUCT##NAME = 1 ; \
if
(bApDebug) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Set "
#CFGNAME
" (type="
#TYPE
";STR) = %s\n"
, arg) ; \
return
NULL; \
}
#undef EPCFG_CHAR
#define EPCFG_CHAR(STRUCT,TYPE,NAME,CFGNAME) \
const
char
* embperl_Apache_Config_##STRUCT##NAME (cmd_parms *cmd,
void
* pDirCfg,
const
char
* arg) \
{ \
((tApacheDirConfig *)pDirCfg) -> STRUCT.NAME = (TYPE)arg[0] ; \
((tApacheDirConfig *)pDirCfg) -> set_##STRUCT##NAME = 1 ; \
if
(bApDebug) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Set "
#CFGNAME
" (type="
#TYPE
";CHAR) = %s\n"
, arg) ; \
return
NULL; \
}
#undef EPCFG_CV
#undef EPCFG_SV
#undef EPCFG_HV
#undef EPCFG_AV
#undef EPCFG_REGEX
#define EPCFG_CV EPCFG_SAVE
#define EPCFG_SV EPCFG_SAVE
#define EPCFG_HV EPCFG_SAVE
#define EPCFG_REGEX EPCFG_SAVE
#define EPCFG_AV(STRUCT,TYPE,NAME,CFGNAME,SEPARATOR) EPCFG_SAVE(STRUCT,TYPE,NAME,CFGNAME)
#undef EPCFG_SAVE
#define EPCFG_SAVE(STRUCT,TYPE,NAME,CFGNAME) \
const
char
* embperl_Apache_Config_##STRUCT##NAME (cmd_parms *cmd,
void
* pDirCfg,
const
char
* arg) \
{ \
((tApacheDirConfig *)pDirCfg) -> save_##STRUCT##NAME = apr_pstrdup(cmd -> pool, arg) ; \
((tApacheDirConfig *)pDirCfg) -> set_##STRUCT##NAME = 1 ; \
if
(bApDebug) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Set "
#CFGNAME
" (type="
#TYPE
") = %s (save for later conversion to Perl data)\n"
, arg) ; \
return
NULL ; \
}
#define EPCFG_APP
#define EPCFG_REQ
#define EPCFG_COMPONENT
#include "epcfg.h"
#endif /* MOD_EMBPERL */
#ifdef EMBPERL_SO
char
* embperl_GetApacheAppName (
tApacheDirConfig * pDirCfg)
{
char
*n = pDirCfg?pDirCfg -> AppConfig.sAppName:
"Embperl"
;
if
(bApDebug)
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: get_appname %s[%d/%d]\n"
, n?n:
""
, getpid(), gettid()) ;
return
n ;
}
#undef EPCFG_STR
#undef EPCFG_INT
#undef EPCFG_EXPIRES
#undef EPCFG_INTOPT
#undef EPCFG_BOOL
#undef EPCFG_CHAR
#define EPCFG_INT EPCFG
#define EPCFG_EXPIRES EPCFG_STR
#define EPCFG_INTOPT EPCFG
#define EPCFG_BOOL EPCFG
#define EPCFG_CHAR EPCFG
#undef EPCFG
#define EPCFG(STRUCT,TYPE,NAME,CFGNAME) \
if
(bApDebug && pDirCfg -> set_##STRUCT##NAME) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Get "
#CFGNAME
" (type="
#TYPE
") %d (0x%x)\n"
, pDirCfg -> STRUCT.NAME, pDirCfg -> STRUCT.NAME) ;
#define EPCFG_STR(STRUCT,TYPE,NAME,CFGNAME) \
if
(bApDebug && pDirCfg -> set_##STRUCT##NAME) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Get "
#CFGNAME
" (type="
#TYPE
") %s\n"
, pDirCfg -> STRUCT.NAME?pDirCfg -> STRUCT.NAME:
"<null>"
) ;
#undef EPCFG_SV
#define EPCFG_SV(STRUCT,TYPE,NAME,CFGNAME) \
if
(pDirCfg -> save_##STRUCT##NAME && !pDirCfg -> STRUCT.NAME) \
{ \
if
(bApDebug) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Get: about to convert "
#CFGNAME
" (type="
#TYPE
";SV) to perl data: %s\n"
, pDirCfg -> save_##STRUCT##NAME) ; \
\
pDirCfg -> STRUCT.NAME = newSVpv((
char
*)pDirCfg -> save_##STRUCT##NAME, 0) ; \
} \
SvREFCNT_inc((SV *)(pDirCfg -> STRUCT.NAME)) ;
#undef EPCFG_CV
#define EPCFG_CV(STRUCT,TYPE,NAME,CFGNAME) \
if
(pDirCfg -> save_##STRUCT##NAME && !pDirCfg -> STRUCT.NAME) \
{ \
int
rc ;\
if
(bApDebug) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Get: about to convert "
#CFGNAME
" (type="
#TYPE
";CV) to perl data: %s\n"
, pDirCfg -> save_##STRUCT##NAME) ; \
\
if
((rc = EvalConfig (pApp, sv_2mortal(newSVpv(pDirCfg -> save_##STRUCT##NAME, 0)), 0, NULL,
"Configuration: EMBPERL_"
#CFGNAME, &pDirCfg -> STRUCT.NAME)) != ok) \
pDirCfg -> STRUCT.NAME = NULL ; \
tainted = 0 ; \
} \
if
(pDirCfg -> STRUCT.NAME) \
SvREFCNT_inc((SV *)(pDirCfg -> STRUCT.NAME)) ;
#undef EPCFG_AV
#define EPCFG_AV(STRUCT,TYPE,NAME,CFGNAME,SEPARATOR) \
if
(pDirCfg -> save_##STRUCT##NAME && !pDirCfg -> STRUCT.NAME) \
{ \
if
(bApDebug) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Get: about to convert "
#CFGNAME
" (type="
#TYPE
";AV) to perl data: %s\n"
, pDirCfg -> save_##STRUCT##NAME) ; \
\
pDirCfg -> STRUCT.NAME = embperl_String2AV(pApp, pDirCfg -> save_##STRUCT##NAME, SEPARATOR) ;\
tainted = 0 ; \
} \
SvREFCNT_inc((SV *)(pDirCfg -> STRUCT.NAME)) ;
#undef EPCFG_HV
#define EPCFG_HV(STRUCT,TYPE,NAME,CFGNAME) \
if
(pDirCfg -> save_##STRUCT##NAME && !pDirCfg -> STRUCT.NAME) \
{ \
if
(bApDebug) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Get: about to convert "
#CFGNAME
" (type="
#TYPE
";HV) to perl data: %s\n"
, pDirCfg -> save_##STRUCT##NAME) ; \
\
pDirCfg -> STRUCT.NAME = embperl_String2HV(pApp, pDirCfg -> save_##STRUCT##NAME,
' '
, NULL) ;\
tainted = 0 ; \
} \
SvREFCNT_inc((SV *)(pDirCfg -> STRUCT.NAME)) ;
#undef EPCFG_REGEX
#define EPCFG_REGEX(STRUCT,TYPE,NAME,CFGNAME) \
if
(pDirCfg -> save_##STRUCT##NAME && !pDirCfg -> STRUCT.NAME) \
{ \
int
rc ; \
if
(bApDebug) \
ap_log_error (APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, APLOG_STATUSCODE NULL,
"EmbperlDebug: Get: about to convert "
#CFGNAME
" (type="
#TYPE
";REGEX) to perl data: %s\n"
, pDirCfg -> save_##STRUCT##NAME) ; \
\
if
((rc = EvalRegEx (pApp, pDirCfg -> save_##STRUCT##NAME,
"Configuration: EMBPERL_"
#CFGNAME, &pDirCfg -> STRUCT.NAME)) != ok) \
pDirCfg -> STRUCT.NAME = NULL ; \
tainted = 0 ; \
} \
if
(pDirCfg -> STRUCT.NAME) \
SvREFCNT_inc((SV *)(pDirCfg -> STRUCT.NAME)) ;
int
embperl_GetApacheAppConfig (
tThreadData * pThread,
tMemPool * pPool,
tApacheDirConfig * pDirCfg,
tAppConfig * pConfig)
{
eptTHX_
tApp * pApp = NULL ;
if
(pDirCfg)
{
#define EPCFG_APP
#undef EPCFG_REQ
#undef EPCFG_COMPONENT
#include "epcfg.h"
memcpy
(&pConfig -> pPool + 1, &pDirCfg -> AppConfig.pPool + 1,
sizeof
(*pConfig) - ((tUInt8 *)(&pConfig -> pPool) - (tUInt8 *)pConfig) -
sizeof
(pConfig -> pPool)) ;
pConfig -> bDebug = pDirCfg -> ComponentConfig.bDebug ;
if
(pDirCfg -> bUseEnv)
embperl_GetCGIAppConfig (pThread, pPool, pConfig, 1, 0, 0) ;
}
else
embperl_DefaultAppConfig (pConfig) ;
return
ok ;
}
int
embperl_GetApacheReqConfig (
tApp * pApp,
tMemPool * pPool,
tApacheDirConfig * pDirCfg,
tReqConfig * pConfig)
{
#define a pApp
epaTHX_
#undef a
if
(pDirCfg)
{
#undef EPCFG_APP
#define EPCFG_REQ
#undef EPCFG_COMPONENT
#include "epcfg.h"
memcpy
(&pConfig -> pPool + 1, &pDirCfg -> ReqConfig.pPool + 1,
sizeof
(*pConfig) - ((tUInt8 *)(&pConfig -> pPool) - (tUInt8 *)pConfig) -
sizeof
(pConfig -> pPool)) ;
pConfig -> bDebug = pDirCfg -> ComponentConfig.bDebug ;
pConfig -> bOptions = pDirCfg -> ComponentConfig.bOptions ;
if
(pDirCfg -> bUseEnv)
embperl_GetCGIReqConfig (pApp, pPool, pConfig, 1, 0, 0) ;
}
else
embperl_DefaultReqConfig (pConfig) ;
pConfig -> bOptions |= optSendHttpHeader ;
return
ok ;
}
int
embperl_GetApacheComponentConfig (
tReq * pReq,
tMemPool * pPool,
tApacheDirConfig * pDirCfg,
tComponentConfig * pConfig)
{
if
(pDirCfg)
{
#define r pReq
epTHX_
#undef r
tApp * pApp = pReq -> pApp ;
#undef EPCFG_APP
#undef EPCFG_REQ
#define EPCFG_COMPONENT
#include "epcfg.h"
memcpy
(&pConfig -> pPool + 1, &pDirCfg -> ComponentConfig.pPool + 1,
sizeof
(*pConfig) - ((tUInt8 *)(&pConfig -> pPool) - (tUInt8 *)pConfig) -
sizeof
(pConfig -> pPool)) ;
if
(pDirCfg -> bUseEnv)
embperl_GetCGIComponentConfig (pReq, pPool, pConfig, 1, 0, 0) ;
}
else
embperl_DefaultComponentConfig (pConfig) ;
return
ok ;
}
struct
addcookie
{
tApp * pApp ;
tReqParam * pParam ;
} ;
static
int
embperl_AddCookie (
void
* s,
const
char
* pKey,
const
char
* pValue)
{
tApp * a = ((
struct
addcookie *)s) -> pApp ;
epaTHX_
HV * pHV ;
if
(!(pHV = ((
struct
addcookie *)s) -> pParam -> pCookies))
pHV = ((
struct
addcookie *)s) -> pParam -> pCookies = newHV () ;
embperl_String2HV(a, pValue,
';'
, pHV) ;
return
1 ;
}
int
embperl_GetApacheReqParam (
tApp * pApp,
tMemPool * pPool,
request_rec * r,
tReqParam * pParam)
{
tApp * a = pApp ;
epaTHX_
char
* p ;
struct
addcookie s ;
char
buf[20] ;
char
* scheme ;
short
port ;
s.pApp = a ;
s.pParam = pParam ;
pParam -> sFilename = r -> filename ;
pParam -> sUnparsedUri = r -> unparsed_uri ;
pParam -> sUri = r -> uri ;
pParam -> sPathInfo = r -> path_info ;
pParam -> sQueryInfo = r -> args ;
if
((p = ep_pstrdup (pPool, apr_table_get (r -> headers_in,
"Accept-Language"
))))
{
while
(
isspace
(*p))
p++ ;
pParam -> sLanguage = p ;
while
(
isalpha
(*p))
p++ ;
*p =
'\0'
;
}
apr_table_do (embperl_AddCookie, &s, r -> headers_in,
"Cookie"
, NULL) ;
buf[0] =
'\0'
;
#ifdef APACHE2
port = r -> connection -> local_addr -> port ;
#else
port = ntohs(r -> connection -> local_addr.sin_port) ;
#endif
#ifdef EAPI
if
(ap_ctx_get (r -> connection -> client -> ctx,
"ssl"
))
{
scheme =
"https"
;
if
(port != 443)
sprintf
(buf,
":%d"
, port) ;
}
else
#endif
{
scheme =
"http"
;
if
(port != 80)
sprintf
(buf,
":%d"
, port) ;
}
pParam -> sServerAddr = ep_pstrcat (pPool, scheme,
"://"
,
r -> hostname?r -> hostname:r -> server -> server_hostname, buf, NULL) ;
return
ok ;
}
#endif /* EMBPERL_SO */
#endif /* APACHE */