X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fwebcit.c;h=34a66f3158209b21b0bad7ec32a854978265a55e;hb=cfa7d8dcaa2bf3b270f3d7de31373cef2e60ff10;hp=df08bd8e026ef9ecc20f3ef079b65e6a69dd4766;hpb=2362c3d4de86f20822ab81015222a196137fd20e;p=citadel.git diff --git a/webcit/webcit.c b/webcit/webcit.c index df08bd8e0..34a66f315 100644 --- a/webcit/webcit.c +++ b/webcit/webcit.c @@ -5,7 +5,8 @@ * persistent session to the Citadel server, handling HTTP WebCit requests as * they arrive and presenting a user interface. */ - +#include +#define SHOW_ME_VAPPEND_PRINTF #include "webcit.h" #include "groupdav.h" #include "webserver.h" @@ -22,8 +23,10 @@ static char *unset = "; expires=28-May-1971 18:10:00 GMT"; HashList *HandlerHash = NULL; - -void WebcitAddUrlHandler(const char * UrlString, long UrlSLen, WebcitHandlerFunc F, int IsAjax) +void WebcitAddUrlHandler(const char * UrlString, + long UrlSLen, + WebcitHandlerFunc F, + long Flags) { WebcitHandler *NewHandler; @@ -32,8 +35,7 @@ void WebcitAddUrlHandler(const char * UrlString, long UrlSLen, WebcitHandlerFunc NewHandler = (WebcitHandler*) malloc(sizeof(WebcitHandler)); NewHandler->F = F; - NewHandler->IsAjax = IsAjax; - + NewHandler->Flags = Flags; Put(HandlerHash, UrlString, UrlSLen, NewHandler, NULL); } @@ -86,63 +88,71 @@ long unescape_input(char *buf) void free_url(void *U) { urlcontent *u = (urlcontent*) U; - free(u->url_data); + FreeStrBuf(&u->url_data); free(u); } /* * Extract variables from the URL. */ -void addurls(char *url, long ulen) +void addurls(StrBuf *url) { - char *aptr, *bptr, *eptr; - char *up; - char *buf; + const char *aptr, *bptr, *eptr, *up; +/// char *buf; int len, keylen; urlcontent *u; struct wcsession *WCC = WC; if (WCC->urlstrings == NULL) WCC->urlstrings = NewHash(1, NULL); - buf = (char*) malloc (ulen + 1); - memcpy(buf, url, ulen); - buf[ulen] = '\0'; - eptr = buf + ulen; - up = buf; - while (!IsEmptyStr(up)) { +// buf = (char*) malloc (ulen + 1); +// memcpy(buf, url, ulen); +/// buf[ulen] = '\0'; + eptr = ChrPtr(url) + StrLength(url); + up = ChrPtr(url); + while ((up < eptr) && (!IsEmptyStr(up))) { aptr = up; while ((aptr < eptr) && (*aptr != '\0') && (*aptr != '=')) aptr++; - if (*aptr != '=') + if (*aptr != '=') { + ///free(buf); return; - *aptr = '\0'; + } + ///*aptr = '\0'; aptr++; bptr = aptr; while ((bptr < eptr) && (*bptr != '\0') && (*bptr != '&') && (*bptr != '?') && (*bptr != ' ')) { bptr++; } - *bptr = '\0'; - u = (urlcontent *) malloc(sizeof(urlcontent)); + //*bptr = '\0'; + keylen = aptr - up - 1; /* -1 -> '=' */ + if(keylen > sizeof(u->url_key)) { + lprintf(1, "URLkey to long! [%s]", up); + continue; + } - keylen = safestrncpy(u->url_key, up, sizeof u->url_key); - if (keylen < 0){ + u = (urlcontent *) malloc(sizeof(urlcontent)); + memcpy(u->url_key, up, keylen); + u->url_key[keylen] = '\0'; + if (keylen < 0) { lprintf(1, "URLkey to long! [%s]", up); + free(u); continue; } Put(WCC->urlstrings, u->url_key, keylen, u, free_url); len = bptr - aptr; - u->url_data = malloc(len + 2); - safestrncpy(u->url_data, aptr, len + 2); - u->url_data_size = unescape_input(u->url_data); - u->url_data[u->url_data_size] = '\0'; + u->url_data = NewStrBufPlain(aptr, len); + StrBufUnescape(u->url_data, 1); + up = bptr; ++up; #ifdef DEBUG_URLSTRINGS - lprintf(9, "%s = [%ld] %s\n", u->url_key, u->url_data_size, u->url_data); + lprintf(9, "%s = [%ld] %s\n", u->url_key, u->url_data_size, ChrPtr(u->url_data)); #endif } + //free(buf); } /* @@ -163,13 +173,13 @@ void dump_vars(void) urlcontent *u; void *U; long HKLen; - char *HKey; + const char *HKey; HashPos *Cursor; Cursor = GetNewHashPos (); while (GetNextHashPos(WCC->urlstrings, Cursor, &HKLen, &HKey, &U)) { u = (urlcontent*) U; - wprintf("%38s = %s\n", u->url_key, u->url_data); + wprintf("%38s = %s\n", u->url_key, ChrPtr(u->url_data)); } } @@ -177,14 +187,14 @@ void dump_vars(void) * Return the value of a variable supplied to the current web page (from the url or a form) */ -const char *XBstr(char *key, size_t keylen, size_t *len) +const char *XBstr(const char *key, size_t keylen, size_t *len) { void *U; if ((WC->urlstrings != NULL) && GetHash(WC->urlstrings, key, keylen, &U)) { - *len = ((urlcontent *)U)->url_data_size; - return ((urlcontent *)U)->url_data; + *len = StrLength(((urlcontent *)U)->url_data); + return ChrPtr(((urlcontent *)U)->url_data); } else { *len = 0; @@ -192,14 +202,14 @@ const char *XBstr(char *key, size_t keylen, size_t *len) } } -const char *XBSTR(char *key, size_t *len) +const char *XBSTR(const char *key, size_t *len) { void *U; if ((WC->urlstrings != NULL) && GetHash(WC->urlstrings, key, strlen (key), &U)){ - *len = ((urlcontent *)U)->url_data_size; - return ((urlcontent *)U)->url_data; + *len = StrLength(((urlcontent *)U)->url_data); + return ChrPtr(((urlcontent *)U)->url_data); } else { *len = 0; @@ -208,113 +218,135 @@ const char *XBSTR(char *key, size_t *len) } -const char *BSTR(char *key) +const char *BSTR(const char *key) { void *U; if ((WC->urlstrings != NULL) && GetHash(WC->urlstrings, key, strlen (key), &U)) - return ((urlcontent *)U)->url_data; + return ChrPtr(((urlcontent *)U)->url_data); else return (""); } -const char *Bstr(char *key, size_t keylen) +const char *Bstr(const char *key, size_t keylen) { void *U; if ((WC->urlstrings != NULL) && GetHash(WC->urlstrings, key, keylen, &U)) - return ((urlcontent *)U)->url_data; + return ChrPtr(((urlcontent *)U)->url_data); else return (""); } -long LBstr(char *key, size_t keylen) +const StrBuf *SBSTR(const char *key) +{ + void *U; + + if ((WC->urlstrings != NULL) && + GetHash(WC->urlstrings, key, strlen (key), &U)) + return ((urlcontent *)U)->url_data; + else + return NULL; +} + +const StrBuf *SBstr(const char *key, size_t keylen) { void *U; if ((WC->urlstrings != NULL) && GetHash(WC->urlstrings, key, keylen, &U)) - return atol(((urlcontent *)U)->url_data); + return ((urlcontent *)U)->url_data; + else + return NULL; +} + +long LBstr(const char *key, size_t keylen) +{ + void *U; + + if ((WC->urlstrings != NULL) && + GetHash(WC->urlstrings, key, keylen, &U)) + return StrTol(((urlcontent *)U)->url_data); else return (0); } -long LBSTR(char *key) +long LBSTR(const char *key) { void *U; if ((WC->urlstrings != NULL) && GetHash(WC->urlstrings, key, strlen(key), &U)) - return atol(((urlcontent *)U)->url_data); + return StrTol(((urlcontent *)U)->url_data); else return (0); } -int IBstr(char *key, size_t keylen) +int IBstr(const char *key, size_t keylen) { void *U; if ((WC->urlstrings != NULL) && GetHash(WC->urlstrings, key, keylen, &U)) - return atoi(((urlcontent *)U)->url_data); + return StrTol(((urlcontent *)U)->url_data); else return (0); } -int IBSTR(char *key) +int IBSTR(const char *key) { void *U; if ((WC->urlstrings != NULL) && GetHash(WC->urlstrings, key, strlen(key), &U)) - return atoi(((urlcontent *)U)->url_data); + return StrToi(((urlcontent *)U)->url_data); else return (0); } -int HaveBstr(char *key, size_t keylen) +int HaveBstr(const char *key, size_t keylen) { void *U; if ((WC->urlstrings != NULL) && GetHash(WC->urlstrings, key, keylen, &U)) - return ((urlcontent *)U)->url_data_size != 0; + return (StrLength(((urlcontent *)U)->url_data) != 0); else return (0); } -int HAVEBSTR(char *key) +int HAVEBSTR(const char *key) { void *U; if ((WC->urlstrings != NULL) && GetHash(WC->urlstrings, key, strlen(key), &U)) - return ((urlcontent *)U)->url_data_size != 0; + return (StrLength(((urlcontent *)U)->url_data) != 0); else return (0); } -int YesBstr(char *key, size_t keylen) +int YesBstr(const char *key, size_t keylen) { void *U; if ((WC->urlstrings != NULL) && GetHash(WC->urlstrings, key, keylen, &U)) - return strcmp( ((urlcontent *)U)->url_data, "yes") == 0; + return strcmp( ChrPtr(((urlcontent *)U)->url_data), "yes") == 0; else return (0); } -int YESBSTR(char *key) +int YESBSTR(const char *key) { void *U; if ((WC->urlstrings != NULL) && GetHash(WC->urlstrings, key, strlen(key), &U)) - return strcmp( ((urlcontent *)U)->url_data, "yes") == 0; + return strcmp( ChrPtr(((urlcontent *)U)->url_data), "yes") == 0; else return (0); } @@ -324,14 +356,34 @@ int YESBSTR(char *key) */ void wprintf(const char *format,...) { + struct wcsession *WCC = WC; va_list arg_ptr; - char wbuf[4096]; + + if (WCC->WBuf == NULL) + WCC->WBuf = NewStrBuf(); va_start(arg_ptr, format); - vsnprintf(wbuf, sizeof wbuf, format, arg_ptr); + StrBufVAppendPrintf(WCC->WBuf, format, arg_ptr); va_end(arg_ptr); - client_write(wbuf, strlen(wbuf)); +/// if (StrLength(WCC-WBuf) > 2048) + ///client_write(wbuf, strlen(wbuf)); +} + +/* + * http-header-printing funcion. uses our vsnprintf wrapper + */ +void hprintf(const char *format,...) +{ + struct wcsession *WCC = WC; + va_list arg_ptr; + + va_start(arg_ptr, format); + StrBufVAppendPrintf(WCC->HBuf, format, arg_ptr); + va_end(arg_ptr); + +/// if (StrLength(WCC-WBuf) > 2048) + ///client_write(wbuf, strlen(wbuf)); } @@ -347,7 +399,7 @@ void wDumpContent(int print_standard_html_footer) { if (print_standard_html_footer) { wprintf("\n"); /* end of "text" div */ - do_template("trailing"); + do_template("trailing", NULL); } /* If we've been saving it all up for one big output burst, @@ -357,89 +409,89 @@ void wDumpContent(int print_standard_html_footer) } + /* * Copy a string, escaping characters which have meaning in HTML. * - * target target buffer - * strbuf source buffer - * nbsp If nonzero, spaces are converted to non-breaking spaces. - * nolinebreaks if set, linebreaks are removed from the string. + * target target buffer + * strbuf source buffer + * nbsp If nonzero, spaces are converted to non-breaking spaces. + * nolinebreaks if set, linebreaks are removed from the string. */ long stresc(char *target, long tSize, char *strbuf, int nbsp, int nolinebreaks) { - char *aptr, *bptr, *eptr; - - *target = '\0'; - aptr = strbuf; - bptr = target; - eptr = target + tSize - 6; // our biggest unit to put in... - - while ((bptr < eptr) && !IsEmptyStr(aptr) ){ - if (*aptr == '<') { - memcpy(bptr, "<", 4); - bptr += 4; - } - else if (*aptr == '>') { - memcpy(bptr, ">", 4); - bptr += 4; - } - else if (*aptr == '&') { - memcpy(bptr, "&", 5); - bptr += 5; - } - else if (*aptr == '\"') { - memcpy(bptr, """, 6); - bptr += 6; - } - else if (*aptr == '\'') { - memcpy(bptr, "'", 5); - bptr += 5; - } - else if (*aptr == LB) { - *bptr = '<'; - bptr ++; - } - else if (*aptr == RB) { - *bptr = '>'; - bptr ++; - } - else if (*aptr == QU) { - *bptr ='"'; - bptr ++; - } - else if ((*aptr == 32) && (nbsp == 1)) { - memcpy(bptr, " ", 6); - bptr += 6; - } - else if ((*aptr == '\n') && (nolinebreaks)) { - *bptr='\0'; /* nothing */ - } - else if ((*aptr == '\r') && (nolinebreaks)) { - *bptr='\0'; /* nothing */ - } - else{ - *bptr = *aptr; - bptr++; - } - aptr ++; - } - *bptr = '\0'; - if ((bptr = eptr - 1 ) && !IsEmptyStr(aptr) ) - return -1; - return (bptr - target); + char *aptr, *bptr, *eptr; + + *target = '\0'; + aptr = strbuf; + bptr = target; + eptr = target + tSize - 6; // our biggest unit to put in... + + + while ((bptr < eptr) && !IsEmptyStr(aptr) ){ + if (*aptr == '<') { + memcpy(bptr, "<", 4); + bptr += 4; + } + else if (*aptr == '>') { + memcpy(bptr, ">", 4); + bptr += 4; + } + else if (*aptr == '&') { + memcpy(bptr, "&", 5); + bptr += 5; + } + else if (*aptr == '\"') { + memcpy(bptr, """, 6); + bptr += 6; + } + else if (*aptr == '\'') { + memcpy(bptr, "'", 5); + bptr += 5; + } + else if (*aptr == LB) { + *bptr = '<'; + bptr ++; + } + else if (*aptr == RB) { + *bptr = '>'; + bptr ++; + } + else if (*aptr == QU) { + *bptr ='"'; + bptr ++; + } + else if ((*aptr == 32) && (nbsp == 1)) { + memcpy(bptr, " ", 6); + bptr += 6; + } + else if ((*aptr == '\n') && (nolinebreaks)) { + *bptr='\0'; /* nothing */ + } + else if ((*aptr == '\r') && (nolinebreaks)) { + *bptr='\0'; /* nothing */ + } + else{ + *bptr = *aptr; + bptr++; + } + aptr ++; + } + *bptr = '\0'; + if ((bptr = eptr - 1 ) && !IsEmptyStr(aptr) ) + return -1; + return (bptr - target); } + void escputs1(char *strbuf, int nbsp, int nolinebreaks) { - char *buf; - long Siz; + StrEscAppend(WC->WBuf, NULL, strbuf, nbsp, nolinebreaks); +} - if (strbuf == NULL) return; - Siz = (3 * strlen(strbuf)) + SIZ ; - buf = malloc(Siz); - stresc(buf, Siz, strbuf, nbsp, nolinebreaks); - wprintf("%s", buf); - free(buf); +void StrEscputs1(const StrBuf *strbuf, int nbsp, int nolinebreaks) +{ + StrEscAppend(WC->WBuf, strbuf, NULL, nbsp, nolinebreaks); } /* @@ -451,15 +503,37 @@ void escputs(char *strbuf) } +/* + * static wrapper for ecsputs1 + */ +void StrEscPuts(const StrBuf *strbuf) +{ + StrEscputs1(strbuf, 0, 0); +} + + /* * urlescape buffer and print it to the client */ -void urlescputs(char *strbuf) +void urlescputs(const char *strbuf) { - char outbuf[SIZ]; - - urlesc(outbuf, SIZ, strbuf); - wprintf("%s", outbuf); + StrBufUrlescAppend(WC->WBuf, NULL, strbuf); +} + +/* + * urlescape buffer and print it to the client + */ +void UrlescPutStrBuf(const StrBuf *strbuf) +{ + StrBufUrlescAppend(WC->WBuf, strbuf, NULL); +} + +/** + * urlescape buffer and print it as header + */ +void hurlescputs(const char *strbuf) +{ + StrBufUrlescAppend(WC->HBuf, NULL, strbuf); } @@ -532,81 +606,26 @@ void jsescputs(char *strbuf) wprintf("%s", outbuf); } -/* - * Copy a string, escaping characters for message text hold - */ -void msgesc(char *target, size_t tlen, char *strbuf) -{ - int len; - char *tend; - char *send; - char *tptr; - char *sptr; - - target[0]='\0'; - len = strlen (strbuf); - send = strbuf + len; - tend = target + tlen; - sptr = strbuf; - tptr = target; - - while (!IsEmptyStr(sptr) && - (sptr < send) && - (tptr < tend)) { - - if (*sptr == '\n') - *tptr = ' '; - else if (*sptr == '\r') - *tptr = ' '; - else if (*sptr == '\'') { - if (tend - tptr < 8) - return; - *(tptr++) = '&'; - *(tptr++) = '#'; - *(tptr++) = '3'; - *(tptr++) = '9'; - *tptr = ';'; - } else { - *tptr = *sptr; - } - tptr++; sptr++; - } - *tptr = '\0'; -} - /* * print a string to the client after cleaning it with msgesc() and stresc() */ void msgescputs1( char *strbuf) { - char *outbuf; - char *outbuf2; - int buflen; + StrBuf *OutBuf = NewStrBuf(); - if (strbuf == NULL) return; - buflen = 3 * strlen(strbuf) + SIZ; - outbuf = malloc( buflen); - outbuf2 = malloc( buflen); - msgesc(outbuf, buflen, strbuf); - stresc(outbuf2, buflen, outbuf, 0, 0); - wprintf("%s", outbuf2); - free(outbuf); - free(outbuf2); + if ((strbuf == NULL) || IsEmptyStr(strbuf)) + return; + StrMsgEscAppend(OutBuf, NULL, strbuf); + StrEscAppend(WC->WBuf, OutBuf, NULL, 0, 0); + FreeStrBuf(&OutBuf); } /* * print a string to the client after cleaning it with msgesc() */ void msgescputs(char *strbuf) { - char *outbuf; - size_t len; - - if (strbuf == NULL) return; - len = (3 * strlen(strbuf)) + SIZ; - outbuf = malloc(len); - msgesc(outbuf, len, strbuf); - wprintf("%s", outbuf); - free(outbuf); + if ((strbuf != NULL) && !IsEmptyStr(strbuf)) + StrMsgEscAppend(WC->WBuf, NULL, strbuf); } @@ -630,11 +649,11 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers char cookie[1024]; char httpnow[128]; - wprintf("HTTP/1.1 200 OK\n"); + hprintf("HTTP/1.1 200 OK\n"); http_datestring(httpnow, sizeof httpnow, time(NULL)); if (do_httpheaders) { - wprintf("Content-type: text/html; charset=utf-8\r\n" + hprintf("Content-type: text/html; charset=utf-8\r\n" "Server: %s / %s\n" "Connection: close\r\n", PACKAGE_STRING, serv_info.serv_software @@ -647,7 +666,7 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers http_datestring(httpTomorow, sizeof httpTomorow, time(NULL) + 60 * 60 * 24 * 2); - wprintf("Pragma: public\r\n" + hprintf("Pragma: public\r\n" "Cache-Control: max-age=3600, must-revalidate\r\n" "Last-modified: %s\r\n" "Expires: %s\r\n", @@ -656,7 +675,7 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers ); } else { - wprintf("Pragma: no-cache\r\n" + hprintf("Pragma: no-cache\r\n" "Cache-Control: no-store\r\n" "Expires: -1\r\n" ); @@ -666,11 +685,11 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers WC->wc_password, WC->wc_roomname); if (unset_cookies) { - wprintf("Set-cookie: webcit=%s; path=/\r\n", unset); + hprintf("Set-cookie: webcit=%s; path=/\r\n", unset); } else { - wprintf("Set-cookie: webcit=%s; path=/\r\n", cookie); + hprintf("Set-cookie: webcit=%s; path=/\r\n", cookie); if (server_cookie != NULL) { - wprintf("%s\n", server_cookie); + hprintf("%s\n", server_cookie); } } @@ -681,12 +700,12 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers "" ); } - do_template("head"); + do_template("head", NULL); } /* ICONBAR */ if (do_htmlhead) { - + begin_burst(); /* check for ImportantMessages (these display in a div overlaying the main screen) */ if (!IsEmptyStr(WC->ImportantMessage)) { @@ -726,13 +745,14 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers * Generic function to do an HTTP redirect. Easy and fun. */ void http_redirect(const char *whichpage) { - wprintf("HTTP/1.1 302 Moved Temporarily\n"); - wprintf("Location: %s\r\n", whichpage); - wprintf("URI: %s\r\n", whichpage); - wprintf("Content-type: text/html; charset=utf-8\r\n\r\n"); + hprintf("HTTP/1.1 302 Moved Temporarily\n"); + hprintf("Location: %s\r\n", whichpage); + hprintf("URI: %s\r\n", whichpage); + hprintf("Content-type: text/html; charset=utf-8\r\n"); wprintf(""); wprintf("Go here.", whichpage); wprintf("\n"); + end_burst(); } @@ -740,48 +760,18 @@ void http_redirect(const char *whichpage) { /* * Output a piece of content to the web browser using conformant HTTP and MIME semantics */ -void http_transmit_thing(char *thing, size_t length, const char *content_type, +void http_transmit_thing(const char *content_type, int is_static) { output_headers(0, 0, 0, 0, 0, is_static); - wprintf("Content-type: %s\r\n" + hprintf("Content-type: %s\r\n" "Server: %s\r\n" "Connection: close\r\n", content_type, PACKAGE_STRING); -#ifdef HAVE_ZLIB - /* If we can send the data out compressed, please do so. */ - if (WC->gzip_ok) { - char *compressed_data = NULL; - size_t compressed_len; - - compressed_len = ((length * 101) / 100) + 100; - compressed_data = malloc(compressed_len); - - if (compress_gzip((Bytef *) compressed_data, - &compressed_len, - (Bytef *) thing, - (uLongf) length, Z_BEST_SPEED) == Z_OK) { - wprintf("Content-encoding: gzip\r\n" - "Content-length: %ld\r\n" - "\r\n", - (long) compressed_len - ); - client_write(compressed_data, (size_t)compressed_len); - free(compressed_data); - return; - } - } -#endif - - /* No compression ... just send it out as-is */ - wprintf("Content-length: %ld\r\n" - "\r\n", - (long) length - ); - client_write(thing, (size_t)length); + end_burst(); } /* @@ -798,7 +788,7 @@ void print_menu_box(char* Title, char *Class, int nLines, ...) long i; svput("BOXTITLE", WCS_STRING, Title); - do_template("beginbox"); + do_template("beginbox", NULL); wprintf(""); - do_template("endbox"); + do_template("endbox", NULL); } @@ -824,60 +814,51 @@ void print_menu_box(char* Title, char *Class, int nLines, ...) */ void output_static(char *what) { - FILE *fp; + int fd; struct stat statbuf; off_t bytes; off_t count = 0; - size_t res; - char *bigbuffer; const char *content_type; int len; + const char *Err; - fp = fopen(what, "rb"); - if (fp == NULL) { + fd = open(what, O_RDONLY); + if (fd <= 0) { lprintf(9, "output_static('%s') -- NOT FOUND --\n", what); - wprintf("HTTP/1.1 404 %s\r\n", strerror(errno)); - wprintf("Content-Type: text/plain\r\n"); - wprintf("\r\n"); + hprintf("HTTP/1.1 404 %s\r\n", strerror(errno)); + hprintf("Content-Type: text/plain\r\n"); wprintf("Cannot open %s: %s\r\n", what, strerror(errno)); + end_burst(); } else { len = strlen (what); content_type = GuessMimeByFilename(what, len); - if (fstat(fileno(fp), &statbuf) == -1) { + if (fstat(fd, &statbuf) == -1) { lprintf(9, "output_static('%s') -- FSTAT FAILED --\n", what); - wprintf("HTTP/1.1 404 %s\r\n", strerror(errno)); - wprintf("Content-Type: text/plain\r\n"); - wprintf("\r\n"); + hprintf("HTTP/1.1 404 %s\r\n", strerror(errno)); + hprintf("Content-Type: text/plain\r\n"); wprintf("Cannot fstat %s: %s\n", what, strerror(errno)); + end_burst(); return; } count = 0; bytes = statbuf.st_size; - if ((bigbuffer = malloc(bytes + 2)) == NULL) { - lprintf(9, "output_static('%s') -- MALLOC FAILED (%s) --\n", what, strerror(errno)); - wprintf("HTTP/1.1 500 internal server error\r\n"); - wprintf("Content-Type: text/plain\r\n"); - wprintf("\r\n"); - return; - } - while (count < bytes) { - if ((res = fread(bigbuffer + count, 1, bytes - count, fp)) == 0) { - lprintf(9, "output_static('%s') -- FREAD FAILED (%s) %zu bytes of %zu --\n", what, strerror(errno), bytes - count, bytes); - wprintf("HTTP/1.1 500 internal server error \r\n"); - wprintf("Content-Type: text/plain\r\n"); - wprintf("\r\n"); + + if (StrBufReadBLOB(WC->WBuf, &fd, 1, bytes, &Err) < 0) + { + if (fd > 0) close(fd); + lprintf(9, "output_static('%s') -- FREAD FAILED (%s) --\n", what, strerror(errno)); + hprintf("HTTP/1.1 500 internal server error \r\n"); + hprintf("Content-Type: text/plain\r\n"); + end_burst(); return; - } - count += res; } - fclose(fp); + close(fd); lprintf(9, "output_static('%s') %s\n", what, content_type); - http_transmit_thing(bigbuffer, (size_t)bytes, content_type, 1); - free(bigbuffer); + http_transmit_thing(content_type, 1); } if (yesbstr("force_close_session")) { end_webcit_session(); @@ -890,35 +871,31 @@ void output_static(char *what) */ void output_image() { + struct wcsession *WCC = WC; char buf[SIZ]; - char *xferbuf = NULL; off_t bytes; const char *MimeType; - + serv_printf("OIMG %s|%s", bstr("name"), bstr("parm")); serv_getln(buf, sizeof buf); if (buf[0] == '2') { bytes = extract_long(&buf[4], 0); - xferbuf = malloc(bytes + 2); /** Read it from the server */ - read_server_binary(xferbuf, bytes); - serv_puts("CLOS"); - serv_getln(buf, sizeof buf); - - MimeType = GuessMimeType (xferbuf, bytes); - /** Write it to the browser */ - if (!IsEmptyStr(MimeType)) - { - http_transmit_thing(xferbuf, - (size_t)bytes, - MimeType, - 0); - free(xferbuf); - return; + + if (read_server_binary(WCC->WBuf, bytes) > 0) { + serv_puts("CLOS"); + serv_getln(buf, sizeof buf); + + MimeType = GuessMimeType (ChrPtr(WCC->WBuf), StrLength(WCC->WBuf)); + /** Write it to the browser */ + if (!IsEmptyStr(MimeType)) + { + http_transmit_thing(MimeType, 0); + return; + } } /* hm... unknown mimetype? fallback to blank gif */ - free(xferbuf); } @@ -934,37 +911,37 @@ void output_image() /* * Extract an embedded photo from a vCard for display on the client */ -void display_vcard_photo_img(char *msgnum_as_string) +void display_vcard_photo_img(void) { long msgnum = 0L; char *vcard; struct vCard *v; - char *xferbuf; - char *photosrc; - int decoded; + char *photosrc; const char *contentType; + struct wcsession *WCC = WC; - msgnum = atol(msgnum_as_string); + msgnum = StrTol(WCC->UrlFragment1); vcard = load_mimepart(msgnum,"1"); v = vcard_load(vcard); photosrc = vcard_get_prop(v, "PHOTO", 1,0,0); - xferbuf = malloc(strlen(photosrc)); - if (xferbuf == NULL) { - lprintf(5, "xferbuf malloc failed\n"); + FlushStrBuf(WCC->WBuf); + StrBufAppendBufPlain(WCC->WBuf, photosrc, -1, 0); + if (StrBufDecodeBase64(WCC->WBuf) <= 0) { + FlushStrBuf(WCC->WBuf); + + hprintf("HTTP/1.1 500 %s\n","Unable to get photo"); + output_headers(0, 0, 0, 0, 0, 0); + hprintf("Content-Type: text/plain\r\n"); + wprintf(_("Could Not decode vcard photo\n")); + end_burst(); return; } - memset(xferbuf, 1, SIZ); - decoded = CtdlDecodeBase64( - xferbuf, - photosrc, - strlen(photosrc)); - contentType = GuessMimeType(xferbuf, decoded); - http_transmit_thing(xferbuf, decoded, contentType, 0); + contentType = GuessMimeType(ChrPtr(WCC->WBuf), StrLength(WCC->WBuf)); + http_transmit_thing(contentType, 0); free(v); free(photosrc); - free(xferbuf); } /* @@ -975,18 +952,16 @@ void display_vcard_photo_img(char *msgnum_as_string) * partnum The MIME part to be output * force_download Nonzero to force set the Content-Type: header to "application/octet-stream" */ -void mimepart(char *msgnum, char *partnum, int force_download) +void mimepart(const char *msgnum, const char *partnum, int force_download) { char buf[256]; off_t bytes; char content_type[256]; - char *content = NULL; serv_printf("OPNA %s|%s", msgnum, partnum); serv_getln(buf, sizeof buf); if (buf[0] == '2') { bytes = extract_long(&buf[4], 0); - content = malloc(bytes + 2); if (force_download) { strcpy(content_type, "application/octet-stream"); } @@ -994,19 +969,18 @@ void mimepart(char *msgnum, char *partnum, int force_download) extract_token(content_type, &buf[4], 3, '|', sizeof content_type); } output_headers(0, 0, 0, 0, 0, 0); - read_server_binary(content, bytes); + + read_server_binary(WC->WBuf, bytes); serv_puts("CLOS"); serv_getln(buf, sizeof buf); - http_transmit_thing(content, bytes, content_type, 0); - free(content); + http_transmit_thing(content_type, 0); } else { - wprintf("HTTP/1.1 404 %s\n", &buf[4]); + hprintf("HTTP/1.1 404 %s\n", &buf[4]); output_headers(0, 0, 0, 0, 0, 0); - wprintf("Content-Type: text/plain\r\n"); - wprintf("\r\n"); + hprintf("Content-Type: text/plain\r\n"); wprintf(_("An error occurred while retrieving this part: %s\n"), &buf[4]); + end_burst(); } - } @@ -1035,7 +1009,6 @@ char *load_mimepart(long msgnum, char *partnum) else { return(NULL); } - } @@ -1048,7 +1021,7 @@ char *load_mimepart(long msgnum, char *partnum) */ void convenience_page(char *titlebarcolor, char *titlebarmsg, char *messagetext) { - wprintf("HTTP/1.1 200 OK\n"); + hprintf("HTTP/1.1 200 OK\n"); output_headers(1, 1, 2, 0, 0, 0); wprintf("
\n"); wprintf("
", titlebarcolor); @@ -1075,7 +1048,11 @@ void blank_page(void) { * A template has been requested */ void url_do_template(void) { - do_template(bstr("template")); + const StrBuf *Tmpl = sbstr("template"); + begin_burst(); + output_headers(1, 0, 0, 0, 1, 0); + DoTemplate(ChrPtr(Tmpl), StrLength(Tmpl), NULL, NULL); + end_burst(); } @@ -1115,7 +1092,7 @@ void change_start_page(void) { set_preference("startpage", NewStrBufPlain(bstr("startpage"), -1), 1); output_headers(1, 1, 0, 0, 0, 0); - do_template("newstartpage"); + do_template("newstartpage", NULL); wDumpContent(1); } @@ -1136,15 +1113,16 @@ void display_success(char *successmessage) */ void authorization_required(const char *message) { - wprintf("HTTP/1.1 401 Authorization Required\r\n"); - wprintf("WWW-Authenticate: Basic realm=\"%s\"\r\n", serv_info.serv_humannode); - wprintf("Content-Type: text/html\r\n\r\n"); + hprintf("HTTP/1.1 401 Authorization Required\r\n"); + hprintf("WWW-Authenticate: Basic realm=\"%s\"\r\n", serv_info.serv_humannode); + hprintf("Content-Type: text/html\r\n"); wprintf("

"); wprintf(_("Authorization Required")); wprintf("

\r\n"); wprintf(_("The resource you requested requires a valid username and password. " "You could not be logged in: %s\n"), message); wDumpContent(0); + } /* @@ -1179,10 +1157,8 @@ void upload_handler(char *name, char *filename, char *partnum, char *disp, u = (urlcontent *) malloc(sizeof(urlcontent)); safestrncpy(u->url_key, name, sizeof(u->url_key)); - u->url_data = malloc(length + 1); - u->url_data_size = length; - memcpy(u->url_data, content, length); - u->url_data[length] = 0; + u->url_data = NewStrBufPlain(content, length); + Put(WC->urlstrings, u->url_key, strlen(u->url_key), u, free_url); #ifdef DEBUG_URLSTRINGS lprintf(9, "Key: <%s> len: [%ld] Data: <%s>\n", u->url_key, u->url_data_size, u->url_data); @@ -1211,14 +1187,14 @@ void upload_handler(char *name, char *filename, char *partnum, char *disp, * Convenience functions to wrap around asynchronous ajax responses */ void begin_ajax_response(void) { + struct wcsession *WCC = WC; + + FlushStrBuf(WCC->HBuf); output_headers(0, 0, 0, 0, 0, 0); - wprintf("Content-type: text/html; charset=UTF-8\r\n" + hprintf("Content-type: text/html; charset=UTF-8\r\n" "Server: %s\r\n" "Connection: close\r\n" - "Pragma: no-cache\r\n" - "Cache-Control: no-cache\r\n" - "Expires: -1\r\n" , PACKAGE_STRING); begin_burst(); @@ -1228,7 +1204,7 @@ void begin_ajax_response(void) { * print ajax response footer */ void end_ajax_response(void) { - wprintf("\r\n"); + ///hprintf("\r\n");///// todo: is this right? wDumpContent(0); } @@ -1297,7 +1273,6 @@ void seconds_since_last_gexp(void) { char buf[256]; - begin_ajax_response(); if ( (time(NULL) - WC->last_pager_check) < 30) { wprintf("NO\n"); } @@ -1311,21 +1286,25 @@ void seconds_since_last_gexp(void) wprintf("NO"); } } - end_ajax_response(); } /** * \brief Detects a 'mobile' user agent */ int is_mobile_ua(char *user_agent) { - if (strstr(user_agent,"iPhone OS") != NULL) { - return 1; - } else if (strstr(user_agent,"Windows CE") != NULL) { - return 1; - } else if (strstr(user_agent,"SymbianOS") != NULL) { - return 1; - } - return 0; + if (strstr(user_agent,"iPhone OS") != NULL) { + return 1; + } else if (strstr(user_agent,"Windows CE") != NULL) { + return 1; + } else if (strstr(user_agent,"SymbianOS") != NULL) { + return 1; + } else if (strstr(user_agent, "Opera Mobi") != NULL) { + return 1; + } else if (strstr(user_agent, "Firefox/2.0.0 Opera 9.51 Beta") != NULL) { + // For some reason a new install of Opera 9.51beta decided to spoof. + return 1; + } + return 0; } @@ -1365,7 +1344,8 @@ void session_loop(struct httprequest *req) char c_httpauth_user[SIZ]; char c_httpauth_pass[SIZ]; char cookie[SIZ]; - + struct wcsession *WCC; + safestrncpy(c_username, "", sizeof c_username); safestrncpy(c_password, "", sizeof c_password); safestrncpy(c_roomname, "", sizeof c_roomname); @@ -1374,9 +1354,18 @@ void session_loop(struct httprequest *req) safestrncpy(c_httpauth_pass, DEFAULT_HTTPAUTH_PASS, sizeof c_httpauth_pass); strcpy(browser_host, ""); - WC->upload_length = 0; - WC->upload = NULL; - WC->is_mobile = 0; + WCC= WC; + if (WCC->WBuf == NULL) + WC->WBuf = NewStrBufPlain(NULL, 32768); + FlushStrBuf(WCC->WBuf); + + if (WCC->HBuf == NULL) + WCC->HBuf = NewStrBuf(); + FlushStrBuf(WCC->HBuf); + + WCC->upload_length = 0; + WCC->upload = NULL; + WCC->is_mobile = 0; hptr = req; if (hptr == NULL) return; @@ -1434,18 +1423,20 @@ void session_loop(struct httprequest *req) } else if (!strncasecmp(buf, "User-agent: ", 12)) { safestrncpy(user_agent, &buf[12], sizeof user_agent); + #ifdef TECH_PREVIEW if (is_mobile_ua(&buf[12])) { - WC->is_mobile = 1; + WCC->is_mobile = 1; } + #endif } else if (!strncasecmp(buf, "X-Forwarded-Host: ", 18)) { if (follow_xff) { - safestrncpy(WC->http_host, &buf[18], sizeof WC->http_host); + safestrncpy(WCC->http_host, &buf[18], sizeof WCC->http_host); } } else if (!strncasecmp(buf, "Host: ", 6)) { - if (IsEmptyStr(WC->http_host)) { - safestrncpy(WC->http_host, &buf[6], sizeof WC->http_host); + if (IsEmptyStr(WCC->http_host)) { + safestrncpy(WCC->http_host, &buf[6], sizeof WCC->http_host); } } else if (!strncasecmp(buf, "X-Forwarded-For: ", 17)) { @@ -1464,15 +1455,24 @@ void session_loop(struct httprequest *req) content = malloc(BuffSize); memset(content, 0, BuffSize); snprintf(content, BuffSize, "Content-type: %s\n" - "Content-length: %d\n\n", - ContentType, ContentLength); + "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. */ - client_read(WC->http_sock, &content[body_start], ContentLength); + client_read(&WCC->http_sock, &content[body_start], ContentLength); if (!strncasecmp(ContentType, "application/x-www-form-urlencoded", 33)) { - addurls(&content[body_start], ContentLength); + StrBuf *Content; + + Content = _NewConstStrBuf(&content[body_start],ContentLength); + addurls(Content); + FreeStrBuf(&Content); } else if (!strncasecmp(ContentType, "multipart", 9)) { content_end = content + ContentLength + body_start; mime_parser(content, content_end, *upload_handler, NULL, NULL, NULL, 0); @@ -1482,21 +1482,25 @@ void session_loop(struct httprequest *req) } /* make a note of where we are in case the user wants to save it */ - safestrncpy(WC->this_page, cmd, sizeof(WC->this_page)); - remove_token(WC->this_page, 2, ' '); - remove_token(WC->this_page, 0, ' '); + safestrncpy(WCC->this_page, cmd, sizeof(WCC->this_page)); + remove_token(WCC->this_page, 2, ' '); + remove_token(WCC->this_page, 0, ' '); /* If there are variables in the URL, we must grab them now */ len = strlen(cmd); for (a = 0; a < len; ++a) { if ((cmd[a] == '?') || (cmd[a] == '&')) { + StrBuf *Params; for (b = a; b < len; ++b) { if (isspace(cmd[b])){ cmd[b] = 0; len = b - 1; } } - addurls(&cmd[a + 1], len - a); + //cmd[len - a] = '\0'; + Params = _NewConstStrBuf(&cmd[a + 1], len - a); + addurls(Params); + FreeStrBuf(&Params); cmd[a] = 0; len = a - 1; } @@ -1504,10 +1508,10 @@ void session_loop(struct httprequest *req) /* If it's a "force 404" situation then display the error and bail. */ if (!strcmp(action, "404")) { - wprintf("HTTP/1.1 404 Not found\r\n"); - wprintf("Content-Type: text/plain\r\n"); - wprintf("\r\n"); + hprintf("HTTP/1.1 404 Not found\r\n"); + hprintf("Content-Type: text/plain\r\n"); wprintf("Not found\r\n"); + end_burst(); goto SKIP_ALL_THIS_CRAP; } @@ -1540,10 +1544,10 @@ void session_loop(struct httprequest *req) else { lprintf(9, "Suspicious request. Ignoring."); - wprintf("HTTP/1.1 404 Security check failed\r\n"); - wprintf("Content-Type: text/plain\r\n"); - wprintf("\r\n"); + hprintf("HTTP/1.1 404 Security check failed\r\n"); + hprintf("Content-Type: text/plain\r\n"); wprintf("You have sent a malformed or invalid request.\r\n"); + end_burst(); } goto SKIP_ALL_THIS_CRAP; /* Don't try to connect */ } @@ -1551,13 +1555,13 @@ void session_loop(struct httprequest *req) /* If the client sent a nonce that is incorrect, kill the request. */ if (strlen(bstr("nonce")) > 0) { lprintf(9, "Comparing supplied nonce %s to session nonce %ld\n", - bstr("nonce"), WC->nonce); - if (ibstr("nonce") != WC->nonce) { + bstr("nonce"), WCC->nonce); + if (ibstr("nonce") != WCC->nonce) { lprintf(9, "Ignoring request with mismatched nonce.\n"); - wprintf("HTTP/1.1 404 Security check failed\r\n"); - wprintf("Content-Type: text/plain\r\n"); - wprintf("\r\n"); + hprintf("HTTP/1.1 404 Security check failed\r\n"); + hprintf("Content-Type: text/plain\r\n"); wprintf("Security check failed.\r\n"); + end_burst(); goto SKIP_ALL_THIS_CRAP; } } @@ -1566,23 +1570,23 @@ void session_loop(struct httprequest *req) * If we're not connected to a Citadel server, try to hook up the * connection now. */ - if (!WC->connected) { + if (!WCC->connected) { if (!strcasecmp(ctdlhost, "uds")) { /* unix domain socket */ snprintf(buf, SIZ, "%s/citadel.socket", ctdlport); - WC->serv_sock = uds_connectsock(buf); + WCC->serv_sock = uds_connectsock(buf); } else { /* tcp socket */ - WC->serv_sock = tcp_connectsock(ctdlhost, ctdlport); + WCC->serv_sock = tcp_connectsock(ctdlhost, ctdlport); } - if (WC->serv_sock < 0) { + if (WCC->serv_sock < 0) { do_logout(); goto SKIP_ALL_THIS_CRAP; } else { - WC->connected = 1; + WCC->connected = 1; serv_getln(buf, sizeof buf); /** get the server welcome message */ /** @@ -1592,7 +1596,7 @@ void session_loop(struct httprequest *req) * and such a header has already turned up something. */ if ( (!follow_xff) || (strlen(browser_host) == 0) ) { - locate_host(browser_host, WC->http_sock); + locate_host(browser_host, WCC->http_sock); } get_serv_info(browser_host, user_agent); @@ -1612,7 +1616,7 @@ void session_loop(struct httprequest *req) } } } - +////////todo: restorte language in this case /* * Functions which can be performed without logging in */ @@ -1629,7 +1633,7 @@ void session_loop(struct httprequest *req) * If we're not logged in, but we have HTTP Authentication data, * try logging in to Citadel using that. */ - if ((!WC->logged_in) + if ((!WCC->logged_in) && (strlen(c_httpauth_user) > 0) && (strlen(c_httpauth_pass) > 0)) { serv_printf("USER %s", c_httpauth_user); @@ -1640,8 +1644,8 @@ void session_loop(struct httprequest *req) if (buf[0] == '2') { become_logged_in(c_httpauth_user, c_httpauth_pass, buf); - safestrncpy(WC->httpauth_user, c_httpauth_user, sizeof WC->httpauth_user); - safestrncpy(WC->httpauth_pass, c_httpauth_pass, sizeof WC->httpauth_pass); + safestrncpy(WCC->httpauth_user, c_httpauth_user, sizeof WCC->httpauth_user); + safestrncpy(WCC->httpauth_pass, c_httpauth_pass, sizeof WCC->httpauth_pass); } else { /* Should only display when password is wrong */ authorization_required(&buf[4]); @@ -1665,8 +1669,8 @@ void session_loop(struct httprequest *req) if (!strncasecmp(action, "groupdav", 8)) { groupdav_main(req, ContentType, /* do GroupDAV methods */ ContentLength, content+body_start); - if (!WC->logged_in) { - WC->killthis = 1; /* If not logged in, don't */ + if (!WCC->logged_in) { + WCC->killthis = 1; /* If not logged in, don't */ } /* keep the session active */ goto SKIP_ALL_THIS_CRAP; } @@ -1679,8 +1683,8 @@ void session_loop(struct httprequest *req) if ((strcasecmp(request_method, "GET")) && (strcasecmp(request_method, "POST"))) { groupdav_main(req, ContentType, /** do GroupDAV methods */ ContentLength, content+body_start); - if (!WC->logged_in) { - WC->killthis = 1; /** If not logged in, don't */ + if (!WCC->logged_in) { + WCC->killthis = 1; /** If not logged in, don't */ } /** keep the session active */ goto SKIP_ALL_THIS_CRAP; } @@ -1689,7 +1693,7 @@ void session_loop(struct httprequest *req) * If we're not logged in, but we have username and password cookies * supplied by the browser, try using them to log in. */ - if ((!WC->logged_in) + if ((!WCC->logged_in) && (!IsEmptyStr(c_username)) && (!IsEmptyStr(c_password))) { serv_printf("USER %s", c_username); @@ -1698,7 +1702,12 @@ void session_loop(struct httprequest *req) serv_printf("PASS %s", c_password); serv_getln(buf, sizeof buf); if (buf[0] == '2') { + StrBuf *Lang; become_logged_in(c_username, c_password, buf); + if (get_preference("language", &Lang)) { + set_selected_language(ChrPtr(Lang)); + go_selected_language(); /* set locale */ + } } } } @@ -1706,11 +1715,11 @@ void session_loop(struct httprequest *req) * If we don't have a current room, but a cookie specifying the * current room is supplied, make an effort to go there. */ - if ((IsEmptyStr(WC->wc_roomname)) && (!IsEmptyStr(c_roomname))) { + if ((IsEmptyStr(WCC->wc_roomname)) && (!IsEmptyStr(c_roomname))) { serv_printf("GOTO %s", c_roomname); serv_getln(buf, sizeof buf); if (buf[0] == '2') { - safestrncpy(WC->wc_roomname, c_roomname, sizeof WC->wc_roomname); + safestrncpy(WCC->wc_roomname, c_roomname, sizeof WCC->wc_roomname); } } @@ -1718,392 +1727,39 @@ void session_loop(struct httprequest *req) output_image(); } else if (!strcasecmp(action, "display_mime_icon")) { display_mime_icon(); - - /* - * All functions handled below this point ... make sure we log in - * before doing anything else! - */ - } else if ((!WC->logged_in) && (!strcasecmp(action, "login"))) { - do_login(); - } else if ((!WC->logged_in) && (!strcasecmp(action, "display_openid_login"))) { - display_openid_login(NULL); - } else if ((!WC->logged_in) && (!strcasecmp(action, "openid_login"))) { - do_openid_login(); - } else if (!strcasecmp(action, "finalize_openid_login")) { - finalize_openid_login(); - } else if (!strcasecmp(action, "openid_manual_create")) { - openid_manual_create(); - } else if (!WC->logged_in) { - display_login(NULL); } - - /* - * Various commands... - */ - else { void *vHandler; WebcitHandler *Handler; - + GetHash(HandlerHash, action, strlen(action) /* TODO*/, &vHandler), Handler = (WebcitHandler*) vHandler; if (Handler != NULL) { - if (Handler->IsAjax) - begin_ajax_response(); - Handler->F(); - if (Handler->IsAjax) - end_ajax_response(); - } - - - else if (!strcasecmp(action, "do_welcome")) { - do_welcome(); - } else if (!strcasecmp(action, "blank")) { - blank_page(); - } else if (!strcasecmp(action, "do_template")) { - url_do_template(); - } else if (!strcasecmp(action, "display_aide_menu")) { - display_aide_menu(); - } else if (!strcasecmp(action, "server_shutdown")) { - display_shutdown(); - } else if (!strcasecmp(action, "display_main_menu")) { - display_main_menu(); - } else if (!strcasecmp(action, "who")) { - who(); - } else if (!strcasecmp(action, "sslg")) { - seconds_since_last_gexp(); - } else if (!strcasecmp(action, "who_inner_html")) { - begin_ajax_response(); - who_inner_div(); - end_ajax_response(); - } else if (!strcasecmp(action, "wholist_section")) { - begin_ajax_response(); - wholist_section(); - end_ajax_response(); - } else if (!strcasecmp(action, "new_messages_html")) { - begin_ajax_response(); - new_messages_section(); - end_ajax_response(); - } else if (!strcasecmp(action, "tasks_inner_html")) { - begin_ajax_response(); - tasks_section(); - end_ajax_response(); - } else if (!strcasecmp(action, "calendar_inner_html")) { - begin_ajax_response(); - calendar_section(); - end_ajax_response(); - } else if (!strcasecmp(action, "mini_calendar")) { - begin_ajax_response(); - ajax_mini_calendar(); - end_ajax_response(); - } else if (!strcasecmp(action, "iconbar_ajax_menu")) { - begin_ajax_response(); - do_iconbar(); - end_ajax_response(); - } else if (!strcasecmp(action, "iconbar_ajax_rooms")) { - begin_ajax_response(); - do_iconbar_roomlist(); - end_ajax_response(); - } else if (!strcasecmp(action, "knrooms")) { - knrooms(); - } else if (!strcasecmp(action, "gotonext")) { - slrp_highest(); - gotonext(); - } else if (!strcasecmp(action, "skip")) { - gotonext(); - } else if (!strcasecmp(action, "ungoto")) { - ungoto(); - } else if (!strcasecmp(action, "dotgoto")) { - if (WC->wc_view != VIEW_MAILBOX) { /* dotgoto acts like dotskip when we're in a mailbox view */ - slrp_highest(); + if (!WCC->logged_in && ((Handler->Flags & ANONYMOUS) == 0)) { + display_login(NULL); + } + else { + if((Handler->Flags & NEED_URL)) { + if (WCC->UrlFragment1 == NULL) + WCC->UrlFragment1 = NewStrBuf(); + if (WCC->UrlFragment2 == NULL) + WCC->UrlFragment2 = NewStrBuf(); + StrBufPrintf(WCC->UrlFragment1, "%s", index[1]); + StrBufPrintf(WCC->UrlFragment2, "%s", index[2]); + } + if ((Handler->Flags & AJAX) != 0) + begin_ajax_response(); + Handler->F(); + if ((Handler->Flags & AJAX) != 0) + end_ajax_response(); + } } - smart_goto(bstr("room")); - } else if (!strcasecmp(action, "dotskip")) { - smart_goto(bstr("room")); - } else if (!strcasecmp(action, "termquit")) { - do_logout(); - } else if (!strcasecmp(action, "readnew")) { - readloop("readnew"); - } else if (!strcasecmp(action, "readold")) { - readloop("readold"); - } else if (!strcasecmp(action, "readfwd")) { - readloop("readfwd"); - } else if (!strcasecmp(action, "headers")) { - readloop("headers"); - } else if (!strcasecmp(action, "do_search")) { - readloop("do_search"); - } else if (!strcasecmp(action, "msg")) { - embed_message(index[1]); - } else if (!strcasecmp(action, "printmsg")) { - print_message(index[1]); - } else if (!strcasecmp(action, "msgheaders")) { - display_headers(index[1]); - } else if (!strcasecmp(action, "vcardphoto")) { - display_vcard_photo_img(index[1]); - } else if (!strcasecmp(action, "wiki")) { - display_wiki_page(); - } else if (!strcasecmp(action, "display_enter")) { - display_enter(); - } else if (!strcasecmp(action, "post")) { - post_message(); - } else if (!strcasecmp(action, "move_msg")) { - move_msg(); - } else if (!strcasecmp(action, "delete_msg")) { - delete_msg(); - } else if (!strcasecmp(action, "userlist")) { - userlist(); - } else if (!strcasecmp(action, "showuser")) { - showuser(); - } else if (!strcasecmp(action, "display_page")) { - display_page(); - } else if (!strcasecmp(action, "page_user")) { - page_user(); - } else if (!strcasecmp(action, "chat")) { - do_chat(); - } else if (!strcasecmp(action, "display_private")) { - display_private("", 0); - } else if (!strcasecmp(action, "goto_private")) { - goto_private(); - } else if (!strcasecmp(action, "zapped_list")) { - zapped_list(); - } else if (!strcasecmp(action, "display_zap")) { - display_zap(); - } else if (!strcasecmp(action, "zap")) { - zap(); - } else if (!strcasecmp(action, "display_entroom")) { - display_entroom(); - } else if (!strcasecmp(action, "entroom")) { - entroom(); - } else if (!strcasecmp(action, "display_whok")) { - display_whok(); - } else if (!strcasecmp(action, "do_invt_kick")) { - do_invt_kick(); - } else if (!strcasecmp(action, "display_editroom")) { - display_editroom(); - } else if (!strcasecmp(action, "netedit")) { - netedit(); - } else if (!strcasecmp(action, "editroom")) { - editroom(); - } else if (!strcasecmp(action, "display_editinfo")) { - display_edit(_("Room info"), "EINF 0", "RINF", "editinfo", 1); - } else if (!strcasecmp(action, "editinfo")) { - save_edit(_("Room info"), "EINF 1", 1); - } else if (!strcasecmp(action, "display_editbio")) { - snprintf(buf, SIZ, "RBIO %s", WC->wc_fullname); - display_edit(_("Your bio"), "NOOP", buf, "editbio", 3); - } else if (!strcasecmp(action, "editbio")) { - save_edit(_("Your bio"), "EBIO", 0); - } else if (!strcasecmp(action, "confirm_move_msg")) { - confirm_move_msg(); - } else if (!strcasecmp(action, "delete_room")) { - delete_room(); - } else if (!strcasecmp(action, "validate")) { - validate(); - /* The users photo display / upload facility */ - } else if (!strcasecmp(action, "display_editpic")) { - display_graphics_upload(_("your photo"), - "_userpic_", - "editpic"); - } else if (!strcasecmp(action, "editpic")) { - do_graphics_upload("_userpic_"); - /* room picture dispay / upload facility */ - } else if (!strcasecmp(action, "display_editroompic")) { - display_graphics_upload(_("the icon for this room"), - "_roompic_", - "editroompic"); - } else if (!strcasecmp(action, "editroompic")) { - do_graphics_upload("_roompic_"); - /* the greetingpage hello pic */ - } else if (!strcasecmp(action, "display_edithello")) { - display_graphics_upload(_("the Greetingpicture for the login prompt"), - "hello", - "edithellopic"); - } else if (!strcasecmp(action, "edithellopic")) { - do_graphics_upload("hello"); - /* the logoff banner */ - } else if (!strcasecmp(action, "display_editgoodbyepic")) { - display_graphics_upload(_("the Logoff banner picture"), - "UIMG 0|%s|goodbuye", - "editgoodbuyepic"); - } else if (!strcasecmp(action, "editgoodbuyepic")) { - do_graphics_upload("UIMG 1|%s|goodbuye"); - - } else if (!strcasecmp(action, "delete_floor")) { - delete_floor(); - } else if (!strcasecmp(action, "rename_floor")) { - rename_floor(); - } else if (!strcasecmp(action, "create_floor")) { - create_floor(); - } else if (!strcasecmp(action, "display_editfloorpic")) { - snprintf(buf, SIZ, "UIMG 0|_floorpic_|%s", - bstr("which_floor")); - display_graphics_upload(_("the icon for this floor"), - buf, - "editfloorpic"); - } else if (!strcasecmp(action, "editfloorpic")) { - snprintf(buf, SIZ, "UIMG 1|_floorpic_|%s", - bstr("which_floor")); - do_graphics_upload(buf); - } else if (!strcasecmp(action, "display_reg")) { - display_reg(0); - } else if (!strcasecmp(action, "display_changepw")) { - display_changepw(); - } else if (!strcasecmp(action, "changepw")) { - changepw(); - } else if (!strcasecmp(action, "display_edit_node")) { - display_edit_node(); - } else if (!strcasecmp(action, "edit_node")) { - edit_node(); - } else if (!strcasecmp(action, "display_netconf")) { - display_netconf(); - } else if (!strcasecmp(action, "display_confirm_delete_node")) { - display_confirm_delete_node(); - } else if (!strcasecmp(action, "delete_node")) { - delete_node(); - } else if (!strcasecmp(action, "display_add_node")) { - display_add_node(); - } else if (!strcasecmp(action, "terminate_session")) { - slrp_highest(); - terminate_session(); - } else if (!strcasecmp(action, "edit_me")) { - edit_me(); - } else if (!strcasecmp(action, "display_siteconfig")) { - display_siteconfig(); - } else if (!strcasecmp(action, "chat_recv")) { - chat_recv(); - } else if (!strcasecmp(action, "chat_send")) { - chat_send(); - } else if (!strcasecmp(action, "siteconfig")) { - siteconfig(); - } else if (!strcasecmp(action, "display_generic")) { - display_generic(); - } else if (!strcasecmp(action, "do_generic")) { - do_generic(); - } else if (!strcasecmp(action, "ajax_servcmd")) { - ajax_servcmd(); - } else if (!strcasecmp(action, "display_menubar")) { - display_menubar(1); - } else if (!strcasecmp(action, "mimepart")) { - mimepart(index[1], index[2], 0); - } else if (!strcasecmp(action, "mimepart_download")) { - mimepart(index[1], index[2], 1); - } else if (!strcasecmp(action, "edit_vcard")) { - edit_vcard(); - } else if (!strcasecmp(action, "submit_vcard")) { - submit_vcard(); - } else if (!strcasecmp(action, "select_user_to_edit")) { - select_user_to_edit(NULL, NULL); - } else if (!strcasecmp(action, "display_edituser")) { - display_edituser(NULL, 0); - } else if (!strcasecmp(action, "edituser")) { - edituser(); - } else if (!strcasecmp(action, "create_user")) { - create_user(); - } else if (!strcasecmp(action, "changeview")) { - change_view(); - } else if (!strcasecmp(action, "change_start_page")) { - change_start_page(); - } else if (!strcasecmp(action, "display_floorconfig")) { - display_floorconfig(NULL); - } else if (!strcasecmp(action, "toggle_self_service")) { - toggle_self_service(); - } else if (!strcasecmp(action, "display_edit_task")) { - display_edit_task(); - } else if (!strcasecmp(action, "save_task")) { - save_task(); - } else if (!strcasecmp(action, "display_edit_event")) { - display_edit_event(); - } else if (!strcasecmp(action, "save_event")) { - save_event(); - } else if (!strcasecmp(action, "respond_to_request")) { - respond_to_request(); - } else if (!strcasecmp(action, "handle_rsvp")) { - handle_rsvp(); - } else if (!strcasecmp(action, "summary")) { - summary(); - } else if (!strcasecmp(action, "summary_inner_div")) { - begin_ajax_response(); - summary_inner_div(); - end_ajax_response(); - } else if (!strcasecmp(action, "display_customize_iconbar")) { - display_customize_iconbar(); - } else if (!strcasecmp(action, "commit_iconbar")) { - commit_iconbar(); - } else if (!strcasecmp(action, "set_room_policy")) { - set_room_policy(); - } else if (!strcasecmp(action, "display_inetconf")) { - display_inetconf(); - } else if (!strcasecmp(action, "save_inetconf")) { - save_inetconf(); - } else if (!strcasecmp(action, "display_smtpqueue")) { - display_smtpqueue(); - } else if (!strcasecmp(action, "display_smtpqueue_inner_div")) { - display_smtpqueue_inner_div(); - } else if (!strcasecmp(action, "display_sieve")) { - display_sieve(); - } else if (!strcasecmp(action, "save_sieve")) { - save_sieve(); - } else if (!strcasecmp(action, "display_pushemail")) { - display_pushemail(); - } else if (!strcasecmp(action, "save_pushemail")) { - save_pushemail(); - } else if (!strcasecmp(action, "display_add_remove_scripts")) { - display_add_remove_scripts(NULL); - } else if (!strcasecmp(action, "create_script")) { - create_script(); - } else if (!strcasecmp(action, "delete_script")) { - delete_script(); - } else if (!strcasecmp(action, "setup_wizard")) { - do_setup_wizard(); - } else if (!strcasecmp(action, "display_preferences")) { - display_preferences(); - } else if (!strcasecmp(action, "set_preferences")) { - set_preferences(); - } else if (!strcasecmp(action, "recp_autocomplete")) { - recp_autocomplete(bstr("recp")); - } else if (!strcasecmp(action, "cc_autocomplete")) { - recp_autocomplete(bstr("cc")); - } else if (!strcasecmp(action, "bcc_autocomplete")) { - recp_autocomplete(bstr("bcc")); - } else if (!strcasecmp(action, "display_address_book_middle_div")) { - display_address_book_middle_div(); - } else if (!strcasecmp(action, "display_address_book_inner_div")) { - display_address_book_inner_div(); - } else if (!strcasecmp(action, "set_floordiv_expanded")) { - set_floordiv_expanded(index[1]); - } else if (!strcasecmp(action, "diagnostics")) { - output_headers(1, 1, 1, 0, 0, 0); - wprintf("Session: %d
\n", WC->wc_session); - wprintf("Command:
\n");
-		escputs(cmd);
-		wprintf("

\n"); - wprintf("Variables:
\n");
-		dump_vars();
-		wprintf("

\n"); - wDumpContent(1); - } else if (!strcasecmp(action, "add_new_note")) { - add_new_note(); - } else if (!strcasecmp(action, "ajax_update_note")) { - ajax_update_note(); - } else if (!strcasecmp(action, "display_room_directory")) { - display_room_directory(); - } else if (!strcasecmp(action, "display_pictureview")) { - display_pictureview(); - } else if (!strcasecmp(action, "download_file")) { - download_file(index[1]); - } else if (!strcasecmp(action, "upload_file")) { - upload_file(); - } else if (!strcasecmp(action, "display_openids")) { - display_openids(); - } else if (!strcasecmp(action, "openid_attach")) { - openid_attach(); - } else if (!strcasecmp(action, "openid_detach")) { - openid_detach(); - } - /* When all else fais, display the main menu. */ else { - display_main_menu(); + if (!WCC->logged_in) + display_login(NULL); + else + display_main_menu(); } } SKIP_ALL_THIS_CRAP: @@ -2113,9 +1769,9 @@ SKIP_ALL_THIS_CRAP: content = NULL; } free_urls(); - if (WC->upload_length > 0) { - free(WC->upload); - WC->upload_length = 0; + if (WCC->upload_length > 0) { + free(WCC->upload); + WCC->upload_length = 0; } } @@ -2132,4 +1788,73 @@ void sleeeeeeeeeep(int seconds) select(0, NULL, NULL, NULL, &tv); } +void diagnostics(void) +{ + output_headers(1, 1, 1, 0, 0, 0); + wprintf("Session: %d
\n", WC->wc_session); + wprintf("Command:
\n");
+	StrEscPuts(WC->UrlFragment1);
+	wprintf("
\n"); + StrEscPuts(WC->UrlFragment2); + wprintf("

\n"); + wprintf("Variables:
\n");
+	dump_vars();
+	wprintf("

\n"); + wDumpContent(1); +} + +void view_mimepart(void) { + mimepart(ChrPtr(WC->UrlFragment1), + ChrPtr(WC->UrlFragment2), + 0); +} + +void download_mimepart(void) { + mimepart(ChrPtr(WC->UrlFragment1), + ChrPtr(WC->UrlFragment2), + 1); +} + +int ConditionalImportantMesage(WCTemplateToken *Tokens, void *Context) +{ + struct wcsession *WCC = WC; + if (WCC != NULL) + return (!IsEmptyStr(WCC->ImportantMessage)); + else + return 0; +} + +void tmplput_importantmessage(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context) +{ + struct wcsession *WCC = WC; + + if (WCC != NULL) { + StrEscAppend(Target, NULL, WCC->ImportantMessage, 0, 0); + WCC->ImportantMessage[0] = '\0'; + } +} + +void tmplput_offer_start_page(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context) +{ + offer_start_page(); +} + +void +InitModule_WEBCIT +(void) +{ + WebcitAddUrlHandler(HKEY("blank"), blank_page, ANONYMOUS); + WebcitAddUrlHandler(HKEY("do_template"), url_do_template, ANONYMOUS); + WebcitAddUrlHandler(HKEY("sslg"), seconds_since_last_gexp, AJAX); + WebcitAddUrlHandler(HKEY("ajax_servcmd"), ajax_servcmd, 0); + WebcitAddUrlHandler(HKEY("change_start_page"), change_start_page, 0); + WebcitAddUrlHandler(HKEY("toggle_self_service"), toggle_self_service, 0); + WebcitAddUrlHandler(HKEY("vcardphoto"), display_vcard_photo_img, NEED_URL); + WebcitAddUrlHandler(HKEY("mimepart"), view_mimepart, NEED_URL); + WebcitAddUrlHandler(HKEY("mimepart_download"), download_mimepart, NEED_URL); + WebcitAddUrlHandler(HKEY("diagnostics"), diagnostics, NEED_URL); + RegisterConditional(HKEY("COND:IMPMSG"), 0, ConditionalImportantMesage); + RegisterNamespace("IMPORTANTMESSAGE", 0, 0, tmplput_importantmessage); + RegisterNamespace("OFFERSTARTPAGE", 0, 0, tmplput_offer_start_page); +}