From: Wilfried Göesgens Date: Mon, 18 Aug 2008 19:47:07 +0000 (+0000) Subject: * migrate the WHO struct to strbuf X-Git-Tag: v7.86~2028 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=3c8aa1790772c4f64f75a9c3ae3260154abd0120 * migrate the WHO struct to strbuf * add SVPUTBuf() which can handle strbuffers * register the ITERATOR("WHO") * provide tokens via the who iterator func: WHO:NAME, WHO:ROOM, WHO:HOST, WHO:REALROOM, WHO:REALHOST, WHO:LASTACTIVE, WHO:SESSION, WHO:IDLE, WHO:NSESSIONS * some fixes to do_template, and the whole other stuff --- diff --git a/webcit/preferences.c b/webcit/preferences.c index ecec9e05d..116b54316 100644 --- a/webcit/preferences.c +++ b/webcit/preferences.c @@ -688,6 +688,11 @@ void tmplput_CFG_Descr(StrBuf *Target, int nArgs, WCTemplateToken *Token, void * } +void CfgZoneTempl(StrBuf *TemplBuffer, void *Context) +{ + +} + void InitModule_PREFERENCES @@ -709,5 +714,6 @@ InitModule_PREFERENCES RegisterNamespace("PREF:VALUE", 1, 1, tmplput_CFG_Value); RegisterNamespace("PREF:DESCR", 1, 1, tmplput_CFG_Descr); + RegisterIterator("PREF:ZONE", ZoneHash, NULL, CfgZoneTempl, NULL); } /*@}*/ diff --git a/webcit/serv_func.c b/webcit/serv_func.c index a9ff29458..bce6cd5ca 100644 --- a/webcit/serv_func.c +++ b/webcit/serv_func.c @@ -109,13 +109,18 @@ void get_serv_info(char *browser_host, char *user_agent) * \brief Read Citadel variformat text and spit it out as HTML. * \param align html align string */ -void fmout(char *align) +inline void fmout(char *align) +{ + _fmout(WC->WBuf, align); +} + +void _fmout(StrBuf *Target, char *align) { int intext = 0; int bq = 0; char buf[SIZ]; - wprintf("
\n", align); + StrBufAppendPrintf(Target, "
\n", align); while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { if ((intext == 1) && (isspace(buf[0]))) { @@ -129,10 +134,10 @@ void fmout(char *align) * " >" quotes and will convert to
tags. */ if ((bq == 0) && (!strncmp(buf, " >", 2))) { - wprintf("
"); + StrBufAppendBufPlain(Target, HKEY("
"), 0); bq = 1; } else if ((bq == 1) && (strncmp(buf, " >", 2))) { - wprintf("
"); + StrBufAppendBufPlain(Target, HKEY("
"), 0); bq = 0; } if ((bq == 1) && (!strncmp(buf, " >", 2))) { @@ -141,8 +146,8 @@ void fmout(char *align) /** Activate embedded URL's */ url(buf, sizeof(buf)); - escputs(buf); - wprintf("\n"); + escputs(buf);//// TODO: Target + StrBufAppendBufPlain(Target, HKEY("\n"), 0); } if (bq == 1) { wprintf(""); diff --git a/webcit/siteconfig.c b/webcit/siteconfig.c index 1a32942ea..25e8ae034 100644 --- a/webcit/siteconfig.c +++ b/webcit/siteconfig.c @@ -8,6 +8,39 @@ #include "webcit.h" #include "webserver.h" + +HashList *ZoneHash = NULL; + + + +void LoadZoneFiles(void) +{ + icalarray *zones; + int z; + long len; + char this_zone[128]; + char *ZName; + HashPos *it; + + ZoneHash = NewHash(1, NULL); + len = sizeof("UTC") + 1; + ZName = malloc(len + 1); + memcpy(ZName, "UTC", len + 1); + Put(ZoneHash, ZName, len, ZName, NULL); + zones = icaltimezone_get_builtin_timezones(); + for (z = 0; z < zones->num_elements; ++z) { + strcpy(this_zone, icaltimezone_get_location(icalarray_element_at(zones, z))); + len = strlen(this_zone); + ZName = (char*)malloc(len +1); + memcpy(ZName, this_zone, len + 1); + Put(ZoneHash, ZName, len, ZName, NULL); + } + SortByHashKey(ZoneHash, 0); +} + + + + /* * \brief display all configuration items */ diff --git a/webcit/subst.c b/webcit/subst.c index cd0afa979..6bff32090 100644 --- a/webcit/subst.c +++ b/webcit/subst.c @@ -279,27 +279,56 @@ inline void SVCALLBACK(char *keyname, var_callback_fptr fcn_ptr) +void SVPUTBuf(const char *keyname, int keylen, StrBuf *Buf, int ref) +{ + wcsubst *ptr; + void *vPtr; + struct wcsession *WCC = WC; + + /** + * First look if we're doing a replacement of + * an existing key + */ + /*PrintHash(WCC->vars, VarPrintTransition, VarPrintEntry);*/ + if (GetHash(WCC->vars, keyname, keylen, &vPtr)) { + ptr = (wcsubst*)vPtr; + if (ptr->wcs_value != NULL) + free(ptr->wcs_value);///TODO: respect type + } + else /** Otherwise allocate a new one */ + { + ptr = (wcsubst *) malloc(sizeof(wcsubst)); + safestrncpy(ptr->wcs_key, keyname, sizeof ptr->wcs_key); + Put(WCC->vars, keyname, keylen, ptr, deletevar); + } + + ptr->wcs_value = NULL; + ptr->wcs_type = (ref)?WCS_STRBUF:WCS_STRBUF_REF; + ptr->wcs_function = (var_callback_fptr) Buf; ////TODO +} + /** * \brief back end for print_value_of() ... does a server command * \param servcmd server command to execute on the citadel server */ -void pvo_do_cmd(char *servcmd) { +void pvo_do_cmd(StrBuf *Target, char *servcmd) { char buf[SIZ]; + int len; serv_puts(servcmd); - serv_getln(buf, sizeof buf); + len = serv_getln(buf, sizeof buf); switch(buf[0]) { case '2': case '3': case '5': - wprintf("%s\n", &buf[4]); + StrBufAppendPrintf(Target, "%s\n", &buf[4]); break; case '1': - fmout("CENTER"); + _fmout(Target, "CENTER"); break; case '4': - wprintf("%s\n", &buf[4]); + StrBufAppendPrintf(Target, "%s\n", &buf[4]); serv_puts("000"); break; } @@ -309,7 +338,7 @@ void pvo_do_cmd(char *servcmd) { * \brief Print the value of a variable * \param keyname get a key to print */ -void print_value_of(const char *keyname, size_t keylen) { +void print_value_of(StrBuf *Target, const char *keyname, size_t keylen) { struct wcsession *WCC = WC; wcsubst *ptr; void *fcn(); @@ -324,14 +353,18 @@ void print_value_of(const char *keyname, size_t keylen) { ptr = (wcsubst*) vVar; switch(ptr->wcs_type) { case WCS_STRING: - wprintf("%s", (const char*)ptr->wcs_value); + StrBufAppendBufPlain(Target, (const char*)ptr->wcs_value, -1, 0); break; case WCS_SERVCMD: - pvo_do_cmd(ptr->wcs_value); + pvo_do_cmd(Target, ptr->wcs_value); break; case WCS_FUNCTION: (*ptr->wcs_function) (); break; + case WCS_STRBUF: + case WCS_STRBUF_REF: + StrBufAppendBuf(Target, (StrBuf*) ptr->wcs_function, 0); + break; default: lprintf(1,"WARNING: invalid value in SV-Hash at %s!", keyname); } @@ -397,6 +430,7 @@ TemplateParam *GetNextParamter(StrBuf *Buf, const char **pCh, const char *pe) } else { StrBufPeek(Buf, pch, -1, '\0'); + lprintf(1, "DBG: got param [%s]\n", pchs); Parm->Start = pchs; Parm->len = pche - pchs; pch ++; /* move after trailing quote */ @@ -419,7 +453,7 @@ TemplateParam *GetNextParamter(StrBuf *Buf, const char **pCh, const char *pe) } else { Parm->lvalue = 0; - lprintf(1, "Error evalating template long param [%s]", *pCh); + lprintf(1, "Error evaluating template long param [%s]", *pCh); free(Parm); return NULL; } @@ -427,6 +461,7 @@ TemplateParam *GetNextParamter(StrBuf *Buf, const char **pCh, const char *pe) while ((*pch == ' ' )|| (*pch == '\t')|| (*pch == '\r')|| + (*pch == ',' )|| (*pch == '\n')) pch ++; *pCh = pch; @@ -456,12 +491,12 @@ WCTemplateToken *NewTemplateSubstitute(StrBuf *Buf, NewToken->HaveParameters = 0;; NewToken->nParameters = 0; - while (pch <= pTmplEnd - 1) { + while (pch < pTmplEnd - 1) { if (*pch == '(') { StrBufPeek(Buf, pch, -1, '\0'); NewToken->NameEnd = pch - NewToken->pName; pch ++; - while (pch <= pTmplEnd - 1) { + while (pch < pTmplEnd - 1) { Param = GetNextParamter(Buf, &pch, pTmplEnd - 1); if (Param != NULL) { NewToken->HaveParameters = 1; @@ -509,7 +544,7 @@ void EvaluateToken(StrBuf *Target, WCTemplateToken *Token, void *Context) HashHandler *Handler; Handler = (HashHandler*) vVar; if ((Token->nParameters < Handler->nMinArgs) || - (Token->nParameters < Handler->nMaxArgs)) { + (Token->nParameters > Handler->nMaxArgs)) { lprintf(1, "Handler [%s] doesn't work with %ld params", Token->pName, Token->nParameters); @@ -524,7 +559,7 @@ void EvaluateToken(StrBuf *Target, WCTemplateToken *Token, void *Context) } } else { - print_value_of(Token->pName, Token->NameEnd); + print_value_of(Target, Token->pName, Token->NameEnd); } } @@ -540,7 +575,9 @@ void ProcessTemplate(WCTemplate *Tmpl, StrBuf *Target, void *Context) i = 0; while (!done) { if (i >= Tmpl->nTokensUsed) { - StrBufAppendBufPlain(Target, pData, len, 0); + StrBufAppendBufPlain(Target, + pData, + len - (pData - pS), 0); done = 1; } else { @@ -639,7 +676,9 @@ void DoTemplate(const char *templatename, long len, void *Context, StrBuf *Targe HashList *Static; HashList *StaticLocal; void *vTmpl; - + + if (Target == NULL) + Target = WC->WBuf; if (WC->is_mobile) { Static = WirelessTemplateCache; StaticLocal = WirelessLocalTemplateCache; @@ -656,7 +695,7 @@ void DoTemplate(const char *templatename, long len, void *Context, StrBuf *Targe } if (vTmpl == NULL) return; - ProcessTemplate(vTmpl, WC->WBuf, Context); + ProcessTemplate(vTmpl, Target, Context); } int LoadTemplateDir(const char *DirName, HashList *wireless, HashList *big) @@ -804,8 +843,8 @@ void tmpl_iterate_subtmpl(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, vo it = GetNewHashPos(); while (GetNextHashPos(List, it, &len, &Key, &vContext)) { It->DoSubTemplate(SubBuf, vContext); - DoTemplate(Tokens->Params[0]->Start, - Tokens->Params[0]->len, + DoTemplate(Tokens->Params[1]->Start, + Tokens->Params[1]->len, vContext, SubBuf); StrBufAppendBuf(Target, SubBuf, 0); diff --git a/webcit/webcit.c b/webcit/webcit.c index 4f488f392..3034419c8 100644 --- a/webcit/webcit.c +++ b/webcit/webcit.c @@ -1094,7 +1094,10 @@ void blank_page(void) { * A template has been requested */ void url_do_template(void) { - do_template(bstr("template"), NULL); + const StrBuf *Tmpl = sbstr("template"); + begin_burst(); + DoTemplate(ChrPtr(Tmpl), StrLength(Tmpl), NULL, NULL); + end_burst(); } @@ -1498,9 +1501,9 @@ void session_loop(struct httprequest *req) BuffSize = ContentLength + SIZ; content = malloc(BuffSize); memset(content, 0, BuffSize); - snprintf(content, BuffSize, "Content-type: %s\n" - "Content-length: %d\n\n", - ContentType, ContentLength); + hprintf("Content-type: %s\n" + "Content-length: %d\n\n", + ContentType, ContentLength); body_start = strlen(content); /** Read the entire input data at once. */ diff --git a/webcit/webcit.h b/webcit/webcit.h index bee4cf009..7f01648f6 100644 --- a/webcit/webcit.h +++ b/webcit/webcit.h @@ -332,16 +332,18 @@ void RegisterITERATOR(const char *Name, long len, RetrieveHashlistFunc GetHash, SubTemplFunc DoSubTempl, HashDestructorFunc Destructor); -#define RegisterIterator(a, b, c, d) RegisterITERATOR(a, sizeof(a)-1, b, c, d) +#define RegisterIterator(a, b, c, d, e) RegisterITERATOR(a, sizeof(a)-1, b, c, d, e) /** * \brief Values for wcs_type */ enum { - WCS_STRING, /**< its a string */ - WCS_FUNCTION, /**< its a function callback */ - WCS_SERVCMD /**< its a command to send to the citadel server */ + WCS_STRING, /**< its a string */ + WCS_FUNCTION, /**< its a function callback */ + WCS_SERVCMD, /**< its a command to send to the citadel server */ + WCS_STRBUF, /**< its a strbuf we own */ + WCS_STRBUF_REF /**< its a strbuf we mustn't free */ }; /** @@ -520,6 +522,9 @@ extern HashList *TemplateCache; extern HashList *LocalTemplateCache; extern HashList *GlobalNS; extern HashList *Iterators; +extern HashList *ZoneHash; + + void InitialiseSemaphores(void); void begin_critical_section(int which_one); @@ -553,6 +558,7 @@ void who(void); void who_inner_div(void); void ajax_mini_calendar(void); void fmout(char *align); +void _fmout(StrBuf *Targt, char *align); void pullquote_fmout(void); void wDumpContent(int); @@ -662,6 +668,9 @@ void SVCALLBACK(char *keyname, var_callback_fptr fcn_ptr); void SVCallback(char *keyname, size_t keylen, var_callback_fptr fcn_ptr); #define svcallback(a, b) SVCallback(a, sizeof(a) - 1, b) +void SVPUTBuf(const char *keyname, int keylen, StrBuf *Buf, int ref); +#define SVPutBuf(a, b, c); SVPUTBuf(a, sizeof(a) - 1, b, c) + void DoTemplate(const char *templatename, long len, void *Context, StrBuf *Target); #define do_template(a, b) DoTemplate(a, sizeof(a) -1, b, NULL); diff --git a/webcit/webserver.c b/webcit/webserver.c index 32887f47c..a550f4928 100644 --- a/webcit/webserver.c +++ b/webcit/webserver.c @@ -589,6 +589,7 @@ const char *nix(void *vptr) {snprintf(foobuf, 32, "%0x", (long) vptr); return fo #endif void InitTemplateCache(void); +extern void LoadZoneFiles(void); /* * \brief Here's where it all begins. * \param argc number of commandline args @@ -624,6 +625,7 @@ int main(int argc, char **argv) TemplateCache = NewHash(1, NULL); GlobalNS = NewHash(1, NULL); Iterators = NewHash(1, NULL); + LoadZoneFiles(); #ifdef DBG_PRINNT_HOOKS_AT_START diff --git a/webcit/who.c b/webcit/who.c index 00a06fdb0..47f152aa7 100644 --- a/webcit/who.c +++ b/webcit/who.c @@ -5,16 +5,11 @@ #include "webcit.h" typedef struct UserStateStruct { - char *UserName; - long UserNameLen; - char *Room; - long RoomLen; - char *Host; - long HostLen; - char *RealRoom; - long RealRoomLen; - char *RealHost; - long RealHostLen; + StrBuf *UserName; + StrBuf *Room; + StrBuf *Host; + StrBuf *RealRoom; + StrBuf *RealHost; long LastActive; int Session; int Idle; @@ -24,11 +19,11 @@ typedef struct UserStateStruct { void DestroyUserStruct(void *vUser) { UserStateStruct *User = (UserStateStruct*) vUser; - free(User->UserName); - free(User->Room); - free(User->Host); - free(User->RealRoom); - free(User->RealHost); + FreeStrBuf(&User->UserName); + FreeStrBuf(&User->Room); + FreeStrBuf(&User->Host); + FreeStrBuf(&User->RealRoom); + FreeStrBuf(&User->RealHost); free(User); } @@ -39,53 +34,54 @@ int CompareUserStruct(const void *VUser1, const void *VUser2) if (User1->Idle != User2->Idle) return User1->Idle > User2->Idle; - return strcasecmp(User1->UserName, User2->UserName); + return strcasecmp(ChrPtr(User1->UserName), + ChrPtr(User2->UserName)); } int GetWholistSection(HashList *List, time_t now) { + StrBuf *Buf, *XBuf; struct wcsession *WCC = WC; /* This is done to make it run faster; WC is a function */ UserStateStruct *User, *OldUser; void *VOldUser; - char buf[SIZ], user[SIZ], room[SIZ], host[SIZ], - realroom[SIZ], realhost[SIZ]; size_t BufLen; + char buf[SIZ]; serv_puts("RWHO"); serv_getln(buf, sizeof buf); if (buf[0] == '1') { - while (BufLen = serv_getln(buf, sizeof buf), strcmp(buf, "000")) { + Buf = NewStrBuf(); + XBuf = NewStrBuf(); + while (BufLen = StrBuf_ServGetln(Buf), strcmp(ChrPtr(Buf), "000")) { if (BufLen <= 0) continue; User = (UserStateStruct*) malloc(sizeof(UserStateStruct)); - User->Session = extract_int(buf, 0); + User->Session = StrBufExtract_int(Buf, 0, '|'); - User->UserNameLen = extract_token(user, buf, 1, '|', sizeof user); - User->UserName = malloc(User->UserNameLen + 1); - memcpy(User->UserName, user, User->UserNameLen + 1); + StrBufExtract_token(XBuf, Buf, 1, '|'); + User->UserName = NewStrBufDup(XBuf); - User->RoomLen = extract_token(room, buf, 2, '|', sizeof room); - User->Room = malloc(User->RoomLen + 1); - memcpy(User->Room, room, User->RoomLen + 1); + StrBufExtract_token(XBuf, Buf, 2, '|'); + User->Room = NewStrBufDup(XBuf); - User->HostLen = extract_token(host, buf, 3, '|', sizeof host); - User->Host = malloc(User->HostLen + 1); - memcpy(User->Host, host, User->HostLen + 1); + StrBufExtract_token(XBuf, Buf, 3, '|'); + User->Host = NewStrBufDup(XBuf); - User->RealRoomLen = extract_token(realroom, buf, 9, '|', sizeof realroom); - User->RealRoom = malloc(User->RealRoomLen + 1); - memcpy(User->RealRoom, realroom, User->RealRoomLen + 1); + StrBufExtract_token(XBuf, Buf, 9, '|'); + User->RealRoom = NewStrBufDup(XBuf); - User->RealHostLen = extract_token(realhost, buf, 10, '|', sizeof realhost); - User->RealHost = malloc(User->RealHostLen + 1); - memcpy(User->RealHost, realhost, User->RealHostLen + 1); + StrBufExtract_token(XBuf, Buf, 10, '|'); + User->RealHost = NewStrBufDup(XBuf); - User->LastActive = extract_long(buf, 5); + User->LastActive = StrBufExtract_long(Buf, 5, '|'); User->Idle = (now - User->LastActive) > 900L; User->SessionCount = 1; - if (GetHash(List, User->UserName, User->UserNameLen, &VOldUser)) { + if (GetHash(List, + ChrPtr(User->UserName), + StrLength(User->UserName), + &VOldUser)) { OldUser = VOldUser; OldUser->SessionCount++; if (!User->Idle) { @@ -98,9 +94,15 @@ int GetWholistSection(HashList *List, time_t now) DestroyUserStruct(User); } else - Put(List, User->UserName, User->UserNameLen, User, DestroyUserStruct); + Put(List, + ChrPtr(User->UserName), + StrLength(User->UserName), + User, DestroyUserStruct); } SortByPayload(List, CompareUserStruct); + + FreeStrBuf(&XBuf); + FreeStrBuf(&Buf); return 1; } else @@ -165,7 +167,7 @@ void who_inner_div(void) { /* (link to page this user) */ wprintf("UserName); + urlescputs(ChrPtr(User->UserName)); wprintf("\">" "UserName); + urlescputs(ChrPtr(User->UserName)); wprintf("\">"); - escputs(User->UserName); + escputs(ChrPtr(User->UserName)); if (User->SessionCount > 1) wprintf(" [%d] ", User->SessionCount); wprintf(""); /* room */ wprintf("\n\t"); - escputs(User->Room); - if (!IsEmptyStr(User->RealRoom) ) { + escputs(ChrPtr(User->Room)); + if (StrLength(User->RealRoom) > 0) { wprintf("
"); escputs(User->RealRoom); wprintf(""); @@ -214,8 +216,8 @@ void who_inner_div(void) { wprintf("\n\t"); /* hostname */ - escputs(User->Host); - if (!IsEmptyStr(User->RealHost)) { + escputs(ChrPtr(User->Host)); + if (StrLength(User->RealHost) > 0) { wprintf("
"); escputs(User->RealHost); wprintf(""); @@ -415,7 +417,7 @@ void wholist_section(void) { it = GetNewHashPos(); while (GetNextHashPos(List, it, &len, &UserName, &VUser)) { User = VUser; - if (strcmp(User->UserName, NLI)) { + if (strcmp(ChrPtr(User->UserName), NLI)) { wprintf("
  • Idle) { wprintf("inactiveuser"); @@ -424,9 +426,9 @@ void wholist_section(void) { wprintf("activeuser"); } wprintf("\">UserName); + urlescputs(ChrPtr(User->UserName)); wprintf("\">"); - escputs(User->UserName); + escputs(ChrPtr(User->UserName)); wprintf("
  • "); } } @@ -440,6 +442,47 @@ void _terminate_session(void) { terminate_session(); } +HashList *GetWholistHash(void) +{ + HashList *List; + char buf[SIZ]; + time_t now; + + serv_puts("TIME"); + serv_getln(buf, sizeof buf); + if (buf[0] == '2') { + now = extract_long(&buf[4], 0); + } + else { + now = time(NULL); + } + + List = NewHash(1, NULL); + GetWholistSection(List, now); + return List; +} + +void WholistSubst(StrBuf *TemplBuffer, void *vContext) +{ + UserStateStruct *User = (UserStateStruct*) vContext; + + SVPutBuf("WHO:NAME", User->UserName, 1); + SVPutBuf("WHO:ROOM", User->Room, 1); + SVPutBuf("WHO:HOST", User->Host, 1); + SVPutBuf("WHO:REALROOM", User->RealRoom, 1); + SVPutBuf("WHO:REALHOST", User->RealHost, 1); + svprintf(HKEY("WHO:LASTACTIVE"), WCS_STRING, "%ld", User->LastActive); + svprintf(HKEY("WHO:SESSION"), WCS_STRING, "%d", User->Session); + svprintf(HKEY("WHO:IDLE"), WCS_STRING, "%s", (User->Idle)? "Idle":"Active"); + svprintf(HKEY("WHO:NSESSIONS"), WCS_STRING, "%d", User->SessionCount); + +} + +void DeleteWholistHash(HashList *KillMe) +{ + DeleteHash(&KillMe); +} + void InitModule_WHO (void) @@ -449,4 +492,6 @@ InitModule_WHO WebcitAddUrlHandler(HKEY("wholist_section"), wholist_section, AJAX); WebcitAddUrlHandler(HKEY("terminate_session"), _terminate_session, 0); WebcitAddUrlHandler(HKEY("edit_me"), edit_me, 0); + + RegisterIterator("WHOLIST", NULL, GetWholistHash, WholistSubst, DeleteWholistHash); }