Refactor utility functions into static library
[project/cgi-io.git] / main.c
diff --git a/main.c b/main.c
index 53c672836294df7f97074ef4492dd48030dcd056..ff9bb63f5cd8fabbb91aa06c61095c93379e8189 100644 (file)
--- a/main.c
+++ b/main.c
@@ -35,6 +35,7 @@
 #include <libubus.h>
 #include <libubox/blobmsg.h>
 
+#include "util.h"
 #include "multipart_parser.h"
 
 #ifndef O_TMPFILE
@@ -42,7 +43,6 @@
 #endif
 
 #define READ_BLOCK 4096
-#define POST_LIMIT 131072
 
 enum part {
        PART_UNKNOWN,
@@ -173,201 +173,6 @@ checksum(const char *applet, size_t sumlen, const char *file)
        return chksum;
 }
 
-static char *
-datadup(const void *in, size_t len)
-{
-       char *out = malloc(len + 1);
-
-       if (!out)
-               return NULL;
-
-       memcpy(out, in, len);
-
-       *(out + len) = 0;
-
-       return out;
-}
-
-static bool
-urldecode(char *buf)
-{
-       char *c, *p;
-
-       if (!buf || !*buf)
-               return true;
-
-#define hex(x) \
-       (((x) <= '9') ? ((x) - '0') : \
-               (((x) <= 'F') ? ((x) - 'A' + 10) : \
-                       ((x) - 'a' + 10)))
-
-       for (c = p = buf; *p; c++)
-       {
-               if (*p == '%')
-               {
-                       if (!isxdigit(*(p + 1)) || !isxdigit(*(p + 2)))
-                               return false;
-
-                       *c = (char)(16 * hex(*(p + 1)) + hex(*(p + 2)));
-
-                       p += 3;
-               }
-               else if (*p == '+')
-               {
-                       *c = ' ';
-                       p++;
-               }
-               else
-               {
-                       *c = *p++;
-               }
-       }
-
-       *c = 0;
-
-       return true;
-}
-
-static char *
-postdecode(char **fields, int n_fields)
-{
-       const char *var;
-       char *p, *postbuf;
-       int i, field, found = 0;
-       ssize_t len = 0, rlen = 0, content_length = 0;
-
-       var = getenv("CONTENT_TYPE");
-
-       if (!var || strncmp(var, "application/x-www-form-urlencoded", 33))
-               return NULL;
-
-       var = getenv("CONTENT_LENGTH");
-
-       if (!var)
-               return NULL;
-
-       content_length = strtol(var, &p, 10);
-
-       if (p == var || content_length <= 0 || content_length >= POST_LIMIT)
-               return NULL;
-
-       postbuf = calloc(1, content_length + 1);
-
-       if (postbuf == NULL)
-               return NULL;
-
-       for (len = 0; len < content_length; )
-       {
-               rlen = read(0, postbuf + len, content_length - len);
-
-               if (rlen <= 0)
-                       break;
-
-               len += rlen;
-       }
-
-       if (len < content_length)
-       {
-               free(postbuf);
-               return NULL;
-       }
-
-       for (p = postbuf, i = 0; i <= len; i++)
-       {
-               if (postbuf[i] == '=')
-               {
-                       postbuf[i] = 0;
-
-                       for (field = 0; field < (n_fields * 2); field += 2)
-                       {
-                               if (!strcmp(p, fields[field]))
-                               {
-                                       fields[field + 1] = postbuf + i + 1;
-                                       found++;
-                               }
-                       }
-               }
-               else if (postbuf[i] == '&' || postbuf[i] == '\0')
-               {
-                       postbuf[i] = 0;
-
-                       if (found >= n_fields)
-                               break;
-
-                       p = postbuf + i + 1;
-               }
-       }
-
-       for (field = 0; field < (n_fields * 2); field += 2)
-       {
-               if (!urldecode(fields[field + 1]))
-               {
-                       free(postbuf);
-                       return NULL;
-               }
-       }
-
-       return postbuf;
-}
-
-static char *
-canonicalize_path(const char *path, size_t len)
-{
-       char *canonpath, *cp;
-       const char *p, *e;
-
-       if (path == NULL || *path == '\0')
-               return NULL;
-
-       canonpath = datadup(path, len);
-
-       if (canonpath == NULL)
-               return NULL;
-
-       /* normalize */
-       for (cp = canonpath, p = path, e = path + len; p < e; ) {
-               if (*p != '/')
-                       goto next;
-
-               /* skip repeating / */
-               if ((p + 1 < e) && (p[1] == '/')) {
-                       p++;
-                       continue;
-               }
-
-               /* /./ or /../ */
-               if ((p + 1 < e) && (p[1] == '.')) {
-                       /* skip /./ */
-                       if ((p + 2 >= e) || (p[2] == '/')) {
-                               p += 2;
-                               continue;
-                       }
-
-                       /* collapse /x/../ */
-                       if ((p + 2 < e) && (p[2] == '.') && ((p + 3 >= e) || (p[3] == '/'))) {
-                               while ((cp > canonpath) && (*--cp != '/'))
-                                       ;
-
-                               p += 3;
-                               continue;
-                       }
-               }
-
-next:
-               *cp++ = *p++;
-       }
-
-       /* remove trailing slash if not root / */
-       if ((cp > canonpath + 1) && (cp[-1] == '/'))
-               cp--;
-       else if (cp == canonpath)
-               *cp++ = '/';
-
-       *cp = '\0';
-
-       return canonpath;
-}
-
 static int
 response(bool success, const char *message)
 {
@@ -916,79 +721,6 @@ lookup_executable(const char *cmd)
        return NULL;
 }
 
-static char **
-parse_command(const char *cmdline)
-{
-       const char *p = cmdline, *s;
-       char **argv = NULL, *out;
-       size_t arglen = 0;
-       int argnum = 0;
-       bool esc;
-
-       while (isspace(*cmdline))
-               cmdline++;
-
-       for (p = cmdline, s = p, esc = false; p; p++) {
-               if (esc) {
-                       esc = false;
-               }
-               else if (*p == '\\' && p[1] != 0) {
-                       esc = true;
-               }
-               else if (isspace(*p) || *p == 0) {
-                       if (p > s) {
-                               argnum += 1;
-                               arglen += sizeof(char *) + (p - s) + 1;
-                       }
-
-                       s = p + 1;
-               }
-
-               if (*p == 0)
-                       break;
-       }
-
-       if (arglen == 0)
-               return NULL;
-
-       argv = calloc(1, arglen + sizeof(char *));
-
-       if (!argv)
-               return NULL;
-
-       out = (char *)argv + sizeof(char *) * (argnum + 1);
-       argv[0] = out;
-
-       for (p = cmdline, s = p, esc = false, argnum = 0; p; p++) {
-               if (esc) {
-                       esc = false;
-                       *out++ = *p;
-               }
-               else if (*p == '\\' && p[1] != 0) {
-                       esc = true;
-               }
-               else if (isspace(*p) || *p == 0) {
-                       if (p > s) {
-                               *out++ = ' ';
-                               argv[++argnum] = out;
-                       }
-
-                       s = p + 1;
-               }
-               else {
-                       *out++ = *p;
-               }
-
-               if (*p == 0)
-                       break;
-       }
-
-       argv[argnum] = NULL;
-       out[-1] = 0;
-
-       return argv;
-}
-
 static int
 main_exec(int argc, char **argv)
 {