diff options
author | John E. Malmberg <wb8tyw@qsl.net> | 2013-07-22 22:15:27 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2013-07-22 22:30:05 +0200 |
commit | 5880db8abd656413e1dc54881d347edaf78f1399 (patch) | |
tree | 655932cae65a118b1969e6a6974b7bdc711a4a16 | |
parent | 0f4ba89ffdf93ed7883b4a1f53f1c383df4fcfad (diff) |
curl: fix upload of a zip file in OpenVMS
Two fixes:
1. Force output file format to be stream-lf so that partial downloads
can be continued.
This should have minor impact as if the file does not exist, it was
created with stream-lf format. The only time this was an issue is if
there was already an existing file with a different format.
2. Fix file uploads are now fixed.
a. VMS binary files such as ZIP archives are now uploaded
correctly.
b. VMS text files are read once to get the correct size
and then converted to line-feed terminated records as
they are read into curl.
The default VMS text formats do not contain either line-feed or
carriage-return terminated records. Those delimiters are added by the
operating system file read calls if the application requests them.
Bug: http://curl.haxx.se/bug/view.cgi?id=496
-rw-r--r-- | src/tool_operate.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/src/tool_operate.c b/src/tool_operate.c index 292e3eb64..a29c6bb0e 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -119,6 +119,64 @@ static int is_fatal_error(int code) return 0; } +#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. + * + */ +static curl_off_t vms_realfilesize(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 vms_realfilesize(name, stat_buf); + break; + default: + return stat_buf->st_size; + } +} + +#endif + + int operate(struct Configurable *config, int argc, argv_item_t argv[]) { char errorbuffer[CURL_ERROR_SIZE]; @@ -664,7 +722,14 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) if(config->resume_from) { /* open file for output: */ +#ifndef __VMS FILE *file = fopen(outfile, config->resume_from?"ab":"wb"); +#else + /* Force VMS output format into stream mode which + is needed for the stat() call above to always work */ + FILE *file = fopen(outfile, config->resume_from?"ab":"wb", + "ctx=stm", "rfm=stmlf", "rat=cr", "mrs=0"); +#endif if(!file) { helpf(config->errors, "Can't open '%s'!\n", outfile); res = CURLE_WRITE_ERROR; @@ -707,8 +772,27 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) * to be considered with one appended if implied CC */ +#ifndef __VMS infd = open(uploadfile, O_RDONLY | O_BINARY); if((infd == -1) || fstat(infd, &fileinfo)) { +#else + /* Calculate the real upload site for VMS */ + infd = -1; + if(stat(uploadfile, &fileinfo) == 0) { + fileinfo.st_size = VmsSpecialSize(uploadfile, &fileinfo); + switch (fileinfo.st_fab_rfm) { + case FAB$C_VAR: + case FAB$C_VFC: + case FAB$C_STMCR: + infd = open(uploadfile, O_RDONLY | O_BINARY); + break; + default: + infd = open(uploadfile, O_RDONLY | O_BINARY, + "rfm=stmlf", "ctx=stm"); + } + } + if(infd == -1) { +#endif helpf(config->errors, "Can't open '%s'!\n", uploadfile); if(infd != -1) { close(infd); |