diff options
Diffstat (limited to 'src/tool_operate.c')
-rw-r--r-- | src/tool_operate.c | 117 |
1 files changed, 82 insertions, 35 deletions
diff --git a/src/tool_operate.c b/src/tool_operate.c index ffb37ff1b..c9dda40b2 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -406,11 +406,26 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) char *outfiles; int infilenum; URLGlob *inglob; + int metalink; /* nonzero for metalink download */ + struct metalinkfile *mlfile; + metalink_resource_t **mlres; outfiles = NULL; infilenum = 1; inglob = NULL; + if(urlnode->flags & GETOUT_METALINK) { + metalink = 1; + mlfile = config->metalinkfile_last; + mlres = mlfile->file->resources; + config->metalinkfile_last = config->metalinkfile_last->next; + } + else { + metalink = 0; + mlfile = NULL; + mlres = NULL; + } + /* urlnode->url is the full URL (it might be NULL) */ if(!urlnode->url) { @@ -444,24 +459,6 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) } } - /* process metalink download in the separate function */ - if(urlnode->flags & GETOUT_METALINK) { - struct OutStruct outs; - long retry_sleep_default; - struct getout *nextnode; - - retry_sleep_default = (config->retry_delay) ? - config->retry_delay*1000L : RETRY_SLEEP_DEFAULT; /* ms */ - /* default output stream is stdout */ - memset(&outs, 0, sizeof(struct OutStruct)); - outs.stream = stdout; - outs.config = config; - operatemetalink(curl, urlnode, retry_sleep_default, outs, heads, - outfiles, config); - /* move on to the next URL */ - continue; - } - /* Here's the loop for uploading multiple files within the same single globbed string. If no upload, we enter the loop once anyway. */ for(up = 0 ; up < infilenum; up++) { @@ -497,7 +494,12 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) break; } - if(!config->globoff) { + if(metalink) { + /* For Metalink download, we don't use glob. Instead we use + the number of resources as urlnum. */ + urlnum = count_next_metalink_resource(mlfile); + } + else if(!config->globoff) { /* Unless explicitly shut off, we expand '{...}' and '[...]' expressions and return total number of URLs in pattern set */ res = glob_url(&urls, urlnode->url, &urlnum, @@ -528,39 +530,55 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) long retry_sleep; char *this_url; HeaderData hdrdata; + int metalink_next_res; outfile = NULL; infdopen = FALSE; infd = STDIN_FILENO; uploadfilesize = -1; /* -1 means unknown */ + metalink_next_res = 0; /* default output stream is stdout */ memset(&outs, 0, sizeof(struct OutStruct)); outs.stream = stdout; outs.config = config; - if(urls) { - res = glob_next_url(&this_url, urls); - if(res) + if(metalink) { + outfile = strdup(mlfile->file->name); + if(!outfile) { + res = CURLE_OUT_OF_MEMORY; goto show_error; - } - else if(!i) { - this_url = strdup(urlnode->url); + } + this_url = strdup((*mlres)->url); if(!this_url) { res = CURLE_OUT_OF_MEMORY; goto show_error; } } - else - this_url = NULL; - if(!this_url) - break; + else { + if(urls) { + res = glob_next_url(&this_url, urls); + if(res) + goto show_error; + } + else if(!i) { + this_url = strdup(urlnode->url); + if(!this_url) { + res = CURLE_OUT_OF_MEMORY; + goto show_error; + } + } + else + this_url = NULL; + if(!this_url) + break; - if(outfiles) { - outfile = strdup(outfiles); - if(!outfile) { - res = CURLE_OUT_OF_MEMORY; - goto show_error; + if(outfiles) { + outfile = strdup(outfiles); + if(!outfile) { + res = CURLE_OUT_OF_MEMORY; + goto show_error; + } } } @@ -1408,6 +1426,28 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) continue; /* curl_easy_perform loop */ } } /* if retry_numretries */ + else if(metalink) { + /* Metalink: Decide to try the next resource or + not. Basically, we want to try the next resource if + download was not successful. */ + long response; + if(CURLE_OK == res) { + /* TODO We want to try next resource when download was + not successful. How to know that? */ + char *effective_url = NULL; + curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &effective_url); + if(effective_url && + curlx_strnequal(effective_url, "http", 4)) { + /* This was HTTP(S) */ + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response); + if(response != 200 && response != 206) { + metalink_next_res = 1; + } + } + } + else + metalink_next_res = 1; + } /* In all ordinary cases, just break out of loop here */ break; /* curl_easy_perform loop */ @@ -1532,7 +1572,14 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) infd = STDIN_FILENO; } - if(urlnum > 1) { + if(metalink) { + if(is_fatal_error(res)) { + break; + } + if(!metalink_next_res || *(++mlres) == NULL) + break; + } + else if(urlnum > 1) { /* when url globbing, exit loop upon critical error */ if(is_fatal_error(res)) break; |