[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnurl] 19/411: curl: add --output-dir
From: |
gnunet |
Subject: |
[gnurl] 19/411: curl: add --output-dir |
Date: |
Wed, 13 Jan 2021 01:17:14 +0100 |
This is an automated email from the git hooks/post-receive script.
nikita pushed a commit to branch master
in repository gnurl.
commit 5620d2cc78c018f6ae15ba9aab371aa388146df0
Author: Daniel Stenberg <daniel@haxx.se>
AuthorDate: Mon Aug 24 08:31:36 2020 +0200
curl: add --output-dir
Works with --create-dirs and with -J
Add test 3008, 3009, 3011, 3012 and 3013 to verify.
Closes #5637
---
docs/TODO | 7 -----
docs/cmdline-opts/Makefile.inc | 1 +
docs/cmdline-opts/output-dir.d | 18 +++++++++++
docs/options-in-versions | 1 +
src/tool_cb_wrt.c | 32 ++++++++++++++------
src/tool_cfgable.c | 1 +
src/tool_cfgable.h | 1 +
src/tool_getparam.c | 5 +++
src/tool_help.c | 2 ++
src/tool_operate.c | 9 ++++++
tests/data/Makefile.inc | 4 +--
tests/data/test3008 | 59 ++++++++++++++++++++++++++++++++++++
tests/data/test3009 | 59 ++++++++++++++++++++++++++++++++++++
tests/data/test3011 | 59 ++++++++++++++++++++++++++++++++++++
tests/data/test3012 | 62 +++++++++++++++++++++++++++++++++++++
tests/data/test3013 | 69 ++++++++++++++++++++++++++++++++++++++++++
tests/runtests.pl | 16 +++++++---
17 files changed, 381 insertions(+), 24 deletions(-)
diff --git a/docs/TODO b/docs/TODO
index 4f9b57bf6..874dba874 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -159,7 +159,6 @@
18.19 expand ~/ in config files
18.20 host name sections in config files
18.21 retry on the redirected-to URL
- 18.22 Add flag to specify download directory
18.23 Set the modification date on an uploaded file
18.24 Use multiple parallel transfers for a single download
@@ -1122,12 +1121,6 @@ that doesn't exist on the server, just like
--ftp-create-dirs.
See https://github.com/curl/curl/issues/5462
-18.22 Add flag to specify download directory
-
- A directory name to basically prepend to the file name -O and -o use. Saves
- user from having to manually "cd" to the directory. Especially useful for
- command lines with multiple -O and different download directories.
-
18.23 Set the modification date on an uploaded file
For SFTP and posssibly FTP, curl could offer an option to set the
diff --git a/docs/cmdline-opts/Makefile.inc b/docs/cmdline-opts/Makefile.inc
index 6a7b953bc..aa1acabe0 100644
--- a/docs/cmdline-opts/Makefile.inc
+++ b/docs/cmdline-opts/Makefile.inc
@@ -127,6 +127,7 @@ DPAGES = \
ntlm.d ntlm-wb.d \
oauth2-bearer.d \
output.d \
+ output-dir.d \
parallel-immediate.d \
parallel-max.d \
parallel.d \
diff --git a/docs/cmdline-opts/output-dir.d b/docs/cmdline-opts/output-dir.d
new file mode 100644
index 000000000..40bcb78ee
--- /dev/null
+++ b/docs/cmdline-opts/output-dir.d
@@ -0,0 +1,18 @@
+Long: output-dir
+Arg: <dir>
+Help: Directory to save files in
+Added: 7.72.0
+See-also: remote-name remote-header-name
+---
+
+This option specifies the directory in which files should be stored, when
+--remote-name or --output are used.
+
+The given output directory is used for all URLs and output options on the
+command line, up until the first --next.
+
+If the specified target directory doesn't exist, the operation will fail
+unless --create-dirs is also used.
+
+If this option is used multiple times, the last specified directory will be
+used.
diff --git a/docs/options-in-versions b/docs/options-in-versions
index 1a27306ae..2945e1373 100644
--- a/docs/options-in-versions
+++ b/docs/options-in-versions
@@ -127,6 +127,7 @@
--ntlm-wb 7.22.0
--oauth2-bearer 7.33.0
--output (-o) 4.0
+--output-dir 7.72.0
--parallel (-Z) 7.66.0
--parallel-immediate 7.68.0
--parallel-max 7.66.0
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 */
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 29d913f62..c13fb7307 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -224,5 +224,5 @@ test2078 \
test2080 \
test2100 \
\
-test3000 test3001 \
-test3002 test3003 test3004 test3005 test3006 test3007 test3010
+test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 \
+test3008 test3009 test3010 test3011 test3012 test3013
diff --git a/tests/data/test3008 b/tests/data/test3008
new file mode 100644
index 000000000..154ce2056
--- /dev/null
+++ b/tests/data/test3008
@@ -0,0 +1,59 @@
+<testcase>
+<info>
+<keywords>
+-O
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<features>
+http
+</features>
+<name>
+--output-dir
+</name>
+<command option="no-output,no-include">
+http://%HOSTIP:%HTTPPORT/this/is/the/3008 -O --output-dir %PWD/log
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /this/is/the/3008 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+
+</protocol>
+<file name="log/3008">
+-foo-
+</file>
+</verify>
+</testcase>
diff --git a/tests/data/test3009 b/tests/data/test3009
new file mode 100644
index 000000000..ec4bcea4d
--- /dev/null
+++ b/tests/data/test3009
@@ -0,0 +1,59 @@
+<testcase>
+<info>
+<keywords>
+-O
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<features>
+http
+</features>
+<name>
+--output-dir a non-existing directory
+</name>
+<command option="no-output,no-include">
+http://%HOSTIP:%HTTPPORT/this/is/the/3009 -O --output-dir %PWD/not-there
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /this/is/the/3009 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+
+</protocol>
+<errorcode>
+23
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/data/test3011 b/tests/data/test3011
new file mode 100644
index 000000000..fcf761050
--- /dev/null
+++ b/tests/data/test3011
@@ -0,0 +1,59 @@
+<testcase>
+<info>
+<keywords>
+-O
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<features>
+http
+</features>
+<name>
+--output-dir with --create-dirs
+</name>
+<command option="no-output,no-include">
+http://%HOSTIP:%HTTPPORT/this/is/the/3011 -O --output-dir %PWD/log/tmp
--create-dirs
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /this/is/the/3011 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+
+</protocol>
+<file name="log/tmp/3011">
+-foo-
+</file>
+</verify>
+</testcase>
diff --git a/tests/data/test3012 b/tests/data/test3012
new file mode 100644
index 000000000..0a64faac4
--- /dev/null
+++ b/tests/data/test3012
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+-O
+-J
+--output-dir
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Disposition: inline; filename="MMM3012MMM"
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<features>
+http
+</features>
+<name>
+--output-dir with -J
+</name>
+<command option="no-output,no-include">
+http://%HOSTIP:%HTTPPORT/this/is/the/3012 -OJ --output-dir %PWD/log
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /this/is/the/3012 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+
+</protocol>
+<file name="log/MMM3012MMM">
+-foo-
+</file>
+</verify>
+</testcase>
diff --git a/tests/data/test3013 b/tests/data/test3013
new file mode 100644
index 000000000..d2fcfa4c0
--- /dev/null
+++ b/tests/data/test3013
@@ -0,0 +1,69 @@
+<testcase>
+<info>
+<keywords>
+-O
+-J
+--output-dir
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Disposition: inline; filename="MMM3013MMM"
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<features>
+http
+</features>
+<name>
+Two --output-dir with --next in between
+</name>
+<command option="no-output,no-include">
+http://%HOSTIP:%HTTPPORT/this/is/the/3013 -O --output-dir %PWD/log
http://%HOSTIP:%HTTPPORT/another/3013 -o second3013 --output-dir %PWD/log
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /this/is/the/3013 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+
+GET /another/3013 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+
+</protocol>
+<file name="log/3013">
+-foo-
+</file>
+<file2 name="log/second3013">
+-foo-
+</file2>
+</verify>
+</testcase>
diff --git a/tests/runtests.pl b/tests/runtests.pl
index b0bddba1c..3985f7fde 100755
--- a/tests/runtests.pl
+++ b/tests/runtests.pl
@@ -2713,15 +2713,21 @@ sub cleardir {
my $file;
# Get all files
- opendir(DIR, $dir) ||
+ opendir(my $dh, $dir) ||
return 0; # can't open dir
- while($file = readdir(DIR)) {
- if(($file !~ /^\.(|\.)$/)) {
- unlink("$dir/$file");
+ while($file = readdir($dh)) {
+ if(($file !~ /^(\.|\.\.)\z/)) {
+ if(-d "$dir/$file") {
+ cleardir("$dir/$file");
+ rmdir("$dir/$file");
+ }
+ else {
+ unlink("$dir/$file");
+ }
$count++;
}
}
- closedir DIR;
+ closedir $dh;
return $count;
}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [gnurl] 14/411: curl: support XDG_CONFIG_HOME to find .curlrc, (continued)
- [gnurl] 14/411: curl: support XDG_CONFIG_HOME to find .curlrc, gnunet, 2021/01/12
- [gnurl] 20/411: docs: --output-dir is added in 7.73.0, nothing else, gnunet, 2021/01/12
- [gnurl] 34/411: socketpair: allow CURL_DISABLE_SOCKETPAIR, gnunet, 2021/01/12
- [gnurl] 22/411: select: fix poll-based check not detecting connect failure, gnunet, 2021/01/12
- [gnurl] 21/411: select.h: make socket validation macros test for INVALID_SOCKET, gnunet, 2021/01/12
- [gnurl] 23/411: select: reduce duplication of Curl_poll in Curl_socket_check, gnunet, 2021/01/12
- [gnurl] 28/411: winbuild/README.md: make <options> visible, gnunet, 2021/01/12
- [gnurl] 31/411: git: ignore libtests in 3XXX area, gnunet, 2021/01/12
- [gnurl] 26/411: lib1560: verify "redirect" to double-slash leading URL, gnunet, 2021/01/12
- [gnurl] 17/411: sftp: add the option CURLKHSTAT_FINE_REPLACE, gnunet, 2021/01/12
- [gnurl] 19/411: curl: add --output-dir,
gnunet <=
- [gnurl] 30/411: doh: add error message for DOH_DNS_NAME_TOO_LONG, gnunet, 2021/01/12
- [gnurl] 29/411: ngtcp2: adapt to the new pkt_info arguments, gnunet, 2021/01/12
- [gnurl] 16/411: RELEASE-NOTES: synced, gnunet, 2021/01/12
- [gnurl] 24/411: multi: implement wait using winsock events, gnunet, 2021/01/12
- [gnurl] 12/411: setopt: if the buffer exists, refuse the new BUFFERSIZE, gnunet, 2021/01/12
- [gnurl] 13/411: etag: save and use the full received contents, gnunet, 2021/01/12
- [gnurl] 27/411: winbuild: convert the instruction text to README.md, gnunet, 2021/01/12
- [gnurl] 15/411: checksrc: verify do-while and spaces between the braces, gnunet, 2021/01/12
- [gnurl] 59/411: docs: add description about CI platforms to CONTRIBUTE.md, gnunet, 2021/01/12
- [gnurl] 67/411: curl.1: add see also no-progress-meter on two spots, gnunet, 2021/01/12