diff options
| author | Yang Tse <yangsita@gmail.com> | 2011-10-03 22:59:38 +0200 | 
|---|---|---|
| committer | Yang Tse <yangsita@gmail.com> | 2011-10-03 23:00:47 +0200 | 
| commit | 0435800f65ce3eddd11ad6d6877d4d0818bfcaa6 (patch) | |
| tree | d97e0db63188b919e1fe57afb5ba0fb2ec0ad07c /src | |
| parent | 56ed07f7df5b743b25711e742d31126ce0b79baf (diff) | |
curl tool: reviewed code moved to tool_*.[ch] files
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.inc | 4 | ||||
| -rw-r--r-- | src/Makefile.vc6 | 12 | ||||
| -rw-r--r-- | src/main.c | 341 | ||||
| -rw-r--r-- | src/tool_binmode.c | 48 | ||||
| -rw-r--r-- | src/tool_binmode.h | 37 | ||||
| -rw-r--r-- | src/tool_formparse.c | 321 | ||||
| -rw-r--r-- | src/tool_formparse.h | 33 | ||||
| -rw-r--r-- | src/vc6curlsrc.dsp | 16 | 
8 files changed, 480 insertions, 332 deletions
| 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
 | 
