+
+ lprintf(1, "%s %d %s\n",ChrPtr(FileName), IsMobile, ChrPtr(Tag));
+ if (LoadTemplates == 0)
+ load_template(FileName, Tag, (IsMobile)?wireless:big);
+ else
+ prepare_template(FileName, Tag, (IsMobile)?wireless:big);
+ }
+ closedir(filedir);
+ FreeStrBuf(&FileName);
+ FreeStrBuf(&Tag);
+ FreeStrBuf(&Dir);
+ return 1;
+}
+
+void InitTemplateCache(void)
+{
+ LoadTemplateDir(static_dirs[0],
+ WirelessTemplateCache,
+ TemplateCache);
+ LoadTemplateDir(static_dirs[1],
+ WirelessLocalTemplateCache,
+ LocalTemplateCache);
+}
+
+void tmplput_serv_ip(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ StrBufAppendPrintf(Target, "%d", WC->ctdl_pid);
+}
+
+void tmplput_serv_nodename(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ StrEscAppend(Target, NULL, serv_info.serv_nodename, 0, 0);
+}
+
+void tmplput_serv_humannode(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ StrEscAppend(Target, NULL, serv_info.serv_humannode, 0, 0);
+}
+
+void tmplput_serv_fqdn(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ StrEscAppend(Target, NULL, serv_info.serv_fqdn, 0, 0);
+}
+
+void tmmplput_serv_software(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ StrEscAppend(Target, NULL, serv_info.serv_software, 0, 0);
+}
+
+void tmplput_serv_rev_level(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ StrBufAppendPrintf(Target, "%d.%02d",
+ serv_info.serv_rev_level / 100,
+ serv_info.serv_rev_level % 100);
+}
+
+void tmmplput_serv_bbs_city(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ StrEscAppend(Target, NULL, serv_info.serv_bbs_city, 0, 0);
+}
+
+void tmplput_current_user(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ StrEscAppend(Target, NULL, WC->wc_fullname, 0, 0);
+}
+
+void tmplput_current_room(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ StrEscAppend(Target, NULL, WC->wc_roomname, 0, 0);
+}
+
+
+typedef struct _HashIterator {
+ HashList *StaticList;
+ int AdditionalParams;
+ int ContextType;
+ RetrieveHashlistFunc GetHash;
+ HashDestructorFunc Destructor;
+ SubTemplFunc DoSubTemplate;
+} HashIterator;
+
+void tmpl_iterate_subtmpl(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ void *vIt;
+ HashIterator *It;
+ HashList *List;
+ HashPos *it;
+ long len;
+ const char *Key;
+ void *vContext;
+ StrBuf *SubBuf;
+ int oddeven = 0;
+
+ if (!GetHash(Iterators,
+ Tokens->Params[0]->Start,
+ Tokens->Params[0]->len,
+ &vIt)) {
+ lprintf(1, "unknown Iterator [%s] (in line %ld); "
+ " [%s]\n",
+ Tokens->Params[0]->Start,
+ Tokens->Line,
+ ChrPtr(Tokens->FlatToken));
+ StrBufAppendPrintf(
+ Target,
+ "<pre>\nunknown Iterator [%s] (in line %ld); \n"
+ " [%s]\n</pre>",
+ Tokens->Params[0]->Start,
+ Tokens->Line,
+ ChrPtr(Tokens->FlatToken));
+ return;
+ }
+
+ It = (HashIterator*) vIt;
+
+ if (Tokens->nParameters < It->AdditionalParams + 2) {
+ lprintf(1, "Iterator [%s] (in line %ld); "
+ "doesn't work with %ld params [%s]\n",
+ Tokens->Params[0]->Start,
+ Tokens->Line,
+ Tokens->nParameters,
+ ChrPtr(Tokens->FlatToken));
+ StrBufAppendPrintf(
+ Target,
+ "<pre>Iterator [%s] \n(in line %ld);\n"
+ "doesn't work with %ld params \n[%s]\n</pre>",
+ Tokens->Params[0]->Start,
+ Tokens->Line,
+ Tokens->nParameters,
+ ChrPtr(Tokens->FlatToken));
+ return;
+ }
+
+ if (It->StaticList == NULL)
+ List = It->GetHash(Target, nArgs, Tokens, Context, ContextType);
+ else
+ List = It->StaticList;
+
+ SubBuf = NewStrBuf();
+ it = GetNewHashPos();
+ while (GetNextHashPos(List, it, &len, &Key, &vContext)) {
+ svprintf(HKEY("ITERATE:ODDEVEN"), WCS_STRING, "%s",
+ (oddeven) ? "odd" : "even");
+ svprintf(HKEY("ITERATE:KEY"), WCS_STRING, "%s", Key);
+
+ if (It->DoSubTemplate != NULL)
+ It->DoSubTemplate(SubBuf, vContext, Tokens);
+ DoTemplate(Tokens->Params[1]->Start,
+ Tokens->Params[1]->len,
+ SubBuf, vContext,
+ It->ContextType);
+
+ StrBufAppendBuf(Target, SubBuf, 0);
+ FlushStrBuf(SubBuf);
+ oddeven = ~ oddeven;
+ }
+ FreeStrBuf(&SubBuf);
+ DeleteHashPos(&it);
+ if (It->Destructor != NULL)
+ It->Destructor(&List);
+}
+
+int ConditionalVar(WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ void *vsubst;
+ wcsubst *subst;
+
+ if (!GetHash(WC->vars,
+ Tokens->Params[2]->Start,
+ Tokens->Params[2]->len,
+ &vsubst))
+ return 0;
+ subst = (wcsubst*) vsubst;
+ if ((subst->ContextRequired != CTX_NONE) &&
+ (subst->ContextRequired != ContextType)) {
+ lprintf(1," WARNING: Conditional requires Context: [%ld]!\n", Tokens->Params[2]->Start);
+ return -1;
+ }
+
+ switch(subst->wcs_type) {
+ case WCS_FUNCTION:
+ return (subst->wcs_function!=NULL);
+ case WCS_SERVCMD:
+ lprintf(1, " -> Server [%s]\n", subst->wcs_value);////todo
+ return 1;
+ case WCS_STRING:
+ case WCS_STRBUF:
+ case WCS_STRBUF_REF:
+ if (Tokens->nParameters < 4)
+ return 1;
+ return (strcmp(Tokens->Params[3]->Start, ChrPtr(subst->wcs_value)) == 0);
+ case WCS_LONG:
+ if (Tokens->nParameters < 4)
+ return (subst->lvalue != 0);
+ return (subst->lvalue == Tokens->Params[3]->lvalue);
+ default:
+ lprintf(1," WARNING: invalid type: [%ld]!\n", subst->wcs_type);
+ return -1;
+ }
+ return 0;
+}
+
+void RegisterITERATOR(const char *Name, long len,
+ int AdditionalParams,
+ HashList *StaticList,
+ RetrieveHashlistFunc GetHash,
+ SubTemplFunc DoSubTempl,
+ HashDestructorFunc Destructor,
+ int ContextType)
+{
+ HashIterator *It = (HashIterator*)malloc(sizeof(HashIterator));
+ It->StaticList = StaticList;
+ It->AdditionalParams = AdditionalParams;
+ It->GetHash = GetHash;
+ It->DoSubTemplate = DoSubTempl;
+ It->Destructor = Destructor;
+ It->ContextType = ContextType;
+ Put(Iterators, Name, len, It, NULL);
+}
+
+void RegisterConditional(const char *Name, long len,
+ int nParams,
+ WCConditionalFunc CondF,
+ int ContextRequired)
+{
+ ConditionalStruct *Cond = (ConditionalStruct*)malloc(sizeof(ConditionalStruct));
+ Cond->nParams = nParams;
+ Cond->CondF = CondF;
+ Cond->ContextRequired = ContextRequired;
+ Put(Contitionals, Name, len, Cond, NULL);
+}
+
+void tmpl_do_boxed(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ if (nArgs == 2) {
+ StrBuf *Headline = NewStrBuf();
+ DoTemplate(Tokens->Params[1]->Start,
+ Tokens->Params[1]->len,
+ Headline,
+ Context,
+ ContextType);
+ SVPutBuf("BOXTITLE", Headline, 0);
+ }
+
+ DoTemplate(HKEY("beginbox"), Target, Context, ContextType);
+ DoTemplate(Tokens->Params[0]->Start,
+ Tokens->Params[0]->len,
+ Target,
+ Context,
+ ContextType);
+ DoTemplate(HKEY("endbox"), Target, Context, ContextType);
+}
+
+void tmpl_do_tabbed(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+ StrBuf **TabNames;
+ int i, ntabs, nTabs;
+
+ nTabs = ntabs = Tokens->nParameters / 2;
+ TabNames = (StrBuf **) malloc(ntabs * sizeof(StrBuf*));
+
+ for (i = 0; i < ntabs; i++) {
+ TabNames[i] = NewStrBuf();
+ if (Tokens->Params[i * 2]->len > 0) {
+ DoTemplate(Tokens->Params[i * 2]->Start,
+ Tokens->Params[i * 2]->len,
+ TabNames[i],
+ Context,
+ ContextType);
+ }
+ else {
+ /** A Tab without subject? we can't count that, add it as silent */
+ nTabs --;