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='. - * - * 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, , 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 +#endif + +#ifdef HAVE_FCNTL_H +# include +#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, , 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, , 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 + +#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='. + * + * 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, , 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