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:
parent
56ed07f7df
commit
0435800f65
@ -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 \
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
341
src/main.c
341
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)
|
||||
|
48
src/tool_binmode.c
Normal file
48
src/tool_binmode.c
Normal 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
37
src/tool_binmode.h
Normal 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
321
src/tool_formparse.c
Normal 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
33
src/tool_formparse.h
Normal 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 */
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user