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;  | 
