From 1fae0900e4474f27b6c20520304b1c1b69321690 Mon Sep 17 00:00:00 2001 From: Jure Grabnar Date: Fri, 28 Mar 2014 13:13:40 +0100 Subject: [PATCH 1/2] Fix metalink issues when type is not present --- src/ChangeLog | 11 +++++++++++ src/metalink.c | 31 +++++++++++++++++++++++++------ src/metalink.h | 4 +++- src/retr.c | 10 ++++++++++ 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index f222037..8c3ba1b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,14 @@ +2014-03-28 Jure Grabnar + + * metalink.h: Change type of 'mlink_resource.type' to enum url_scheme. + Include url.h. + * metalink.c (parse_metalink): Find out resources' protocol type from URL if + not present in tag in metalink file. + Include url.h. + (elect_resources): Do not crash when protocol type is NULL. + Count number of resources still available, if zero, assign NULL. + * retr.c: Add check for number of resources available. Do not crash when zero. + 2014-03-04 Giuseppe Scrivano * http.c (modify_param_value, extract_param): Aesthetic change. diff --git a/src/metalink.c b/src/metalink.c index 76db2fa..4c8f02b 100644 --- a/src/metalink.c +++ b/src/metalink.c @@ -42,6 +42,7 @@ as that of the covered work. */ #include "sha256.h" #include "metalink.h" #include "utils.h" +#include "url.h" #define HASH_TYPES 3 @@ -134,7 +135,20 @@ parse_metalink(char *input_file) ++(file->num_of_res); resource->url = xstrdup ((*resources)->url); - resource->type = ((*resources)->type ? xstrdup ((*resources)->type) : NULL); + + if ((*resources)->type) + { + /* Append "://" to resource type so url_scheme() recognizes type */ + char *temp_url = malloc ( strlen ( (*resources)->type) + 4); + sprintf (temp_url, "%s://", (*resources)->type); + + resource->type = url_scheme (temp_url); + + free (temp_url); + } + else + resource->type = url_scheme (resource->url); + resource->location = ((*resources)->location ? xstrdup ((*resources)->location) : NULL); resource->preference = (*resources)->preference; resource->maxconnections = (*resources)->maxconnections; @@ -143,7 +157,7 @@ parse_metalink(char *input_file) (file->resources) = resource; } - for (checksums = (*files)->checksums; *checksums; ++checksums) + for (checksums = (*files)->checksums; checksums && *checksums; ++checksums) { mlink_checksum *checksum = malloc (sizeof(mlink_checksum)); @@ -215,19 +229,25 @@ elect_resources (mlink *mlink) while (res_next = res->next) { - if (strcmp(res_next->type, "ftp") && strcmp(res_next->type, "http")) + if (schemes_are_similar_p (res_next->type, SCHEME_INVALID)) { res->next = res_next->next; free(res_next); + + --(file->num_of_res); } else res = res_next; } res = file->resources; - if (strcmp(res->type, "ftp") && strcmp(res->type, "http")) + if (schemes_are_similar_p (res->type, SCHEME_INVALID)) { file->resources = res->next; - free(res); + free (res); + + --(file->num_of_res); + if (!file->num_of_res) + file->resources = NULL; } } } @@ -301,7 +321,6 @@ delete_mlink(mlink *metalink) while (res) { xfree_null (res->url); - xfree_null (res->type); xfree_null (res->location); res_temp = res; diff --git a/src/metalink.h b/src/metalink.h index 3906e22..264320c 100644 --- a/src/metalink.h +++ b/src/metalink.h @@ -32,6 +32,8 @@ as that of the covered work. */ #ifndef MLINK_H #define MLINK_H +#include "url.h" + typedef struct metalink_piece_hash { struct metalink_piece_hash *next; @@ -53,7 +55,7 @@ typedef struct metalink_resource struct metalink_resource *next; char *url; - char *type; + enum url_scheme type; char *location; int preference; int maxconnections; diff --git a/src/retr.c b/src/retr.c index 8c361de..d89fc83 100644 --- a/src/retr.c +++ b/src/retr.c @@ -1095,6 +1095,16 @@ retrieve_from_file (const char *file, bool html, int *count) file = mlink->files; while (file) { + if (!file->num_of_res) + { + logprintf (LOG_VERBOSE, _("Downloading %s failed. File could " + "not be downloaded from any of the " + "URLs listed in metalink file.\n"), + file->name); + file = file->next; + continue; + } + memset (thread_ctx, '\0', opt.jobs * (sizeof *thread_ctx)); /* If chunk_size is too small, set it equal to MIN_CHUNK_SIZE. */ -- 1.9.0