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