From 530102b3b16fdc6f008cdf312e5977a878f295db Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sun, 10 Nov 2013 21:43:18 +0000 Subject: libcurl update git-svn-id: http://svn.miranda-ng.org/main/trunk@6864 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/FTPFileYM/curl/lib/formdata.c | 170 ++++++++++++++++++++++++---------- 1 file changed, 122 insertions(+), 48 deletions(-) (limited to 'plugins/FTPFileYM/curl/lib/formdata.c') diff --git a/plugins/FTPFileYM/curl/lib/formdata.c b/plugins/FTPFileYM/curl/lib/formdata.c index 2ba58dda1c..f718a3e4e9 100644 --- a/plugins/FTPFileYM/curl/lib/formdata.c +++ b/plugins/FTPFileYM/curl/lib/formdata.c @@ -24,9 +24,6 @@ #include -/* Length of the random boundary string. */ -#define BOUNDARY_LENGTH 40 - #if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) @@ -35,7 +32,7 @@ #include "urldata.h" /* for struct SessionHandle */ #include "formdata.h" -#include "curl_rand.h" +#include "sslgen.h" #include "strequal.h" #include "curl_memory.h" #include "sendf.h" @@ -56,6 +53,7 @@ static char *Curl_basename(char *path); #endif static size_t readfromfile(struct Form *form, char *buffer, size_t size); +static char *formboundary(struct SessionHandle *data); /* What kind of Content-Type to use on un-specified files with unrecognized extensions. */ @@ -170,8 +168,8 @@ static FormInfo * AddFormInfo(char *value, * Returns some valid contenttype for filename. * ***************************************************************************/ -static const char * ContentTypeForFilename (const char *filename, - const char *prevtype) +static const char *ContentTypeForFilename(const char *filename, + const char *prevtype) { const char *contenttype = NULL; unsigned int i; @@ -180,7 +178,7 @@ static const char * ContentTypeForFilename (const char *filename, * extensions and pick the first we match! */ struct ContentType { - char extension[6]; + const char *extension; const char *type; }; static const struct ContentType ctts[]={ @@ -428,7 +426,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, /* Get contents from a given file name */ case CURLFORM_FILECONTENT: - if(current_form->flags != 0) + if(current_form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE)) return_value = CURL_FORMADD_OPTION_TWICE; else { const char *filename = array_state? @@ -669,9 +667,11 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, if(((form->flags & HTTPPOST_FILENAME) || (form->flags & HTTPPOST_BUFFER)) && !form->contenttype ) { + char *f = form->flags & HTTPPOST_BUFFER? + form->showfilename : form->value; + /* our contenttype is missing */ - form->contenttype - = strdup(ContentTypeForFilename(form->value, prevtype)); + form->contenttype = strdup(ContentTypeForFilename(f, prevtype)); if(!form->contenttype) { return_value = CURL_FORMADD_MEMORY; break; @@ -776,6 +776,70 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost, return result; } +#ifdef __VMS +#include +/* + * get_vms_file_size does what it takes to get the real size of the file + * + * For fixed files, find out the size of the EOF block and adjust. + * + * For all others, have to read the entire file in, discarding the contents. + * Most posted text files will be small, and binary files like zlib archives + * and CD/DVD images should be either a STREAM_LF format or a fixed format. + * + */ +curl_off_t VmsRealFileSize(const char * name, + const struct_stat * stat_buf) +{ + char buffer[8192]; + curl_off_t count; + int ret_stat; + FILE * file; + + file = fopen(name, "r"); + if(file == NULL) + return 0; + + count = 0; + ret_stat = 1; + while(ret_stat > 0) { + ret_stat = fread(buffer, 1, sizeof(buffer), file); + if(ret_stat != 0) + count += ret_stat; + } + fclose(file); + + return count; +} + +/* + * + * VmsSpecialSize checks to see if the stat st_size can be trusted and + * if not to call a routine to get the correct size. + * + */ +static curl_off_t VmsSpecialSize(const char * name, + const struct_stat * stat_buf) +{ + switch(stat_buf->st_fab_rfm) { + case FAB$C_VAR: + case FAB$C_VFC: + return VmsRealFileSize(name, stat_buf); + break; + default: + return stat_buf->st_size; + } +} + +#endif + +#ifndef __VMS +#define filesize(name, stat_data) (stat_data.st_size) +#else + /* Getting the expected file size needs help on VMS */ +#define filesize(name, stat_data) VmsSpecialSize(name, &stat_data) +#endif + /* * AddFormData() adds a chunk of data to the FormData linked list. * @@ -830,8 +894,8 @@ static CURLcode AddFormData(struct FormData **formp, file */ if(!strequal("-", newform->line)) { struct_stat file; - if(!stat(newform->line, &file) && S_ISREG(file.st_mode)) - *size += file.st_size; + if(!stat(newform->line, &file) && !S_ISDIR(file.st_mode)) + *size += filesize(newform->line, file); else return CURLE_BAD_FUNCTION_ARGUMENT; } @@ -1100,7 +1164,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data, if(!post) return result; /* no input => no output! */ - boundary = Curl_FormBoundary(); + boundary = formboundary(data); if(!boundary) return CURLE_OUT_OF_MEMORY; @@ -1156,7 +1220,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data, the magic to include several files with the same field name */ Curl_safefree(fileboundary); - fileboundary = Curl_FormBoundary(); + fileboundary = formboundary(data); if(!fileboundary) { result = CURLE_OUT_OF_MEMORY; break; @@ -1342,6 +1406,36 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata ) return 0; } +#ifndef __VMS +# define fopen_read fopen +#else + /* + * vmsfopenread + * + * For upload to work as expected on VMS, different optional + * parameters must be added to the fopen command based on + * record format of the file. + * + */ +# define fopen_read vmsfopenread +static FILE * vmsfopenread(const char *file, const char *mode) { + struct_stat statbuf; + int result; + + result = stat(file, &statbuf); + + switch (statbuf.st_fab_rfm) { + case FAB$C_VAR: + case FAB$C_VFC: + case FAB$C_STMCR: + return fopen(file, "r"); + break; + default: + return fopen(file, "r", "rfm=stmlf", "ctx=stm"); + } +} +#endif + /* * readfromfile() * @@ -1364,7 +1458,7 @@ static size_t readfromfile(struct Form *form, char *buffer, else { if(!form->fp) { /* this file hasn't yet been opened */ - form->fp = fopen(form->data->line, "rb"); /* b is for binary */ + form->fp = fopen_read(form->data->line, "rb"); /* b is for binary */ if(!form->fp) return (size_t)-1; /* failure */ } @@ -1459,6 +1553,18 @@ char *Curl_formpostheader(void *formp, size_t *len) return header; } +/* + * formboundary() creates a suitable boundary string and returns an allocated + * one. + */ +static char *formboundary(struct SessionHandle *data) +{ + /* 24 dashes and 16 hexadecimal digits makes 64 bit (18446744073709551615) + combinations */ + return aprintf("------------------------%08x%08x", + Curl_rand(data), Curl_rand(data)); +} + #else /* CURL_DISABLE_HTTP */ CURLFORMcode curl_formadd(struct curl_httppost **httppost, struct curl_httppost **last_post, @@ -1484,37 +1590,5 @@ void curl_formfree(struct curl_httppost *form) /* does nothing HTTP is disabled */ } -#endif /* CURL_DISABLE_HTTP */ -#if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) - -/* - * Curl_FormBoundary() creates a suitable boundary string and returns an - * allocated one. This is also used by SSL-code so it must be present even - * if HTTP is disabled! - */ -char *Curl_FormBoundary(void) -{ - char *retstring; - size_t i; - - static const char table16[]="0123456789abcdef"; - - retstring = malloc(BOUNDARY_LENGTH+1); - - if(!retstring) - return NULL; /* failed */ - - strcpy(retstring, "----------------------------"); - - for(i=strlen(retstring); i