diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/formdata.c | 98 | 
1 files changed, 96 insertions, 2 deletions
| diff --git a/lib/formdata.c b/lib/formdata.c index 1984a9712..9d90f72e4 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -774,6 +774,70 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost,    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.   * @@ -829,7 +893,7 @@ static CURLcode AddFormData(struct FormData **formp,        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;        } @@ -1340,6 +1404,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()   * @@ -1362,7 +1456,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 */      } | 
