mirror of
https://github.com/curl/curl.git
synced 2026-08-25 22:13:33 +03:00
curl: add --output-dir
Works with --create-dirs and with -J Add test 3008, 3009, 3011, 3012 and 3013 to verify. Closes #5637
This commit is contained in:
parent
510d98157f
commit
5620d2cc78
17 changed files with 381 additions and 24 deletions
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ struct OperationConfig {
|
|||
double connecttimeout;
|
||||
long maxredirs;
|
||||
curl_off_t max_filesize;
|
||||
char *output_dir;
|
||||
char *headerfile;
|
||||
char *ftpport;
|
||||
char *iface;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue