summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2020-08-24 08:31:36 +0200
committerDaniel Stenberg <daniel@haxx.se>2020-08-24 22:41:37 +0200
commit5620d2cc78c018f6ae15ba9aab371aa388146df0 (patch)
tree897b7e75250a644e5aeae81de5daf3498602286b /src
parent510d98157f21dee5793c4e975fde3317b6139267 (diff)
downloadcurl-5620d2cc78c018f6ae15ba9aab371aa388146df0.tar.gz
curl: add --output-dir
Works with --create-dirs and with -J Add test 3008, 3009, 3011, 3012 and 3013 to verify. Closes #5637
Diffstat (limited to 'src')
-rw-r--r--src/tool_cb_wrt.c32
-rw-r--r--src/tool_cfgable.c1
-rw-r--r--src/tool_cfgable.h1
-rw-r--r--src/tool_getparam.c5
-rw-r--r--src/tool_help.c2
-rw-r--r--src/tool_operate.c9
6 files changed, 40 insertions, 10 deletions
diff --git a/src/tool_cb_wrt.c b/src/tool_cb_wrt.c
index 64b62fefd..6fc51f9a5 100644
--- a/src/tool_cb_wrt.c
+++ b/src/tool_cb_wrt.c
@@ -39,6 +39,15 @@
#include "memdebug.h" /* keep this as LAST include */
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+#ifdef WIN32
+#define OPENMODE S_IREAD | S_IWRITE
+#else
+#define OPENMODE S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH
+#endif
+
/* create a local file for writing, return TRUE on success */
bool tool_create_output_file(struct OutStruct *outs,
struct OperationConfig *config)
@@ -55,21 +64,24 @@ bool tool_create_output_file(struct OutStruct *outs,
if(outs->is_cd_filename) {
/* don't overwrite existing files */
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
- int fd = open(outs->filename, O_CREAT | O_WRONLY | O_EXCL | O_BINARY,
-#ifdef WIN32
- S_IREAD | S_IWRITE
-#else
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH
-#endif
- );
+ int fd;
+ char *name = outs->filename;
+ char *aname = NULL;
+ if(config->output_dir) {
+ aname = aprintf("%s/%s", config->output_dir, name);
+ if(!aname) {
+ errorf(global, "out of memory\n");
+ return FALSE;
+ }
+ name = aname;
+ }
+ fd = open(name, O_CREAT | O_WRONLY | O_EXCL | O_BINARY, OPENMODE);
if(fd != -1) {
file = fdopen(fd, "wb");
if(!file)
close(fd);
}
+ free(aname);
}
else
/* open file for writing */
diff --git a/src/tool_cfgable.c b/src/tool_cfgable.c
index 63bdeaa46..e99602c4f 100644
--- a/src/tool_cfgable.c
+++ b/src/tool_cfgable.c
@@ -89,6 +89,7 @@ static void free_config_fields(struct OperationConfig *config)
Curl_safefree(config->mail_auth);
Curl_safefree(config->netrc_file);
+ Curl_safefree(config->output_dir);
urlnode = config->url_list;
while(urlnode) {
diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h
index 4a90d0b72..620bfef3e 100644
--- a/src/tool_cfgable.h
+++ b/src/tool_cfgable.h
@@ -80,6 +80,7 @@ struct OperationConfig {
double connecttimeout;
long maxredirs;
curl_off_t max_filesize;
+ char *output_dir;
char *headerfile;
char *ftpport;
char *iface;
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index 0648c29b9..74b6b7369 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -303,6 +303,7 @@ static const struct LongShort aliases[]= {
{"o", "output", ARG_FILENAME},
{"O", "remote-name", ARG_NONE},
{"Oa", "remote-name-all", ARG_BOOL},
+ {"Ob", "output-dir", ARG_STRING},
{"p", "proxytunnel", ARG_BOOL},
{"P", "ftp-port", ARG_STRING},
{"q", "disable", ARG_BOOL},
@@ -1911,6 +1912,10 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
config->default_node_flags = toggle?GETOUT_USEREMOTE:0;
break;
}
+ else if(subletter == 'b') { /* --output-dir */
+ GetStr(&config->output_dir, nextarg);
+ break;
+ }
/* FALLTHROUGH */
case 'o': /* --output */
/* output file */
diff --git a/src/tool_help.c b/src/tool_help.c
index 0fc818d3c..29680d05a 100644
--- a/src/tool_help.c
+++ b/src/tool_help.c
@@ -284,6 +284,8 @@ static const struct helptxt helptext[] = {
"OAuth 2 Bearer Token"},
{"-o, --output <file>",
"Write to file instead of stdout"},
+ {" --output-dir <dir>",
+ "Directory to save files in"},
{"-Z, --parallel",
"Perform transfers in parallel"},
{" --parallel-immediate",
diff --git a/src/tool_operate.c b/src/tool_operate.c
index 1e4ed7df8..aaadeeb9d 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -1050,6 +1050,15 @@ static CURLcode single_transfer(struct GlobalConfig *global,
}
}
+ if(config->output_dir) {
+ char *d = aprintf("%s/%s", config->output_dir, per->outfile);
+ if(!d) {
+ result = CURLE_WRITE_ERROR;
+ break;
+ }
+ free(per->outfile);
+ per->outfile = d;
+ }
/* Create the directory hierarchy, if not pre-existent to a multiple
file output call */