* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, 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
#include <curl/curl.h>
-#if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY)
+#ifndef CURL_DISABLE_HTTP
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
#include <libgen.h>
#include "urldata.h" /* for struct SessionHandle */
#include "formdata.h"
-#include "sslgen.h"
+#include "vtls/vtls.h"
#include "strequal.h"
#include "curl_memory.h"
#include "sendf.h"
+#include "strdup.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
/* The last #include file should be: */
#include "memdebug.h"
-#endif /* !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) */
-
-#ifndef CURL_DISABLE_HTTP
-
#ifndef HAVE_BASENAME
static char *Curl_basename(char *path);
#define basename(x) Curl_basename((x))
* 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;
* extensions and pick the first we match!
*/
struct ContentType {
- char extension[6];
+ const char *extension;
const char *type;
};
static const struct ContentType ctts[]={
/***************************************************************************
*
- * memdup()
- *
- * Copies the 'source' data to a newly allocated buffer buffer (that is
- * returned). Uses buffer_length if not null, else uses strlen to determine
- * the length of the buffer to be copied
- *
- * Returns the new pointer or NULL on failure.
- *
- ***************************************************************************/
-static char *memdup(const char *src, size_t buffer_length)
-{
- size_t length;
- bool add = FALSE;
- char *buffer;
-
- if(buffer_length)
- length = buffer_length;
- else if(src) {
- length = strlen(src);
- add = TRUE;
- }
- else
- /* no length and a NULL src pointer! */
- return strdup("");
-
- buffer = malloc(length+add);
- if(!buffer)
- return NULL; /* fail */
-
- memcpy(buffer, src, length);
-
- /* if length unknown do null termination */
- if(add)
- buffer[length] = '\0';
-
- return buffer;
-}
-
-/***************************************************************************
- *
* FormAdd()
*
* Stores a formpost parameter and builds the appropriate linked list.
/* 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?
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;
(form == first_form) ) {
/* Note that there's small risk that form->name is NULL here if the
app passed in a bad combo, so we better check for that first. */
- if(form->name)
+ if(form->name) {
/* copy name (without strdup; possibly contains null characters) */
- form->name = memdup(form->name, form->namelength);
+ form->name = Curl_memdup(form->name, form->namelength?
+ form->namelength:
+ strlen(form->name)+1);
+ }
if(!form->name) {
return_value = CURL_FORMADD_MEMORY;
break;
}
if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
- HTTPPOST_CALLBACK)) ) {
+ HTTPPOST_CALLBACK)) && form->value) {
/* copy value (without strdup; possibly contains null characters) */
- form->value = memdup(form->value, form->contentslength);
+ form->value = Curl_memdup(form->value, form->contentslength?
+ form->contentslength:
+ strlen(form->value)+1);
if(!form->value) {
return_value = CURL_FORMADD_MEMORY;
break;
return result;
}
+#ifdef __VMS
+#include <fabdef.h>
+/*
+ * 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.
*
if(!strequal("-", newform->line)) {
struct_stat file;
if(!stat(newform->line, &file) && !S_ISDIR(file.st_mode))
- *size += file.st_size;
+ *size += filesize(newform->line, file);
else
return CURLE_BAD_FUNCTION_ARGUMENT;
}
int curl_formget(struct curl_httppost *form, void *arg,
curl_formget_callback append)
{
- CURLcode rc;
+ CURLcode result;
curl_off_t size;
struct FormData *data, *ptr;
- rc = Curl_getformdata(NULL, &data, form, NULL, &size);
- if(rc != CURLE_OK)
- return (int)rc;
+ result = Curl_getformdata(NULL, &data, form, NULL, &size);
+ if(result)
+ return (int)result;
for(ptr = data; ptr; ptr = ptr->next) {
if((ptr->type == FORM_FILE) || (ptr->type == FORM_CALLBACK)) {
/* filename need be escaped */
filename_escaped = malloc(strlen(filename)*2+1);
- if(!filename_escaped)
+ if(!filename_escaped) {
+ Curl_safefree(filebasename);
return CURLE_OUT_OF_MEMORY;
+ }
p0 = filename_escaped;
p1 = filename;
while(*p1) {
}
result = AddFormDataf(&form, &size,
- "\r\nContent-Type: multipart/mixed,"
+ "\r\nContent-Type: multipart/mixed;"
" boundary=%s\r\n",
fileboundary);
if(result)
} while((post = post->next) != NULL); /* for each field */
/* end-boundary for everything */
- if(CURLE_OK == result)
- result = AddFormDataf(&form, &size,
- "\r\n--%s--\r\n",
- boundary);
+ if(!result)
+ result = AddFormDataf(&form, &size, "\r\n--%s--\r\n", boundary);
if(result) {
Curl_formclean(&firstform);
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()
*
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 */
}