aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn E. Malmberg <wb8tyw@qsl.net>2013-07-22 22:15:27 +0200
committerDaniel Stenberg <daniel@haxx.se>2013-07-22 22:30:05 +0200
commit5880db8abd656413e1dc54881d347edaf78f1399 (patch)
tree655932cae65a118b1969e6a6974b7bdc711a4a16
parent0f4ba89ffdf93ed7883b4a1f53f1c383df4fcfad (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.c84
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);