Loading src/tool_getparam.c +4 −59 Original line number Diff line number Diff line Loading @@ -829,65 +829,10 @@ ParameterError getparameter(char *flag, /* f or -long-flag */ case 'J': /* --metalink */ { #ifdef HAVE_LIBMETALINK metalink_error_t r; metalink_t* metalink; metalink_file_t **files; struct metalink *ml; r = metalink_parse_file(nextarg, &metalink); if(r != 0) { fprintf(stderr, "ERROR: code=%d\n", r); exit(EXIT_FAILURE); } ml = new_metalink(metalink); if(config->metalink_list) { config->metalink_last->next = ml; config->metalink_last = ml; } else { config->metalink_list = config->metalink_last = ml; } for(files = metalink->files; *files; ++files) { struct getout *url; /* Skip an entry which has no resource. */ if(!(*files)->resources[0]) continue; if(config->url_get || ((config->url_get = config->url_list) != NULL)) { /* there's a node here, if it already is filled-in continue to find an "empty" node */ while(config->url_get && (config->url_get->flags & GETOUT_URL)) config->url_get = config->url_get->next; } /* now there might or might not be an available node to fill in! */ if(config->url_get) /* existing node */ url = config->url_get; else /* there was no free node, create one! */ url=new_getout(config); if(url) { struct metalinkfile *mlfile; /* Set name as url */ GetStr(&url->url, (*files)->name); /* set flag metalink here */ url->flags |= GETOUT_URL | GETOUT_METALINK; mlfile = new_metalinkfile(*files); if(config->metalinkfile_list) { config->metalinkfile_last->next = mlfile; config->metalinkfile_last = mlfile; } else { config->metalinkfile_list = config->metalinkfile_last = mlfile; } } if(parse_metalink(config, nextarg) == -1) { warnf(config, "Could not parse Metalink file: %s\n", nextarg); /* TODO Is PARAM_BAD_USE appropriate here? */ return PARAM_BAD_USE; } #else warnf(config, "--metalink option is ignored because the binary is " Loading src/tool_metalink.c +78 −0 Original line number Diff line number Diff line Loading @@ -21,9 +21,23 @@ ***************************************************************************/ #include "tool_setup.h" #include "tool_metalink.h" #include "tool_getparam.h" #include "tool_paramhlp.h" #include "memdebug.h" /* keep this as LAST include */ /* Copied from tool_getparam.c */ #define GetStr(str,val) do { \ if(*(str)) { \ free(*(str)); \ *(str) = NULL; \ } \ if((val)) \ *(str) = strdup((val)); \ if(!(val)) \ return PARAM_NO_MEM; \ } WHILE_FALSE struct metalinkfile *new_metalinkfile(metalink_file_t *metalinkfile) { struct metalinkfile *f; f = (struct metalinkfile*)malloc(sizeof(struct metalinkfile)); Loading Loading @@ -64,3 +78,67 @@ void clean_metalink(struct Configurable *config) } config->metalink_last = 0; } int parse_metalink(struct Configurable *config, const char *infile) { metalink_error_t r; metalink_t* metalink; metalink_file_t **files; struct metalink *ml; r = metalink_parse_file(infile, &metalink); if(r != 0) { return -1; } ml = new_metalink(metalink); if(config->metalink_list) { config->metalink_last->next = ml; config->metalink_last = ml; } else { config->metalink_list = config->metalink_last = ml; } for(files = metalink->files; *files; ++files) { struct getout *url; /* Skip an entry which has no resource. */ if(!(*files)->resources[0]) continue; if(config->url_get || ((config->url_get = config->url_list) != NULL)) { /* there's a node here, if it already is filled-in continue to find an "empty" node */ while(config->url_get && (config->url_get->flags & GETOUT_URL)) config->url_get = config->url_get->next; } /* now there might or might not be an available node to fill in! */ if(config->url_get) /* existing node */ url = config->url_get; else /* there was no free node, create one! */ url=new_getout(config); if(url) { struct metalinkfile *mlfile; /* Set name as url */ GetStr(&url->url, (*files)->name); /* set flag metalink here */ url->flags |= GETOUT_URL | GETOUT_METALINK; mlfile = new_metalinkfile(*files); if(config->metalinkfile_list) { config->metalinkfile_last->next = mlfile; config->metalinkfile_last = mlfile; } else { config->metalinkfile_list = config->metalinkfile_last = mlfile; } } } return 0; } src/tool_metalink.h +2 −0 Original line number Diff line number Diff line Loading @@ -48,4 +48,6 @@ int count_next_metalink_resource(struct metalinkfile *mlfile); void clean_metalink(struct Configurable *config); int parse_metalink(struct Configurable *config, const char *infile); #endif /* HEADER_CURL_TOOL_METALINK_H */ src/tool_operate.c +42 −11 Original line number Diff line number Diff line Loading @@ -130,7 +130,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) struct OutStruct heads; #ifdef HAVE_LIBMETALINK struct metalinkfile *mlfile_last; struct metalinkfile *mlfile_last = NULL; #endif /* HAVE_LIBMETALINK */ CURL *curl = NULL; Loading Loading @@ -392,10 +392,6 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) } } #ifdef HAVE_LIBMETALINK mlfile_last = config->metalinkfile_list; #endif /* HAVE_LIBMETALINK */ /* ** Nested loops start here. */ Loading @@ -409,16 +405,23 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) char *outfiles; int infilenum; URLGlob *inglob; #ifdef HAVE_LIBMETALINK int metalink; /* nonzero for metalink download */ struct metalinkfile *mlfile; metalink_resource_t **mlres; #endif /* HAVE_LIBMETALINK */ outfiles = NULL; infilenum = 1; inglob = NULL; #ifdef HAVE_LIBMETALINK if(urlnode->flags & GETOUT_METALINK) { metalink = 1; if(mlfile_last == NULL) { mlfile_last = config->metalinkfile_list; } mlfile = mlfile_last; mlfile_last = mlfile_last->next; mlres = mlfile->file->resources; Loading @@ -428,6 +431,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) mlfile = NULL; mlres = NULL; } #endif /* HAVE_LIBMETALINK */ /* urlnode->url is the full URL (it might be NULL) */ Loading Loading @@ -497,12 +501,15 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) break; } #ifdef HAVE_LIBMETALINK 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) { else #endif /* HAVE_LIBMETALINK */ 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, Loading Loading @@ -533,20 +540,24 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) long retry_sleep; char *this_url; HeaderData hdrdata; int metalink_next_res; #ifdef HAVE_LIBMETALINK int metalink_next_res = 0; #endif /* HAVE_LIBMETALINK */ 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; #ifdef HAVE_LIBMETALINK if(metalink) { /* For Metalink download, use name in Metalink file as filename. */ outfile = strdup(mlfile->file->name); if(!outfile) { res = CURLE_OUT_OF_MEMORY; Loading @@ -559,6 +570,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) } } else { #endif /* HAVE_LIBMETALINK */ if(urls) { res = glob_next_url(&this_url, urls); if(res) Loading @@ -583,7 +595,9 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) goto show_error; } } #ifdef HAVE_LIBMETALINK } #endif /* HAVE_LIBMETALINK */ if((urlnode->flags&GETOUT_USEREMOTE) || (outfile && !curlx_strequal("-", outfile)) ) { Loading Loading @@ -1429,6 +1443,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) continue; /* curl_easy_perform loop */ } } /* if retry_numretries */ #ifdef HAVE_LIBMETALINK else if(metalink) { /* Metalink: Decide to try the next resource or not. Basically, we want to try the next resource if Loading @@ -1451,6 +1466,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) else metalink_next_res = 1; } #endif /* HAVE_LIBMETALINK */ /* In all ordinary cases, just break out of loop here */ break; /* curl_easy_perform loop */ Loading Loading @@ -1562,10 +1578,21 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) #ifdef HAVE_LIBMETALINK if(!metalink && res == CURLE_OK && outs.filename) { /* Check the content-type header field and if it indicates Metalink file, parse it and add getout for them. */ char *content_type; curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &content_type); if(content_type != NULL) { printf("file=%s, content-type=%s\n", outs.filename, content_type); if(content_type && Curl_raw_equal("application/metalink+xml", content_type)) { if(!(config->mute)) { fprintf(config->errors, "\nParsing Metalink file: %s\n", outs.filename); } if(parse_metalink(config, outs.filename) == 0) fprintf(config->errors, "Metalink file is parsed successfully\n"); else fprintf(config->errors, "Could not parse Metalink file.\n"); } } #endif /* HAVE_LIBMETALINK */ Loading @@ -1586,14 +1613,18 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) infd = STDIN_FILENO; } #ifdef HAVE_LIBMETALINK if(metalink) { /* Should exit if error is fatal. */ if(is_fatal_error(res)) { break; } if(!metalink_next_res || *(++mlres) == NULL) break; } else if(urlnum > 1) { else #endif /* HAVE_LIBMETALINK */ if(urlnum > 1) { /* when url globbing, exit loop upon critical error */ if(is_fatal_error(res)) break; Loading Loading
src/tool_getparam.c +4 −59 Original line number Diff line number Diff line Loading @@ -829,65 +829,10 @@ ParameterError getparameter(char *flag, /* f or -long-flag */ case 'J': /* --metalink */ { #ifdef HAVE_LIBMETALINK metalink_error_t r; metalink_t* metalink; metalink_file_t **files; struct metalink *ml; r = metalink_parse_file(nextarg, &metalink); if(r != 0) { fprintf(stderr, "ERROR: code=%d\n", r); exit(EXIT_FAILURE); } ml = new_metalink(metalink); if(config->metalink_list) { config->metalink_last->next = ml; config->metalink_last = ml; } else { config->metalink_list = config->metalink_last = ml; } for(files = metalink->files; *files; ++files) { struct getout *url; /* Skip an entry which has no resource. */ if(!(*files)->resources[0]) continue; if(config->url_get || ((config->url_get = config->url_list) != NULL)) { /* there's a node here, if it already is filled-in continue to find an "empty" node */ while(config->url_get && (config->url_get->flags & GETOUT_URL)) config->url_get = config->url_get->next; } /* now there might or might not be an available node to fill in! */ if(config->url_get) /* existing node */ url = config->url_get; else /* there was no free node, create one! */ url=new_getout(config); if(url) { struct metalinkfile *mlfile; /* Set name as url */ GetStr(&url->url, (*files)->name); /* set flag metalink here */ url->flags |= GETOUT_URL | GETOUT_METALINK; mlfile = new_metalinkfile(*files); if(config->metalinkfile_list) { config->metalinkfile_last->next = mlfile; config->metalinkfile_last = mlfile; } else { config->metalinkfile_list = config->metalinkfile_last = mlfile; } } if(parse_metalink(config, nextarg) == -1) { warnf(config, "Could not parse Metalink file: %s\n", nextarg); /* TODO Is PARAM_BAD_USE appropriate here? */ return PARAM_BAD_USE; } #else warnf(config, "--metalink option is ignored because the binary is " Loading
src/tool_metalink.c +78 −0 Original line number Diff line number Diff line Loading @@ -21,9 +21,23 @@ ***************************************************************************/ #include "tool_setup.h" #include "tool_metalink.h" #include "tool_getparam.h" #include "tool_paramhlp.h" #include "memdebug.h" /* keep this as LAST include */ /* Copied from tool_getparam.c */ #define GetStr(str,val) do { \ if(*(str)) { \ free(*(str)); \ *(str) = NULL; \ } \ if((val)) \ *(str) = strdup((val)); \ if(!(val)) \ return PARAM_NO_MEM; \ } WHILE_FALSE struct metalinkfile *new_metalinkfile(metalink_file_t *metalinkfile) { struct metalinkfile *f; f = (struct metalinkfile*)malloc(sizeof(struct metalinkfile)); Loading Loading @@ -64,3 +78,67 @@ void clean_metalink(struct Configurable *config) } config->metalink_last = 0; } int parse_metalink(struct Configurable *config, const char *infile) { metalink_error_t r; metalink_t* metalink; metalink_file_t **files; struct metalink *ml; r = metalink_parse_file(infile, &metalink); if(r != 0) { return -1; } ml = new_metalink(metalink); if(config->metalink_list) { config->metalink_last->next = ml; config->metalink_last = ml; } else { config->metalink_list = config->metalink_last = ml; } for(files = metalink->files; *files; ++files) { struct getout *url; /* Skip an entry which has no resource. */ if(!(*files)->resources[0]) continue; if(config->url_get || ((config->url_get = config->url_list) != NULL)) { /* there's a node here, if it already is filled-in continue to find an "empty" node */ while(config->url_get && (config->url_get->flags & GETOUT_URL)) config->url_get = config->url_get->next; } /* now there might or might not be an available node to fill in! */ if(config->url_get) /* existing node */ url = config->url_get; else /* there was no free node, create one! */ url=new_getout(config); if(url) { struct metalinkfile *mlfile; /* Set name as url */ GetStr(&url->url, (*files)->name); /* set flag metalink here */ url->flags |= GETOUT_URL | GETOUT_METALINK; mlfile = new_metalinkfile(*files); if(config->metalinkfile_list) { config->metalinkfile_last->next = mlfile; config->metalinkfile_last = mlfile; } else { config->metalinkfile_list = config->metalinkfile_last = mlfile; } } } return 0; }
src/tool_metalink.h +2 −0 Original line number Diff line number Diff line Loading @@ -48,4 +48,6 @@ int count_next_metalink_resource(struct metalinkfile *mlfile); void clean_metalink(struct Configurable *config); int parse_metalink(struct Configurable *config, const char *infile); #endif /* HEADER_CURL_TOOL_METALINK_H */
src/tool_operate.c +42 −11 Original line number Diff line number Diff line Loading @@ -130,7 +130,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) struct OutStruct heads; #ifdef HAVE_LIBMETALINK struct metalinkfile *mlfile_last; struct metalinkfile *mlfile_last = NULL; #endif /* HAVE_LIBMETALINK */ CURL *curl = NULL; Loading Loading @@ -392,10 +392,6 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) } } #ifdef HAVE_LIBMETALINK mlfile_last = config->metalinkfile_list; #endif /* HAVE_LIBMETALINK */ /* ** Nested loops start here. */ Loading @@ -409,16 +405,23 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) char *outfiles; int infilenum; URLGlob *inglob; #ifdef HAVE_LIBMETALINK int metalink; /* nonzero for metalink download */ struct metalinkfile *mlfile; metalink_resource_t **mlres; #endif /* HAVE_LIBMETALINK */ outfiles = NULL; infilenum = 1; inglob = NULL; #ifdef HAVE_LIBMETALINK if(urlnode->flags & GETOUT_METALINK) { metalink = 1; if(mlfile_last == NULL) { mlfile_last = config->metalinkfile_list; } mlfile = mlfile_last; mlfile_last = mlfile_last->next; mlres = mlfile->file->resources; Loading @@ -428,6 +431,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) mlfile = NULL; mlres = NULL; } #endif /* HAVE_LIBMETALINK */ /* urlnode->url is the full URL (it might be NULL) */ Loading Loading @@ -497,12 +501,15 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) break; } #ifdef HAVE_LIBMETALINK 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) { else #endif /* HAVE_LIBMETALINK */ 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, Loading Loading @@ -533,20 +540,24 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) long retry_sleep; char *this_url; HeaderData hdrdata; int metalink_next_res; #ifdef HAVE_LIBMETALINK int metalink_next_res = 0; #endif /* HAVE_LIBMETALINK */ 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; #ifdef HAVE_LIBMETALINK if(metalink) { /* For Metalink download, use name in Metalink file as filename. */ outfile = strdup(mlfile->file->name); if(!outfile) { res = CURLE_OUT_OF_MEMORY; Loading @@ -559,6 +570,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) } } else { #endif /* HAVE_LIBMETALINK */ if(urls) { res = glob_next_url(&this_url, urls); if(res) Loading @@ -583,7 +595,9 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) goto show_error; } } #ifdef HAVE_LIBMETALINK } #endif /* HAVE_LIBMETALINK */ if((urlnode->flags&GETOUT_USEREMOTE) || (outfile && !curlx_strequal("-", outfile)) ) { Loading Loading @@ -1429,6 +1443,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) continue; /* curl_easy_perform loop */ } } /* if retry_numretries */ #ifdef HAVE_LIBMETALINK else if(metalink) { /* Metalink: Decide to try the next resource or not. Basically, we want to try the next resource if Loading @@ -1451,6 +1466,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) else metalink_next_res = 1; } #endif /* HAVE_LIBMETALINK */ /* In all ordinary cases, just break out of loop here */ break; /* curl_easy_perform loop */ Loading Loading @@ -1562,10 +1578,21 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) #ifdef HAVE_LIBMETALINK if(!metalink && res == CURLE_OK && outs.filename) { /* Check the content-type header field and if it indicates Metalink file, parse it and add getout for them. */ char *content_type; curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &content_type); if(content_type != NULL) { printf("file=%s, content-type=%s\n", outs.filename, content_type); if(content_type && Curl_raw_equal("application/metalink+xml", content_type)) { if(!(config->mute)) { fprintf(config->errors, "\nParsing Metalink file: %s\n", outs.filename); } if(parse_metalink(config, outs.filename) == 0) fprintf(config->errors, "Metalink file is parsed successfully\n"); else fprintf(config->errors, "Could not parse Metalink file.\n"); } } #endif /* HAVE_LIBMETALINK */ Loading @@ -1586,14 +1613,18 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) infd = STDIN_FILENO; } #ifdef HAVE_LIBMETALINK if(metalink) { /* Should exit if error is fatal. */ if(is_fatal_error(res)) { break; } if(!metalink_next_res || *(++mlres) == NULL) break; } else if(urlnum > 1) { else #endif /* HAVE_LIBMETALINK */ if(urlnum > 1) { /* when url globbing, exit loop upon critical error */ if(is_fatal_error(res)) break; Loading