From e3cd50f8c7ff8aea50dbf5d8c38ac72ab6f2dd57 Mon Sep 17 00:00:00 2001 From: Hubert Tarasiuk Date: Fri, 3 Jul 2015 00:21:35 +0200 Subject: [PATCH 11/12] Geolocation support for Metalink resources. * doc/wget.text: Add information about --preferred-location. * src/init.c: Add --preferred-location option. * src/main.c (option_data): Handle --preferred-location argument. (main): Sort resources based on location if requested. * src/metalink.c (metalink_res_cmp): Compare based on location if priority and preference are equal. * src/options.h (options): Add preferred_location option. --- doc/wget.texi | 5 +++++ src/init.c | 4 ++++ src/main.c | 25 +++++++++++++++++++++++++ src/metalink.c | 11 +++++++++++ src/options.h | 1 + 5 files changed, 46 insertions(+) diff --git a/doc/wget.texi b/doc/wget.texi index a9a0f6b..0b683d8 100644 --- a/doc/wget.texi +++ b/doc/wget.texi @@ -518,6 +518,11 @@ Issues HTTP HEAD request instead of GET and extracts Metalink metadata from response headers. Then it switches to Metalink download. If no valid Metalink metadata is found, it falls back to ordinary HTTP download. address@hidden preferred-location address@hidden --preferred-location +Set preferred location for Metalink resources. This has effect if multiple +resources with same priority are available. + @cindex force html @item -F diff --git a/src/init.c b/src/init.c index dbff1b3..ed4171e 100644 --- a/src/init.c +++ b/src/init.c @@ -245,6 +245,9 @@ static const struct { { "postdata", &opt.post_data, cmd_string }, { "postfile", &opt.post_file_name, cmd_file }, { "preferfamily", NULL, cmd_spec_prefer_family }, +#ifdef HAVE_METALINK + { "preferred-location", &opt.preferred_location, cmd_string }, +#endif { "preservepermissions", &opt.preserve_perm, cmd_boolean }, #ifdef HAVE_SSL { "privatekey", &opt.private_key, cmd_file }, @@ -1801,6 +1804,7 @@ cleanup (void) xfree (opt.input_filename); #ifdef HAVE_METALINK xfree (opt.input_metalink); + xfree (opt.preferred_location); #endif xfree (opt.output_document); free_vec (opt.accepts); diff --git a/src/main.c b/src/main.c index a66f7bc..79a37b5 100644 --- a/src/main.c +++ b/src/main.c @@ -274,6 +274,9 @@ static struct cmdline_option option_data[] = { "post-data", 0, OPT_VALUE, "postdata", -1 }, { "post-file", 0, OPT_VALUE, "postfile", -1 }, { "prefer-family", 0, OPT_VALUE, "preferfamily", -1 }, +#ifdef HAVE_METALINK + { "preferred-location", 0, OPT_VALUE, "preferred-location", -1 }, +#endif { "preserve-permissions", 0, OPT_BOOLEAN, "preservepermissions", -1 }, { IF_SSL ("private-key"), 0, OPT_VALUE, "privatekey", -1 }, { IF_SSL ("private-key-type"), 0, OPT_VALUE, "privatekeytype", -1 }, @@ -595,6 +598,8 @@ Download:\n"), #ifdef HAVE_METALINK N_("\ --metalink-over-http use Metalink metadata from HTTP response headers\n"), + N_("\ + --preferred-location preferred location for Metalink resources\n"), #endif "\n", @@ -1771,6 +1776,26 @@ outputting to a regular file.\n")); } else { + /* We need to sort the resources if preferred location + was specified by the user. */ + if (opt.preferred_location && opt.preferred_location[0]) + { + metalink_file_t **mfile_ptr; + for (mfile_ptr = metalink->files; *mfile_ptr; mfile_ptr++) + { + metalink_resource_t **mres_ptr; + metalink_file_t *mfile = *mfile_ptr; + size_t mres_count = 0; + + for (mres_ptr = mfile->resources; *mres_ptr; mres_ptr++) + mres_count++; + + stable_sort (mfile->resources, + mres_count, + sizeof (metalink_resource_t *), + metalink_res_cmp); + } + } retr_err = retrieve_from_metalink (metalink); if (retr_err != RETROK) { diff --git a/src/metalink.c b/src/metalink.c index b751864..f5ae1c1 100644 --- a/src/metalink.c +++ b/src/metalink.c @@ -448,6 +448,17 @@ int metalink_res_cmp (const void* v1, const void* v2) return res2->preference - res1->preference; if (res1->priority != res2->priority) return res1->priority - res2->priority; + if (opt.preferred_location) + { + int cmp = 0; + if (res1->location && + !strcasecmp (opt.preferred_location, res1->location)) + cmp -= 1; + if (res2->location && + !strcasecmp (opt.preferred_location, res2->location)) + cmp += 1; + return cmp; + } return 0; } diff --git a/src/options.h b/src/options.h index c377b50..1ede7b3 100644 --- a/src/options.h +++ b/src/options.h @@ -61,6 +61,7 @@ struct options #ifdef HAVE_METALINK char *input_metalink; /* Input metalink file */ bool metalink_over_http; /* Use Metalink if present in HTTP response */ + char *preferred_location; /* Preferred location for Metalink resources */ #endif char *choose_config; /* Specified config file */ bool noconfig; /* Ignore all config files? */ -- 2.4.3