Diff for /libaitwww/src/aitwww.c between versions 1.1 and 1.3.4.2

version 1.1, 2012/03/08 23:40:21 version 1.3.4.2, 2012/07/31 22:59:33
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 = io_malloc(ctlen + 1);
                 if (!str) {                  if (!str) {
                        LOGERR;                        www_SetErr(io_GetErrno(), "%s", io_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);                io_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)                io_freeVar(&t->cgi_name);
                        free(t->cgi_name);                io_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);                io_free(t);
         }          }
   
        free(*cgi);        io_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 = io_malloc(sizeof(cgi_t));
         if (!cgi) {          if (!cgi) {
                LOGERR;                www_SetErr(io_GetErrno(), "%s", io_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 = io_strdup(str);
   
         while (*wrk) {          while (*wrk) {
                t = malloc(sizeof(struct tagCGI));                t = io_malloc(sizeof(struct tagCGI));
                 if (!t) {                  if (!t) {
                        LOGERR;                        www_SetErr(io_GetErrno(), "%s", io_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);        io_free(base);
        return 0;        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)))
                        break;                        return AIT_GET_STR(t->cgi_value);
   
        return t->cgi_value;        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 = io_malloc(sizeof(struct tagCGI));
         if (!tmp) {          if (!tmp) {
                LOGERR;                www_SetErr(io_GetErrno(), "%s", io_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 = io_allocVar();
        if (value)        if (!tmp->cgi_name) {
                tmp->cgi_value = strdup(value);                www_SetErr(io_GetErrno(), "%s", io_GetError());
                 io_free(tmp);
                 return -1;
         } else
                 AIT_SET_STR(tmp->cgi_name, name);
         tmp->cgi_value = io_allocVar();
         if (!tmp->cgi_name) {
                 www_SetErr(io_GetErrno(), "%s", io_GetError());
                 io_freeVar(&tmp->cgi_name);
                 io_free(tmp);
                 return -1;
         } else
                 AIT_SET_STR(tmp->cgi_value, value);
   
        SLIST_INSERT_AFTER(t, tmp, cgi_node);        if (!t)
                 SLIST_INSERT_HEAD(cgi, tmp, cgi_node);
         else
                 SLIST_INSERT_AFTER(t, tmp, cgi_node);
         return 0;          return 0;
 }  }
   
Line 321  www_addValue(cgi_t * __restrict cgi, const char *name, Line 332  www_addValue(cgi_t * __restrict cgi, const char *name,
 int  int
 www_delPair(cgi_t * __restrict cgi, const char *name)  www_delPair(cgi_t * __restrict cgi, const char *name)
 {  {
        struct tagCGI *t;        struct tagCGI *t, *tmp;
   
         if (!cgi || !name) {          if (!cgi || !name) {
                 www_SetErr(EINVAL, "Invalid argument(s)");                  www_SetErr(EINVAL, "Invalid argument(s)");
Line 329  www_delPair(cgi_t * __restrict cgi, const char *name) Line 340  www_delPair(cgi_t * __restrict cgi, const char *name)
         }          }
   
         /* search for delete */          /* search for delete */
        SLIST_FOREACH(t, cgi, cgi_node)        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);
   
                           io_freeVar(&t->cgi_name);
                           io_freeVar(&t->cgi_value);
                           io_free(t);
                         return 1;                          return 1;
                 }                  }
   
Line 339  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 352  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 = io_allocVar();
                 if (!s) {                  if (!s) {
                        LOGERR;                        www_SetErr(io_GetErrno(), "%s", io_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 380  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 = io_allocVar();
         if (!s) {          if (!s) {
                LOGERR;                www_SetErr(io_GetErrno(), "%s", io_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 404  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;
Line 417  addAttr(const char **ct) Line 466  addAttr(const char **ct)
         if (!(eq = strchr(c, '=')))          if (!(eq = strchr(c, '=')))
                 return NULL;                  return NULL;
   
        /* parse name */        a = io_malloc(sizeof(struct tagCGI));
        name = malloc(eq - c + 1);        if (!a) {
        if (!name) {                www_SetErr(io_GetErrno(), "%s", io_GetError());
                LOGERR; 
                 return NULL;                  return NULL;
         } else {  
                 strncpy(name, c, eq - c);  
                 name[eq - c] = 0;  
         }          }
        /* parse value */        a->cgi_name = io_allocVar();
        value = quotStr(++eq, &c);        if (!a->cgi_name) {
        if (!value) {                www_SetErr(io_GetErrno(), "%s", io_GetError());
                free(name);                io_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) {
                 io_freeVar(&a->cgi_name);
                 io_free(a);
                 return NULL;                  return NULL;
         } else {  
                 a->cgi_name = name;  
                 a->cgi_value = value;  
                 *ct = c;  
         }          }
   
           *ct = c;
         return a;          return a;
 }  }
   
Line 463  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 = io_malloc(sizeof(cgi_t));
         if (!cgi) {          if (!cgi) {
                LOGERR;                www_SetErr(io_GetErrno(), "%s", io_GetError());
                 return NULL;                  return NULL;
         } else {          } else {
                 memset(cgi, 0, sizeof(cgi_t));                  memset(cgi, 0, sizeof(cgi_t));
Line 484  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 = io_malloc(sizeof(struct tagCGI));
                 if (!t) {                  if (!t) {
                        LOGERR;                        www_SetErr(io_GetErrno(), "%s", io_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 = io_allocVar();
                if (t->cgi_value) {                if (!t->cgi_value) {
                        len = mime_getRawData(m, t->cgi_value, len + 1);                        www_SetErr(io_GetErrno(), "%s", io_GetError());
                        t->cgi_value[len] = 0;                        io_freeVar(&t->cgi_name);
                         io_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 538  www_parseAttributes(const char **ct) Line 600  www_parseAttributes(const char **ct)
                 return NULL;                  return NULL;
         }          }
   
        attr = malloc(sizeof(cgi_t));        attr = io_malloc(sizeof(cgi_t));
         if (!attr) {          if (!attr) {
                LOGERR;                www_SetErr(io_GetErrno(), "%s", io_GetError());
                 return NULL;                  return NULL;
         } else {          } else {
                 memset(attr, 0, sizeof(cgi_t));                  memset(attr, 0, sizeof(cgi_t));
Line 560  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 voidinline 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;
 }  }
   

Removed from v.1.1  
changed lines
  Added in v.1.3.4.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>