1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-22 08:08:50 -05:00

curl tool: reviewed code moved to tool_*.[ch] files

This commit is contained in:
Yang Tse 2011-10-03 22:59:38 +02:00
parent 56ed07f7df
commit 0435800f65
9 changed files with 482 additions and 332 deletions

View File

@ -10,6 +10,7 @@ SOURCEPATH ../../../src
SOURCE \ SOURCE \
main.c hugehelp.c urlglob.c writeout.c writeenv.c \ main.c hugehelp.c urlglob.c writeout.c writeenv.c \
getpass.c homedir.c curlutil.c xattr.c \ getpass.c homedir.c curlutil.c xattr.c \
tool_binmode.c \
tool_bname.c \ tool_bname.c \
tool_cb_dbg.c \ tool_cb_dbg.c \
tool_cb_hdr.c \ tool_cb_hdr.c \
@ -23,6 +24,7 @@ SOURCE \
tool_dirhie.c \ tool_dirhie.c \
tool_doswin.c \ tool_doswin.c \
tool_easysrc.c \ tool_easysrc.c \
tool_formparse.c \
tool_libinfo.c \ tool_libinfo.c \
tool_mfiles.c \ tool_mfiles.c \
tool_msgs.c \ tool_msgs.c \

View File

@ -16,6 +16,7 @@ CURLX_ONES = $(top_srcdir)/lib/strtoofft.c \
CURL_CFILES = main.c hugehelp.c urlglob.c writeout.c writeenv.c \ CURL_CFILES = main.c hugehelp.c urlglob.c writeout.c writeenv.c \
getpass.c homedir.c curlutil.c xattr.c \ getpass.c homedir.c curlutil.c xattr.c \
tool_binmode.c \
tool_bname.c \ tool_bname.c \
tool_cb_dbg.c \ tool_cb_dbg.c \
tool_cb_hdr.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_dirhie.c \
tool_doswin.c \ tool_doswin.c \
tool_easysrc.c \ tool_easysrc.c \
tool_formparse.c \
tool_libinfo.c \ tool_libinfo.c \
tool_mfiles.c \ tool_mfiles.c \
tool_msgs.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 \ CURL_HFILES = hugehelp.h setup.h config-win32.h config-mac.h \
config-riscos.h urlglob.h version.h xattr.h \ config-riscos.h urlglob.h version.h xattr.h \
writeout.h writeenv.h getpass.h homedir.h curlutil.h \ writeout.h writeenv.h getpass.h homedir.h curlutil.h \
tool_binmode.h \
tool_bname.h \ tool_bname.h \
tool_cb_dbg.h \ tool_cb_dbg.h \
tool_cb_hdr.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_dirhie.h \
tool_doswin.h \ tool_doswin.h \
tool_easysrc.h \ tool_easysrc.h \
tool_formparse.h \
tool_libinfo.h \ tool_libinfo.h \
tool_mfiles.h \ tool_mfiles.h \
tool_msgs.h \ tool_msgs.h \

View File

@ -141,6 +141,7 @@ RELEASE_OBJS= \
nonblockr.obj \ nonblockr.obj \
rawstrr.obj \ rawstrr.obj \
strtoofftr.obj \ strtoofftr.obj \
tool_binmoder.obj \
tool_bnamer.obj \ tool_bnamer.obj \
tool_cb_dbgr.obj \ tool_cb_dbgr.obj \
tool_cb_hdrr.obj \ tool_cb_hdrr.obj \
@ -154,6 +155,7 @@ RELEASE_OBJS= \
tool_dirhier.obj \ tool_dirhier.obj \
tool_doswinr.obj \ tool_doswinr.obj \
tool_easysrcr.obj \ tool_easysrcr.obj \
tool_formparser.obj \
tool_libinfor.obj \ tool_libinfor.obj \
tool_mfilesr.obj \ tool_mfilesr.obj \
tool_msgsr.obj \ tool_msgsr.obj \
@ -174,6 +176,7 @@ DEBUG_OBJS= \
nonblockd.obj \ nonblockd.obj \
rawstrd.obj \ rawstrd.obj \
strtoofftd.obj \ strtoofftd.obj \
tool_binmoded.obj \
tool_bnamed.obj \ tool_bnamed.obj \
tool_cb_dbgd.obj \ tool_cb_dbgd.obj \
tool_cb_hdrd.obj \ tool_cb_hdrd.obj \
@ -187,6 +190,7 @@ DEBUG_OBJS= \
tool_dirhied.obj \ tool_dirhied.obj \
tool_doswind.obj \ tool_doswind.obj \
tool_easysrcd.obj \ tool_easysrcd.obj \
tool_formparsed.obj \
tool_libinfod.obj \ tool_libinfod.obj \
tool_mfilesd.obj \ tool_mfilesd.obj \
tool_msgsd.obj \ tool_msgsd.obj \
@ -336,6 +340,8 @@ rawstrr.obj: ../lib/rawstr.c
$(CCR) $(CFLAGS) /Fo"$@" ../lib/rawstr.c $(CCR) $(CFLAGS) /Fo"$@" ../lib/rawstr.c
strtoofftr.obj: ../lib/strtoofft.c strtoofftr.obj: ../lib/strtoofft.c
$(CCR) $(CFLAGS) /Fo"$@" ../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 tool_bnamer.obj: tool_bname.c
$(CCR) $(CFLAGS) /Fo"$@" tool_bname.c $(CCR) $(CFLAGS) /Fo"$@" tool_bname.c
tool_cb_dbgr.obj: tool_cb_dbg.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 $(CCR) $(CFLAGS) /Fo"$@" tool_doswin.c
tool_easysrcr.obj: tool_easysrc.c tool_easysrcr.obj: tool_easysrc.c
$(CCR) $(CFLAGS) /Fo"$@" 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 tool_libinfor.obj: tool_libinfo.c
$(CCR) $(CFLAGS) /Fo"$@" tool_libinfo.c $(CCR) $(CFLAGS) /Fo"$@" tool_libinfo.c
tool_mfilesr.obj: tool_mfiles.c tool_mfilesr.obj: tool_mfiles.c
@ -400,6 +408,8 @@ rawstrd.obj: ../lib/rawstr.c
$(CCD) $(CFLAGS) /Fo"$@" ../lib/rawstr.c $(CCD) $(CFLAGS) /Fo"$@" ../lib/rawstr.c
strtoofftd.obj: ../lib/strtoofft.c strtoofftd.obj: ../lib/strtoofft.c
$(CCD) $(CFLAGS) /Fo"$@" ../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 tool_bnamed.obj: tool_bname.c
$(CCD) $(CFLAGS) /Fo"$@" tool_bname.c $(CCD) $(CFLAGS) /Fo"$@" tool_bname.c
tool_cb_dbgd.obj: tool_cb_dbg.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 $(CCD) $(CFLAGS) /Fo"$@" tool_doswin.c
tool_easysrcd.obj: tool_easysrc.c tool_easysrcd.obj: tool_easysrc.c
$(CCD) $(CFLAGS) /Fo"$@" 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 tool_libinfod.obj: tool_libinfo.c
$(CCD) $(CFLAGS) /Fo"$@" tool_libinfo.c $(CCD) $(CFLAGS) /Fo"$@" tool_libinfo.c
tool_mfilesd.obj: tool_mfiles.c tool_mfilesd.obj: tool_mfiles.c

View File

@ -113,6 +113,9 @@
#include "tool_cb_hdr.h" #include "tool_cb_hdr.h"
#include "tool_cb_dbg.h" #include "tool_cb_dbg.h"
#include "tool_binmode.h"
#include "tool_formparse.h"
#ifdef USE_MANUAL #ifdef USE_MANUAL
# include "hugehelp.h" # include "hugehelp.h"
#endif #endif
@ -151,16 +154,6 @@ static int vms_show = 0;
#define DEFAULT_MAXREDIRS 50L #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 #ifndef O_BINARY
/* since O_BINARY as used in bitmasks, setting it to zero makes it usable in /* since O_BINARY as used in bitmasks, setting it to zero makes it usable in
source code but yet it doesn't ruin anything */ source code but yet it doesn't ruin anything */
@ -193,35 +186,6 @@ char **__crt0_glob_function (char *arg)
#define CURLseparator "--_curl_--" #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 \ #define CURL_CA_CERT_ERRORMSG1 \
"More details here: http://curl.haxx.se/docs/sslcerts.html\n\n" \ "More details here: http://curl.haxx.se/docs/sslcerts.html\n\n" \
"curl performs SSL certificate verification by default, " \ "curl performs SSL certificate verification by default, " \
@ -481,15 +445,6 @@ static int parseconfig(const char *filename,
struct Configurable *config); struct Configurable *config);
static char *my_get_line(FILE *fp); 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) \ #define GetStr(str,val) \
do { \ do { \
if(*(str)) { \ if(*(str)) { \
@ -498,8 +453,9 @@ do { \
} \ } \
if((val)) \ if((val)) \
*(str) = strdup((val)); \ *(str) = strdup((val)); \
if(!*(str)) \
return PARAM_NO_MEM; \
} WHILE_FALSE } WHILE_FALSE
#endif
static void clean_getout(struct Configurable *config) 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); 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 { typedef enum {
PARAM_OK, PARAM_OK,
PARAM_OPTION_AMBIGUOUS, PARAM_OPTION_AMBIGUOUS,
@ -2009,7 +1686,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
if(curlx_strequal("-", p)) { if(curlx_strequal("-", p)) {
file = stdin; file = stdin;
SET_BINMODE(stdin); set_binmode(stdin);
} }
else { else {
file = fopen(p, "rb"); file = fopen(p, "rb");
@ -2072,7 +1749,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
if(curlx_strequal("-", nextarg)) { if(curlx_strequal("-", nextarg)) {
file = stdin; file = stdin;
if(subletter == 'b') /* forced data-binary */ if(subletter == 'b') /* forced data-binary */
SET_BINMODE(stdin); set_binmode(stdin);
} }
else { else {
file = fopen(nextarg, "rb"); file = fopen(nextarg, "rb");
@ -3666,7 +3343,7 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
DEBUGASSERT(infdopen == FALSE); DEBUGASSERT(infdopen == FALSE);
DEBUGASSERT(infd == STDIN_FILENO); DEBUGASSERT(infd == STDIN_FILENO);
SET_BINMODE(stdin); set_binmode(stdin);
if(curlx_strequal(uploadfile, ".")) { if(curlx_strequal(uploadfile, ".")) {
if(curlx_nonblock((curl_socket_t)infd, TRUE) < 0) if(curlx_nonblock((curl_socket_t)infd, TRUE) < 0)
warnf(config, warnf(config,
@ -3735,7 +3412,7 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
if((!outfile || !strcmp(outfile, "-")) && !config->use_ascii) { if((!outfile || !strcmp(outfile, "-")) && !config->use_ascii) {
/* We get the output to stdout and we have not got the ASCII/text /* We get the output to stdout and we have not got the ASCII/text
flag, then set stdout to be binary */ flag, then set stdout to be binary */
SET_BINMODE(stdout); set_binmode(stdout);
} }
if(config->tcp_nodelay) if(config->tcp_nodelay)

48
src/tool_binmode.c Normal file
View File

@ -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 */

37
src/tool_binmode.h Normal file
View File

@ -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 */

321
src/tool_formparse.c Normal file
View File

@ -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;
}

33
src/tool_formparse.h Normal file
View File

@ -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 */

View File

@ -171,6 +171,10 @@ SOURCE=..\lib\strtoofft.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\tool_binmode.c
# End Source File
# Begin Source File
SOURCE=.\tool_bname.c SOURCE=.\tool_bname.c
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -223,6 +227,10 @@ SOURCE=.\tool_easysrc.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\tool_formparse.c
# End Source File
# Begin Source File
SOURCE=.\tool_libinfo.c SOURCE=.\tool_libinfo.c
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -303,6 +311,10 @@ SOURCE=..\lib\strtoofft.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\tool_binmode.h
# End Source File
# Begin Source File
SOURCE=.\tool_bname.h SOURCE=.\tool_bname.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -355,6 +367,10 @@ SOURCE=.\tool_easysrc.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\tool_formparse.h
# End Source File
# Begin Source File
SOURCE=.\tool_libinfo.h SOURCE=.\tool_libinfo.h
# End Source File # End Source File
# Begin Source File # Begin Source File