X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fwebcit.c;h=ed3bf025e0c0979e8f422c521a77563fceffab0a;hb=a5de3dbe7d1106599728013612c12cd9b007dfdb;hp=b25347a4001b022839cc6bc7fb50aa43565fb011;hpb=cf934431c7c8c1091b38c0b374f6a3b9293841ca;p=citadel.git diff --git a/webcit/webcit.c b/webcit/webcit.c index b25347a40..ed3bf025e 100644 --- a/webcit/webcit.c +++ b/webcit/webcit.c @@ -20,15 +20,33 @@ */ static char *unset = "; expires=28-May-1971 18:10:00 GMT"; +static HashList *HandlerHash = NULL; + + +void WebcitAddUrlHandler(const char * UrlString, long UrlSLen, WebcitHandlerFunc F, int IsAjax) +{ + WebcitHandler *NewHandler; + + if (HandlerHash == NULL) + HandlerHash = NewHash(1, NULL); + + NewHandler = (WebcitHandler*) malloc(sizeof(WebcitHandler)); + NewHandler->F = F; + NewHandler->IsAjax = IsAjax; + + Put(HandlerHash, UrlString, UrlSLen, NewHandler, NULL); +} + /** * \brief remove escaped strings from i.e. the url string (like %20 for blanks) * \param buf the buffer to examine */ -void unescape_input(char *buf) +long unescape_input(char *buf) { int a, b; char hex[3]; long buflen; + long len; buflen = strlen(buf); @@ -42,19 +60,35 @@ void unescape_input(char *buf) if (buf[a] == '+') buf[a] = ' '; if (buf[a] == '%') { - hex[0] = buf[a + 1]; - hex[1] = buf[a + 2]; - hex[2] = 0; - b = 0; - sscanf(hex, "%02x", &b); - buf[a] = (char) b; - memmove(&buf[a + 1], &buf[a + 3], buflen - a - 2); + /* 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; + buflen -=2; + } } a++; } + return a; +} +void free_url(void *U) +{ + urlcontent *u = (urlcontent*) U; + free(u->url_data); + free(u); } /** @@ -63,57 +97,57 @@ void unescape_input(char *buf) */ void addurls(char *url) { - char *up, *ptr; - char buf[SIZ]; - int a, b, len, n; - struct urlcontent *u; - + char *aptr, *bptr, *eptr; + char *up; + char buf[SIZ] = ""; + int len, n, keylen; + urlcontent *u; + struct wcsession *WCC = WC; + + if (WCC->urlstrings == NULL) + WCC->urlstrings = NewHash(1, NULL); + eptr = buf + sizeof (buf); up = url; + /** locate the = sign */ + n = safestrncpy(buf, up, sizeof buf); + if (n < 0) /** hm, we exceeded the buffer... hmmm what todo now? */ + n = -n; + up = buf; +// while ((up < eptr) && (*up != '?') && (*up != '&')) +// up++; while (!IsEmptyStr(up)) { - - /** locate the = sign */ - n = safestrncpy(buf, up, sizeof buf); - if (n < 0) /** hm, we exceeded the buffer... hmmm what todo now? */ - n = -n; - b = (-1); - for (a = n; a >= 0; --a) - if (buf[a] == '=') - b = a; - if (b < 0) + aptr = up; + while ((aptr < eptr) && (*aptr != '\0') && (*aptr != '=')) + aptr++; + if (*aptr != '=') return; - buf[b] = 0; - - u = (struct urlcontent *) malloc(sizeof(struct urlcontent)); - u->next = WC->urlstrings; - WC->urlstrings = u; - safestrncpy(u->url_key, buf, sizeof u->url_key); - - /** now chop that part off */ - for (a = 0; a <= b; ++a) - ++up; - - /** locate "&" and "?" delimiters */ - ptr = up; - len = b = strlen(up); - for (a = 0; a < len; ++a) { - if ( (ptr[0] == '&') || (ptr[0] == '?') ) { - b = a; - break; - } - ++ptr; + *aptr = '\0'; + aptr++; + bptr = aptr; + while ((bptr < eptr) && (*bptr != '\0') + && (*bptr != '&') && (*bptr != '?') && (*bptr != ' ')) { + bptr++; + } + *bptr = '\0'; + u = (urlcontent *) malloc(sizeof(urlcontent)); + + keylen = safestrncpy(u->url_key, up, sizeof u->url_key); + if (keylen < 0){ + lprintf(1, "URLkey to long! [%s]", up); + continue; } - ptr = up + b; - *ptr = '\0'; - len = b; + Put(WCC->urlstrings, u->url_key, keylen, u, free_url); + len = bptr - aptr; u->url_data = malloc(len + 2); - safestrncpy(u->url_data, up, b + 1); - u->url_data[b] = 0; - unescape_input(u->url_data); - up = ptr; + safestrncpy(u->url_data, aptr, len + 2); + u->url_data_size = unescape_input(u->url_data); + u->url_data[u->url_data_size] = '\0'; + up = bptr; ++up; - - /* lprintf(9, "%s = %s\n", u->url_key, u->url_data); */ +/* + lprintf(9, "%s = [%ld] %s\n", u->url_key, u->url_data_size, u->url_data); +*/ } } @@ -122,24 +156,25 @@ void addurls(char *url) */ void free_urls(void) { - struct urlcontent *u; - - while (WC->urlstrings != NULL) { - free(WC->urlstrings->url_data); - u = WC->urlstrings->next; - free(WC->urlstrings); - WC->urlstrings = u; - } + DeleteHash(&WC->urlstrings); } /** * \brief Diagnostic function to display the contents of all variables */ + void dump_vars(void) { - struct urlcontent *u; - - for (u = WC->urlstrings; u != NULL; u = u->next) { + struct wcsession *WCC = WC; + urlcontent *u; + void *U; + long HKLen; + 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); } } @@ -148,15 +183,147 @@ void dump_vars(void) * \brief Return the value of a variable supplied to the current web page (from the url or a form) * \param key The name of the variable we want */ -char *bstr(char *key) + +const char *XBstr(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; + } + else { + *len = 0; + return (""); + } +} + +const char *XBSTR(char *key, size_t *len) { - struct urlcontent *u; + void *U; - for (u = WC->urlstrings; u != NULL; u = u->next) { - if (!strcasecmp(u->url_key, key)) - return (u->url_data); + if ((WC->urlstrings != NULL) && + GetHash(WC->urlstrings, key, strlen (key), &U)){ + *len = ((urlcontent *)U)->url_data_size; + return ((urlcontent *)U)->url_data; + } + else { + *len = 0; + return (""); } - return (""); +} + + +const char *BSTR(char *key) +{ + void *U; + + if ((WC->urlstrings != NULL) && + GetHash(WC->urlstrings, key, strlen (key), &U)) + return ((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 ((urlcontent *)U)->url_data; + else + return (""); +} + +long LBstr(char *key, size_t keylen) +{ + void *U; + + if ((WC->urlstrings != NULL) && + GetHash(WC->urlstrings, key, keylen, &U)) + return atol(((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 atol(((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 atoi(((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 atoi(((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 ((urlcontent *)U)->url_data_size != 0; + else + return (0); +} + +int HAVEBSTR(char *key) +{ + void *U; + + if ((WC->urlstrings != NULL) && + GetHash(WC->urlstrings, key, strlen(key), &U)) + return ((urlcontent *)U)->url_data_size != 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( ((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( ((urlcontent *)U)->url_data, "yes") == 0; + else + return (0); } /** @@ -729,7 +896,7 @@ void output_static(char *what) http_transmit_thing(bigbuffer, (size_t)bytes, content_type, 1); free(bigbuffer); } - if (!strcasecmp(bstr("force_close_session"), "yes")) { + if (yesbstr("force_close_session")) { end_webcit_session(); } } @@ -985,20 +1152,25 @@ void upload_handler(char *name, char *filename, char *partnum, char *disp, void *content, char *cbtype, char *cbcharset, size_t length, char *encoding, void *userdata) { - struct urlcontent *u; - + urlcontent *u; +/* lprintf(9, "upload_handler() name=%s, type=%s, len=%d\n", name, cbtype, length); +*/ + if (WC->urlstrings == NULL) + WC->urlstrings = NewHash(1, NULL); /* Form fields */ if ( (length > 0) && (IsEmptyStr(cbtype)) ) { - u = (struct urlcontent *) malloc(sizeof(struct urlcontent)); - u->next = WC->urlstrings; - WC->urlstrings = u; + 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; - /* lprintf(9, "Key: <%s> Data: <%s>\n", u->url_key, u->url_data); */ + Put(WC->urlstrings, u->url_key, strlen(u->url_key), u, free_url); + +/* lprintf(9, "Key: <%s> len: [%ld] Data: <%s>\n", u->url_key, u->url_data_size, u->url_data);*/ } /** Uploaded files */ @@ -1352,7 +1524,7 @@ void session_loop(struct httprequest *req) if (strlen(bstr("nonce")) > 0) { lprintf(9, "Comparing supplied nonce %s to session nonce %ld\n", bstr("nonce"), WC->nonce); - if (atoi(bstr("nonce")) != WC->nonce) { + if (ibstr("nonce") != WC->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"); @@ -1533,6 +1705,7 @@ void session_loop(struct httprequest *req) * Various commands... */ + else if (!strcasecmp(action, "do_welcome")) { do_welcome(); } else if (!strcasecmp(action, "blank")) { @@ -1872,7 +2045,7 @@ void session_loop(struct httprequest *req) else { display_main_menu(); } - +} SKIP_ALL_THIS_CRAP: fflush(stdout); if (content != NULL) {