X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fwebcit.c;h=edc19a0c6422ec9079ed8edd56833871d90a4b65;hb=1b302cba797e9b8d6f94304f80c52ac63845503a;hp=7e3080bcec5fce19606bdf5d71b33c86639d975c;hpb=b12f7c07a9528027f808009fc7e1b8e4fd48570e;p=citadel.git diff --git a/webcit/webcit.c b/webcit/webcit.c index 7e3080bce..edc19a0c6 100644 --- a/webcit/webcit.c +++ b/webcit/webcit.c @@ -5,14 +5,13 @@ * 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 +#include #include "webcit.h" #include "groupdav.h" #include "webserver.h" -#include -#include /* * String to unset the cookie. @@ -39,324 +38,13 @@ void WebcitAddUrlHandler(const char * UrlString, Put(HandlerHash, UrlString, UrlSLen, NewHandler, NULL); } -/* - * remove escaped strings from i.e. the url string (like %20 for blanks) - */ -long unescape_input(char *buf) -{ - int a, b; - char hex[3]; - long buflen; - long len; - - buflen = strlen(buf); - - while ((buflen > 0) && (isspace(buf[buflen - 1]))){ - buf[buflen - 1] = 0; - buflen --; - } - - a = 0; - while (a < buflen) { - if (buf[a] == '+') - buf[a] = ' '; - if (buf[a] == '%') { - /* don't let % chars through, rather truncate the input. */ - if (a + 2 > buflen) { - buf[a] = '\0'; - buflen = a; - } - else { - hex[0] = buf[a + 1]; - hex[1] = buf[a + 2]; - hex[2] = 0; - b = 0; - sscanf(hex, "%02x", &b); - buf[a] = (char) b; - len = buflen - a - 2; - if (len > 0) - memmove(&buf[a + 1], &buf[a + 3], len); - - buflen -=2; - } - } - a++; - } - return a; -} - -void free_url(void *U) -{ - urlcontent *u = (urlcontent*) U; - FreeStrBuf(&u->url_data); - free(u); -} - -/* - * Extract variables from the URL. - */ -void addurls(StrBuf *url) -{ - 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 = ChrPtr(url) + StrLength(url); - up = ChrPtr(url); - while ((up < eptr) && (!IsEmptyStr(up))) { - aptr = up; - while ((aptr < eptr) && (*aptr != '\0') && (*aptr != '=')) - aptr++; - if (*aptr != '=') { - ///free(buf); - return; - } - ///*aptr = '\0'; - aptr++; - bptr = aptr; - while ((bptr < eptr) && (*bptr != '\0') - && (*bptr != '&') && (*bptr != '?') && (*bptr != ' ')) { - bptr++; - } - //*bptr = '\0'; - keylen = aptr - up - 1; /* -1 -> '=' */ - if(keylen > sizeof(u->url_key)) { - lprintf(1, "URLkey to long! [%s]", up); - continue; - } - - 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 = 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, ChrPtr(u->url_data)); -#endif - } - //free(buf); -} - -/* - * free urlstring memory - */ -void free_urls(void) -{ - DeleteHash(&WC->urlstrings); -} - -/* - * Diagnostic function to display the contents of all variables - */ - -void dump_vars(void) -{ - struct wcsession *WCC = WC; - urlcontent *u; - void *U; - long HKLen; - 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, ChrPtr(u->url_data)); - } -} - -/* - * 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) -{ - void *U; - - if ((WC->urlstrings != NULL) && - GetHash(WC->urlstrings, key, keylen, &U)) { - *len = StrLength(((urlcontent *)U)->url_data); - return ChrPtr(((urlcontent *)U)->url_data); - } - else { - *len = 0; - return (""); - } -} - -const char *XBSTR(char *key, size_t *len) -{ - void *U; - - if ((WC->urlstrings != NULL) && - GetHash(WC->urlstrings, key, strlen (key), &U)){ - *len = StrLength(((urlcontent *)U)->url_data); - return ChrPtr(((urlcontent *)U)->url_data); - } - else { - *len = 0; - return (""); - } -} - - -const char *BSTR(char *key) -{ - void *U; - - if ((WC->urlstrings != NULL) && - GetHash(WC->urlstrings, key, strlen (key), &U)) - return ChrPtr(((urlcontent *)U)->url_data); - else - return (""); -} - -const char *Bstr(char *key, size_t keylen) -{ - void *U; - - if ((WC->urlstrings != NULL) && - GetHash(WC->urlstrings, key, keylen, &U)) - return ChrPtr(((urlcontent *)U)->url_data); - else - return (""); -} - -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 ((urlcontent *)U)->url_data; - else - return NULL; -} - -long LBstr(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) -{ - void *U; - - if ((WC->urlstrings != NULL) && - GetHash(WC->urlstrings, key, strlen(key), &U)) - return StrTol(((urlcontent *)U)->url_data); - else - return (0); -} - -int IBstr(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); -} - -int IBSTR(char *key) -{ - void *U; - - if ((WC->urlstrings != NULL) && - GetHash(WC->urlstrings, key, strlen(key), &U)) - return StrToi(((urlcontent *)U)->url_data); - else - return (0); -} - -int HaveBstr(char *key, size_t keylen) -{ - void *U; - - if ((WC->urlstrings != NULL) && - GetHash(WC->urlstrings, key, keylen, &U)) - return (StrLength(((urlcontent *)U)->url_data) != 0); - else - return (0); -} - -int HAVEBSTR(char *key) -{ - void *U; - - if ((WC->urlstrings != NULL) && - GetHash(WC->urlstrings, key, strlen(key), &U)) - return (StrLength(((urlcontent *)U)->url_data) != 0); - else - return (0); -} - - -int YesBstr(char *key, size_t keylen) -{ - void *U; - - if ((WC->urlstrings != NULL) && - GetHash(WC->urlstrings, key, keylen, &U)) - return strcmp( ChrPtr(((urlcontent *)U)->url_data), "yes") == 0; - else - return (0); -} - -int YESBSTR(char *key) -{ - void *U; - - if ((WC->urlstrings != NULL) && - GetHash(WC->urlstrings, key, strlen(key), &U)) - return strcmp( ChrPtr(((urlcontent *)U)->url_data), "yes") == 0; - else - return (0); -} /* * web-printing funcion. uses our vsnprintf wrapper */ void wprintf(const char *format,...) { - struct wcsession *WCC = WC; + wcsession *WCC = WC; va_list arg_ptr; if (WCC->WBuf == NULL) @@ -365,9 +53,6 @@ void wprintf(const char *format,...) va_start(arg_ptr, format); StrBufVAppendPrintf(WCC->WBuf, format, arg_ptr); va_end(arg_ptr); - -/// if (StrLength(WCC-WBuf) > 2048) - ///client_write(wbuf, strlen(wbuf)); } /* @@ -375,30 +60,27 @@ void wprintf(const char *format,...) */ void hprintf(const char *format,...) { - struct wcsession *WCC = WC; + 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)); } + /* * wrap up an HTTP session, closes tags, etc. * * print_standard_html_footer should be set to: - * 0 to transmit only, - * 1 to append the main menu and closing tags, - * 2 to append the closing tags only. + * 0 - to transmit only, + * nonzero - to append the closing tags */ void wDumpContent(int print_standard_html_footer) { if (print_standard_html_footer) { - wprintf("\n"); /* end of "text" div */ + wprintf(" \n"); do_template("trailing", NULL); } @@ -410,225 +92,6 @@ 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. - */ -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); -} - - -void escputs1(char *strbuf, int nbsp, int nolinebreaks) -{ - StrEscAppend(WC->WBuf, NULL, strbuf, nbsp, nolinebreaks); -} - -void StrEscputs1(const StrBuf *strbuf, int nbsp, int nolinebreaks) -{ - StrEscAppend(WC->WBuf, strbuf, NULL, nbsp, nolinebreaks); -} - -/* - * static wrapper for ecsputs1 - */ -void escputs(char *strbuf) -{ - escputs1(strbuf, 0, 0); -} - - -/* - * static wrapper for ecsputs1 - */ -void StrEscPuts(const StrBuf *strbuf) -{ - StrEscputs1(strbuf, 0, 0); -} - - -/* - * urlescape buffer and print it to the client - */ -void urlescputs(const char *strbuf) -{ - 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); -} - - -/* - * Copy a string, escaping characters for JavaScript strings. - */ -void jsesc(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 == '<') - *tptr = '['; - else if (*sptr == '>') - *tptr = ']'; - else if (*sptr == '\'') { - if (tend - tptr < 3) - return; - *(tptr++) = '\\'; - *tptr = '\''; - } - else if (*sptr == '"') { - if (tend - tptr < 8) - return; - *(tptr++) = '&'; - *(tptr++) = 'q'; - *(tptr++) = 'u'; - *(tptr++) = 'o'; - *(tptr++) = 't'; - *tptr = ';'; - } - else if (*sptr == '&') { - if (tend - tptr < 7) - return; - *(tptr++) = '&'; - *(tptr++) = 'a'; - *(tptr++) = 'm'; - *(tptr++) = 'p'; - *tptr = ';'; - } else { - *tptr = *sptr; - } - tptr++; sptr++; - } - *tptr = '\0'; -} - -/* - * escape and print javascript - */ -void jsescputs(char *strbuf) -{ - char outbuf[SIZ]; - - jsesc(outbuf, SIZ, strbuf); - wprintf("%s", outbuf); -} - -/* - * print a string to the client after cleaning it with msgesc() and stresc() - */ -void msgescputs1( char *strbuf) -{ - StrBuf *OutBuf = NewStrBuf(); - - if ((strbuf == NULL) || IsEmptyStr(strbuf)) - return; - StrMsgEscAppend(OutBuf, NULL, strbuf); - StrEscAppend(WC->WBuf, OutBuf, NULL, 0, 0); -} - -/* - * print a string to the client after cleaning it with msgesc() - */ -void msgescputs(char *strbuf) { - if ((strbuf != NULL) && !IsEmptyStr(strbuf)) - StrMsgEscAppend(WC->WBuf, NULL, strbuf); -} - - - /* * Output HTTP headers and leading HTML for a page @@ -645,6 +108,7 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers int suppress_check, /* 1 = suppress check for instant messages */ int cache /* 1 = allow browser to cache this page */ ) { + wcsession *WCC = WC; char cookie[1024]; char httpnow[128]; @@ -655,7 +119,8 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers hprintf("Content-type: text/html; charset=utf-8\r\n" "Server: %s / %s\n" "Connection: close\r\n", - PACKAGE_STRING, serv_info.serv_software + PACKAGE_STRING, + ChrPtr(WCC->serv_info->serv_software) ); } @@ -680,8 +145,9 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers ); } - stuff_to_cookie(cookie, 1024, WC->wc_session, WC->wc_username, - WC->wc_password, WC->wc_roomname); + stuff_to_cookie(cookie, 1024, + WCC->wc_session, WCC->wc_username, + WCC->wc_password, WCC->wc_roomname); if (unset_cookies) { hprintf("Set-cookie: webcit=%s; path=/\r\n", unset); @@ -694,17 +160,7 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers if (do_htmlhead) { begin_burst(); - if (!access("static.local/webcit.css", R_OK)) { - svprintf(HKEY("CSSLOCAL"), WCS_STRING, - "" - ); - } 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)) { @@ -713,18 +169,16 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers escputs(WC->ImportantMessage); wprintf("
\n" "\n" - "\n"); - WC->ImportantMessage[0] = 0; + ); + StrBufAppendPrintf(WCC->trailing_javascript, + "setTimeout('hide_imsg_popup()', 5000); \n" + ); + WCC->ImportantMessage[0] = 0; } - if ( (WC->logged_in) && (!unset_cookies) ) { - wprintf("
"); - do_selected_iconbar(); - /** check for instant messages (these display in a new window) */ + if ( (WCC->logged_in) && (!unset_cookies) ) { + //DoTemplate(HKEY("iconbar"), NULL, &NoCtx); page_popup(); - wprintf("
"); } if (do_room_banner == 1) { @@ -739,6 +193,13 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers } } +void output_custom_content_header(const char *ctype) { + hprintf("HTTP/1.1 200 OK\r\n"); + hprintf("Content-type: %s; charset=utf-8\r\n",ctype); + hprintf("Server: %s / %s\r\n", PACKAGE_STRING, ChrPtr(WC->serv_info->serv_software)); + hprintf("Connection: close\r\n"); +} + /* * Generic function to do an HTTP redirect. Easy and fun. @@ -762,6 +223,12 @@ void http_redirect(const char *whichpage) { void http_transmit_thing(const char *content_type, int is_static) { +#ifndef TECH_PREVIEW + lprintf(9, "http_transmit_thing(%s)%s\n", + content_type, + (is_static ? " (static)" : "") + ); +#endif output_headers(0, 0, 0, 0, 0, is_static); hprintf("Content-type: %s\r\n" @@ -787,7 +254,7 @@ void print_menu_box(char* Title, char *Class, int nLines, ...) long i; svput("BOXTITLE", WCS_STRING, Title); - do_template("beginbox", NULL); + do_template("beginboxx", NULL); wprintf("
    ", Class); @@ -856,7 +323,9 @@ void output_static(char *what) close(fd); +#ifndef TECH_PREVIEW lprintf(9, "output_static('%s') %s\n", what, content_type); +#endif http_transmit_thing(content_type, 1); } if (yesbstr("force_close_session")) { @@ -864,152 +333,6 @@ void output_static(char *what) } } -/* - * When the browser requests an image file from the Citadel server, - * this function is called to transmit it. - */ -void output_image() -{ - struct wcsession *WCC = WC; - char buf[SIZ]; - 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); - - /** Read it from the server */ - - 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 */ - } - - - /* - * Instead of an ugly 404, send a 1x1 transparent GIF - * when there's no such image on the server. - */ - char blank_gif[SIZ]; - snprintf (blank_gif, SIZ, "%s%s", static_dirs[0], "/blank.gif"); - output_static(blank_gif); -} - -/* - * Extract an embedded photo from a vCard for display on the client - */ -void display_vcard_photo_img(void) -{ - long msgnum = 0L; - char *vcard; - struct vCard *v; - char *photosrc; - const char *contentType; - struct wcsession *WCC = WC; - - msgnum = StrTol(WCC->UrlFragment1); - - vcard = load_mimepart(msgnum,"1"); - v = vcard_load(vcard); - - photosrc = vcard_get_prop(v, "PHOTO", 1,0,0); - 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; - } - contentType = GuessMimeType(ChrPtr(WCC->WBuf), StrLength(WCC->WBuf)); - http_transmit_thing(contentType, 0); - free(v); - free(photosrc); -} - -/* - * Generic function to output an arbitrary MIME part from an arbitrary - * message number on the server. - * - * msgnum Number of the item on the citadel server - * partnum The MIME part to be output - * force_download Nonzero to force set the Content-Type: header to "application/octet-stream" - */ -void mimepart(const char *msgnum, const char *partnum, int force_download) -{ - char buf[256]; - off_t bytes; - char content_type[256]; - - serv_printf("OPNA %s|%s", msgnum, partnum); - serv_getln(buf, sizeof buf); - if (buf[0] == '2') { - bytes = extract_long(&buf[4], 0); - if (force_download) { - strcpy(content_type, "application/octet-stream"); - } - else { - extract_token(content_type, &buf[4], 3, '|', sizeof content_type); - } - output_headers(0, 0, 0, 0, 0, 0); - - read_server_binary(WC->WBuf, bytes); - serv_puts("CLOS"); - serv_getln(buf, sizeof buf); - http_transmit_thing(content_type, 0); - } else { - hprintf("HTTP/1.1 404 %s\n", &buf[4]); - output_headers(0, 0, 0, 0, 0, 0); - hprintf("Content-Type: text/plain\r\n"); - wprintf(_("An error occurred while retrieving this part: %s\n"), &buf[4]); - end_burst(); - } -} - - -/* - * Read any MIME part of a message, from the server, into memory. - */ -char *load_mimepart(long msgnum, char *partnum) -{ - char buf[SIZ]; - off_t bytes; - char content_type[SIZ]; - char *content; - - serv_printf("DLAT %ld|%s", msgnum, partnum); - serv_getln(buf, sizeof buf); - if (buf[0] == '6') { - bytes = extract_long(&buf[4], 0); - extract_token(content_type, &buf[4], 3, '|', sizeof content_type); - - content = malloc(bytes + 2); - serv_read(content, bytes); - - content[bytes] = 0; /* null terminate for good measure */ - return(content); - } - else { - return(NULL); - } -} - /* * Convenience functions to display a page containing only a string @@ -1047,52 +370,12 @@ void blank_page(void) { * A template has been requested */ void url_do_template(void) { + const StrBuf *MimeType; const StrBuf *Tmpl = sbstr("template"); begin_burst(); - output_headers(1, 0, 0, 0, 1, 0); - DoTemplate(ChrPtr(Tmpl), StrLength(Tmpl), NULL, NULL); - end_burst(); -} - - - -/* - * Offer to make any page the user's "start page." - */ -void offer_start_page(void) { - wprintf("this_page); - wprintf("\">"); - wprintf(_("Make this my start page")); - wprintf(""); -#ifdef TECH_PREVIEW - wprintf("
    wc_roomname); - wprintf("\" title=\"RSS 2.0 feed for "); - escputs(WC->wc_roomname); - wprintf("\">\"RSS\"\n"); -#endif -} - - -/* - * Change the user's start page - */ -void change_start_page(void) { - - if (bstr("startpage") == NULL) { - safestrncpy(WC->ImportantMessage, - _("You no longer have a start page selected."), - sizeof WC->ImportantMessage); - display_main_menu(); - return; - } - - set_preference("startpage", NewStrBufPlain(bstr("startpage"), -1), 1); - - output_headers(1, 1, 0, 0, 0, 0); - do_template("newstartpage", NULL); - wDumpContent(1); + output_headers(0, 0, 0, 0, 1, 0); + MimeType = DoTemplate(SKEY(Tmpl), NULL, &NoCtx); + http_transmit_thing(ChrPtr(MimeType), 0); } @@ -1113,7 +396,7 @@ void display_success(char *successmessage) void authorization_required(const char *message) { hprintf("HTTP/1.1 401 Authorization Required\r\n"); - hprintf("WWW-Authenticate: Basic realm=\"%s\"\r\n", serv_info.serv_humannode); + hprintf("WWW-Authenticate: Basic realm=\"%s\"\r\n", ChrPtr(WC->serv_info->serv_humannode)); hprintf("Content-Type: text/html\r\n"); wprintf("

    "); wprintf(_("Authorization Required")); @@ -1124,69 +407,11 @@ void authorization_required(const char *message) } -/* - * This function is called by the MIME parser to handle data uploaded by - * the browser. Form data, uploaded files, and the data from HTTP PUT - * operations (such as those found in GroupDAV) all arrive this way. - * - * name Name of the item being uploaded - * filename Filename of the item being uploaded - * partnum MIME part identifier (not needed) - * disp MIME content disposition (not needed) - * content The actual data - * cbtype MIME content-type - * cbcharset Character set - * length Content length - * encoding MIME encoding type (not needed) - * userdata Not used here - */ -void upload_handler(char *name, char *filename, char *partnum, char *disp, - void *content, char *cbtype, char *cbcharset, - size_t length, char *encoding, void *userdata) -{ - urlcontent *u; -#ifdef DEBUG_URLSTRINGS - lprintf(9, "upload_handler() name=%s, type=%s, len=%d\n", name, cbtype, length); -#endif - if (WC->urlstrings == NULL) - WC->urlstrings = NewHash(1, NULL); - - /* Form fields */ - if ( (length > 0) && (IsEmptyStr(cbtype)) ) { - u = (urlcontent *) malloc(sizeof(urlcontent)); - - safestrncpy(u->url_key, name, sizeof(u->url_key)); - 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); -#endif - } - - /** Uploaded files */ - if ( (length > 0) && (!IsEmptyStr(cbtype)) ) { - WC->upload = malloc(length); - if (WC->upload != NULL) { - WC->upload_length = length; - safestrncpy(WC->upload_filename, filename, - sizeof(WC->upload_filename)); - safestrncpy(WC->upload_content_type, cbtype, - sizeof(WC->upload_content_type)); - memcpy(WC->upload, content, length); - } - else { - lprintf(3, "malloc() failed: %s\n", strerror(errno)); - } - } - -} - /* * Convenience functions to wrap around asynchronous ajax responses */ void begin_ajax_response(void) { - struct wcsession *WCC = WC; + wcsession *WCC = WC; FlushStrBuf(WCC->HBuf); output_headers(0, 0, 0, 0, 0, 0); @@ -1203,7 +428,6 @@ void begin_ajax_response(void) { * print ajax response footer */ void end_ajax_response(void) { - ///hprintf("\r\n");///// todo: is this right? wDumpContent(0); } @@ -1276,6 +500,7 @@ void seconds_since_last_gexp(void) wprintf("NO\n"); } else { + memset(buf, 0, 5); serv_puts("NOOP"); serv_getln(buf, sizeof buf); if (buf[3] == '*') { @@ -1300,7 +525,7 @@ int is_mobile_ua(char *user_agent) { } 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. + /* For some reason a new install of Opera 9.51beta decided to spoof. */ return 1; } return 0; @@ -1310,48 +535,50 @@ int is_mobile_ua(char *user_agent) { /* * Entry point for WebCit transaction */ -void session_loop(struct httprequest *req) +void session_loop(HashList *HTTPHeaders, StrBuf *ReqLine, StrBuf *request_method, StrBuf *ReadBuf) { - char cmd[1024]; + StrBuf *Buf; + const char *pch, *pchs, *pche; + void *vLine; char action[1024]; char arg[8][128]; size_t sizes[10]; char *index[10]; char buf[SIZ]; - char request_method[128]; - char pathname[1024]; - int a, b, nBackDots, nEmpty; + int a, nBackDots, nEmpty; int ContentLength = 0; - char ContentType[512]; - char *content = NULL; - char *content_end = NULL; - struct httprequest *hptr; - char browser_host[256]; + StrBuf *ContentType = NULL; + StrBuf *UrlLine = NULL; + StrBuf *content = NULL; + const char *content_end = NULL; + StrBuf *browser_host = NULL; char user_agent[256]; int body_start = 0; int is_static = 0; int n_static = 0; int len = 0; + void *vHandler; + WebcitHandler *Handler; + /* * We stuff these with the values coming from the client cookies, * so we can use them to reconnect a timed out session if we have to. */ - char c_username[SIZ]; - char c_password[SIZ]; - char c_roomname[SIZ]; + StrBuf *c_username; + StrBuf *c_password; + StrBuf *c_roomname; char c_httpauth_string[SIZ]; - char c_httpauth_user[SIZ]; - char c_httpauth_pass[SIZ]; - char cookie[SIZ]; - struct wcsession *WCC; + StrBuf *c_httpauth_user; + StrBuf *c_httpauth_pass; + wcsession *WCC; - safestrncpy(c_username, "", sizeof c_username); - safestrncpy(c_password, "", sizeof c_password); - safestrncpy(c_roomname, "", sizeof c_roomname); + Buf = NewStrBuf(); + c_username = NewStrBuf(); + c_password = NewStrBuf(); + c_roomname = NewStrBuf(); safestrncpy(c_httpauth_string, "", sizeof c_httpauth_string); - safestrncpy(c_httpauth_user, DEFAULT_HTTPAUTH_USER, sizeof c_httpauth_user); - safestrncpy(c_httpauth_pass, DEFAULT_HTTPAUTH_PASS, sizeof c_httpauth_pass); - strcpy(browser_host, ""); + c_httpauth_user = NewStrBufPlain(HKEY(DEFAULT_HTTPAUTH_USER)); + c_httpauth_pass = NewStrBufPlain(HKEY(DEFAULT_HTTPAUTH_PASS)); WCC= WC; if (WCC->WBuf == NULL) @@ -1365,14 +592,8 @@ void session_loop(struct httprequest *req) WCC->upload_length = 0; WCC->upload = NULL; WCC->is_mobile = 0; - - hptr = req; - if (hptr == NULL) return; - - safestrncpy(cmd, hptr->line, sizeof cmd); - hptr = hptr->next; - extract_token(request_method, cmd, 0, ' ', sizeof request_method); - extract_token(pathname, cmd, 1, ' ', sizeof pathname); + WCC->trailing_javascript = NewStrBuf(); + WCC->nWildfireHeaders = 0; /** Figure out the action */ index[0] = action; @@ -1382,12 +603,12 @@ void session_loop(struct httprequest *req) index[a] = arg[a-1]; sizes[a] = sizeof arg[a-1]; } -//// index[9] = &foo; todo +/*/// index[9] = &foo; todo */ nBackDots = 0; nEmpty = 0; for ( a = 0; a < 9; ++a) { - extract_token(index[a], pathname, a + 1, '/', sizes[a]); + extract_token(index[a], ChrPtr(ReqLine), a + 1, '/', sizes[a]); if (strstr(index[a], "?")) *strstr(index[a], "?") = 0; if (strstr(index[a], "&")) *strstr(index[a], "&") = 0; if (strstr(index[a], " ")) *strstr(index[a], " ") = 0; @@ -1397,113 +618,109 @@ void session_loop(struct httprequest *req) nEmpty++; } - while (hptr != NULL) { - safestrncpy(buf, hptr->line, sizeof buf); - /* lprintf(9, "HTTP HEADER: %s\n", buf); */ - hptr = hptr->next; - - if (!strncasecmp(buf, "Cookie: webcit=", 15)) { - safestrncpy(cookie, &buf[15], sizeof cookie); - cookie_to_stuff(cookie, NULL, - c_username, sizeof c_username, - c_password, sizeof c_password, - c_roomname, sizeof c_roomname); - } - else if (!strncasecmp(buf, "Authorization: Basic ", 21)) { - CtdlDecodeBase64(c_httpauth_string, &buf[21], strlen(&buf[21])); - extract_token(c_httpauth_user, c_httpauth_string, 0, ':', sizeof c_httpauth_user); - extract_token(c_httpauth_pass, c_httpauth_string, 1, ':', sizeof c_httpauth_pass); - } - else if (!strncasecmp(buf, "Content-length: ", 16)) { - ContentLength = atoi(&buf[16]); - } - else if (!strncasecmp(buf, "Content-type: ", 14)) { - safestrncpy(ContentType, &buf[14], sizeof ContentType); - } - else if (!strncasecmp(buf, "User-agent: ", 12)) { - safestrncpy(user_agent, &buf[12], sizeof user_agent); - #ifdef TECH_PREVIEW - if (is_mobile_ua(&buf[12])) { - WCC->is_mobile = 1; - } - #endif - } - else if (!strncasecmp(buf, "X-Forwarded-Host: ", 18)) { - if (follow_xff) { - safestrncpy(WCC->http_host, &buf[18], sizeof WCC->http_host); - } + + if (GetHash(HTTPHeaders, HKEY("COOKIE"), &vLine) && + (vLine != NULL)){ + cookie_to_stuff((StrBuf *)vLine, NULL, + c_username, + c_password, + c_roomname); + } + if (GetHash(HTTPHeaders, HKEY("AUTHORIZATION"), &vLine) && + (vLine!=NULL)) { +/* TODO: wrap base64 in strbuf */ + CtdlDecodeBase64(c_httpauth_string, ChrPtr((StrBuf*)vLine), StrLength((StrBuf*)vLine)); + FlushStrBuf(Buf); + StrBufAppendBufPlain(Buf, c_httpauth_string, -1, 0); + StrBufExtract_token(c_httpauth_user, Buf, 0, ':'); + StrBufExtract_token(c_httpauth_pass, Buf, 1, ':'); + } + if (GetHash(HTTPHeaders, HKEY("CONTENT-LENGTH"), &vLine) && + (vLine!=NULL)) { + ContentLength = StrToi((StrBuf*)vLine); + } + if (GetHash(HTTPHeaders, HKEY("CONTENT-TYPE"), &vLine) && + (vLine!=NULL)) { + ContentType = (StrBuf*)vLine; + } + if (GetHash(HTTPHeaders, HKEY("USER-AGENT"), &vLine) && + (vLine!=NULL)) { + safestrncpy(user_agent, ChrPtr((StrBuf*)vLine), sizeof user_agent); +#ifdef TECH_PREVIEW + if ((WCC->is_mobile < 0) && is_mobile_ua(&buf[12])) { + WCC->is_mobile = 1; } - else if (!strncasecmp(buf, "Host: ", 6)) { - if (IsEmptyStr(WCC->http_host)) { - safestrncpy(WCC->http_host, &buf[6], sizeof WCC->http_host); - } + else { + WCC->is_mobile = 0; } - else if (!strncasecmp(buf, "X-Forwarded-For: ", 17)) { - safestrncpy(browser_host, &buf[17], sizeof browser_host); - while (num_tokens(browser_host, ',') > 1) { - remove_token(browser_host, 0, ','); - } - striplt(browser_host); +#endif + } + if ((follow_xff) && + GetHash(HTTPHeaders, HKEY("X-FORWARDED-HOST"), &vLine) && + (vLine != NULL)) { + WCC->http_host = (StrBuf*)vLine; + } + if ((StrLength(WCC->http_host) == 0) && + GetHash(HTTPHeaders, HKEY("HOST"), &vLine) && + (vLine!=NULL)) { + WCC->http_host = (StrBuf*)vLine; + } + + if (GetHash(HTTPHeaders, HKEY("X-FORWARDED-FOR"), &vLine) && + (vLine!=NULL)) { + browser_host = (StrBuf*) vLine; + + while (StrBufNum_tokens(browser_host, ',') > 1) { + StrBufRemove_token(browser_host, 0, ','); } + StrBufTrim(browser_host); } if (ContentLength > 0) { - int BuffSize; - - BuffSize = ContentLength + SIZ; - content = malloc(BuffSize); - memset(content, 0, BuffSize); - snprintf(content, BuffSize, "Content-type: %s\n" + content = NewStrBuf(); + StrBufPrintf(content, "Content-type: %s\n" "Content-length: %d\n\n", - ContentType, ContentLength); + ChrPtr(ContentType), ContentLength); /* hprintf("Content-type: %s\n" "Content-length: %d\n\n", ContentType, ContentLength); */ - body_start = strlen(content); + body_start = StrLength(content); /** Read the entire input data at once. */ - client_read(&WCC->http_sock, &content[body_start], ContentLength); - - if (!strncasecmp(ContentType, "application/x-www-form-urlencoded", 33)) { - 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); + client_read(&WCC->http_sock, content, ReadBuf, ContentLength + body_start); + + if (!strncasecmp(ChrPtr(ContentType), "application/x-www-form-urlencoded", 33)) { + StrBufCutLeft(content, body_start); + ParseURLParams(content); + } else if (!strncasecmp(ChrPtr(ContentType), "multipart", 9)) { + content_end = ChrPtr(content) + ContentLength + body_start; + mime_parser(ChrPtr(content), content_end, *upload_handler, NULL, NULL, NULL, 0); } } else { content = NULL; } /* make a note of where we are in case the user wants to save it */ - safestrncpy(WCC->this_page, cmd, sizeof(WCC->this_page)); - remove_token(WCC->this_page, 2, ' '); - remove_token(WCC->this_page, 0, ' '); + WCC->this_page = NewStrBufDup(ReqLine); + StrBufRemove_token(WCC->this_page, 2, ' '); + StrBufRemove_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; - } - } - //cmd[len - a] = '\0'; - Params = _NewConstStrBuf(&cmd[a + 1], len - a); - addurls(Params); - FreeStrBuf(&Params); - cmd[a] = 0; - len = a - 1; + UrlLine = NewStrBufDup(ReqLine); + len = StrLength(UrlLine); + pch = pchs = ChrPtr(UrlLine); + pche = pchs + len; + while (pch < pche) { + if ((*pch == '?') || (*pch == '&')) { + StrBufCutLeft(UrlLine, pch - pchs + 1); + ParseURLParams(UrlLine); + break; } + pch ++; } + FreeStrBuf(&UrlLine); /* If it's a "force 404" situation then display the error and bail. */ if (!strcmp(action, "404")) { @@ -1516,7 +733,7 @@ void session_loop(struct httprequest *req) /* Static content can be sent without connecting to Citadel. */ is_static = 0; - for (a=0; anonce) { lprintf(9, "Ignoring request with mismatched nonce.\n"); hprintf("HTTP/1.1 404 Security check failed\r\n"); - hprintf("Content-Type: text/plain\r\n"); + hprintf("Content-Type: text/plain\r\n\r\n"); wprintf("Security check failed.\r\n"); end_burst(); goto SKIP_ALL_THIS_CRAP; @@ -1586,36 +803,51 @@ void session_loop(struct httprequest *req) } else { WCC->connected = 1; - serv_getln(buf, sizeof buf); /** get the server welcome message */ + serv_getln(buf, sizeof buf); /* get the server greeting */ - /** + /* Are there too many users already logged in? */ + if (!strncmp(buf, "571", 3)) { + wprintf(_("This server is already serving its maximum number of users and cannot accept any additional logins at this time. Please try again later or contact your system administrator.")); + end_burst(); + end_webcit_session(); + goto SKIP_ALL_THIS_CRAP; + } + + /* * From what host is our user connecting? Go with * the host at the other end of the HTTP socket, * unless we are following X-Forwarded-For: headers * and such a header has already turned up something. */ - if ( (!follow_xff) || (strlen(browser_host) == 0) ) { + if ( (!follow_xff) || (StrLength(browser_host) == 0) ) { + if (browser_host == NULL) { + browser_host = NewStrBuf(); + Put(HTTPHeaders, HKEY("FreeMeWithTheOtherHeaders"), + browser_host, HFreeStrBuf); + } locate_host(browser_host, WCC->http_sock); } - get_serv_info(browser_host, user_agent); - if (serv_info.serv_rev_level < MINIMUM_CIT_VERSION) { + WCC->serv_info = get_serv_info(browser_host, user_agent); + if (WCC->serv_info->serv_rev_level < MINIMUM_CIT_VERSION) { + begin_burst(); wprintf(_("You are connected to a Citadel " "server running Citadel %d.%02d. \n" "In order to run this version of WebCit " "you must also have Citadel %d.%02d or" " newer.\n\n\n"), - serv_info.serv_rev_level / 100, - serv_info.serv_rev_level % 100, + WCC->serv_info->serv_rev_level / 100, + WCC->serv_info->serv_rev_level % 100, MINIMUM_CIT_VERSION / 100, MINIMUM_CIT_VERSION % 100 ); + end_burst(); end_webcit_session(); goto SKIP_ALL_THIS_CRAP; } } } -////////todo: restorte language in this case +/*///////todo: restore language in this case */ /* * Functions which can be performed without logging in */ @@ -1624,7 +856,7 @@ void session_loop(struct httprequest *req) goto SKIP_ALL_THIS_CRAP; } if (!strcasecmp(action, "freebusy")) { - do_freebusy(cmd); + do_freebusy(ChrPtr(ReqLine)); goto SKIP_ALL_THIS_CRAP; } @@ -1633,21 +865,34 @@ void session_loop(struct httprequest *req) * try logging in to Citadel using that. */ if ((!WCC->logged_in) - && (strlen(c_httpauth_user) > 0) - && (strlen(c_httpauth_pass) > 0)) { - serv_printf("USER %s", c_httpauth_user); - serv_getln(buf, sizeof buf); - if (buf[0] == '3') { - serv_printf("PASS %s", c_httpauth_pass); - serv_getln(buf, sizeof buf); - if (buf[0] == '2') { + && (StrLength(c_httpauth_user) > 0) + && (StrLength(c_httpauth_pass) > 0)) + { + FlushStrBuf(Buf); + serv_printf("USER %s", ChrPtr(c_httpauth_user)); + StrBuf_ServGetln(Buf); + if (GetServerStatus(Buf, NULL) == 3) { + serv_printf("PASS %s", ChrPtr(c_httpauth_pass)); + StrBuf_ServGetln(Buf); + if (GetServerStatus(Buf, NULL) == 2) { become_logged_in(c_httpauth_user, - c_httpauth_pass, buf); - safestrncpy(WCC->httpauth_user, c_httpauth_user, sizeof WCC->httpauth_user); - safestrncpy(WCC->httpauth_pass, c_httpauth_pass, sizeof WCC->httpauth_pass); + c_httpauth_pass, Buf); + if (WCC->httpauth_user == NULL) + WCC->httpauth_user = NewStrBufDup(c_httpauth_user); + else { + FlushStrBuf(WCC->httpauth_user); + StrBufAppendBuf(WCC->httpauth_user, c_httpauth_user, 0); + } + if (WCC->httpauth_pass == NULL) + WCC->httpauth_pass = NewStrBufDup(c_httpauth_pass); + else { + FlushStrBuf(WCC->httpauth_pass); + StrBufAppendBuf(WCC->httpauth_pass, c_httpauth_pass, 0); + } } else { /* Should only display when password is wrong */ authorization_required(&buf[4]); + FreeStrBuf(&Buf); goto SKIP_ALL_THIS_CRAP; } } @@ -1656,7 +901,7 @@ void session_loop(struct httprequest *req) /* This needs to run early */ #ifdef TECH_PREVIEW if (!strcasecmp(action, "rss")) { - display_rss(bstr("room"), request_method); + display_rss(sbstr("room"), request_method); goto SKIP_ALL_THIS_CRAP; } #endif @@ -1666,8 +911,10 @@ void session_loop(struct httprequest *req) * our session's authentication. */ if (!strncasecmp(action, "groupdav", 8)) { - groupdav_main(req, ContentType, /* do GroupDAV methods */ - ContentLength, content+body_start); + groupdav_main(HTTPHeaders, + ReqLine, request_method, + ContentType, /* do GroupDAV methods */ + ContentLength, content, body_start); if (!WCC->logged_in) { WCC->killthis = 1; /* If not logged in, don't */ } /* keep the session active */ @@ -1679,9 +926,10 @@ void session_loop(struct httprequest *req) * Automatically send requests with any method other than GET or * POST to the GroupDAV code as well. */ - if ((strcasecmp(request_method, "GET")) && (strcasecmp(request_method, "POST"))) { - groupdav_main(req, ContentType, /** do GroupDAV methods */ - ContentLength, content+body_start); + if ((strcasecmp(ChrPtr(request_method), "GET")) && (strcasecmp(ChrPtr(request_method), "POST"))) { + groupdav_main(HTTPHeaders, ReqLine, + request_method, ContentType, /** do GroupDAV methods */ + ContentLength, content, body_start); if (!WCC->logged_in) { WCC->killthis = 1; /** If not logged in, don't */ } /** keep the session active */ @@ -1693,66 +941,76 @@ void session_loop(struct httprequest *req) * supplied by the browser, try using them to log in. */ if ((!WCC->logged_in) - && (!IsEmptyStr(c_username)) - && (!IsEmptyStr(c_password))) { - serv_printf("USER %s", c_username); - serv_getln(buf, sizeof buf); - if (buf[0] == '3') { - serv_printf("PASS %s", c_password); - serv_getln(buf, sizeof buf); - if (buf[0] == '2') { + && (StrLength(c_username)>0) + && (StrLength(c_password)>0)) { + serv_printf("USER %s", ChrPtr(c_username)); + StrBuf_ServGetln(Buf); + if (GetServerStatus(Buf, NULL) == 3) { + serv_printf("PASS %s", ChrPtr(c_password)); + StrBuf_ServGetln(Buf); + if (GetServerStatus(Buf, NULL) == 2) { StrBuf *Lang; - become_logged_in(c_username, c_password, buf); + become_logged_in(c_username, c_password, Buf); if (get_preference("language", &Lang)) { set_selected_language(ChrPtr(Lang)); go_selected_language(); /* set locale */ } + get_preference("default_header_charset", &WCC->DefaultCharset); } } } + /* - * If we don't have a current room, but a cookie specifying the - * current room is supplied, make an effort to go there. + * If a 'gotofirst' parameter has been specified, attempt to goto that room + * prior to doing anything else. */ - if ((IsEmptyStr(WCC->wc_roomname)) && (!IsEmptyStr(c_roomname))) { - serv_printf("GOTO %s", c_roomname); - serv_getln(buf, sizeof buf); - if (buf[0] == '2') { - safestrncpy(WCC->wc_roomname, c_roomname, sizeof WCC->wc_roomname); - } + if (havebstr("gotofirst")) { + gotoroom(sbstr("gotofirst")); /* do this quietly to avoid session output! */ } - if (!strcasecmp(action, "image")) { - output_image(); - } else if (!strcasecmp(action, "display_mime_icon")) { - display_mime_icon(); - } - else { - void *vHandler; - WebcitHandler *Handler; - - GetHash(HandlerHash, action, strlen(action) /* TODO*/, &vHandler), - Handler = (WebcitHandler*) vHandler; - if (Handler != NULL) { - if (!WCC->logged_in && ((Handler->Flags & ANONYMOUS) == 0)) { - display_login(NULL); + /* + * If we don't have a current room, but a cookie specifying the + * current room is supplied, make an effort to go there. + */ + if ((StrLength(WCC->wc_roomname) == 0) && (StrLength(c_roomname) > 0)) { + serv_printf("GOTO %s", ChrPtr(c_roomname)); + StrBuf_ServGetln(Buf); + if (GetServerStatus(Buf, NULL) == 2) { + if (WCC->wc_roomname == NULL) { + WCC->wc_roomname = NewStrBufDup(c_roomname); } 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(); + FlushStrBuf(WCC->wc_roomname); + StrBufAppendBuf(WCC->wc_roomname, c_roomname, 0); + } + } + } + + GetHash(HandlerHash, action, strlen(action) /* TODO*/, &vHandler), + Handler = (WebcitHandler*) vHandler; + if (Handler != NULL) { + 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(); + if (WCC->UrlFragment3 == NULL) + WCC->UrlFragment3 = NewStrBuf(); + StrBufPrintf(WCC->UrlFragment1, "%s", index[0]); + StrBufPrintf(WCC->UrlFragment2, "%s", index[1]); + StrBufPrintf(WCC->UrlFragment3, "%s", index[2]); } + if ((Handler->Flags & AJAX) != 0) + begin_ajax_response(); + Handler->F(); + if ((Handler->Flags & AJAX) != 0) + end_ajax_response(); } + } /* When all else fais, display the main menu. */ else { if (!WCC->logged_in) @@ -1760,18 +1018,31 @@ void session_loop(struct httprequest *req) else display_main_menu(); } -} + SKIP_ALL_THIS_CRAP: + if (WCC->SavePrefsToServer) { + save_preferences(); + WCC->SavePrefsToServer = 0; + } + FreeStrBuf(&Buf); + FreeStrBuf(&c_username); + FreeStrBuf(&c_password); + FreeStrBuf(&c_roomname); + FreeStrBuf(&c_httpauth_user); + FreeStrBuf(&c_httpauth_pass); + FreeStrBuf(&WCC->this_page); fflush(stdout); if (content != NULL) { - free(content); + FreeStrBuf(&content); content = NULL; } - free_urls(); + DeleteHash(&WCC->urlstrings); if (WCC->upload_length > 0) { free(WCC->upload); WCC->upload_length = 0; } + FreeStrBuf(&WCC->trailing_javascript); + WCC->http_host = NULL; } @@ -1787,58 +1058,48 @@ 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) +int ConditionalImportantMesage(StrBuf *Target, WCTemplputParams *TP) { - struct wcsession *WCC = WC; + wcsession *WCC = WC; if (WCC != NULL) return (!IsEmptyStr(WCC->ImportantMessage)); else return 0; } -void tmplput_importantmessage(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context) +void tmplput_importantmessage(StrBuf *Target, WCTemplputParams *TP) { - struct wcsession *WCC = WC; + wcsession *WCC = WC; if (WCC != NULL) { +/* + StrBufAppendTemplate(Target, nArgs, Tokens, Context, ContextType, + WCC->ImportantMessage, 0); +*/ StrEscAppend(Target, NULL, WCC->ImportantMessage, 0, 0); - WCC->ImportantMessage[0] = '\0'; + WCC->ImportantMessage[0] = '\0'; } } -void tmplput_offer_start_page(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context) +void tmplput_trailing_javascript(StrBuf *Target, WCTemplputParams *TP) +{ + wcsession *WCC = WC; + + if (WCC != NULL) + StrBufAppendTemplate(Target, TP, WCC->trailing_javascript, 0); +} + +void tmplput_csslocal(StrBuf *Target, WCTemplputParams *TP) { - offer_start_page(); + extern StrBuf *csslocal; + StrBufAppendBuf(Target, + csslocal, 0); } + + + void InitModule_WEBCIT (void) @@ -1847,13 +1108,9 @@ InitModule_WEBCIT 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); + + RegisterConditional(HKEY("COND:IMPMSG"), 0, ConditionalImportantMesage, CTX_NONE); + RegisterNamespace("CSSLOCAL", 0, 0, tmplput_csslocal, CTX_NONE); + RegisterNamespace("IMPORTANTMESSAGE", 0, 0, tmplput_importantmessage, CTX_NONE); + RegisterNamespace("TRAILING_JAVASCRIPT", 0, 0, tmplput_trailing_javascript, CTX_NONE); }