/*
* $Id$
*/
-/**
- * \defgroup Subst Variable substitution type stuff
- * \ingroup CitadelConfig
- */
-
-/*@{*/
#include "sysdep.h"
#include <sys/types.h>
#include "webcit.h"
#include "webserver.h"
-extern char *static_dirs[PATH_MAX]; /**< Disk representation */
+extern char *static_dirs[PATH_MAX]; /* Disk representation */
HashList *WirelessTemplateCache;
HashList *WirelessLocalTemplateCache;
WCTemplputParams NoCtx;
StrBuf *I18nDump = NULL;
+const char EmptyStr[]="";
+
#define SV_GETTEXT 1
#define SV_CONDITIONAL 2
#define SV_NEG_CONDITIONAL 3
/*
- * \brief Dynamic content for variable substitution in templates
+ * Dynamic content for variable substitution in templates
*/
typedef struct _wcsubst {
ContextFilter Filter;
- int wcs_type; /* which type of Substitution are we */
- char wcs_key[32]; /* copy of our hashkey for debugging */
- StrBuf *wcs_value; /* if we're a string, keep it here */
- long lvalue; /* type long? keep data here */
- WCHandlerFunc wcs_function; /* funcion hook ???*/
+ int wcs_type; /* which type of Substitution are we */
+ char wcs_key[32]; /* copy of our hashkey for debugging */
+ StrBuf *wcs_value; /* if we're a string, keep it here */
+ long lvalue; /* type long? keep data here */
+ WCHandlerFunc wcs_function; /* funcion hook ???*/
} wcsubst;
typedef struct _HashHandler {
ContextFilter Filter;
-
+ WCPreevalFunc PreEvalFunc;
WCHandlerFunc HandlerFunc;
}HashHandler;
"Context ROOMS",
"Context FLOORS",
"Context ITERATE",
+ "Context ICAL",
+ "Context DavNamespace",
"Context UNKNOWN"
};
Err = (TP->Tokens!= NULL)? TP->Tokens->pName:"";
break;
case ERR_PARM1:
- Err = (TP->Tokens!= NULL)? TP->Tokens->Params[0]->Start:"";
+ Err = ((TP->Tokens!= NULL) &&
+ (TP->Tokens->nParameters > 0))?
+ TP->Tokens->Params[0]->Start : "";
break;
case ERR_PARM2:
- Err = (TP->Tokens!= NULL)? TP->Tokens->Params[1]->Start:"";
+ Err = ((TP->Tokens!= NULL) &&
+ (TP->Tokens->nParameters > 1))?
+ TP->Tokens->Params[1]->Start : "";
break;
}
if (TP->Tokens != NULL)
return;
*/
WCC = WC;
- if (WCC == NULL)
- return;
+ if (WCC == NULL) {
+ FreeStrBuf(&Info);
+ FreeStrBuf(&Error);
+ return;
+ }
Header = NewStrBuf();
if (TP->Tokens != NULL)
Error,
eERROR), 1);
*/
- WildFireSerializePayload(Header, WCC->HBuf, &WCC->nWildfireHeaders, NULL);
+ WildFireSerializePayload(Header, WCC->HBuf, &WCC->Hdr->nWildfireHeaders, NULL);
}
else
{
ChrPtr(Error),
ChrPtr(TP->Tokens->FlatToken));
SerializeJson(Header, WildFireException(HKEY(__FILE__), __LINE__, Info, 1), 1);
- WildFireSerializePayload(Header, WCC->HBuf, &WCC->nWildfireHeaders, NULL);
+ WildFireSerializePayload(Header, WCC->HBuf, &WCC->Hdr->nWildfireHeaders, NULL);
}
FreeStrBuf(&Header);
FreeStrBuf(&Info);
0,
Info,
1), 1);
- WildFireSerializePayload(Header, WCC->HBuf, &WCC->nWildfireHeaders, NULL);
+ WildFireSerializePayload(Header, WCC->HBuf, &WCC->Hdr->nWildfireHeaders, NULL);
FreeStrBuf(&Header);
FreeStrBuf(&Info);
int nMinArgs,
int nMaxArgs,
WCHandlerFunc HandlerFunc,
+ WCPreevalFunc PreevalFunc,
int ContextRequired)
{
HashHandler *NewHandler;
NewHandler = (HashHandler*) malloc(sizeof(HashHandler));
+ memset(NewHandler, 0, sizeof(HashHandler));
NewHandler->Filter.nMinArgs = nMinArgs;
NewHandler->Filter.nMaxArgs = nMaxArgs;
NewHandler->Filter.ContextType = ContextRequired;
NewHandler->Filter.ControlContextType = CTX_NONE;
+ NewHandler->PreEvalFunc = PreevalFunc;
NewHandler->HandlerFunc = HandlerFunc;
Put(GlobalNS, NSName, len, NewHandler, NULL);
}
HashHandler *NewHandler;
NewHandler = (HashHandler*) malloc(sizeof(HashHandler));
+ memset(NewHandler, 0, sizeof(HashHandler));
NewHandler->Filter.nMinArgs = nMinArgs;
NewHandler->Filter.nMaxArgs = nMaxArgs;
NewHandler->Filter.ContextType = CTX_NONE;
}
-/**
- * \brief debugging function to print array to log
+/*
+ * debugging function to print array to log
*/
void VarPrintTransition(void *vVar1, void *vVar2, int odd){}
-/**
- * \brief debugging function to print array to log
+
+/*
+ * debugging function to print array to log
*/
void VarPrintEntry(const char *Key, void *vSubst, int odd)
{
-/**
- * \brief Clear out the list of substitution variables local to this session
+/*
+ * Clear out the list of substitution variables local to this session
*/
void clear_substs(wcsession *wc) {
}
}
-/**
- * \brief Clear out the list of substitution variables local to this session
+/*
+ * Clear out the list of substitution variables local to this session
*/
void clear_local_substs(void) {
clear_substs (WC);
}
-/**
- * \brief destructor; kill one entry.
+/*
+ * destructor; kill one entry.
*/
void deletevar(void *data)
{
}
-/**
- * \brief Add a substitution variable (local to this session) (strlen version...)
- * \param keyname the replacementstring to substitute
- * \param keytype the kind of the key
- * \param format the format string ala printf
- * \param ... the arguments to substitute in the formatstring
+/*
+ * Add a substitution variable (local to this session) (strlen version...)
+ * keyname the replacementstring to substitute
+ * keytype the kind of the key
+ * format the format string ala printf
+ * ... the arguments to substitute in the formatstring
*/
void SVPRINTF(char *keyname, int keytype, const char *format,...)
{
wcsession *WCC = WC;
keylen = strlen(keyname);
- /**
+ /*
* First look if we're doing a replacement of
* an existing key
*/
ptr = NewSubstVar(keyname, keylen, keytype);
}
- /** Format the string */
+ /* Format the string */
va_start(arg_ptr, format);
StrBufVAppendPrintf(ptr->wcs_value, format, arg_ptr);
va_end(arg_ptr);
}
-/**
- * \brief Add a substitution variable (local to this session)
- * \param keyname the replacementstring to substitute
- * \param keytype the kind of the key
- * \param format the format string ala printf
- * \param ... the arguments to substitute in the formatstring
+/*
+ * Add a substitution variable (local to this session)
+ * keyname the replacementstring to substitute
+ * keytype the kind of the key
+ * format the format string ala printf
+ * ... the arguments to substitute in the formatstring
*/
void svprintf(char *keyname, size_t keylen, int keytype, const char *format,...)
{
wcsubst *ptr = NULL;
wcsession *WCC = WC;
- /**
+ /*
* First look if we're doing a replacement of
* an existing key
*/
va_end(arg_ptr);
}
-/**
- * \brief Add a substitution variable (local to this session)
- * \param keyname the replacementstring to substitute
- * \param keytype the kind of the key
- * \param format the format string ala printf
- * \param ... the arguments to substitute in the formatstring
+/*
+ * Add a substitution variable (local to this session)
+ * keyname the replacementstring to substitute
+ * keytype the kind of the key
+ * format the format string ala printf
+ * ... the arguments to substitute in the formatstring
*/
void SVPut(char *keyname, size_t keylen, int keytype, char *Data)
{
wcsession *WCC = WC;
- /**
+ /*
* First look if we're doing a replacement of
* an existing key
*/
*len = TP->Tokens->Params[N]->len;
break;
case TYPE_BSTR:
+ if (TP->Tokens->Params[N]->len == 0) {
+ LogTemplateError(Target,
+ "TokenParameter", N, TP,
+ "Requesting parameter %d; of type BSTR, empty lookup string not admitted.", N);
+ *len = 0;
+ *Value = EmptyStr;
+ break;
+ }
Buf = (StrBuf*) SBstr(TKEY(N));
*Value = ChrPtr(Buf);
*len = StrLength(Buf);
break;
case TYPE_PREFSTR:
+ if (TP->Tokens->Params[N]->len == 0) {
+ LogTemplateError(Target,
+ "TokenParameter", N, TP,
+ "Requesting parameter %d; of type PREFSTR, empty lookup string not admitted.", N);
+ *len = 0;
+ *Value = EmptyStr;
+ break;
+ }
get_PREFERENCE(TKEY(N), &Buf);
*Value = ChrPtr(Buf);
*len = StrLength(Buf);
*len = strlen(*Value);
break;
case TYPE_SUBTEMPLATE:
+ if (TP->Tokens->Params[N]->len == 0) {
+ LogTemplateError(Target,
+ "TokenParameter", N, TP,
+ "Requesting parameter %d; of type SUBTEMPLATE, empty lookup string not admitted.", N);
+ *len = 0;
+ *Value = EmptyStr;
+ break;
+ }
+
memset(&SubTP, 0, sizeof(WCTemplputParams *));
SubTP.Context = TP->Context;
SubTP.Filter.ContextType = TP->Filter.ContextType;
return atol(TP->Tokens->Params[N]->Start);
break;
case TYPE_BSTR:
+ if (TP->Tokens->Params[N]->len == 0) {
+ LogTemplateError(Target,
+ "TokenParameter", N, TP,
+ "Requesting parameter %d; of type BSTR, empty lookup string not admitted.", N);
+ return 0;
+ }
return LBstr(TKEY(N));
break;
case TYPE_PREFSTR:
LogTemplateError(Target,
"TokenParameter", N, TP,
"requesting a prefstring in param %d want a number", N);
+ if (TP->Tokens->Params[N]->len == 0) {
+ LogTemplateError(Target,
+ "TokenParameter", N, TP,
+ "Requesting parameter %d; of type PREFSTR, empty lookup string not admitted.", N);
+ return 0;
+ }
if (get_PREF_LONG(TKEY(N), &Ret, dflt))
return Ret;
return 0;
case TYPE_LONG:
return TP->Tokens->Params[N]->lvalue;
case TYPE_PREFINT:
+ if (TP->Tokens->Params[N]->len == 0) {
+ LogTemplateError(Target,
+ "TokenParameter", N, TP,
+ "Requesting parameter %d; of type PREFINT, empty lookup string not admitted.", N);
+ return 0;
+ }
if (get_PREF_LONG(TKEY(N), &Ret, dflt))
return Ret;
return 0;
case 'J':
StrECMAEscAppend(Target, Source, NULL);
break;
+ case 'K':
+ StrHtmlEcmaEscAppend(Target, Source, NULL, 0, 0);
+ break;
case 'U':
StrBufUrlescAppend(Target, Source, NULL);
break;
if (Template->TokenSpace <= 0) {
Template->Tokens = (WCTemplateToken**)malloc(
sizeof(WCTemplateToken*) * 10);
+ memset(Template->Tokens, 0, sizeof(WCTemplateToken*));
Template->TokenSpace = 10;
}
else {
{
const char *pch = *pCh;
const char *pchs, *pche;
- TemplateParam *Parm = (TemplateParam *) malloc(sizeof(TemplateParam));
+ TemplateParam *Parm;
char quote = '\0';
int ParamBrace = 0;
+ Parm = (TemplateParam *) malloc(sizeof(TemplateParam));
+ memset(Parm, 0, sizeof(TemplateParam));
Parm->Type = TYPE_STR;
/* Skip leading whitespaces */
void *vVar;
const char *pch;
TemplateParam *Param;
- WCTemplateToken *NewToken = (WCTemplateToken*)malloc(sizeof(WCTemplateToken));
+ WCTemplateToken *NewToken;
WCTemplputParams TP;
+ NewToken = (WCTemplateToken*)malloc(sizeof(WCTemplateToken));
+ memset(NewToken, 0, sizeof(WCTemplateToken));
TP.Tokens = NewToken;
NewToken->FileName = pTmpl->FileName; /* to print meaningfull log messages... */
NewToken->Flags = 0;
NewToken->NameEnd = NewToken->TokenEnd - 2;
NewToken->PreEval = NULL;
NewToken->FlatToken = NewStrBufPlain(pTmplStart + 2, pTmplEnd - pTmplStart - 2);
-
+ StrBufShrinkToFit(NewToken->FlatToken, 1);
+
StrBufPeek(Buf, pTmplStart, + 1, '\0');
StrBufPeek(Buf, pTmplEnd, -1, '\0');
pch = NewToken->pName = pTmplStart + 2;
else {
NewToken->PreEval = Handler;
NewToken->Flags = SV_PREEVALUATED;
+ if (Handler->PreEvalFunc != NULL)
+ Handler->PreEvalFunc(NewToken);
}
}
break;
void *prepare_template(StrBuf *filename, StrBuf *Key, HashList *PutThere)
{
WCTemplate *NewTemplate;
+
NewTemplate = (WCTemplate *) malloc(sizeof(WCTemplate));
+ memset(NewTemplate, 0, sizeof(WCTemplate));
NewTemplate->Data = NULL;
NewTemplate->FileName = NewStrBufDup(filename);
+ StrBufShrinkToFit(NewTemplate->FileName, 1);
NewTemplate->nTokensUsed = 0;
NewTemplate->TokenSpace = 0;
NewTemplate->Tokens = NULL;
}
NewTemplate = (WCTemplate *) malloc(sizeof(WCTemplate));
+ memset(NewTemplate, 0, sizeof(WCTemplate));
NewTemplate->Data = NewStrBufPlain(NULL, statbuf.st_size);
NewTemplate->FileName = NewStrBufDup(filename);
NewTemplate->nTokensUsed = 0;
close(fd);
Line = 0;
+ StrBufShrinkToFit(NewTemplate->Data, 1);
+ StrBufShrinkToFit(NewTemplate->MimeType, 1);
pS = pch = ChrPtr(NewTemplate->Data);
pE = pS + StrLength(NewTemplate->Data);
while (pch < pE) {
/** Find one <? > */
pos = (-1);
for (; pch < pE; pch ++) {
- if ((*pch=='<')&&(*(pch + 1)=='?'))
+ if ((*pch=='<')&&(*(pch + 1)=='?') &&
+ !((pch == pS) && /* we must ommit a <?xml */
+ (*(pch + 2) == 'x') &&
+ (*(pch + 3) == 'm') &&
+ (*(pch + 4) == 'l')))
break;
if (*pch=='\n') Line ++;
}
int XPectContextType,
int Flags)
{
- HashIterator *It = (HashIterator*)malloc(sizeof(HashIterator));
+ HashIterator *It;
+
+ It = (HashIterator*)malloc(sizeof(HashIterator));
+ memset(It, 0, sizeof(HashIterator));
It->StaticList = StaticList;
It->AdditionalParams = AdditionalParams;
It->GetHash = GetHash;
int LastN;
}IterateStruct;
-void tmpl_iterate_subtmpl(StrBuf *Target, WCTemplputParams *TP)
+int preeval_iterate(WCTemplateToken *Token)
{
+ WCTemplputParams TPP;
+ WCTemplputParams *TP;
void *vIt;
+
+ memset(&TPP, 0, sizeof(WCTemplputParams));
+ TP = &TPP;
+ TP->Tokens = Token;
+ if (!GetHash(Iterators, TKEY(0), &vIt)) {
+ LogTemplateError(
+ NULL, "Iterator", ERR_NAME, TP,
+ "not found");
+ return 0;
+ }
+ Token->Preeval2 = vIt;
+ return 1;
+}
+
+void tmpl_iterate_subtmpl(StrBuf *Target, WCTemplputParams *TP)
+{
HashIterator *It;
HashList *List;
HashPos *it;
memset(&Status, 0, sizeof(IterateStruct));
memcpy (&SubTP, &TP, sizeof(WCTemplputParams));
- if (!GetHash(Iterators, TKEY(0), &vIt)) {
+ It = (HashIterator*) TP->Tokens->Preeval2;
+ if (It == NULL) {
LogTemplateError(
Target, "Iterator", ERR_PARM1, TP, "Unknown!");
return;
}
- It = (HashIterator*) vIt;
-
if (TP->Tokens->nParameters < It->AdditionalParams + 2) {
LogTemplateError(
Target, "Iterator", ERR_PARM1, TP,
while (GetNextHashPos(List, it, &Status.KeyLen, &Status.Key, &vContext)) {
if ((Status.n >= StartAt) && (Status.n <= StopAt)) {
if (DetectGroupChange && Status.n > 0) {
- Status.GroupChange = (SortBy->GroupChange(vContext, vLastContext))? 1:0;
+ Status.GroupChange = SortBy->GroupChange(vContext, vLastContext);
}
Status.LastN = (Status.n + 1) == nMembersUsed;
SubTP.Context = vContext;
int conditional_ITERATE_ISGROUPCHANGE(StrBuf *Target, WCTemplputParams *TP)
{
IterateStruct *Ctx = CCTX;
- return Ctx->GroupChange;
+ if (TP->Tokens->nParameters < 3)
+ return Ctx->GroupChange;
+
+ return TP->Tokens->Params[2]->lvalue == Ctx->GroupChange;
}
void tmplput_ITERATE_ODDEVEN(StrBuf *Target, WCTemplputParams *TP)
StrBufAppendPrintf(Target, "%d", Ctx->n);
}
+int conditional_ITERATE_FIRSTN(StrBuf *Target, WCTemplputParams *TP)
+{
+ IterateStruct *Ctx = CCTX;
+ return Ctx->n == 0;
+}
+
int conditional_ITERATE_LASTN(StrBuf *Target, WCTemplputParams *TP)
{
IterateStruct *Ctx = CCTX;
WCConditionalFunc CondF,
int ContextRequired)
{
- ConditionalStruct *Cond = (ConditionalStruct*)malloc(sizeof(ConditionalStruct));
+ ConditionalStruct *Cond;
+
+ Cond = (ConditionalStruct*)malloc(sizeof(ConditionalStruct));
+ memset(Cond, 0, sizeof(ConditionalStruct));
Cond->PlainName = Name;
Cond->Filter.nMaxArgs = nParams;
Cond->Filter.nMinArgs = nParams;
WCConditionalFunc CondF,
int ControlContextRequired)
{
- ConditionalStruct *Cond = (ConditionalStruct*)malloc(sizeof(ConditionalStruct));
+ ConditionalStruct *Cond;
+
+ Cond = (ConditionalStruct*)malloc(sizeof(ConditionalStruct));
+ memset(Cond, 0, sizeof(ConditionalStruct));
Cond->PlainName = Name;
Cond->Filter.nMaxArgs = nParams;
Cond->Filter.nMinArgs = nParams;
Headline = NewStrBufPlain(Ch, len);
}
}
- memcpy (&SubTP, TP, sizeof(WCTemplputParams));
+ memcpy (&SubTP, TP, sizeof(WCTemplputParams));
SubTP.Context = Headline;
SubTP.Filter.ContextType = CTX_STRBUF;
DoTemplate(HKEY("beginbox"), Target, &SubTP);
nTabs = ntabs = TP->Tokens->nParameters / 2;
TabNames = (StrBuf **) malloc(ntabs * sizeof(StrBuf*));
+ memset(TabNames, 0, ntabs * sizeof(StrBuf*));
for (i = 0; i < ntabs; i++) {
if ((TP->Tokens->Params[i * 2]->Type == TYPE_STR) &&
CompareFunc GroupChange,
long ContextType)
{
- SortStruct *NewSort = (SortStruct*) malloc(sizeof(SortStruct));
+ SortStruct *NewSort;
+
+ NewSort = (SortStruct*) malloc(sizeof(SortStruct));
+ memset(NewSort, 0, sizeof(SortStruct));
NewSort->Name = NewStrBufPlain(name, len);
if (prepend != NULL)
NewSort->PrefPrepend = NewStrBufPlain(prepend, preplen);
(void)
{
memset(&NoCtx, 0, sizeof(WCTemplputParams));
- RegisterNamespace("SORT:ICON", 1, 2, tmplput_SORT_ICON, CTX_NONE);
- RegisterNamespace("SORT:ORDER", 1, 2, tmplput_SORT_ORDER, CTX_NONE);
- RegisterNamespace("SORT:NEXT", 1, 2, tmplput_SORT_NEXT, CTX_NONE);
- RegisterNamespace("CONTEXTSTR", 0, 1, tmplput_ContextString, CTX_STRBUF);
- RegisterNamespace("ITERATE", 2, 100, tmpl_iterate_subtmpl, CTX_NONE);
- RegisterNamespace("DOBOXED", 1, 2, tmpl_do_boxed, CTX_NONE);
- RegisterNamespace("DOTABBED", 2, 100, tmpl_do_tabbed, CTX_NONE);
- RegisterNamespace("LONGVECTOR", 1, 1, tmplput_long_vector, CTX_LONGVECTOR);
+ RegisterNamespace("SORT:ICON", 1, 2, tmplput_SORT_ICON, NULL, CTX_NONE);
+ RegisterNamespace("SORT:ORDER", 1, 2, tmplput_SORT_ORDER, NULL, CTX_NONE);
+ RegisterNamespace("SORT:NEXT", 1, 2, tmplput_SORT_NEXT, NULL, CTX_NONE);
+ RegisterNamespace("CONTEXTSTR", 0, 1, tmplput_ContextString, NULL, CTX_STRBUF);
+ RegisterNamespace("ITERATE", 2, 100, tmpl_iterate_subtmpl, preeval_iterate, CTX_NONE);
+ RegisterNamespace("DOBOXED", 1, 2, tmpl_do_boxed, NULL, CTX_NONE);
+ RegisterNamespace("DOTABBED", 2, 100, tmpl_do_tabbed, NULL, CTX_NONE);
+ RegisterNamespace("LONGVECTOR", 1, 1, tmplput_long_vector, NULL, CTX_LONGVECTOR);
RegisterConditional(HKEY("COND:SUBST"), 3, ConditionalVar, CTX_NONE);
RegisterConditional(HKEY("COND:CONTEXTSTR"), 3, ConditionalContextStr, CTX_STRBUF);
RegisterConditional(HKEY("COND:LONGVECTOR"), 4, ConditionalLongVector, CTX_LONGVECTOR);
RegisterControlConditional(HKEY("COND:ITERATE:LASTN"), 2,
conditional_ITERATE_LASTN,
CTX_ITERATE);
+ RegisterControlConditional(HKEY("COND:ITERATE:FIRSTN"), 2,
+ conditional_ITERATE_FIRSTN,
+ CTX_ITERATE);
+
RegisterControlNS(HKEY("ITERATE:ODDEVEN"), 0, 0, tmplput_ITERATE_ODDEVEN, CTX_ITERATE);
RegisterControlNS(HKEY("ITERATE:KEY"), 0, 0, tmplput_ITERATE_KEY, CTX_ITERATE);
RegisterControlNS(HKEY("ITERATE:N"), 0, 0, tmplput_ITERATE_LASTN, CTX_ITERATE);
{
}
-
-
-
-
-/*@}*/