Support Metalink.

This change adds experimental Metalink support to curl.
To enable Metalink support, run configure with --with-libmetalink.
To feed Metalink file to curl, use --metalink option like this:

  $ curl -O --metalink foo.metalink

We use libmetalink to parse Metalink files.
This commit is contained in:
Tatsuhiro Tsujikawa
2012-04-26 22:59:52 +09:00
committed by Daniel Stenberg
parent efb8471a69
commit b5fdbe848b
9 changed files with 1225 additions and 2 deletions

View File

@@ -44,6 +44,10 @@
#include "tool_parsecfg.h"
#include "tool_version.h"
#ifdef HAVE_LIBMETALINK
# include "tool_metalink.h"
#endif /* HAVE_LIBMETALINK */
#include "memdebug.h" /* keep this as LAST include */
#ifdef MSDOS
@@ -170,6 +174,9 @@ static const struct LongShort aliases[]= {
{"$G", "delegation", TRUE},
{"$H", "mail-auth", TRUE},
{"$I", "post303", FALSE},
#ifdef HAVE_LIBMETALINK
{"$J", "metalink", TRUE},
#endif /* HAVE_LIBMETALINK */
{"0", "http1.0", FALSE},
{"1", "tlsv1", FALSE},
{"2", "sslv2", FALSE},
@@ -819,6 +826,72 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
case 'H': /* --mail-auth */
GetStr(&config->mail_auth, nextarg);
break;
#ifdef HAVE_LIBMETALINK
case 'J': /* --metalink */
{
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;
}
}
}
break;
}
#endif /* HAVE_LIBMETALINK */
}
break;
case '#': /* --progress-bar */