#include "ep.h"
#include "epmacro.h"
void
OutputToHtml (
register
req * r,
const
char
* sData)
{
char
* pHtml ;
const
char
* p = sData ;
EPENTRY (OutputToHtml) ;
if
(r -> Component.pCurrEscape == NULL)
{
oputs (r, sData) ;
return
;
}
while
(*sData)
{
if
(*sData ==
'\\'
&& (r -> Component.nCurrEscMode & escEscape) == 0)
{
if
(p != sData)
owrite (r, p, sData - p) ;
sData++ ;
p = sData ;
}
else
{
pHtml = r -> Component.pCurrEscape[(unsigned
char
)(*sData)].sHtml ;
if
(*pHtml)
{
if
(p != sData)
owrite (r, p, sData - p) ;
oputs (r, pHtml) ;
p = sData + 1;
}
}
sData++ ;
}
if
(p != sData)
owrite (r, p, sData - p) ;
}
void
OutputEscape (
register
req * r,
const
char
* sData,
int
nDataLen,
struct
tCharTrans * pEscTab,
char
cEscChar)
{
char
* pHtml ;
const
char
* p ;
int
l ;
EPENTRY (OutputEscape) ;
if
(pEscTab == NULL)
{
owrite (r, sData, nDataLen) ;
return
;
}
p = sData ;
l = nDataLen ;
while
(l > 0)
{
if
(cEscChar && *sData == cEscChar)
{
if
(p != sData)
owrite (r, p, sData - p) ;
sData++, l-- ;
p = sData ;
}
else
{
pHtml = pEscTab[(unsigned
char
)(*sData)].sHtml ;
if
(*pHtml)
{
if
(p != sData)
owrite (r, p, sData - p) ;
oputs (r, pHtml) ;
p = sData + 1;
}
}
sData++, l-- ;
}
if
(p != sData)
owrite (r, p, sData - p) ;
}
SV * Escape (
register
req * r,
const
char
* sData,
int
nDataLen,
int
nEscMode,
struct
tCharTrans * pEscTab,
char
cEscChar)
{
epTHX_
char
* pHtml ;
const
char
* p ;
int
l ;
SV * pSV = newSVpv(
""
,0) ;
EPENTRY (Escape) ;
if
(nEscMode >= 0)
{
if
((nEscMode & escXML) && !r -> Component.bEscInUrl)
pEscTab = Char2XML ;
else
if
((nEscMode & escHtml) && !r -> Component.bEscInUrl)
{
struct
tCharTrans * pChar2Html ;
if
(nEscMode & escHtmlUtf8)
pChar2Html = Char2HtmlMin ;
else
if
(r -> Config.nOutputEscCharset == ocharsetLatin1)
pChar2Html = Char2Html ;
else
if
(r -> Config.nOutputEscCharset == ocharsetLatin2)
pChar2Html = Char2HtmlLatin2 ;
else
pChar2Html = Char2HtmlMin ;
pEscTab = pChar2Html ;
}
else
if
(nEscMode & escUrl)
pEscTab = Char2Url ;
else
pEscTab = NULL ;
if
(nEscMode & escEscape)
cEscChar =
'\0'
;
else
cEscChar =
'\\'
;
}
if
(pEscTab == NULL)
{
sv_setpvn (pSV, sData, nDataLen) ;
return
pSV ;
}
p = sData ;
l = nDataLen ;
while
(l > 0)
{
if
(cEscChar && *sData == cEscChar)
{
if
(p != sData)
sv_catpvn (pSV, (
char
*)p, sData - p) ;
sData++, l-- ;
p = sData ;
}
else
{
pHtml = pEscTab[(unsigned
char
)(*sData)].sHtml ;
if
(*pHtml)
{
if
(p != sData)
sv_catpvn (pSV, (
char
*)p, sData - p) ;
sv_catpv (pSV, pHtml) ;
p = sData + 1;
}
}
sData++, l-- ;
}
if
(p != sData)
sv_catpvn (pSV, (
char
*)p, sData - p) ;
return
pSV ;
}
#if 0
static
const
char
* stristr (
const
char
* pString,
const
char
* pSubString)
{
char
c = *pSubString ;
int
l =
strlen
(pSubString) ;
do
{
while
(*pString &&
toupper
(*pString) != c)
pString++ ;
if
(*pString ==
'\0'
)
return
NULL ;
if
(strnicmp (pString, pSubString, l) == 0)
return
pString ;
pString++ ;
}
while
(TRUE) ;
}
static
char
* strlower (
char
* pString)
{
char
* p = pString ;
while
(*p)
{
*p =
tolower
(*p) ;
p++ ;
}
return
pString ;
}
#endif
const
char
* strnstr (
const
char
* pString,
const
char
* pSubString,
int
nMax)
{
char
c = *pSubString ;
int
l =
strlen
(pSubString) ;
while
(nMax-- > 0)
{
while
(*pString && *pString != c)
pString++ ;
if
(*pString ==
'\0'
)
return
NULL ;
if
(
strncmp
(pString, pSubString, l) == 0)
return
pString ;
pString++ ;
}
return
NULL ;
}
char
* sstrdup (
tReq * r,
char
* pString)
{
epTHX_
char
* p ;
if
(pString == NULL)
return
NULL ;
p =
malloc
(
strlen
(pString) + 1) ;
strcpy
(p, pString) ;
return
p ;
}
static
int
CmpCharTrans (
const
void
* pKey,
const
void
* pEntry)
{
return
strcmp
((
const
char
*)pKey, ((
struct
tCharTrans *)pEntry) -> sHtml) ;
}
int
TransHtml (
register
req * r,
char
* sData,
int
nLen)
{
char
* p = sData ;
char
* s ;
char
* e ;
struct
tCharTrans * pChar ;
int
bInUrl = r -> Component.bEscInUrl ;
bool
bUrlEsc = r -> Component.Config.nInputEscMode & iescUrl ;
bool
bHtmlEsc = r -> Component.Config.nInputEscMode & iescHtml ;
bool
bRemove = r -> Component.Config.nInputEscMode & iescRemoveTags ;
if
(bUrlEsc && bHtmlEsc && !bInUrl)
bUrlEsc = 0 ;
EPENTRY (TransHtml) ;
if
(bInUrl == 16)
{
if
(nLen == 0)
nLen =
strlen
(sData) ;
e = sData + nLen ;
while
(p < e)
{
if
(*p ==
'}'
&& p[1] ==
'{'
)
*p++ =
' '
, *p++ =
' '
;
if
(*p ==
'\\'
&& p[1] !=
'\0'
)
*p++ =
' '
;
p++ ;
}
return
nLen ;
}
if
(r -> Component.Config.nInputEscMode == iescNone)
{
#if PERL_VERSION < 5
if
(nLen == 0)
nLen =
strlen
(sData) ;
e = sData + nLen ;
while
(p < e)
{
if
(*p ==
'\r'
)
*p =
' '
;
p++ ;
}
#endif
return
nLen ;
}
s = NULL ;
if
(nLen == 0)
nLen =
strlen
(sData) ;
e = sData + nLen ;
while
(p < e)
{
if
(*p ==
'\\'
)
{
if
(bRemove && p[1] ==
'<'
)
{
memmove
(p, p + 1, e - p - 1) ;
e[-1] =
' '
;
p++ ;
while
(p < e && *p !=
'>'
)
p++ ;
}
else
if
(bHtmlEsc && p[1] ==
'&'
)
{
memmove
(p, p + 1, e - p - 1) ;
e[-1] =
' '
;
p++ ;
while
(p < e && *p !=
';'
)
p++ ;
}
else
if
(bUrlEsc && p[1] ==
'%'
)
{
memmove
(p, p + 1, e - p - 1) ;
e[-1] =
' '
;
p += 3 ;
}
else
p++ ;
}
#if PERL_VERSION < 5
else
if
(*p ==
'\r'
)
{
*p++ =
' '
;
}
#endif
else
{
if
(bRemove && p[0] ==
'<'
&& (
isalpha
(p[1]) || p[1] ==
'/'
))
{
s = p ;
p++ ;
while
(p < e && *p !=
'>'
)
p++ ;
if
(p < e)
p++ ;
else
{
p = s ;
s = NULL ;
}
}
else
if
(bHtmlEsc && p[0] ==
'&'
)
{
s = p ;
p++ ;
while
(p < e && *p !=
';'
)
p++ ;
if
(p < e)
{
*p =
'\0'
;
p++ ;
pChar = (
struct
tCharTrans *)
bsearch
(s, Html2Char, sizeHtml2Char,
sizeof
(
struct
tCharTrans), CmpCharTrans) ;
if
(pChar)
*s++ = pChar -> c ;
else
{
*(p-1)=
';'
;
p = s ;
s = NULL ;
}
}
else
{
p = s ;
s = NULL ;
}
}
else
if
(bUrlEsc && p[0] ==
'%'
&&
isdigit
(p[1]) &&
isxdigit
(p[2]))
{
s = p ;
p += 3 ;
*s++ = ((
toupper
(p[-2]) - (
isdigit
(p[-2])?
'0'
:(
'A'
- 10))) << 4)
+ (
toupper
(p[-1]) - (
isdigit
(p[-1])?
'0'
:(
'A'
- 10))) ;
}
if
(s && (p - s) > 0)
{
memmove
(s, p, e - p + 1) ;
memset
(e - (p - s),
' '
, (p - s)) ;
nLen -= p - s ;
p = s ;
s = NULL ;
}
else
if
(p < e)
p++ ;
}
}
return
nLen ;
}
void
TransHtmlSV (
register
req * r,
SV * pSV)
{
epTHX_
STRLEN vlen ;
STRLEN nlen ;
char
* pVal = SvPV (pSV, vlen) ;
nlen = TransHtml (r, pVal, vlen) ;
pVal[nlen] =
'\0'
;
SvCUR_set(pSV, nlen) ;
}
const
char
* GetHtmlArg (
const
char
* pTag,
const
char
* pArg,
int
* pLen)
{
const
char
* pVal ;
const
char
* pEnd ;
int
l ;
l =
strlen
(pArg) ;
while
(*pTag)
{
*pLen = 0 ;
while
(*pTag && !
isalpha
(*pTag))
pTag++ ;
pVal = pTag ;
while
(*pVal && !
isspace
(*pVal) && *pVal !=
'='
&& *pVal !=
'>'
)
pVal++ ;
while
(*pVal &&
isspace
(*pVal))
pVal++ ;
if
(*pVal ==
'='
)
{
pVal++ ;
while
(*pVal &&
isspace
(*pVal))
pVal++ ;
pEnd = pVal ;
if
(*pVal ==
'"'
|| *pVal ==
'\''
)
{
char
nType =
'\0'
;
char
q = *pVal++ ;
pEnd++ ;
while
((*pEnd != q || nType) && *pEnd !=
'\0'
)
{
if
(nType ==
'\0'
&& *pEnd ==
'['
&& (pEnd[1] ==
'+'
|| pEnd[1] ==
'-'
|| pEnd[1] ==
'$'
|| pEnd[1] ==
'!'
|| pEnd[1] ==
'#'
))
nType = *++pEnd ;
else
if
(nType && *pEnd == nType && pEnd[1] ==
']'
)
{
nType =
'\0'
;
pEnd++ ;
}
pEnd++ ;
}
}
else
{
char
nType =
'\0'
;
while
((!
isspace
(*pEnd) || nType) && *pEnd !=
'\0'
&& *pEnd !=
'>'
)
{
if
(nType ==
'\0'
&& *pEnd ==
'['
&& (pEnd[1] ==
'+'
|| pEnd[1] ==
'-'
|| pEnd[1] ==
'$'
|| pEnd[1] ==
'!'
|| pEnd[1] ==
'#'
))
nType = *++pEnd ;
else
if
(nType && *pEnd == nType && pEnd[1] ==
']'
)
{
nType =
'\0'
;
pEnd++ ;
}
pEnd++ ;
}
}
*pLen = pEnd - pVal ;
}
else
pEnd = pVal ;
if
(strnicmp (pTag, pArg, l) == 0 && (pTag[l] ==
'='
||
isspace
(pTag[l]) || pTag[l] ==
'>'
|| pTag[l] ==
'\0'
))
{
if
(*pLen > 0)
return
pVal ;
else
return
pTag ;
}
pTag = pEnd ;
}
*pLen = 0 ;
return
NULL ;
}
char
* GetHashValueLen (
tReq * r,
HV * pHash,
const
char
* sKey,
int
nLen,
int
nMaxLen,
char
* sValue)
{
epTHX_
SV ** ppSV ;
char
* p ;
STRLEN len ;
ppSV = hv_fetch(pHash, (
char
*)sKey, nLen, 0) ;
if
(ppSV != NULL)
{
p = SvPV (*ppSV ,len) ;
if
(len >= (STRLEN)nMaxLen)
len = nMaxLen - 1 ;
strncpy
(sValue, p, len) ;
}
else
len = 0 ;
sValue[len] =
'\0'
;
return
sValue ;
}
char
* GetHashValue (
tReq * r,
HV * pHash,
const
char
* sKey,
int
nMaxLen,
char
* sValue)
{
return
GetHashValueLen (r, pHash, sKey,
strlen
(sKey), nMaxLen, sValue) ;
}
IV GetHashValueInt (
pTHX_
HV * pHash,
const
char
* sKey,
IV nDefault)
{
SV ** ppSV ;
ppSV = hv_fetch(pHash, (
char
*)sKey,
strlen
(sKey), 0) ;
if
(ppSV != NULL)
return
SvIV (*ppSV) ;
return
nDefault ;
}
UV GetHashValueUInt (
tReq * r,
HV * pHash,
const
char
* sKey,
UV nDefault)
{
SV ** ppSV ;
#ifdef PERL_IMPLICIT_CONTEXT
pTHX ;
if
(r)
{
aTHX = r -> pPerlTHX ;
}
else
{
aTHX = PERL_GET_THX ;
}
#endif
ppSV = hv_fetch(pHash, (
char
*)sKey,
strlen
(sKey), 0) ;
if
(ppSV != NULL && *ppSV && SvOK(*ppSV))
{
return
SvUV ((*ppSV)) ;
}
return
nDefault ;
}
char
* GetHashValueStr (
pTHX_
HV * pHash,
const
char
* sKey,
char
* sDefault)
{
SV ** ppSV ;
STRLEN l ;
ppSV = hv_fetch(pHash, (
char
*)sKey,
strlen
(sKey), 0) ;
if
(ppSV != NULL)
return
SvPV (*ppSV, l) ;
return
sDefault ;
}
char
* GetHashValueStrDup (
pTHX_
tMemPool * pPool,
HV * pHash,
const
char
* sKey,
char
* sDefault)
{
SV ** ppSV ;
STRLEN l ;
char
* s ;
ppSV = hv_fetch(pHash, (
char
*)sKey,
strlen
(sKey), 0) ;
if
(ppSV != NULL)
{
if
((s = SvPV (*ppSV, l)))
return
ep_pstrdup (pPool, s);
else
return
NULL ;
}
if
(sDefault)
return
ep_pstrdup (pPool, sDefault) ;
else
return
NULL ;
}
char
* GetHashValueStrDupA (
pTHX_
HV * pHash,
const
char
* sKey,
char
* sDefault)
{
SV ** ppSV ;
STRLEN l ;
char
* s ;
ppSV = hv_fetch(pHash, (
char
*)sKey,
strlen
(sKey), 0) ;
if
(ppSV != NULL)
{
if
((s = SvPV (*ppSV, l)))
return
strdup (s);
else
return
NULL ;
}
if
(sDefault)
return
strdup (sDefault) ;
else
return
NULL ;
}
void
GetHashValueStrOrHash (
tReq * r,
HV * pHash,
const
char
* sKey,
char
* * sValue,
HV * * pHV)
{
epTHX_
SV ** ppSV ;
STRLEN l ;
ppSV = hv_fetch(pHash, (
char
*)sKey,
strlen
(sKey), 0) ;
if
(ppSV != NULL)
{
if
(!SvROK(*ppSV) || SvTYPE (SvRV(*ppSV)) != SVt_PVHV)
*sValue = SvPV (*ppSV, l), *pHV = NULL ;
else
*pHV = (HV *)SvRV(*ppSV), *sValue = NULL ;
}
}
SV * GetHashValueSVinc (
tReq * r,
HV * pHash,
const
char
* sKey,
SV * sDefault)
{
epTHX_
SV ** ppSV ;
ppSV = hv_fetch(pHash, (
char
*)sKey,
strlen
(sKey), 0) ;
if
(ppSV != NULL)
{
SvREFCNT_inc (*ppSV) ;
return
*ppSV ;
}
if
(sDefault)
return
SvREFCNT_inc (sDefault) ;
else
return
NULL ;
}
SV * GetHashValueSV (
tReq * r,
HV * pHash,
const
char
* sKey)
{
epTHX_
SV ** ppSV ;
ppSV = hv_fetch(pHash, (
char
*)sKey,
strlen
(sKey), 0) ;
if
(ppSV != NULL)
{
return
*ppSV ;
}
return
NULL ;
}
int
GetHashValueHREF (
req * r,
HV * pHash,
const
char
* sKey,
HV * * ppHV)
{
epTHX_
SV ** ppSV ;
HV * pHV ;
ppSV = hv_fetch(pHash, (
char
*)sKey,
strlen
(sKey), 0) ;
if
(ppSV != NULL)
{
if
(!SvROK(*ppSV))
{
strncpy
(r -> errdat2, sKey,
sizeof
(r -> errdat1) - 1) ;
return
rcNotHashRef ;
}
pHV = (HV *)SvRV(*ppSV) ;
if
(SvTYPE(pHV) != SVt_PVHV)
{
strncpy
(r -> errdat2, sKey,
sizeof
(r -> errdat1) - 1) ;
return
rcNotHashRef ;
}
*ppHV = pHV ;
return
ok ;
}
strncpy
(r -> errdat2, sKey,
sizeof
(r -> errdat1) - 1) ;
return
rcNotHashRef ;
}
int
GetHashValueCREF (
req * r,
HV * pHash,
const
char
* sKey,
CV * * ppCV)
{
epTHX_
int
rc ;
SV ** ppSV ;
CV * pCV ;
ppSV = hv_fetch(pHash, (
char
*)sKey,
strlen
(sKey), 0) ;
if
(ppSV != NULL)
{
if
(SvPOK(*ppSV))
{
if
((rc = EvalConfig (r -> pApp, *ppSV, 0, NULL, sKey, ppCV)) != ok)
return
rc ;
return
ok ;
}
if
(!SvROK(*ppSV))
{
strncpy
(r -> errdat2, sKey,
sizeof
(r -> errdat1) - 1) ;
return
rcNotCodeRef ;
}
pCV = (CV *)SvRV(*ppSV) ;
if
(SvTYPE(pCV) != SVt_PVCV)
{
strncpy
(r -> errdat2, sKey,
sizeof
(r -> errdat1) - 1) ;
return
rcNotCodeRef ;
}
*ppCV = (CV *)SvREFCNT_inc ((SV *)pCV) ;
return
ok ;
}
*ppCV = NULL ;
return
ok ;
}
void
SetHashValueStr (
tReq * r,
HV * pHash,
const
char
* sKey,
char
* sValue)
{
epTHX_
SV * pSV = newSVpv (sValue, 0) ;
hv_store(pHash, (
char
*)sKey,
strlen
(sKey), pSV, 0) ;
}
void
SetHashValueInt (
tReq * r,
HV * pHash,
const
char
* sKey,
IV nValue)
{
SV * pSV ;
#ifdef PERL_IMPLICIT_CONTEXT
pTHX ;
if
(r)
aTHX = r -> pPerlTHX ;
else
aTHX = PERL_GET_THX ;
#endif
tainted = 0 ;
pSV = newSViv (nValue) ;
hv_store(pHash, (
char
*)sKey,
strlen
(sKey), pSV, 0) ;
}
SV * CreateHashRef (
tReq * r,
char
* sKey, ...)
{
epTHX_
va_list
marker;
SV * pVal ;
HV * pHash = newHV() ;
int
nType ;
va_start
(marker, sKey);
while
(sKey)
{
nType =
va_arg
(marker,
int
) ;
if
(nType == hashtstr)
{
char
* p =
va_arg
(marker,
char
*) ;
if
(p)
pVal = newSVpv (p, 0) ;
else
pVal = NULL ;
}
else
if
(nType == hashtint)
pVal = newSViv (
va_arg
(marker,
int
)) ;
else
pVal =
va_arg
(marker, SV *) ;
if
(pVal)
hv_store (pHash, sKey,
strlen
(sKey), pVal, 0) ;
sKey =
va_arg
(marker,
char
*) ;
}
va_end
(marker) ;
return
newRV_noinc ((SV *)pHash) ;
}
int
GetLineNoOf (
register
req * r,
char
* pPos)
{
if
(r -> Component.pSourcelinePos == NULL)
return
r -> Component.nSourceline = r -> Component.Param.nFirstLine ;
if
(r -> Component.pLineNoCurrPos)
pPos = r -> Component.pLineNoCurrPos ;
if
(pPos == NULL || pPos == r -> Component.pSourcelinePos || pPos < r -> Component.pBuf || pPos > r -> Component.pEndPos)
return
r -> Component.nSourceline ;
if
(pPos > r -> Component.pSourcelinePos)
{
char
* p = r -> Component.pSourcelinePos ;
while
(p < pPos && p < r -> Component.pEndPos)
{
if
(*p++ ==
'\n'
)
r -> Component.nSourceline++ ;
}
}
else
{
char
* p = r -> Component.pSourcelinePos ;
while
(p > pPos && p > r -> Component.pBuf)
{
if
(*--p ==
'\n'
)
r -> Component.nSourceline-- ;
}
}
r -> Component.pSourcelinePos = pPos ;
return
r -> Component.nSourceline ;
}
int
GetLineNo (
register
req * r)
{
char
* pPos ;
if
(r == NULL)
return
0 ;
pPos = r -> Component.pCurrPos ;
return
GetLineNoOf (r, pPos) ;
}
#ifdef EP2
void
ClearSymtab (
register
req * r,
const
char
* sPackage,
int
bDebug)
{
SV * val;
char
* key;
I32 klen;
SV * sv;
HV * hv;
AV * av;
struct
io * io ;
HV * symtab ;
STRLEN l ;
CV * pCV ;
SV * pSV ;
SV * * ppSV ;
SV * pSVErr ;
HV * pCleanupHV ;
char
* s ;
char
* sObjName ;
dTHR;
epTHX_
if
((symtab = gv_stashpv ((
char
*)sPackage, 0)) == NULL)
return
;
ppSV = hv_fetch (symtab,
"_ep_DomTree"
,
sizeof
(
"_ep_DomTree"
) - 1, 0) ;
if
(!ppSV || !*ppSV)
{
if
(bDebug)
lprintf (r -> pApp,
"[%d]CUP: No Perl code in %s\n"
, r -> pThread -> nPid, sPackage) ;
return
;
}
pSV = newSVpvf (
"%s::CLEANUP"
, sPackage) ;
newSVpvf2(pSV) ;
s = SvPV (pSV, l) ;
pCV = perl_get_cv (s, 0) ;
if
(pCV)
{
dSP ;
if
(bDebug)
lprintf (r -> pApp,
"[%d]CUP: Call &%s::CLEANUP\n"
, r -> pThread -> nPid, sPackage) ;
PUSHMARK(sp) ;
perl_call_sv ((SV *)pCV, G_EVAL | G_NOARGS | G_DISCARD) ;
pSVErr = ERRSV ;
if
(SvTRUE (pSVErr))
{
STRLEN l ;
char
* p = SvPV (pSVErr, l) ;
if
(l >
sizeof
(r -> errdat1) - 1)
l =
sizeof
(r -> errdat1) - 1 ;
strncpy
(r -> errdat1, p, l) ;
if
(l > 0 && r -> errdat1[l-1] ==
'\n'
)
l-- ;
r -> errdat1[l] =
'\0'
;
LogError (r, rcEvalErr) ;
sv_setpv(pSVErr,
""
);
}
}
pCleanupHV = perl_get_hv (s, 1) ;
SvREFCNT_dec(pSV) ;
(
void
)hv_iterinit(symtab);
while
((val = hv_iternextsv(symtab, &key, &klen)))
{
if
(SvTYPE(val) != SVt_PVGV || SvANY(val) == NULL)
{
continue
;
}
s = GvNAME((GV *)val) ;
l =
strlen
(s) ;
ppSV = hv_fetch (pCleanupHV, s, l, 0) ;
if
(ppSV && *ppSV && SvIV (*ppSV) == 0)
{
continue
;
}
if
(!(ppSV && *ppSV && SvTRUE (*ppSV)))
{
if
(GvIMPORTED((GV*)val))
{
continue
;
}
if
(s[0] ==
':'
&& s[1] ==
':'
)
{
continue
;
}
}
sObjName = NULL ;
if
((sv = GvSV((GV*)val)) && SvTYPE (sv) == SVt_PVMG)
{
HV * pStash = SvSTASH (sv) ;
if
(pStash)
{
sObjName = HvNAME(pStash) ;
if
(sObjName &&
strcmp
(sObjName,
"DBIx::Recordset"
) == 0)
{
SV * pSV = newSVpvf (
"DBIx::Recordset::Undef ('%s')"
, s) ;
newSVpvf2(pSV) ;
if
(bDebug)
lprintf (r -> pApp,
"[%d]CUP: Recordset *%s\n"
, r -> pThread -> nPid, s) ;
EvalDirect (r, pSV, 0, NULL) ;
SvREFCNT_dec (pSV) ;
}
}
}
if
((sv = GvSV((GV*)val)) && SvROK (sv) && SvOBJECT (SvRV(sv)))
{
HV * pStash = SvSTASH (SvRV(sv)) ;
if
(pStash)
{
sObjName = HvNAME(pStash) ;
if
(sObjName &&
strcmp
(sObjName,
"DBIx::Recordset"
) == 0)
{
SV * pSV = newSVpvf (
"DBIx::Recordset::Undef ('%s')"
, s) ;
newSVpvf2(pSV) ;
if
(bDebug)
lprintf (r -> pApp,
"[%d]CUP: Recordset *%s\n"
, r -> pThread -> nPid, s) ;
EvalDirect (r, pSV, 0, NULL) ;
SvREFCNT_dec (pSV) ;
}
}
}
if
((sv = GvSV((GV*)val)) && (SvOK (sv) || SvROK (sv)))
{
if
(bDebug)
lprintf (r -> pApp,
"[%d]CUP: $%s = %s %s%s\n"
, r -> pThread -> nPid, s, SvPV (sv, l), sObjName?
" Object of "
:
""
, sObjName?sObjName:
""
) ;
if
((sv = GvSV((GV*)val)) && SvREADONLY (sv))
{
}
else
{
sv_unmagic (sv,
'q'
) ;
sv_setsv(sv, &sv_undef);
}
}
if
((hv = GvHV((GV*)val)))
{
if
(bDebug)
lprintf (r -> pApp,
"[%d]CUP: %%%s = ...\n"
, r -> pThread -> nPid, s) ;
sv_unmagic ((SV *)hv,
'P'
) ;
hv_clear(hv);
}
if
((av = GvAV((GV*)val)))
{
if
(bDebug)
lprintf (r -> pApp,
"[%d]CUP: @%s = ...\n"
, r -> pThread -> nPid, s) ;
sv_unmagic ((SV *)av,
'P'
) ;
av_clear(av);
}
if
((io = GvIO((GV*)val)))
{
if
(bDebug)
lprintf (r -> pApp,
"[%d]CUP: IO %s = ...\n"
, r -> pThread -> nPid, s) ;
}
}
}
#endif
void
UndefSub (
register
req * r,
const
char
* sName,
const
char
* sPackage)
{
CV * pCV ;
int
l =
strlen
(sName) +
strlen
(sPackage) ;
char
* sFullname = _malloc (r, l + 3) ;
epTHX_
strcpy
(sFullname, sPackage) ;
strcat
(sFullname,
"::"
) ;
strcat
(sFullname, sName) ;
if
(!(pCV = perl_get_cv (sFullname, 0)))
{
_free (r, sFullname) ;
return
;
}
_free (r, sFullname) ;
cv_undef (pCV) ;
}
char
* GetSessionID (
register
req * r,
HV * pSessionHash,
char
* * ppInitialID,
IV * pModified)
{
SV * pSVID = NULL ;
MAGIC * pMG ;
char
* pUID =
""
;
STRLEN ulen = 0 ;
STRLEN ilen = 0 ;
epTHX_
if
(r -> nSessionMgnt)
{
SV * pUserHashObj = NULL ;
if
((pMG = mg_find((SV *)pSessionHash,
'P'
)))
{
dSP;
int
n ;
pUserHashObj = pMG -> mg_obj ;
PUSHMARK(sp);
XPUSHs(pUserHashObj) ;
PUTBACK;
n = perl_call_method (
"getids"
, G_ARRAY) ;
SPAGAIN;
if
(n > 2)
{
int
savewarn = dowarn ;
dowarn = 0 ;
*pModified = POPi ;
pSVID = POPs;
pUID = SvPV (pSVID, ulen) ;
pSVID = POPs;
*ppInitialID = SvPV (pSVID, ilen) ;
dowarn = savewarn ;
}
PUTBACK;
}
}
return
pUID ;
}
static
void
dirname (
const
char
* filename,
char
* dirname,
int
size)
{
char
* p =
strrchr
(filename,
'/'
) ;
if
(p == NULL)
{
strncpy
(dirname,
"."
, size) ;
return
;
}
if
(size - 1 > p - filename)
size = p - filename ;
strncpy
(dirname, filename, size) ;
dirname[size] =
'\0'
;
return
;
}
#ifdef WIN32
#define isAbsPath(sFilename) \
(sFilename[0] ==
'/'
|| sFilename[0] ==
'\\'
|| \
(
isalpha
(sFilename[0]) && sFilename[1] ==
':'
&& \
(sFilename[2] ==
'\\'
|| sFilename[2] ==
'/'
) \
) \
)
#else
#define isAbsPath(sFilename) (sFilename[0] == '/')
#endif
char
* embperl_File2Abs (
register
req * r,
tMemPool * pPool,
const
char
* sFilename)
{
epTHX_
#ifdef WIN32
char
* c ;
#endif
char
* sAbsname ;
if
(sFilename == NULL)
return
NULL ;
if
(!isAbsPath(sFilename))
{
int
l =
strlen
(sFilename) +
strlen
(r -> Component.sCWD) + 2 ;
sAbsname = pPool?ep_palloc(pPool, l):
malloc
(l) ;
strcpy
(sAbsname, r -> Component.sCWD) ;
strcat
(sAbsname, PATH_SEPARATOR_STR) ;
strcat
(sAbsname, sFilename) ;
}
else
sAbsname = pPool?ep_pstrdup (pPool, sFilename):strdup (sFilename) ;
#ifdef WIN32
c = sAbsname ;
while
(*c)
{
if
(*c ==
'/'
)
*c =
'\\'
;
c++ ;
}
#endif
return
sAbsname ;
}
void
embperl_SetCWDToFile (
register
req * r,
const
char
* sFilename)
{
epTHX_
char
* sAbsFilename ;
char
* p ;
if
((r -> Component.Config.bOptions & optDisableChdir) ||
sFilename == NULL || *sFilename ==
'\0'
||
r -> Component.Param.pInput)
return
;
sAbsFilename = embperl_File2Abs(r, r -> pPool, sFilename) ;
p =
strrchr
(sAbsFilename, PATH_SEPARATOR_CHAR) ;
while
(p && p > sAbsFilename + 2 && p[-1] ==
'.'
&& p[-2] ==
'.'
&& p[-3] == PATH_SEPARATOR_CHAR)
{
p[-3] =
'\0'
;
p =
strrchr
(sAbsFilename, PATH_SEPARATOR_CHAR) ;
}
r -> Component.sCWD = sAbsFilename ;
if
(p)
*p =
'\0'
;
}
void
Dirname (
const
char
* filename,
char
* dirname,
int
size)
{
char
* p =
strrchr
(filename,
'/'
) ;
if
(p == NULL)
{
strncpy
(dirname,
"."
, size) ;
return
;
}
if
(size - 1 > p - filename)
size = p - filename ;
strncpy
(dirname, filename, size) ;
dirname[size] =
'\0'
;
return
;
}
void
ChdirToSource (
register
req * r,
char
* sInputfile)
{
if
((r -> Component.Config.bOptions & optDisableChdir) == 0 &&
sInputfile != NULL && *sInputfile !=
'\0'
&&
!r -> Component.Param.pInput && !r -> Component.sResetDir[0])
{
char
dir[PATH_MAX];
#ifdef WIN32
char
drive[_MAX_DRIVE];
char
fname[_MAX_FNAME];
char
ext[_MAX_EXT];
char
* c = sInputfile ;
while
(*c)
{
if
(*c ==
'/'
)
*c =
'\\'
;
c++ ;
}
r -> nResetDrive = _getdrive () ;
getcwd (r -> Component.sResetDir,
sizeof
(r -> Component.sResetDir) - 1) ;
_splitpath(sInputfile, drive, dir, fname, ext );
_chdrive (drive[0] -
'A'
+ 1) ;
#else
Dirname (sInputfile, dir,
sizeof
(dir) - 1) ;
getcwd (r -> Component.sResetDir,
sizeof
(r -> Component.sResetDir) - 1) ;
#endif
if
(dir[0])
{
if
(chdir (dir) < 0)
{
strncpy
(r -> errdat1, dir,
sizeof
(r -> errdat1) - 1) ;
LogError (r, rcChdirError) ;
}
else
{
if
(!(dir[0] ==
'/'
#ifdef WIN32
||
dir[0] ==
'\\'
||
(
isalpha
(dir[0]) && dir[1] ==
':'
&&
(dir[2] ==
'\\'
|| dir[2] ==
'/'
))
#endif
))
{
strcpy
(r->Component.sCWD,r -> Component.sResetDir) ;
strcat
(r->Component.sCWD,
"/"
) ;
strcat
(r->Component.sCWD,dir) ;
}
else
strcpy
(r->Component.sCWD,dir) ;
}
}
else
r -> Component.Config.bOptions |= optDisableChdir ;
}
else
r -> Component.Config.bOptions |= optDisableChdir ;
}
char
* embperl_PathSearch (
register
req * r,
tMemPool * pPool,
const
char
* sFilename,
int
nPathNdx)
{
epTHX_
AV *pPathAV = r -> Config.pPathAV ;
int
skip = 0 ;
int
i ;
struct
stat st ;
char
* absfn = NULL ;
char
* fn ;
STRLEN l ;
if
(r -> Config.bDebug & dbgObjectSearch)
lprintf (r -> pApp,
"[%d]Search for %s\n"
, r -> pThread -> nPid, sFilename) ;
if
(isAbsPath(sFilename) || !pPathAV || AvFILL (pPathAV) < r -> Component.nPathNdx)
{
absfn = embperl_File2Abs (r, pPool, sFilename) ;
if
(r -> Config.bDebug & dbgObjectSearch)
lprintf (r -> pApp,
"[%d]Search: nothing to search return %s\n"
, r -> pThread -> nPid, absfn) ;
return
absfn ;
}
while
(sFilename[0] ==
'.'
&& sFilename[1] ==
'.'
&& (sFilename[2] ==
'/'
|| sFilename[2] ==
'\\'
))
{
skip++ ;
sFilename += 3 ;
}
if
(skip)
skip += nPathNdx >= 0?nPathNdx:r -> Component.pPrev?r -> Component.pPrev -> nPathNdx:0 ;
if
(skip == 0 && sFilename[0] ==
'.'
&& (sFilename[1] ==
'/'
|| sFilename[1] ==
'\\'
))
{
absfn = embperl_File2Abs (r, pPool, sFilename) ;
if
(stat (absfn, &st) == 0)
{
if
(r -> Config.bDebug & dbgObjectSearch)
lprintf (r -> pApp,
"[%d]Search: starts with ./ return %s\n"
, r -> pThread -> nPid, absfn) ;
return
absfn ;
}
if
(r -> Config.bDebug & dbgObjectSearch)
lprintf (r -> pApp,
"[%d]Search: starts with ./, but not found\n"
, r -> pThread -> nPid) ;
return
NULL ;
}
for
(i = skip ; i <= AvFILL (pPathAV); i++)
{
fn = ep_pstrcat(r -> pPool, SvPV(*av_fetch (pPathAV, i, 0), l), PATH_SEPARATOR_STR, sFilename, NULL) ;
if
(r -> Config.bDebug & dbgObjectSearch)
lprintf (r -> pApp,
"[%d]Search: #%d test dir=%s, fn=%s (skip=%d)\n"
, r -> pThread -> nPid,
i, SvPV(*av_fetch (pPathAV, i, 0), l), fn, skip) ;
if
(stat (fn, &st) == 0)
{
r -> Component.nPathNdx = i ;
absfn = embperl_File2Abs (r, pPool, fn) ;
if
(r -> Config.bDebug & dbgObjectSearch)
lprintf (r -> pApp,
"[%d]Search: found %s\n"
, r -> pThread -> nPid, absfn) ;
return
absfn ;
}
}
if
(r -> Config.bDebug & dbgObjectSearch)
lprintf (r -> pApp,
"[%d]Search: not found %s\n"
, r -> pThread -> nPid) ;
return
NULL ;
}
char
* embperl_PathStr (
register
req * r,
const
char
* sFilename)
{
epTHX_
AV *pPathAV = r -> Config.pPathAV ;
int
skip = r -> Component.pPrev?r -> Component.pPrev -> nPathNdx:0 ;
int
i ;
char
* fn ;
char
* pPath =
""
;
STRLEN l ;
if
(isAbsPath(sFilename) || !pPathAV || AvFILL (pPathAV) < r -> Component.nPathNdx)
return
embperl_File2Abs (r, r -> pPool, sFilename) ;
while
(sFilename[0] ==
'.'
&& sFilename[1] ==
'.'
&& (sFilename[2] ==
'/'
|| sFilename[2] ==
'\\'
))
{
skip++ ;
sFilename += 3 ;
}
for
(i = skip ; i <= AvFILL (pPathAV); i++)
{
fn = ep_pstrcat(r -> pPool, SvPV(*av_fetch (pPathAV, i, 0), l), PATH_SEPARATOR_STR, sFilename, NULL) ;
pPath = ep_pstrcat(r -> pPool, pPath, fn,
";"
, NULL) ;
}
return
pPath ;
}
AV * embperl_String2AV (
tApp * a,
const
char
* sData,
const
char
* sSeparator)
{
AV * pAV ;
#ifdef PERL_IMPLICIT_CONTEXT
pTHX ;
if
(a)
aTHX = a -> pPerlTHX ;
else
aTHX = PERL_GET_THX ;
#endif
pAV = newAV () ;
while
(*sData)
{
int
n =
strcspn
(sData, sSeparator) ;
if
(n > 0)
av_push (pAV, newSVpv((
char
*)sData, n)) ;
sData += n ;
if
(*sData)
sData++ ;
}
return
pAV ;
}
HV * embperl_String2HV (
tApp * a,
const
char
* sData,
char
cSeparator,
HV * pHV)
{
char
* p ;
char
q ;
char
* pVal ;
char
* pKeyEnd ;
#ifdef PERL_IMPLICIT_CONTEXT
pTHX ;
if
(a)
aTHX = a -> pPerlTHX ;
else
aTHX = PERL_GET_THX ;
#endif
if
(!pHV)
pHV = newHV () ;
while
(*sData)
{
while
(
isspace
(*sData))
sData++ ;
if
(*sData ==
'\''
|| *sData ==
'"'
)
q = *sData++ ;
else
q = cSeparator ;
p =
strchr
(sData,
'='
) ;
if
(!p)
break
;
pKeyEnd = p ;
while
(pKeyEnd > sData &&
isspace
(pKeyEnd[-1]))
pKeyEnd-- ;
p++ ;
while
(
isspace
(*p))
p++ ;
if
(*p ==
'\''
|| *p ==
'"'
)
q = *p++ ;
pVal = p ;
while
(*p && *p != q)
p++ ;
hv_store(pHV, sData, pKeyEnd - sData, newSVpv(pVal, p - pVal), 0) ;
sData = p ;
if
(*sData)
sData++ ;
}
return
pHV ;
}
static
char
* embperl_GetText1 (
tReq * r,
const
char
* sMsgId,
AV * arr)
{
epTHX_
IV len ;
IV i ;
SV ** ppSV ;
STRLEN l ;
if
(!arr || SvTYPE(arr) != SVt_PVAV)
return
NULL ;
len = av_len(arr);
for
(i = len; i >= 0; i--)
{
SV * * pHVREF = av_fetch(arr, i, 0);
if
(pHVREF && *pHVREF && SvROK (*pHVREF))
{
HV * pHV = (HV *)SvRV (*pHVREF) ;
if
(SvTYPE (pHV) == SVt_PVCV)
{
SV * pSVErr ;
SV * pRet ;
int
num ;
dSP ;
PUSHMARK(sp) ;
XPUSHs (sv_2mortal(newSVpv(sMsgId,0))) ;
PUTBACK ;
num = perl_call_sv ((SV *)pHV, G_EVAL) ;
pSVErr = ERRSV ;
if
(SvTRUE (pSVErr))
{
STRLEN l ;
char
* p = SvPV (pSVErr, l) ;
if
(l >
sizeof
(r -> errdat1) - 1)
l =
sizeof
(r -> errdat1) - 1 ;
strncpy
(r -> errdat1, p, l) ;
if
(l > 0 && r -> errdat1[l-1] ==
'\n'
)
l-- ;
r -> errdat1[l] =
'\0'
;
LogError (r, rcEvalErr) ;
sv_setpv(pSVErr,
""
);
return
NULL ;
}
else
{
SPAGAIN ;
if
(num > 0)
pRet = POPs ;
PUTBACK ;
return
num && pRet && SvOK(pRet)?SvPV (pRet, l):NULL ;
}
}
if
(SvTYPE (pHV) != SVt_PVHV)
continue
;
ppSV = hv_fetch(pHV, (
char
*)sMsgId,
strlen
(sMsgId), 0) ;
if
(ppSV != NULL)
{
return
SvOK(*ppSV)?SvPV (*ppSV, l):NULL ;
}
}
}
return
NULL ;
}
const
char
* embperl_GetText (
tReq * r,
const
char
* sMsgId)
{
epTHX_
char
* pMsg ;
if
((pMsg = embperl_GetText1(r, sMsgId, r -> pMessages)))
return
pMsg ;
if
((pMsg = embperl_GetText1(r, sMsgId, r -> pDefaultMessages)))
return
pMsg ;
return
sMsgId ;
}
int
embperl_OptionListSearch (
tOptionEntry * pList,
bool
bMult,
const
char
* sCmd,
const
char
* sOptions,
int
* pnValue)
{
char
* sKeyword ;
char
* sOpts = strdup (sOptions) ;
dTHX ;
*pnValue = 0 ;
sKeyword =
strtok
(sOpts,
", \t\n"
) ;
while
(sKeyword)
{
tOptionEntry * pEntry = pList ;
bool
found = 0 ;
while
(pEntry -> sOption)
{
if
(stricmp (sKeyword, pEntry -> sOption) == 0)
{
*pnValue |= pEntry -> nValue ;
if
(!bMult)
{
if
(sOpts)
free
(sOpts) ;
return
ok ;
}
found = 1 ;
}
}
if
(!found)
{
LogErrorParam (NULL, rcUnknownOption, sKeyword, sCmd) ;
if
(sOpts)
free
(sOpts) ;
return
rcUnknownOption ;
}
}
if
(sOpts)
free
(sOpts) ;
return
ok ;
}
#define Mult_s 1
#define Mult_m 60
#define Mult_h (60*60)
#define Mult_d (60*60*24)
#define Mult_M (60*60*24*30)
#define Mult_y (60*60*24*365)
static
int
expire_mult(
char
s)
{
switch
(s) {
case
's'
:
return
Mult_s;
case
'm'
:
return
Mult_m;
case
'h'
:
return
Mult_h;
case
'd'
:
return
Mult_d;
case
'M'
:
return
Mult_M;
case
'y'
:
return
Mult_y;
default
:
return
1;
};
}
static
time_t
expire_calc(
const
char
*time_str)
{
int
is_neg = 0, offset = 0;
char
buf[256];
int
ix = 0;
if
(*time_str ==
'-'
) {
is_neg = 1;
++time_str;
}
else
if
(*time_str ==
'+'
) {
++time_str;
}
else
if
(!stricmp(time_str,
"now"
)) {
}
else
{
return
0;
}
while
(*time_str &&
isdigit
(*time_str)) {
buf[ix++] = *time_str++;
}
buf[ix] =
'\0'
;
offset =
atoi
(buf);
return
time
(NULL) +
(expire_mult(*time_str) * (is_neg ? (0 - offset) : offset));
}
static
const
char
ep_month_snames[12][4] =
{
"Jan"
,
"Feb"
,
"Mar"
,
"Apr"
,
"May"
,
"Jun"
,
"Jul"
,
"Aug"
,
"Sep"
,
"Oct"
,
"Nov"
,
"Dec"
};
static
const
char
ep_day_snames[7][4] =
{
"Sun"
,
"Mon"
,
"Tue"
,
"Wed"
,
"Thu"
,
"Fri"
,
"Sat"
};
const
char
* embperl_CalcExpires(
const
char
*sTime,
char
* sResult,
int
bHTTP)
{
time_t
when;
#ifdef WIN32
struct
tm
*tms;
#else
struct
tm
tms;
#endif
int
sep = bHTTP ?
' '
:
'-'
;
dTHX ;
if
(!sTime) {
return
NULL;
}
when = expire_calc(sTime);
if
(!when) {
strcpy
( sResult, sTime );
return
sResult ;
}
#ifdef WIN32
tms =
gmtime
(&when);
sprintf
(sResult,
"%s, %.2d%c%s%c%.2d %.2d:%.2d:%.2d GMT"
,
ep_day_snames[tms->tm_wday],
tms->tm_mday, sep, ep_month_snames[tms->tm_mon], sep,
tms->tm_year + 1900,
tms->tm_hour, tms->tm_min, tms->tm_sec);
#else
gmtime_r(&when, &tms);
sprintf
(sResult,
"%s, %.2d%c%s%c%.2d %.2d:%.2d:%.2d GMT"
,
ep_day_snames[tms.tm_wday],
tms.tm_mday, sep, ep_month_snames[tms.tm_mon], sep,
tms.tm_year + 1900,
tms.tm_hour, tms.tm_min, tms.tm_sec);
#endif
return
sResult ;
}
#ifdef WIN32
extern
long
_timezone;
#else
#if !defined(__BSD_VISIBLE) && !defined(__DARWIN_UNIX03)
extern
long
timezone;
#endif
#endif
char
* embperl_GetDateTime (
char
* sResult)
{
time_t
when =
time
(NULL);
int
sep =
' '
;
int
tz ;
#ifdef WIN32
struct
tm
*tms;
#else
struct
tm
tms;
#endif
dTHX ;
#ifdef WIN32
tms =
localtime
(&when);
sprintf
(sResult,
"%s, %.2d%c%s%c%.2d %.2d:%.2d:%.2d %s%04d"
,
ep_day_snames[tms->tm_wday],
tms->tm_mday, sep, ep_month_snames[tms->tm_mon], sep,
tms->tm_year + 1900,
tms->tm_hour, tms->tm_min, tms->tm_sec, tz > 0?
"+"
:
""
, tz);
#else
localtime_r(&when, &tms);
#if !defined(__BSD_VISIBLE) && !defined(__DARWIN_UNIX03)
tz = -timezone / 36 + (tms.tm_isdst?100:0) ;
#else
tz = -tms.tm_gmtoff / 36 + (tms.tm_isdst?100:0) ;
#endif
sprintf
(sResult,
"%s, %.2d%c%s%c%.2d %.2d:%.2d:%.2d %s%04d"
,
ep_day_snames[tms.tm_wday],
tms.tm_mday, sep, ep_month_snames[tms.tm_mon], sep,
tms.tm_year + 1900,
tms.tm_hour, tms.tm_min, tms.tm_sec, tz > 0?
"+"
:
""
, tz);
#endif
return
sResult ;
}
#ifdef DMALLOC
static
int
RemoveDMallocMagic (pTHX_ SV * pSV, MAGIC * mg)
{
char
* s = *((
char
* *)(mg -> mg_ptr)) ;
_free_leap(__FILE__, __LINE__, s) ;
return
ok ;
}
static
MGVTBL DMalloc_mvtTab = { NULL, NULL, NULL, NULL, RemoveDMallocMagic } ;
#define MGTTYPE '!'
SV * AddDMallocMagic (
SV * pSV,
char
* sText,
char
* sFile,
int
nLine)
{
dTHX ;
if
(pSV && (!SvMAGICAL(pSV) || !mg_find (pSV, MGTTYPE)))
{
char
* s = _strdup_leap(sFile, nLine, sText) ;
struct
magic * pMagic ;
if
((!SvMAGICAL(pSV) || !(pMagic = mg_find (pSV, MGTTYPE))))
{
sv_magicext ((SV *)pSV, NULL, MGTTYPE, &DMalloc_mvtTab, (
char
*)&s,
sizeof
(s)) ;
pMagic = mg_find (pSV, MGTTYPE) ;
}
if
(pMagic)
{
}
else
{
LogError (CurrReq, rcMagicError) ;
}
}
return
pSV ;
}
#endif