version 1.1.1.1.2.2, 2012/03/09 10:03:21
|
version 1.4.6.1, 2013/01/17 14:52:44
|
Line 12 terms:
|
Line 12 terms:
|
All of the documentation and software included in the ELWIX and AITNET |
All of the documentation and software included in the ELWIX and AITNET |
Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org> |
Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org> |
|
|
Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 | Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 |
by Michael Pounov <misho@elwix.org>. All rights reserved. |
by Michael Pounov <misho@elwix.org>. All rights reserved. |
|
|
Redistribution and use in source and binary forms, with or without |
Redistribution and use in source and binary forms, with or without |
Line 44 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF TH
|
Line 44 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF TH
|
SUCH DAMAGE. |
SUCH DAMAGE. |
*/ |
*/ |
#include "global.h" |
#include "global.h" |
#include "tools.h" |
|
#include "mime.h" |
#include "mime.h" |
|
|
|
|
Line 76 www_SetErr(int eno, char *estr, ...)
|
Line 75 www_SetErr(int eno, char *estr, ...)
|
va_list lst; |
va_list lst; |
|
|
www_Errno = eno; |
www_Errno = eno; |
memset(www_Error, 0, STRSIZ); | memset(www_Error, 0, sizeof www_Errno); |
va_start(lst, estr); |
va_start(lst, estr); |
vsnprintf(www_Error, STRSIZ, estr, lst); | vsnprintf(www_Error, sizeof www_Errno, estr, lst); |
va_end(lst); |
va_end(lst); |
} |
} |
|
|
Line 99 www_initCGI(void)
|
Line 98 www_initCGI(void)
|
|
|
str = getenv("REQUEST_METHOD"); |
str = getenv("REQUEST_METHOD"); |
if (!str) { |
if (!str) { |
www_SetErr(EBADMSG, "Request method not found"); | www_SetErr(EFAULT, "Request method not found"); |
return NULL; |
return NULL; |
} |
} |
if (!strcmp(str, "GET") || !strcmp(str, "HEAD")) { |
if (!strcmp(str, "GET") || !strcmp(str, "HEAD")) { |
/* GET | HEAD */ |
/* GET | HEAD */ |
str = getenv("QUERY_STRING"); |
str = getenv("QUERY_STRING"); |
if (!str) { |
if (!str) { |
www_SetErr(EBADMSG, "Query string not found"); | www_SetErr(EFAULT, "Query string not found"); |
return NULL; |
return NULL; |
} |
} |
cgi = www_parseQuery(str); |
cgi = www_parseQuery(str); |
Line 114 www_initCGI(void)
|
Line 113 www_initCGI(void)
|
/* POST */ |
/* POST */ |
str = getenv("CONTENT_LENGTH"); |
str = getenv("CONTENT_LENGTH"); |
if (!str) { |
if (!str) { |
www_SetErr(EBADMSG, "Content length not found"); | www_SetErr(EFAULT, "Content length not found"); |
return NULL; |
return NULL; |
} else |
} else |
ctlen = strtol(str, NULL, 0); |
ctlen = strtol(str, NULL, 0); |
|
|
s = getenv("CONTENT_TYPE"); |
s = getenv("CONTENT_TYPE"); |
if (!s) { |
if (!s) { |
www_SetErr(EBADMSG, "Content type not found"); | www_SetErr(EFAULT, "Content type not found"); |
return NULL; |
return NULL; |
} |
} |
if (www_cmp(s, "multipart/form-data") && |
if (www_cmp(s, "multipart/form-data") && |
www_cmp(s, "application/x-www-form-urlencoded")) { |
www_cmp(s, "application/x-www-form-urlencoded")) { |
www_SetErr(EBADMSG, "MIME parts are broken"); | www_SetErr(EFAULT, "MIME parts are broken"); |
return NULL; |
return NULL; |
} |
} |
|
|
/* allocated space for post data */ |
/* allocated space for post data */ |
str = malloc(ctlen + 1); | str = e_malloc(ctlen + 1); |
if (!str) { |
if (!str) { |
LOGERR; | www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); |
return NULL; |
return NULL; |
} | } else |
| memset(str, 0, ctlen + 1); |
for (i = 0; i < ctlen && (rlen = |
for (i = 0; i < ctlen && (rlen = |
read(STDIN_FILENO, (void*) str + i, ctlen - i)) > 0; i += rlen); |
read(STDIN_FILENO, (void*) str + i, ctlen - i)) > 0; i += rlen); |
str[ctlen] = 0; |
str[ctlen] = 0; |
Line 145 www_initCGI(void)
|
Line 145 www_initCGI(void)
|
else if (!www_cmp(s, "multipart/form-data")) |
else if (!www_cmp(s, "multipart/form-data")) |
cgi = www_parseMultiPart(str, ctlen, s); |
cgi = www_parseMultiPart(str, ctlen, s); |
|
|
free(str); | e_free(str); |
} else { |
} else { |
/* Unknown method */ |
/* Unknown method */ |
www_SetErr(EBADMSG, "Unknown request method"); | www_SetErr(EFAULT, "Unknown request method"); |
return NULL; |
return NULL; |
} |
} |
|
|
Line 170 www_closeCGI(cgi_t ** __restrict cgi)
|
Line 170 www_closeCGI(cgi_t ** __restrict cgi)
|
return; |
return; |
|
|
while ((t = SLIST_FIRST(*cgi))) { |
while ((t = SLIST_FIRST(*cgi))) { |
if (t->cgi_name) | ait_freeVar(&t->cgi_name); |
free(t->cgi_name); | ait_freeVar(&t->cgi_value); |
if (t->cgi_value) | |
free(t->cgi_value); | |
|
|
SLIST_REMOVE_HEAD(*cgi, cgi_node); |
SLIST_REMOVE_HEAD(*cgi, cgi_node); |
free(t); | e_free(t); |
} |
} |
|
|
free(*cgi); | e_free(*cgi); |
*cgi = NULL; |
*cgi = NULL; |
} |
} |
|
|
Line 201 www_parseQuery(const char *str)
|
Line 199 www_parseQuery(const char *str)
|
return NULL; |
return NULL; |
} |
} |
|
|
cgi = malloc(sizeof(cgi_t)); | cgi = e_malloc(sizeof(cgi_t)); |
if (!cgi) { |
if (!cgi) { |
LOGERR; | www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); |
return NULL; |
return NULL; |
} else { |
} else { |
memset(cgi, 0, sizeof(cgi_t)); |
memset(cgi, 0, sizeof(cgi_t)); |
SLIST_INIT(cgi); |
SLIST_INIT(cgi); |
} |
} |
|
|
base = wrk = strdup(str); | base = wrk = e_strdup(str); |
|
|
while (*wrk) { |
while (*wrk) { |
t = malloc(sizeof(struct tagCGI)); | t = e_malloc(sizeof(struct tagCGI)); |
if (!t) { |
if (!t) { |
LOGERR; | www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); |
www_closeCGI(&cgi); |
www_closeCGI(&cgi); |
return NULL; |
return NULL; |
} else |
} else |
memset(t, 0, sizeof(struct tagCGI)); |
memset(t, 0, sizeof(struct tagCGI)); |
|
|
t->cgi_name = www_getpair(&wrk, "="); |
t->cgi_name = www_getpair(&wrk, "="); |
www_unescape(t->cgi_name); | www_unescape(AIT_GET_STR(t->cgi_name)); |
|
|
t->cgi_value = www_getpair(&wrk, "&;"); |
t->cgi_value = www_getpair(&wrk, "&;"); |
www_unescape(t->cgi_value); | www_unescape(AIT_GET_STR(t->cgi_value)); |
|
|
if (!old) |
if (!old) |
SLIST_INSERT_HEAD(cgi, t, cgi_node); |
SLIST_INSERT_HEAD(cgi, t, cgi_node); |
Line 234 www_parseQuery(const char *str)
|
Line 232 www_parseQuery(const char *str)
|
old = t; |
old = t; |
} |
} |
|
|
free(base); | e_free(base); |
return cgi; |
return cgi; |
} |
} |
|
|
Line 256 www_getValue(cgi_t * __restrict cgi, const char *name)
|
Line 254 www_getValue(cgi_t * __restrict cgi, const char *name)
|
} |
} |
|
|
SLIST_FOREACH(t, cgi, cgi_node) |
SLIST_FOREACH(t, cgi, cgi_node) |
if (t->cgi_name && !strcmp(name, t->cgi_name)) | if (t->cgi_name && !strcmp(name, AIT_GET_STR(t->cgi_name))) |
return t->cgi_value; | return AIT_GET_STR(t->cgi_value); |
|
|
return NULL; |
return NULL; |
} |
} |
Line 282 www_addValue(cgi_t * __restrict cgi, const char *name,
|
Line 280 www_addValue(cgi_t * __restrict cgi, const char *name,
|
|
|
/* search for update */ |
/* search for update */ |
SLIST_FOREACH_SAFE(t, cgi, cgi_node, tmp) { |
SLIST_FOREACH_SAFE(t, cgi, cgi_node, tmp) { |
if (t->cgi_name && !strcmp(name, t->cgi_name)) { | if (t->cgi_name && !strcmp(name, AIT_GET_STR(t->cgi_name))) { |
if (t->cgi_value) | AIT_FREE_VAL(t->cgi_value); |
free(t->cgi_value); | AIT_SET_STR(t->cgi_value, value); |
if (value) | |
t->cgi_value = strdup(value); | |
/* update */ |
/* update */ |
return 1; |
return 1; |
} |
} |
Line 296 www_addValue(cgi_t * __restrict cgi, const char *name,
|
Line 292 www_addValue(cgi_t * __restrict cgi, const char *name,
|
} |
} |
|
|
/* add new one */ |
/* add new one */ |
tmp = malloc(sizeof(struct tagCGI)); | tmp = e_malloc(sizeof(struct tagCGI)); |
if (!tmp) { |
if (!tmp) { |
LOGERR; | www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); |
return -1; |
return -1; |
} else |
} else |
memset(tmp, 0, sizeof(struct tagCGI)); |
memset(tmp, 0, sizeof(struct tagCGI)); |
|
|
tmp->cgi_name = strdup(name); | tmp->cgi_name = ait_allocVar(); |
if (value) | if (!tmp->cgi_name) { |
tmp->cgi_value = strdup(value); | www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); |
| e_free(tmp); |
| return -1; |
| } else |
| AIT_SET_STR(tmp->cgi_name, name); |
| tmp->cgi_value = ait_allocVar(); |
| if (!tmp->cgi_name) { |
| www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); |
| ait_freeVar(&tmp->cgi_name); |
| e_free(tmp); |
| return -1; |
| } else |
| AIT_SET_STR(tmp->cgi_value, value); |
|
|
if (!t) |
if (!t) |
SLIST_INSERT_HEAD(cgi, tmp, cgi_node); |
SLIST_INSERT_HEAD(cgi, tmp, cgi_node); |
Line 333 www_delPair(cgi_t * __restrict cgi, const char *name)
|
Line 341 www_delPair(cgi_t * __restrict cgi, const char *name)
|
|
|
/* search for delete */ |
/* search for delete */ |
SLIST_FOREACH_SAFE(t, cgi, cgi_node, tmp) |
SLIST_FOREACH_SAFE(t, cgi, cgi_node, tmp) |
if (t->cgi_name && !strcmp(name, t->cgi_name)) { | if (t->cgi_name && !strcmp(name, AIT_GET_STR(t->cgi_name))) { |
SLIST_REMOVE(cgi, t, tagCGI, cgi_node); |
SLIST_REMOVE(cgi, t, tagCGI, cgi_node); |
|
|
if (t->cgi_name) | ait_freeVar(&t->cgi_name); |
free(t->cgi_name); | ait_freeVar(&t->cgi_value); |
if (t->cgi_value) | e_free(t); |
free(t->cgi_value); | |
free(t); | |
return 1; |
return 1; |
} |
} |
|
|
Line 348 www_delPair(cgi_t * __restrict cgi, const char *name)
|
Line 354 www_delPair(cgi_t * __restrict cgi, const char *name)
|
} |
} |
|
|
/* |
/* |
|
* www_listPairs() - Walk over CGI session variables |
|
* |
|
* @cgi = Cgi session |
|
* @func = If !=NULL call function for each element |
|
* @arg = Optional argument pass through callback |
|
* return: -1 error or >-1 number of elements |
|
*/ |
|
inline int |
|
www_listPairs(cgi_t * __restrict cgi, list_cb_t func, void *arg) |
|
{ |
|
register int ret = 0; |
|
struct tagCGI *t; |
|
|
|
if (!cgi) { |
|
www_SetErr(EINVAL, "Invalid CGI session argument"); |
|
return -1; |
|
} |
|
|
|
SLIST_FOREACH(t, cgi, cgi_node) { |
|
ret++; |
|
|
|
if (func) |
|
func(t, arg); |
|
} |
|
|
|
return ret; |
|
} |
|
|
|
/* |
* www_header() - Output initial html header |
* www_header() - Output initial html header |
* |
* |
* @output = file handle |
* @output = file handle |
Line 361 www_header(FILE *output)
|
Line 396 www_header(FILE *output)
|
return fputs("Content-type: text/html\n\n", f); |
return fputs("Content-type: text/html\n\n", f); |
} |
} |
|
|
static char * | static ait_val_t * |
quotStr(const char *str, const char **end) |
quotStr(const char *str, const char **end) |
{ |
{ |
char *s, *e; | char *e; |
int n, len = 0; |
int n, len = 0; |
register int i; |
register int i; |
|
ait_val_t *s; |
|
|
/* get str w/o " */ |
/* get str w/o " */ |
if (*str != '"') { |
if (*str != '"') { |
n = strspn(str, "!#$%&'*+-.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
n = strspn(str, "!#$%&'*+-.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
"^_`abcdefghijklmnopqrstuvwxyz{|}~"); |
"^_`abcdefghijklmnopqrstuvwxyz{|}~"); |
s = malloc(n + 1); | s = ait_allocVar(); |
if (!s) { |
if (!s) { |
LOGERR; | www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); |
return NULL; |
return NULL; |
} else { |
} else { |
strncpy(s, str, n); | AIT_SET_STRSIZ(s, n + 1); |
s[n] = 0; | strlcpy(AIT_GET_STR(s), str, AIT_LEN(s)); |
*end = str + n; |
*end = str + n; |
return s; |
return s; |
} |
} |
Line 389 quotStr(const char *str, const char **end)
|
Line 425 quotStr(const char *str, const char **end)
|
return NULL; |
return NULL; |
else |
else |
len = e - str; |
len = e - str; |
s = malloc(len + 1); | |
| s = ait_allocVar(); |
if (!s) { |
if (!s) { |
LOGERR; | www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); |
return NULL; |
return NULL; |
|
} else { |
|
AIT_SET_STRSIZ(s, len + 1); |
|
e = AIT_GET_STR(s); |
} |
} |
|
|
for (i = 0; i < len; i++, str++) { |
for (i = 0; i < len; i++, str++) { |
if (*str == '\\' || *str == '\n') |
if (*str == '\\' || *str == '\n') |
s[i] = *++str; | e[i] = *++str; |
else if (*str == '"') |
else if (*str == '"') |
break; |
break; |
else |
else |
s[i] = *str; | e[i] = *str; |
} |
} |
s[i] = 0; | e[i] = 0; |
|
|
*end = ++str; |
*end = ++str; |
return s; |
return s; |
Line 413 static struct tagCGI *
|
Line 453 static struct tagCGI *
|
addAttr(const char **ct) |
addAttr(const char **ct) |
{ |
{ |
struct tagCGI *a; |
struct tagCGI *a; |
const char *c, *eq; | const char *c; |
char *name, *value; | char *eq; |
|
|
if (!*ct || !(c = strchr(*ct, ';'))) |
if (!*ct || !(c = strchr(*ct, ';'))) |
return NULL; |
return NULL; |
else |
else |
c++; |
c++; |
while (isspace(*c)) | while (isspace((int) *c)) |
c++; |
c++; |
|
|
if (!(eq = strchr(c, '='))) |
if (!(eq = strchr(c, '='))) |
return NULL; |
return NULL; |
|
|
/* parse name */ | a = e_malloc(sizeof(struct tagCGI)); |
name = malloc(eq - c + 1); | if (!a) { |
if (!name) { | www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); |
LOGERR; | |
return NULL; |
return NULL; |
} else { |
|
strncpy(name, c, eq - c); |
|
name[eq - c] = 0; |
|
} |
} |
/* parse value */ | a->cgi_name = ait_allocVar(); |
value = quotStr(++eq, &c); | if (!a->cgi_name) { |
if (!value) { | www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); |
free(name); | e_free(a); |
return NULL; |
return NULL; |
} |
} |
|
|
/* fill tagCGI */ | *eq++ = 0; |
a = malloc(sizeof(struct tagCGI)); | AIT_SET_STR(a->cgi_name, c); |
if (!a) { | a->cgi_value = quotStr(eq, &c); |
LOGERR; | if (!a->cgi_value) { |
| ait_freeVar(&a->cgi_name); |
| e_free(a); |
return NULL; |
return NULL; |
} else { |
|
a->cgi_name = name; |
|
a->cgi_value = value; |
|
*ct = c; |
|
} |
} |
|
|
|
*ct = c; |
return a; |
return a; |
} |
} |
|
|
Line 472 www_parseMultiPart(const char *str, int ctlen, const c
|
Line 508 www_parseMultiPart(const char *str, int ctlen, const c
|
struct tagCGI *t, *old = NULL; |
struct tagCGI *t, *old = NULL; |
const char *s; |
const char *s; |
int len; |
int len; |
|
ait_val_t *v; |
|
|
if (!str) { |
if (!str) { |
www_SetErr(EINVAL, "String is NULL"); |
www_SetErr(EINVAL, "String is NULL"); |
return NULL; |
return NULL; |
} |
} |
|
|
cgi = malloc(sizeof(cgi_t)); | cgi = e_malloc(sizeof(cgi_t)); |
if (!cgi) { |
if (!cgi) { |
LOGERR; | www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); |
return NULL; |
return NULL; |
} else { |
} else { |
memset(cgi, 0, sizeof(cgi_t)); |
memset(cgi, 0, sizeof(cgi_t)); |
Line 493 www_parseMultiPart(const char *str, int ctlen, const c
|
Line 530 www_parseMultiPart(const char *str, int ctlen, const c
|
www_closeCGI(&cgi); |
www_closeCGI(&cgi); |
return NULL; |
return NULL; |
} |
} |
mime = mime_parseMultiPart(str, ctlen, www_getAttribute(attr, "boundary"), NULL); | v = www_getAttribute(attr, "boundary"); |
| mime = mime_parseMultiPart(str, ctlen, AIT_GET_STR(v), NULL); |
www_freeAttributes(&attr); |
www_freeAttributes(&attr); |
|
if (!mime) { |
|
www_closeCGI(&cgi); |
|
return NULL; |
|
} |
|
|
SLIST_FOREACH(m, mime, mime_node) { |
SLIST_FOREACH(m, mime, mime_node) { |
s = mime_getValue(m, "content-disposition"); |
s = mime_getValue(m, "content-disposition"); |
attr = www_parseAttributes(&s); |
attr = www_parseAttributes(&s); |
|
if (!www_getAttribute(attr, "name")) { |
|
www_freeAttributes(&attr); |
|
continue; |
|
} |
|
|
t = malloc(sizeof(struct tagCGI)); | t = e_malloc(sizeof(struct tagCGI)); |
if (!t) { |
if (!t) { |
LOGERR; | www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); |
mime_close(&mime); |
mime_close(&mime); |
www_closeCGI(&cgi); |
www_closeCGI(&cgi); |
return NULL; |
return NULL; |
} else |
} else |
memset(t, 0, sizeof(struct tagCGI)); |
memset(t, 0, sizeof(struct tagCGI)); |
|
|
t->cgi_name = strdup(www_getAttribute(attr, "name")); | AIT_COPY_VAL(t->cgi_name, www_getAttribute(attr, "name")); |
len = mime_calcRawSize(m); |
len = mime_calcRawSize(m); |
t->cgi_value = malloc(len + 1); | t->cgi_value = ait_allocVar(); |
if (t->cgi_value) { | if (!t->cgi_value) { |
len = mime_getRawData(m, t->cgi_value, len + 1); | www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); |
t->cgi_value[len] = 0; | ait_freeVar(&t->cgi_name); |
| e_free(t); |
| mime_close(&mime); |
| www_closeCGI(&cgi); |
| return NULL; |
| } else { |
| AIT_SET_STRSIZ(t->cgi_value, len + 1); |
| len = mime_getRawData(m, AIT_GET_STR(t->cgi_value), AIT_LEN(t->cgi_value)); |
} |
} |
|
|
www_freeAttributes(&attr); |
www_freeAttributes(&attr); |
Line 547 www_parseAttributes(const char **ct)
|
Line 600 www_parseAttributes(const char **ct)
|
return NULL; |
return NULL; |
} |
} |
|
|
attr = malloc(sizeof(cgi_t)); | attr = e_malloc(sizeof(cgi_t)); |
if (!attr) { |
if (!attr) { |
LOGERR; | www_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); |
return NULL; |
return NULL; |
} else { |
} else { |
memset(attr, 0, sizeof(cgi_t)); |
memset(attr, 0, sizeof(cgi_t)); |
Line 569 www_parseAttributes(const char **ct)
|
Line 622 www_parseAttributes(const char **ct)
|
} |
} |
|
|
/* |
/* |
* www_freeAttributes() - Free attributes | * www_getAttribute() - Get Attribute from attribute session |
* |
* |
* @attr = Attributes | * @cgi = Inited attribute session |
* return: none | * @name = Name of attribute variable |
| * return: NULL not found or !=NULL value |
*/ |
*/ |
inline void | inline ait_val_t * |
www_freeAttributes(cgi_t ** __restrict attr) | www_getAttribute(cgi_t * __restrict cgi, const char *name) |
{ |
{ |
struct tagCGI *t; |
struct tagCGI *t; |
|
|
if (!attr || !*attr) | if (!cgi || !name) { |
return; | www_SetErr(EINVAL, "Invalid argument(s)"); |
| return NULL; |
/* free mime attributes */ | |
while ((t = SLIST_FIRST(*attr))) { | |
if (t->cgi_name) | |
free(t->cgi_name); | |
if (t->cgi_value) | |
free(t->cgi_value); | |
SLIST_REMOVE_HEAD(*attr, cgi_node); | |
free(t); | |
} |
} |
|
|
free(*attr); | SLIST_FOREACH(t, cgi, cgi_node) |
*attr = NULL; | if (t->cgi_name && !strcmp(name, AIT_GET_STR(t->cgi_name))) |
} | |
| |
/* | |
* www_getAttribute() - Get attribute by name | |
* | |
* @attr = Attributes | |
* @name = Name of attribute | |
* return: NULL not found or !=NULL attribute value | |
*/ | |
inline const char * | |
www_getAttribute(cgi_t * __restrict attr, const char *name) | |
{ | |
struct tagCGI *t; | |
| |
SLIST_FOREACH(t, attr, cgi_node) | |
if (!strcasecmp(t->cgi_name, name)) | |
return t->cgi_value; |
return t->cgi_value; |
|
|
return NULL; |
return NULL; |
} |
} |
|
|