aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/Symbian/group/curl.mmp2
-rw-r--r--src/Makefile.inc4
-rw-r--r--src/Makefile.vc612
-rw-r--r--src/main.c341
-rw-r--r--src/tool_binmode.c48
-rw-r--r--src/tool_binmode.h37
-rw-r--r--src/tool_formparse.c321
-rw-r--r--src/tool_formparse.h33
-rw-r--r--src/vc6curlsrc.dsp16
9 files changed, 482 insertions, 332 deletions
diff --git a/packages/Symbian/group/curl.mmp b/packages/Symbian/group/curl.mmp
index 7ea755555..ab20f7f20 100644
--- a/packages/Symbian/group/curl.mmp
+++ b/packages/Symbian/group/curl.mmp
@@ -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 \
diff --git a/src/Makefile.inc b/src/Makefile.inc
index 28d7f05d9..640fd6332 100644
--- a/src/Makefile.inc
+++ b/src/Makefile.inc
@@ -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 \
diff --git a/src/Makefile.vc6 b/src/Makefile.vc6
index dce14182e..9d6ea269e 100644
--- a/src/Makefile.vc6
+++ b/src/Makefile.vc6
@@ -141,6 +141,7 @@ RELEASE_OBJS= \
nonblockr.obj \
rawstrr.obj \
strtoofftr.obj \
+ tool_binmoder.obj \
tool_bnamer.obj \
tool_cb_dbgr.obj \
tool_cb_hdrr.obj \
@@ -154,6 +155,7 @@ RELEASE_OBJS= \
tool_dirhier.obj \
tool_doswinr.obj \
tool_easysrcr.obj \
+ tool_formparser.obj \
tool_libinfor.obj \
tool_mfilesr.obj \
tool_msgsr.obj \
@@ -174,6 +176,7 @@ DEBUG_OBJS= \
nonblockd.obj \
rawstrd.obj \
strtoofftd.obj \
+ tool_binmoded.obj \
tool_bnamed.obj \
tool_cb_dbgd.obj \
tool_cb_hdrd.obj \
@@ -187,6 +190,7 @@ DEBUG_OBJS= \
tool_dirhied.obj \
tool_doswind.obj \
tool_easysrcd.obj \
+ tool_formparsed.obj \
tool_libinfod.obj \
tool_mfilesd.obj \
tool_msgsd.obj \
@@ -336,6 +340,8 @@ rawstrr.obj: ../lib/rawstr.c
$(CCR) $(CFLAGS) /Fo"$@" ../lib/rawstr.c
strtoofftr.obj: ../lib/strtoofft.c
$(CCR) $(CFLAGS) /Fo"$@" ../lib/strtoofft.c
+tool_binmoder.obj: tool_binmode.c
+ $(CCR) $(CFLAGS) /Fo"$@" tool_binmode.c
tool_bnamer.obj: tool_bname.c
$(CCR) $(CFLAGS) /Fo"$@" tool_bname.c
tool_cb_dbgr.obj: tool_cb_dbg.c
@@ -362,6 +368,8 @@ tool_doswinr.obj: tool_doswin.c
$(CCR) $(CFLAGS) /Fo"$@" tool_doswin.c
tool_easysrcr.obj: tool_easysrc.c
$(CCR) $(CFLAGS) /Fo"$@" tool_easysrc.c
+tool_formparser.obj: tool_formparse.c
+ $(CCR) $(CFLAGS) /Fo"$@" tool_formparse.c
tool_libinfor.obj: tool_libinfo.c
$(CCR) $(CFLAGS) /Fo"$@" tool_libinfo.c
tool_mfilesr.obj: tool_mfiles.c
@@ -400,6 +408,8 @@ rawstrd.obj: ../lib/rawstr.c
$(CCD) $(CFLAGS) /Fo"$@" ../lib/rawstr.c
strtoofftd.obj: ../lib/strtoofft.c
$(CCD) $(CFLAGS) /Fo"$@" ../lib/strtoofft.c
+tool_binmoded.obj: tool_binmode.c
+ $(CCD) $(CFLAGS) /Fo"$@" tool_binmode.c
tool_bnamed.obj: tool_bname.c
$(CCD) $(CFLAGS) /Fo"$@" tool_bname.c
tool_cb_dbgd.obj: tool_cb_dbg.c
@@ -426,6 +436,8 @@ tool_doswind.obj: tool_doswin.c
$(CCD) $(CFLAGS) /Fo"$@" tool_doswin.c
tool_easysrcd.obj: tool_easysrc.c
$(CCD) $(CFLAGS) /Fo"$@" tool_easysrc.c
+tool_formparsed.obj: tool_formparse.c
+ $(CCD) $(CFLAGS) /Fo"$@" tool_formparse.c
tool_libinfod.obj: tool_libinfo.c
$(CCD) $(CFLAGS) /Fo"$@" tool_libinfo.c
tool_mfilesd.obj: tool_mfiles.c
diff --git a/src/main.c b/src/main.c
index ce3f503f8..f331e4d9a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -113,6 +113,9 @@
#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
index 000000000..4afe9a413
--- /dev/null
+++ b/src/tool_binmode.c
@@ -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
index 000000000..abd22e44d
--- /dev/null
+++ b/src/tool_binmode.h
@@ -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
index 000000000..5d6263e5c
--- /dev/null
+++ b/src/tool_formparse.c
@@ -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
index 000000000..eebf507f4
--- /dev/null
+++ b/src/tool_formparse.h
@@ -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 */
+
diff --git a/src/vc6curlsrc.dsp b/src/vc6curlsrc.dsp
index f8dadbd67..38d8a1ec7 100644
--- a/src/vc6curlsrc.dsp
+++ b/src/vc6curlsrc.dsp
@@ -171,6 +171,10 @@ SOURCE=..\lib\strtoofft.c
# End Source File
# Begin Source File
+SOURCE=.\tool_binmode.c
+# End Source File
+# Begin Source File
+
SOURCE=.\tool_bname.c
# End Source File
# Begin Source File
@@ -223,6 +227,10 @@ SOURCE=.\tool_easysrc.c
# End Source File
# Begin Source File
+SOURCE=.\tool_formparse.c
+# End Source File
+# Begin Source File
+
SOURCE=.\tool_libinfo.c
# End Source File
# Begin Source File
@@ -303,6 +311,10 @@ SOURCE=..\lib\strtoofft.h
# End Source File
# Begin Source File
+SOURCE=.\tool_binmode.h
+# End Source File
+# Begin Source File
+
SOURCE=.\tool_bname.h
# End Source File
# Begin Source File
@@ -355,6 +367,10 @@ SOURCE=.\tool_easysrc.h
# End Source File
# Begin Source File
+SOURCE=.\tool_formparse.h
+# End Source File
+# Begin Source File
+
SOURCE=.\tool_libinfo.h
# End Source File
# Begin Source File