mirror of
https://github.com/curl/curl.git
synced 2026-08-26 16:23:32 +03:00
curl: add --skip-existing
With this option, the entire download is skipped if the selected target filename already exists when the opertion is about to begin. Test 994, 995 and 996 verify. Ref: #11012 Closes #13993
This commit is contained in:
parent
eec908bb6e
commit
732cb15b97
13 changed files with 213 additions and 25 deletions
|
|
@ -302,6 +302,7 @@ struct OperationConfig {
|
|||
struct State state; /* for create_transfer() */
|
||||
bool rm_partial; /* on error, remove partially written output
|
||||
files */
|
||||
bool skip_existing;
|
||||
#ifdef USE_ECH
|
||||
char *ech; /* Config set by --ech keywords */
|
||||
char *ech_config; /* Config set by "--ech esl:" option */
|
||||
|
|
|
|||
|
|
@ -287,6 +287,7 @@ static const struct LongShort aliases[]= {
|
|||
{"show-error", ARG_BOOL, 'S', C_SHOW_ERROR},
|
||||
{"show-headers", ARG_BOOL, 'i', C_SHOW_HEADERS},
|
||||
{"silent", ARG_BOOL, 's', C_SILENT},
|
||||
{"skip-existing", ARG_BOOL, ' ', C_SKIP_EXISTING},
|
||||
{"socks4", ARG_STRG, ' ', C_SOCKS4},
|
||||
{"socks4a", ARG_STRG, ' ', C_SOCKS4A},
|
||||
{"socks5", ARG_STRG, ' ', C_SOCKS5},
|
||||
|
|
@ -2435,6 +2436,9 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
|||
case C_SILENT: /* --silent */
|
||||
global->silent = toggle;
|
||||
break;
|
||||
case C_SKIP_EXISTING: /* --skip-existing */
|
||||
config->skip_existing = toggle;
|
||||
break;
|
||||
case C_SHOW_ERROR: /* --show-error */
|
||||
global->showerror = toggle;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -242,6 +242,7 @@ typedef enum {
|
|||
C_SHOW_ERROR,
|
||||
C_SHOW_HEADERS,
|
||||
C_SILENT,
|
||||
C_SKIP_EXISTING,
|
||||
C_SOCKS4,
|
||||
C_SOCKS4A,
|
||||
C_SOCKS5,
|
||||
|
|
|
|||
|
|
@ -662,6 +662,9 @@ const struct helptxt helptext[] = {
|
|||
{"-s, --silent",
|
||||
"Silent mode",
|
||||
CURLHELP_IMPORTANT | CURLHELP_VERBOSE},
|
||||
{" --skip-existing",
|
||||
"Skip download if local file already exists",
|
||||
CURLHELP_CURL | CURLHELP_OUTPUT},
|
||||
{" --socks4 <host[:port]>",
|
||||
"SOCKS4 proxy on given host + port",
|
||||
CURLHELP_PROXY},
|
||||
|
|
|
|||
|
|
@ -460,6 +460,9 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
|
|||
if(per->infdopen)
|
||||
close(per->infd);
|
||||
|
||||
if(per->skip)
|
||||
goto skip;
|
||||
|
||||
#ifdef __VMS
|
||||
if(is_vms_shell()) {
|
||||
/* VMS DCL shell behavior */
|
||||
|
|
@ -731,7 +734,7 @@ noretry:
|
|||
curl_easy_getinfo(curl, CURLINFO_FILETIME_T, &filetime);
|
||||
setfiletime(filetime, outs->filename, global);
|
||||
}
|
||||
|
||||
skip:
|
||||
/* Write the --write-out data before cleanup but after result is final */
|
||||
if(config->writeout)
|
||||
ourWriteOut(config, per, result);
|
||||
|
|
@ -1197,6 +1200,15 @@ static CURLcode single_transfer(struct GlobalConfig *global,
|
|||
break;
|
||||
}
|
||||
|
||||
if(per->outfile && config->skip_existing) {
|
||||
struct_stat fileinfo;
|
||||
if(!stat(per->outfile, &fileinfo)) {
|
||||
/* file is present */
|
||||
notef(global, "skips transfer, \"%s\" exists locally",
|
||||
per->outfile);
|
||||
per->skip = TRUE;
|
||||
}
|
||||
}
|
||||
if((urlnode->flags & GETOUT_USEREMOTE)
|
||||
&& config->content_disposition) {
|
||||
/* Our header callback MIGHT set the filename */
|
||||
|
|
@ -2611,25 +2623,29 @@ static CURLcode serial_transfers(struct GlobalConfig *global,
|
|||
long delay_ms;
|
||||
bool bailout = FALSE;
|
||||
struct timeval start;
|
||||
result = pre_transfer(global, per);
|
||||
if(result)
|
||||
break;
|
||||
|
||||
if(global->libcurl) {
|
||||
result = easysrc_perform();
|
||||
start = tvnow();
|
||||
if(!per->skip) {
|
||||
result = pre_transfer(global, per);
|
||||
if(result)
|
||||
break;
|
||||
}
|
||||
start = tvnow();
|
||||
#ifdef DEBUGBUILD
|
||||
if(getenv("CURL_FORBID_REUSE"))
|
||||
(void)curl_easy_setopt(per->curl, CURLOPT_FORBID_REUSE, 1L);
|
||||
|
||||
if(global->test_event_based)
|
||||
result = curl_easy_perform_ev(per->curl);
|
||||
else
|
||||
if(global->libcurl) {
|
||||
result = easysrc_perform();
|
||||
if(result)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
if(getenv("CURL_FORBID_REUSE"))
|
||||
(void)curl_easy_setopt(per->curl, CURLOPT_FORBID_REUSE, 1L);
|
||||
|
||||
if(global->test_event_based)
|
||||
result = curl_easy_perform_ev(per->curl);
|
||||
else
|
||||
#endif
|
||||
result = curl_easy_perform(per->curl);
|
||||
result = curl_easy_perform(per->curl);
|
||||
}
|
||||
|
||||
returncode = post_per_transfer(global, per, result, &retry, &delay_ms);
|
||||
if(retry) {
|
||||
|
|
|
|||
|
|
@ -44,25 +44,16 @@ struct per_transfer {
|
|||
char *this_url;
|
||||
unsigned int urlnum; /* the index of the given URL */
|
||||
char *outfile;
|
||||
bool infdopen; /* TRUE if infd needs closing */
|
||||
int infd;
|
||||
bool noprogress;
|
||||
struct ProgressData progressbar;
|
||||
struct OutStruct outs;
|
||||
struct OutStruct heads;
|
||||
struct OutStruct etag_save;
|
||||
struct HdrCbData hdrcbdata;
|
||||
long num_headers;
|
||||
bool was_last_header_empty;
|
||||
|
||||
bool added; /* set TRUE when added to the multi handle */
|
||||
time_t startat; /* when doing parallel transfers, this is a retry transfer
|
||||
that has been set to sleep until this time before it
|
||||
should get started (again) */
|
||||
bool abort; /* when doing parallel transfers and this is TRUE then a critical
|
||||
error (eg --fail-early) has occurred in another transfer and
|
||||
this transfer will be aborted in the progress callback */
|
||||
|
||||
/* for parallel progress bar */
|
||||
curl_off_t dltotal;
|
||||
curl_off_t dlnow;
|
||||
|
|
@ -77,6 +68,15 @@ struct per_transfer {
|
|||
char *uploadfile;
|
||||
char *errorbuffer; /* allocated and assigned while this is used for a
|
||||
transfer */
|
||||
bool infdopen; /* TRUE if infd needs closing */
|
||||
bool noprogress;
|
||||
bool was_last_header_empty;
|
||||
|
||||
bool added; /* set TRUE when added to the multi handle */
|
||||
bool abort; /* when doing parallel transfers and this is TRUE then a critical
|
||||
error (eg --fail-early) has occurred in another transfer and
|
||||
this transfer will be aborted in the progress callback */
|
||||
bool skip; /* considered already done */
|
||||
};
|
||||
|
||||
CURLcode operate(struct GlobalConfig *config, int argc, argv_item_t argv[]);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue