]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
curl tool: reviewed code moved to tool_*.[ch] files
authorYang Tse <yangsita@gmail.com>
Mon, 3 Oct 2011 20:59:38 +0000 (22:59 +0200)
committerYang Tse <yangsita@gmail.com>
Mon, 3 Oct 2011 21:00:47 +0000 (23:00 +0200)
packages/Symbian/group/curl.mmp
src/Makefile.inc
src/Makefile.vc6
src/main.c
src/tool_binmode.c [new file with mode: 0644]
src/tool_binmode.h [new file with mode: 0644]
src/tool_formparse.c [new file with mode: 0644]
src/tool_formparse.h [new file with mode: 0644]
src/vc6curlsrc.dsp

index 7ea7555552b685f53acb02a1afd49542f046d820..ab20f7f20e83b87725b621b921914b55f985db87 100644 (file)
@@ -10,6 +10,7 @@ SOURCEPATH  ../../../src
 SOURCE \
     main.c hugehelp.c urlglob.c writeout.c writeenv.c \
     getpass.c homedir.c curlutil.c xattr.c \
+    tool_binmode.c \
     tool_bname.c \
     tool_cb_dbg.c \
     tool_cb_hdr.c \
@@ -23,6 +24,7 @@ SOURCE \
     tool_dirhie.c \
     tool_doswin.c \
     tool_easysrc.c \
+    tool_formparse.c \
     tool_libinfo.c \
     tool_mfiles.c \
     tool_msgs.c \
index 28d7f05d926d8255313a04b2a5c2794710653e38..640fd6332b12cb624a1ff84a608ea66062cb722b 100644 (file)
@@ -16,6 +16,7 @@ CURLX_ONES = $(top_srcdir)/lib/strtoofft.c \
 
 CURL_CFILES = main.c hugehelp.c urlglob.c writeout.c writeenv.c \
        getpass.c homedir.c curlutil.c xattr.c \
+       tool_binmode.c \
        tool_bname.c \
        tool_cb_dbg.c \
        tool_cb_hdr.c \
@@ -29,6 +30,7 @@ CURL_CFILES = main.c hugehelp.c urlglob.c writeout.c writeenv.c \
        tool_dirhie.c \
        tool_doswin.c \
        tool_easysrc.c \
+       tool_formparse.c \
        tool_libinfo.c \
        tool_mfiles.c \
        tool_msgs.c \
@@ -39,6 +41,7 @@ CURL_CFILES = main.c hugehelp.c urlglob.c writeout.c writeenv.c \
 CURL_HFILES = hugehelp.h setup.h config-win32.h config-mac.h \
        config-riscos.h urlglob.h version.h xattr.h \
        writeout.h writeenv.h getpass.h homedir.h curlutil.h \
+       tool_binmode.h \
        tool_bname.h \
        tool_cb_dbg.h \
        tool_cb_hdr.h \
@@ -52,6 +55,7 @@ CURL_HFILES = hugehelp.h setup.h config-win32.h config-mac.h \
        tool_dirhie.h \
        tool_doswin.h \
        tool_easysrc.h \
+       tool_formparse.h \
        tool_libinfo.h \
        tool_mfiles.h \
        tool_msgs.h \
index dce14182e609fa21872799c3bf26b1c0a63db514..9d6ea269ef15b9ef21d824801e6aa499bb292ee4 100644 (file)
@@ -141,6 +141,7 @@ RELEASE_OBJS= \
        nonblockr.obj \\r
        rawstrr.obj \\r
        strtoofftr.obj \\r
+       tool_binmoder.obj \\r
        tool_bnamer.obj \\r
        tool_cb_dbgr.obj \\r
        tool_cb_hdrr.obj \\r
@@ -154,6 +155,7 @@ RELEASE_OBJS= \
        tool_dirhier.obj \\r
        tool_doswinr.obj \\r
        tool_easysrcr.obj \\r
+       tool_formparser.obj \\r
        tool_libinfor.obj \\r
        tool_mfilesr.obj \\r
        tool_msgsr.obj \\r
@@ -174,6 +176,7 @@ DEBUG_OBJS= \
        nonblockd.obj \\r
        rawstrd.obj \\r
        strtoofftd.obj \\r
+       tool_binmoded.obj \\r
        tool_bnamed.obj \\r
        tool_cb_dbgd.obj \\r
        tool_cb_hdrd.obj \\r
@@ -187,6 +190,7 @@ DEBUG_OBJS= \
        tool_dirhied.obj \\r
        tool_doswind.obj \\r
        tool_easysrcd.obj \\r
+       tool_formparsed.obj \\r
        tool_libinfod.obj \\r
        tool_mfilesd.obj \\r
        tool_msgsd.obj \\r
@@ -336,6 +340,8 @@ rawstrr.obj: ../lib/rawstr.c
        $(CCR) $(CFLAGS) /Fo"$@" ../lib/rawstr.c\r
 strtoofftr.obj: ../lib/strtoofft.c\r
        $(CCR) $(CFLAGS) /Fo"$@" ../lib/strtoofft.c\r
+tool_binmoder.obj: tool_binmode.c\r
+       $(CCR) $(CFLAGS) /Fo"$@" tool_binmode.c\r
 tool_bnamer.obj: tool_bname.c\r
        $(CCR) $(CFLAGS) /Fo"$@" tool_bname.c\r
 tool_cb_dbgr.obj: tool_cb_dbg.c\r
@@ -362,6 +368,8 @@ tool_doswinr.obj: tool_doswin.c
        $(CCR) $(CFLAGS) /Fo"$@" tool_doswin.c\r
 tool_easysrcr.obj: tool_easysrc.c\r
        $(CCR) $(CFLAGS) /Fo"$@" tool_easysrc.c\r
+tool_formparser.obj: tool_formparse.c\r
+       $(CCR) $(CFLAGS) /Fo"$@" tool_formparse.c\r
 tool_libinfor.obj: tool_libinfo.c\r
        $(CCR) $(CFLAGS) /Fo"$@" tool_libinfo.c\r
 tool_mfilesr.obj: tool_mfiles.c\r
@@ -400,6 +408,8 @@ rawstrd.obj: ../lib/rawstr.c
        $(CCD) $(CFLAGS) /Fo"$@" ../lib/rawstr.c\r
 strtoofftd.obj: ../lib/strtoofft.c\r
        $(CCD) $(CFLAGS) /Fo"$@" ../lib/strtoofft.c\r
+tool_binmoded.obj: tool_binmode.c\r
+       $(CCD) $(CFLAGS) /Fo"$@" tool_binmode.c\r
 tool_bnamed.obj: tool_bname.c\r
        $(CCD) $(CFLAGS) /Fo"$@" tool_bname.c\r
 tool_cb_dbgd.obj: tool_cb_dbg.c\r
@@ -426,6 +436,8 @@ tool_doswind.obj: tool_doswin.c
        $(CCD) $(CFLAGS) /Fo"$@" tool_doswin.c\r
 tool_easysrcd.obj: tool_easysrc.c\r
        $(CCD) $(CFLAGS) /Fo"$@" tool_easysrc.c\r
+tool_formparsed.obj: tool_formparse.c\r
+       $(CCD) $(CFLAGS) /Fo"$@" tool_formparse.c\r
 tool_libinfod.obj: tool_libinfo.c\r
        $(CCD) $(CFLAGS) /Fo"$@" tool_libinfo.c\r
 tool_mfilesd.obj: tool_mfiles.c\r
index ce3f503f8c1fa076a1588ef1fb512ab9d3f88b54..f331e4d9a5464454a4e9c322a50e0ebafce02185 100644 (file)
 #include "tool_cb_hdr.h"
 #include "tool_cb_dbg.h"
 
+#include "tool_binmode.h"
+#include "tool_formparse.h"
+
 #ifdef USE_MANUAL
 #  include "hugehelp.h"
 #endif
@@ -151,16 +154,6 @@ static int vms_show = 0;
 
 #define DEFAULT_MAXREDIRS  50L
 
-#if defined(O_BINARY) && defined(HAVE_SETMODE)
-#ifdef __HIGHC__
-#define SET_BINMODE(file) _setmode(file,O_BINARY)
-#else
-#define SET_BINMODE(file) setmode(fileno(file),O_BINARY)
-#endif
-#else
-#define SET_BINMODE(file)   ((void)0)
-#endif
-
 #ifndef O_BINARY
 /* since O_BINARY as used in bitmasks, setting it to zero makes it usable in
    source code but yet it doesn't ruin anything */
@@ -193,35 +186,6 @@ char **__crt0_glob_function (char *arg)
 
 #define CURLseparator   "--_curl_--"
 
-/*
- * Default sizeof(off_t) in case it hasn't been defined in config file.
- */
-
-#ifndef SIZEOF_OFF_T
-#  if defined(__VMS) && !defined(__VAX)
-#    if defined(_LARGEFILE)
-#      define SIZEOF_OFF_T 8
-#    endif
-#  elif defined(__OS400__) && defined(__ILEC400__)
-#    if defined(_LARGE_FILES)
-#      define SIZEOF_OFF_T 8
-#    endif
-#  elif defined(__MVS__) && defined(__IBMC__)
-#    if defined(_LP64) || defined(_LARGE_FILES)
-#      define SIZEOF_OFF_T 8
-#    endif
-#  elif defined(__370__) && defined(__IBMC__)
-#    if defined(_LP64) || defined(_LARGE_FILES)
-#      define SIZEOF_OFF_T 8
-#    endif
-#  elif defined(TPF)
-#    define SIZEOF_OFF_T 8
-#  endif
-#  ifndef SIZEOF_OFF_T
-#    define SIZEOF_OFF_T 4
-#  endif
-#endif
-
 #define CURL_CA_CERT_ERRORMSG1                                          \
   "More details here: http://curl.haxx.se/docs/sslcerts.html\n\n"       \
   "curl performs SSL certificate verification by default, "             \
@@ -481,15 +445,6 @@ static int parseconfig(const char *filename,
                        struct Configurable *config);
 static char *my_get_line(FILE *fp);
 
-#if 0
-static void GetStr(char **string,
-                   const char *value)
-{
-  Curl_safefree(*string);
-  if(value)
-    *string = strdup(value);
-}
-#else
 #define GetStr(str,val) \
 do { \
   if(*(str)) { \
@@ -498,8 +453,9 @@ do { \
   } \
   if((val)) \
     *(str) = strdup((val)); \
+  if(!*(str)) \
+    return PARAM_NO_MEM; \
 } WHILE_FALSE
-#endif
 
 static void clean_getout(struct Configurable *config)
 {
@@ -552,285 +508,6 @@ static void list_engines(const struct curl_slist *engines)
     printf("  %s\n", engines->data);
 }
 
-/***************************************************************************
- *
- * formparse()
- *
- * Reads a 'name=value' parameter and builds the appropriate linked list.
- *
- * Specify files to upload with 'name=@filename'. Supports specified
- * given Content-Type of the files. Such as ';type=<content-type>'.
- *
- * If literal_value is set, any initial '@' or '<' in the value string
- * loses its special meaning, as does any embedded ';type='.
- *
- * You may specify more than one file for a single name (field). Specify
- * multiple files by writing it like:
- *
- * 'name=@filename,filename2,filename3'
- *
- * If you want content-types specified for each too, write them like:
- *
- * 'name=@filename;type=image/gif,filename2,filename3'
- *
- * If you want custom headers added for a single part, write them in a separate
- * file and do like this:
- *
- * 'name=foo;headers=@headerfile' or why not
- * 'name=@filemame;headers=@headerfile'
- *
- * To upload a file, but to fake the file name that will be included in the
- * formpost, do like this:
- *
- * 'name=@filename;filename=/dev/null'
- *
- * This function uses curl_formadd to fulfill it's job. Is heavily based on
- * the old curl_formparse code.
- *
- ***************************************************************************/
-
-#define FORM_FILE_SEPARATOR ','
-#define FORM_TYPE_SEPARATOR ';'
-
-static int formparse(struct Configurable *config,
-                     const char *input,
-                     struct curl_httppost **httppost,
-                     struct curl_httppost **last_post,
-                     bool literal_value)
-{
-  /* nextarg MUST be a string in the format 'name=contents' and we'll
-     build a linked list with the info */
-  char name[256];
-  char *contents;
-  char major[128];
-  char minor[128];
-  char *contp;
-  const char *type = NULL;
-  char *sep;
-  char *sep2;
-
-  if((1 == sscanf(input, "%255[^=]=", name)) &&
-     ((contp = strchr(input, '=')) != NULL)) {
-    /* the input was using the correct format */
-
-    /* Allocate the contents */
-    contents = strdup(contp+1);
-    if(!contents) {
-      fprintf(config->errors, "out of memory\n");
-      return 1;
-    }
-    contp = contents;
-
-    if('@' == contp[0] && !literal_value) {
-
-      /* we use the @-letter to indicate file name(s) */
-
-      struct multi_files *multi_start = NULL;
-      struct multi_files *multi_current = NULL;
-
-      contp++;
-
-      do {
-        /* since this was a file, it may have a content-type specifier
-           at the end too, or a filename. Or both. */
-        char *ptr;
-        char *filename=NULL;
-
-        sep=strchr(contp, FORM_TYPE_SEPARATOR);
-        sep2=strchr(contp, FORM_FILE_SEPARATOR);
-
-        /* pick the closest */
-        if(sep2 && (sep2 < sep)) {
-          sep = sep2;
-
-          /* no type was specified! */
-        }
-
-        type = NULL;
-
-        if(sep) {
-
-          /* if we got here on a comma, don't do much */
-          if(FORM_FILE_SEPARATOR == *sep)
-            ptr = NULL;
-          else
-            ptr = sep+1;
-
-          *sep=0; /* terminate file name at separator */
-
-          while(ptr && (FORM_FILE_SEPARATOR!= *ptr)) {
-
-            /* pass all white spaces */
-            while(ISSPACE(*ptr))
-              ptr++;
-
-            if(checkprefix("type=", ptr)) {
-              /* set type pointer */
-              type = &ptr[5];
-
-              /* verify that this is a fine type specifier */
-              if(2 != sscanf(type, "%127[^/]/%127[^;,\n]",
-                             major, minor)) {
-                warnf(config, "Illegally formatted content-type field!\n");
-                Curl_safefree(contents);
-                FreeMultiInfo(&multi_start, &multi_current);
-                return 2; /* illegal content-type syntax! */
-              }
-
-              /* now point beyond the content-type specifier */
-              sep = (char *)type + strlen(major)+strlen(minor)+1;
-
-              /* there's a semicolon following - we check if it is a filename
-                 specified and if not we simply assume that it is text that
-                 the user wants included in the type and include that too up
-                 to the next zero or semicolon. */
-              if((*sep==';') && !checkprefix(";filename=", sep)) {
-                sep2 = strchr(sep+1, ';');
-                if(sep2)
-                  sep = sep2;
-                else
-                  sep = sep+strlen(sep); /* point to end of string */
-              }
-
-              if(*sep) {
-                *sep=0; /* zero terminate type string */
-
-                ptr=sep+1;
-              }
-              else
-                ptr = NULL; /* end */
-            }
-            else if(checkprefix("filename=", ptr)) {
-              filename = &ptr[9];
-              ptr=strchr(filename, FORM_TYPE_SEPARATOR);
-              if(!ptr) {
-                ptr=strchr(filename, FORM_FILE_SEPARATOR);
-              }
-              if(ptr) {
-                *ptr=0; /* zero terminate */
-                ptr++;
-              }
-            }
-            else
-              /* confusion, bail out of loop */
-              break;
-          }
-          /* find the following comma */
-          if(ptr)
-            sep=strchr(ptr, FORM_FILE_SEPARATOR);
-          else
-            sep=NULL;
-        }
-        else {
-          sep=strchr(contp, FORM_FILE_SEPARATOR);
-        }
-        if(sep) {
-          /* the next file name starts here */
-          *sep =0;
-          sep++;
-        }
-        /* if type == NULL curl_formadd takes care of the problem */
-
-        if(!AddMultiFiles(contp, type, filename, &multi_start,
-                          &multi_current)) {
-          warnf(config, "Error building form post!\n");
-          Curl_safefree(contents);
-          return 3;
-        }
-        contp = sep; /* move the contents pointer to after the separator */
-
-      } while(sep && *sep); /* loop if there's another file name */
-
-      /* now we add the multiple files section */
-      if(multi_start) {
-        struct curl_forms *forms = NULL;
-        struct multi_files *ptr = multi_start;
-        unsigned int i, count = 0;
-        while(ptr) {
-          ptr = ptr->next;
-          ++count;
-        }
-        forms = malloc((count+1)*sizeof(struct curl_forms));
-        if(!forms) {
-          fprintf(config->errors, "Error building form post!\n");
-          Curl_safefree(contents);
-          FreeMultiInfo(&multi_start, &multi_current);
-          return 4;
-        }
-        for(i = 0, ptr = multi_start; i < count; ++i, ptr = ptr->next) {
-          forms[i].option = ptr->form.option;
-          forms[i].value = ptr->form.value;
-        }
-        forms[count].option = CURLFORM_END;
-        FreeMultiInfo(&multi_start, &multi_current);
-        if(curl_formadd(httppost, last_post,
-                        CURLFORM_COPYNAME, name,
-                        CURLFORM_ARRAY, forms, CURLFORM_END) != 0) {
-          warnf(config, "curl_formadd failed!\n");
-          Curl_safefree(forms);
-          Curl_safefree(contents);
-          return 5;
-        }
-        Curl_safefree(forms);
-      }
-    }
-    else {
-      struct curl_forms info[4];
-      int i = 0;
-      char *ct = literal_value? NULL: strstr(contp, ";type=");
-
-      info[i].option = CURLFORM_COPYNAME;
-      info[i].value = name;
-      i++;
-
-      if(ct) {
-        info[i].option = CURLFORM_CONTENTTYPE;
-        info[i].value = &ct[6];
-        i++;
-        ct[0]=0; /* zero terminate here */
-      }
-
-      if(contp[0]=='<' && !literal_value) {
-        info[i].option = CURLFORM_FILECONTENT;
-        info[i].value = contp+1;
-        i++;
-        info[i].option = CURLFORM_END;
-
-        if(curl_formadd(httppost, last_post,
-                        CURLFORM_ARRAY, info, CURLFORM_END ) != 0) {
-          warnf(config, "curl_formadd failed, possibly the file %s is bad!\n",
-                contp+1);
-          Curl_safefree(contents);
-          return 6;
-        }
-      }
-      else {
-#ifdef CURL_DOES_CONVERSIONS
-        convert_to_network(contp, strlen(contp));
-#endif
-        info[i].option = CURLFORM_COPYCONTENTS;
-        info[i].value = contp;
-        i++;
-        info[i].option = CURLFORM_END;
-        if(curl_formadd(httppost, last_post,
-                        CURLFORM_ARRAY, info, CURLFORM_END) != 0) {
-          warnf(config, "curl_formadd failed!\n");
-          Curl_safefree(contents);
-          return 7;
-        }
-      }
-    }
-
-  }
-  else {
-    warnf(config, "Illegally formatted input field!\n");
-    return 1;
-  }
-  Curl_safefree(contents);
-  return 0;
-}
-
-
 typedef enum {
   PARAM_OK,
   PARAM_OPTION_AMBIGUOUS,
@@ -2009,7 +1686,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
 
           if(curlx_strequal("-", p)) {
             file = stdin;
-            SET_BINMODE(stdin);
+            set_binmode(stdin);
           }
           else {
             file = fopen(p, "rb");
@@ -2072,7 +1749,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
         if(curlx_strequal("-", nextarg)) {
           file = stdin;
           if(subletter == 'b') /* forced data-binary */
-            SET_BINMODE(stdin);
+            set_binmode(stdin);
         }
         else {
           file = fopen(nextarg, "rb");
@@ -3666,7 +3343,7 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
           DEBUGASSERT(infdopen == FALSE);
           DEBUGASSERT(infd == STDIN_FILENO);
 
-          SET_BINMODE(stdin);
+          set_binmode(stdin);
           if(curlx_strequal(uploadfile, ".")) {
             if(curlx_nonblock((curl_socket_t)infd, TRUE) < 0)
               warnf(config,
@@ -3735,7 +3412,7 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
         if((!outfile || !strcmp(outfile, "-")) && !config->use_ascii) {
           /* We get the output to stdout and we have not got the ASCII/text
              flag, then set stdout to be binary */
-          SET_BINMODE(stdout);
+          set_binmode(stdout);
         }
 
         if(config->tcp_nodelay)
diff --git a/src/tool_binmode.c b/src/tool_binmode.c
new file mode 100644 (file)
index 0000000..4afe9a4
--- /dev/null
@@ -0,0 +1,48 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "setup.h"
+
+#ifdef HAVE_SETMODE
+
+#ifdef HAVE_IO_H
+#  include <io.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#  include <fcntl.h>
+#endif
+
+#include "tool_binmode.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+void set_binmode(FILE *stream)
+{
+#ifdef __HIGHC__
+  _setmode(stream, O_BINARY);
+#else
+  setmode(fileno(stream), O_BINARY);
+#endif
+}
+
+#endif /* HAVE_SETMODE */
+
diff --git a/src/tool_binmode.h b/src/tool_binmode.h
new file mode 100644 (file)
index 0000000..abd22e4
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef HEADER_CURL_TOOL_BINMODE_H
+#define HEADER_CURL_TOOL_BINMODE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "setup.h"
+
+#ifdef HAVE_SETMODE
+
+void set_binmode(FILE *stream);
+
+#else
+
+#define set_binmode(x) Curl_nop_stmt
+
+#endif /* HAVE_SETMODE */
+
+#endif /* HEADER_CURL_TOOL_BINMODE_H */
+
diff --git a/src/tool_formparse.c b/src/tool_formparse.c
new file mode 100644 (file)
index 0000000..5d6263e
--- /dev/null
@@ -0,0 +1,321 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "setup.h"
+
+#include <curl/curl.h>
+
+#include "rawstr.h"
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_cfgable.h"
+#include "tool_mfiles.h"
+#include "tool_msgs.h"
+#include "tool_formparse.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+/***************************************************************************
+ *
+ * formparse()
+ *
+ * Reads a 'name=value' parameter and builds the appropriate linked list.
+ *
+ * Specify files to upload with 'name=@filename'. Supports specified
+ * given Content-Type of the files. Such as ';type=<content-type>'.
+ *
+ * If literal_value is set, any initial '@' or '<' in the value string
+ * loses its special meaning, as does any embedded ';type='.
+ *
+ * You may specify more than one file for a single name (field). Specify
+ * multiple files by writing it like:
+ *
+ * 'name=@filename,filename2,filename3'
+ *
+ * If you want content-types specified for each too, write them like:
+ *
+ * 'name=@filename;type=image/gif,filename2,filename3'
+ *
+ * If you want custom headers added for a single part, write them in a separate
+ * file and do like this:
+ *
+ * 'name=foo;headers=@headerfile' or why not
+ * 'name=@filemame;headers=@headerfile'
+ *
+ * To upload a file, but to fake the file name that will be included in the
+ * formpost, do like this:
+ *
+ * 'name=@filename;filename=/dev/null'
+ *
+ * This function uses curl_formadd to fulfill it's job. Is heavily based on
+ * the old curl_formparse code.
+ *
+ ***************************************************************************/
+
+#define FORM_FILE_SEPARATOR ','
+#define FORM_TYPE_SEPARATOR ';'
+
+int formparse(struct Configurable *config,
+              const char *input,
+              struct curl_httppost **httppost,
+              struct curl_httppost **last_post,
+              bool literal_value)
+{
+  /* nextarg MUST be a string in the format 'name=contents' and we'll
+     build a linked list with the info */
+  char name[256];
+  char *contents = NULL;
+  char major[128];
+  char minor[128];
+  char *contp;
+  const char *type = NULL;
+  char *sep;
+  char *sep2;
+
+  if((1 == sscanf(input, "%255[^=]=", name)) &&
+     ((contp = strchr(input, '=')) != NULL)) {
+    /* the input was using the correct format */
+
+    /* Allocate the contents */
+    contents = strdup(contp+1);
+    if(!contents) {
+      fprintf(config->errors, "out of memory\n");
+      return 1;
+    }
+    contp = contents;
+
+    if('@' == contp[0] && !literal_value) {
+
+      /* we use the @-letter to indicate file name(s) */
+
+      struct multi_files *multi_start = NULL;
+      struct multi_files *multi_current = NULL;
+
+      contp++;
+
+      do {
+        /* since this was a file, it may have a content-type specifier
+           at the end too, or a filename. Or both. */
+        char *ptr;
+        char *filename = NULL;
+
+        sep = strchr(contp, FORM_TYPE_SEPARATOR);
+        sep2 = strchr(contp, FORM_FILE_SEPARATOR);
+
+        /* pick the closest */
+        if(sep2 && (sep2 < sep)) {
+          sep = sep2;
+
+          /* no type was specified! */
+        }
+
+        type = NULL;
+
+        if(sep) {
+
+          /* if we got here on a comma, don't do much */
+          if(FORM_FILE_SEPARATOR == *sep)
+            ptr = NULL;
+          else
+            ptr = sep+1;
+
+          *sep = '\0'; /* terminate file name at separator */
+
+          while(ptr && (FORM_FILE_SEPARATOR!= *ptr)) {
+
+            /* pass all white spaces */
+            while(ISSPACE(*ptr))
+              ptr++;
+
+            if(checkprefix("type=", ptr)) {
+              /* set type pointer */
+              type = &ptr[5];
+
+              /* verify that this is a fine type specifier */
+              if(2 != sscanf(type, "%127[^/]/%127[^;,\n]",
+                             major, minor)) {
+                warnf(config, "Illegally formatted content-type field!\n");
+                Curl_safefree(contents);
+                FreeMultiInfo(&multi_start, &multi_current);
+                return 2; /* illegal content-type syntax! */
+              }
+
+              /* now point beyond the content-type specifier */
+              sep = (char *)type + strlen(major)+strlen(minor)+1;
+
+              /* there's a semicolon following - we check if it is a filename
+                 specified and if not we simply assume that it is text that
+                 the user wants included in the type and include that too up
+                 to the next zero or semicolon. */
+              if((*sep==';') && !checkprefix(";filename=", sep)) {
+                sep2 = strchr(sep+1, ';');
+                if(sep2)
+                  sep = sep2;
+                else
+                  sep = sep + strlen(sep); /* point to end of string */
+              }
+
+              if(*sep) {
+                *sep = '\0'; /* zero terminate type string */
+
+                ptr = sep+1;
+              }
+              else
+                ptr = NULL; /* end */
+            }
+            else if(checkprefix("filename=", ptr)) {
+              filename = &ptr[9];
+              ptr = strchr(filename, FORM_TYPE_SEPARATOR);
+              if(!ptr) {
+                ptr = strchr(filename, FORM_FILE_SEPARATOR);
+              }
+              if(ptr) {
+                *ptr = '\0'; /* zero terminate */
+                ptr++;
+              }
+            }
+            else
+              /* confusion, bail out of loop */
+              break;
+          }
+          /* find the following comma */
+          if(ptr)
+            sep = strchr(ptr, FORM_FILE_SEPARATOR);
+          else
+            sep = NULL;
+        }
+        else {
+          sep = strchr(contp, FORM_FILE_SEPARATOR);
+        }
+        if(sep) {
+          /* the next file name starts here */
+          *sep = '\0';
+          sep++;
+        }
+        /* if type == NULL curl_formadd takes care of the problem */
+
+        if(!AddMultiFiles(contp, type, filename, &multi_start,
+                          &multi_current)) {
+          warnf(config, "Error building form post!\n");
+          Curl_safefree(contents);
+          FreeMultiInfo(&multi_start, &multi_current);
+          return 3;
+        }
+        contp = sep; /* move the contents pointer to after the separator */
+
+      } while(sep && *sep); /* loop if there's another file name */
+
+      /* now we add the multiple files section */
+      if(multi_start) {
+        struct curl_forms *forms = NULL;
+        struct multi_files *ptr = multi_start;
+        unsigned int i, count = 0;
+        while(ptr) {
+          ptr = ptr->next;
+          ++count;
+        }
+        forms = malloc((count+1)*sizeof(struct curl_forms));
+        if(!forms) {
+          fprintf(config->errors, "Error building form post!\n");
+          Curl_safefree(contents);
+          FreeMultiInfo(&multi_start, &multi_current);
+          return 4;
+        }
+        for(i = 0, ptr = multi_start; i < count; ++i, ptr = ptr->next) {
+          forms[i].option = ptr->form.option;
+          forms[i].value = ptr->form.value;
+        }
+        forms[count].option = CURLFORM_END;
+        FreeMultiInfo(&multi_start, &multi_current);
+        if(curl_formadd(httppost, last_post,
+                        CURLFORM_COPYNAME, name,
+                        CURLFORM_ARRAY, forms, CURLFORM_END) != 0) {
+          warnf(config, "curl_formadd failed!\n");
+          Curl_safefree(forms);
+          Curl_safefree(contents);
+          return 5;
+        }
+        Curl_safefree(forms);
+      }
+    }
+    else {
+      struct curl_forms info[4];
+      int i = 0;
+      char *ct = literal_value ? NULL : strstr(contp, ";type=");
+
+      info[i].option = CURLFORM_COPYNAME;
+      info[i].value = name;
+      i++;
+
+      if(ct) {
+        info[i].option = CURLFORM_CONTENTTYPE;
+        info[i].value = &ct[6];
+        i++;
+        ct[0] = '\0'; /* zero terminate here */
+      }
+
+      if(contp[0]=='<' && !literal_value) {
+        info[i].option = CURLFORM_FILECONTENT;
+        info[i].value = contp+1;
+        i++;
+        info[i].option = CURLFORM_END;
+
+        if(curl_formadd(httppost, last_post,
+                        CURLFORM_ARRAY, info, CURLFORM_END ) != 0) {
+          warnf(config, "curl_formadd failed, possibly the file %s is bad!\n",
+                contp+1);
+          Curl_safefree(contents);
+          return 6;
+        }
+      }
+      else {
+#ifdef CURL_DOES_CONVERSIONS
+        if(convert_to_network(contp, strlen(contp))) {
+          warnf(config, "curl_formadd failed!\n");
+          Curl_safefree(contents);
+          return 7;
+        }
+#endif
+        info[i].option = CURLFORM_COPYCONTENTS;
+        info[i].value = contp;
+        i++;
+        info[i].option = CURLFORM_END;
+        if(curl_formadd(httppost, last_post,
+                        CURLFORM_ARRAY, info, CURLFORM_END) != 0) {
+          warnf(config, "curl_formadd failed!\n");
+          Curl_safefree(contents);
+          return 8;
+        }
+      }
+    }
+
+  }
+  else {
+    warnf(config, "Illegally formatted input field!\n");
+    return 1;
+  }
+  Curl_safefree(contents);
+  return 0;
+}
+
diff --git a/src/tool_formparse.h b/src/tool_formparse.h
new file mode 100644 (file)
index 0000000..eebf507
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef HEADER_CURL_TOOL_FORMPARSE_H
+#define HEADER_CURL_TOOL_FORMPARSE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "setup.h"
+
+int formparse(struct Configurable *config,
+              const char *input,
+              struct curl_httppost **httppost,
+              struct curl_httppost **last_post,
+              bool literal_value);
+
+#endif /* HEADER_CURL_TOOL_FORMPARSE_H */
+
index f8dadbd6768ebe5fc1c755c56fe4300e9cd400f1..38d8a1ec71de7bf61038d7362cd435d0dada7b4d 100644 (file)
@@ -171,6 +171,10 @@ SOURCE=..\lib\strtoofft.c
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=.\tool_binmode.c\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=.\tool_bname.c\r
 # End Source File\r
 # Begin Source File\r
@@ -223,6 +227,10 @@ SOURCE=.\tool_easysrc.c
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=.\tool_formparse.c\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=.\tool_libinfo.c\r
 # End Source File\r
 # Begin Source File\r
@@ -303,6 +311,10 @@ SOURCE=..\lib\strtoofft.h
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=.\tool_binmode.h\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=.\tool_bname.h\r
 # End Source File\r
 # Begin Source File\r
@@ -355,6 +367,10 @@ SOURCE=.\tool_easysrc.h
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=.\tool_formparse.h\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=.\tool_libinfo.h\r
 # End Source File\r
 # Begin Source File\r