Minimize usage of structs from libmetalink

This commit is contained in:
Tatsuhiro Tsujikawa
2012-05-25 19:24:32 +09:00
committed by Daniel Stenberg
parent 9f7f7925da
commit 6a655ca192
4 changed files with 146 additions and 73 deletions

View File

@@ -203,11 +203,8 @@ struct Configurable {
long gssapi_delegation; long gssapi_delegation;
bool ssl_allow_beast; /* allow this SSL vulnerability */ bool ssl_allow_beast; /* allow this SSL vulnerability */
#ifdef HAVE_LIBMETALINK #ifdef HAVE_LIBMETALINK
struct metalinkfile *metalinkfile_list; /* point to the first node */ metalinkfile *metalinkfile_list; /* point to the first node */
struct metalinkfile *metalinkfile_last; /* point to the last/current node */ metalinkfile *metalinkfile_last; /* point to the last/current node */
struct metalink *metalink_list; /* point to the first node */
struct metalink *metalink_last; /* point to the last/current node */
#endif /* HAVE_LIBMETALINK */ #endif /* HAVE_LIBMETALINK */
}; /* struct Configurable */ }; /* struct Configurable */

View File

@@ -36,6 +36,7 @@
#include "tool_metalink.h" #include "tool_metalink.h"
#include "tool_getparam.h" #include "tool_getparam.h"
#include "tool_paramhlp.h" #include "tool_paramhlp.h"
#include "tool_cfgable.h"
#include "memdebug.h" /* keep this as LAST include */ #include "memdebug.h" /* keep this as LAST include */
@@ -273,45 +274,121 @@ int Curl_digest_final(digest_context *context, unsigned char *result)
return 0; return 0;
} }
struct metalinkfile *new_metalinkfile(metalink_file_t *metalinkfile) { static metalink_checksum *new_metalink_checksum(const char *hash_name,
struct metalinkfile *f; const char *hash_value)
f = (struct metalinkfile*)malloc(sizeof(struct metalinkfile)); {
f->file = metalinkfile; metalink_checksum *chksum;
chksum = malloc(sizeof(metalink_checksum));
chksum->next = NULL;
chksum->hash_name = strdup(hash_name);
chksum->hash_value = strdup(hash_value);
return chksum;
}
static void delete_metalink_checksum(metalink_checksum *chksum)
{
if(chksum == NULL) {
return;
}
Curl_safefree(chksum->hash_value);
Curl_safefree(chksum->hash_name);
Curl_safefree(chksum);
}
static metalink_resource *new_metalink_resource(const char *url)
{
metalink_resource *res;
res = malloc(sizeof(metalink_resource));
res->next = NULL;
res->url = strdup(url);
return res;
}
static void delete_metalink_resource(metalink_resource *res)
{
if(res == NULL) {
return;
}
Curl_safefree(res->url);
Curl_safefree(res);
}
static metalinkfile *new_metalinkfile(metalink_file_t *fileinfo)
{
metalinkfile *f;
f = (metalinkfile*)malloc(sizeof(metalinkfile));
f->next = NULL; f->next = NULL;
f->filename = strdup(fileinfo->name);
f->checksum = NULL;
f->resource = NULL;
if(fileinfo->checksums) {
metalink_checksum_t **p;
metalink_checksum root, *tail;
root.next = NULL;
tail = &root;
for(p = fileinfo->checksums; *p; ++p) {
metalink_checksum *chksum;
chksum = new_metalink_checksum((*p)->type, (*p)->hash);
tail->next = chksum;
tail = chksum;
}
f->checksum = root.next;
}
if(fileinfo->resources) {
metalink_resource_t **p;
metalink_resource root, *tail;
root.next = NULL;
tail = &root;
for(p = fileinfo->resources; *p; ++p) {
metalink_resource *res;
res = new_metalink_resource((*p)->url);
tail->next = res;
tail = res;
}
f->resource = root.next;
}
return f; return f;
} }
struct metalink *new_metalink(metalink_t *metalink) { static void delete_metalinkfile(metalinkfile *mlfile)
struct metalink *ml; {
ml = (struct metalink*)malloc(sizeof(struct metalink)); metalink_checksum *mc;
ml->metalink = metalink; metalink_resource *res;
ml->next = NULL; if(mlfile == NULL) {
return ml; return;
}
Curl_safefree(mlfile->filename);
for(mc = mlfile->checksum; mc;) {
metalink_checksum *next;
next = mc->next;
delete_metalink_checksum(mc);
mc = next;
}
for(res = mlfile->resource; res;) {
metalink_resource *next;
next = res->next;
delete_metalink_resource(res);
res = next;
}
Curl_safefree(mlfile);
} }
int count_next_metalink_resource(struct metalinkfile *mlfile) int count_next_metalink_resource(metalinkfile *mlfile)
{ {
int count = 0; int count = 0;
metalink_resource_t **mlres; metalink_resource *res;
for(mlres = mlfile->file->resources; *mlres; ++mlres, ++count); for(res = mlfile->resource; res; res = res->next, ++count);
return count; return count;
} }
void clean_metalink(struct Configurable *config) void clean_metalink(struct Configurable *config)
{ {
while(config->metalinkfile_list) { while(config->metalinkfile_list) {
struct metalinkfile *mlfile = config->metalinkfile_list; metalinkfile *mlfile = config->metalinkfile_list;
config->metalinkfile_list = config->metalinkfile_list->next; config->metalinkfile_list = config->metalinkfile_list->next;
Curl_safefree(mlfile); delete_metalinkfile(mlfile);
} }
config->metalinkfile_last = 0; config->metalinkfile_last = 0;
while(config->metalink_list) {
struct metalink *ml = config->metalink_list;
config->metalink_list = config->metalink_list->next;
metalink_delete(ml->metalink);
Curl_safefree(ml);
}
config->metalink_last = 0;
} }
int parse_metalink(struct Configurable *config, const char *infile) int parse_metalink(struct Configurable *config, const char *infile)
@@ -319,27 +396,16 @@ int parse_metalink(struct Configurable *config, const char *infile)
metalink_error_t r; metalink_error_t r;
metalink_t* metalink; metalink_t* metalink;
metalink_file_t **files; metalink_file_t **files;
struct metalink *ml;
r = metalink_parse_file(infile, &metalink); r = metalink_parse_file(infile, &metalink);
if(r != 0) { if(r != 0) {
return -1; return -1;
} }
if(metalink->files == NULL) { if(metalink->files == NULL) {
fprintf(config->errors, "\nMetalink does not contain any file.\n"); fprintf(config->errors, "\nMetalink does not contain any file.\n");
metalink_delete(metalink);
return 0; return 0;
} }
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) { for(files = metalink->files; *files; ++files) {
struct getout *url; struct getout *url;
/* Skip an entry which has no resource. */ /* Skip an entry which has no resource. */
@@ -363,16 +429,17 @@ int parse_metalink(struct Configurable *config, const char *infile)
url = config->url_get; url = config->url_get;
else else
/* there was no free node, create one! */ /* there was no free node, create one! */
url=new_getout(config); url = new_getout(config);
if(url) { if(url) {
struct metalinkfile *mlfile; metalinkfile *mlfile;
mlfile = new_metalinkfile(*files);
/* Set name as url */ /* Set name as url */
GetStr(&url->url, (*files)->name); GetStr(&url->url, mlfile->filename);
/* set flag metalink here */ /* set flag metalink here */
url->flags |= GETOUT_URL | GETOUT_METALINK; url->flags |= GETOUT_URL | GETOUT_METALINK;
mlfile = new_metalinkfile(*files);
if(config->metalinkfile_list) { if(config->metalinkfile_list) {
config->metalinkfile_last->next = mlfile; config->metalinkfile_last->next = mlfile;
@@ -383,6 +450,7 @@ int parse_metalink(struct Configurable *config, const char *infile)
} }
} }
} }
metalink_delete(metalink);
return 0; return 0;
} }
@@ -510,25 +578,25 @@ static int check_hash(const char *filename,
} }
int metalink_check_hash(struct Configurable *config, int metalink_check_hash(struct Configurable *config,
struct metalinkfile *mlfile, metalinkfile *mlfile,
const char *filename) const char *filename)
{ {
metalink_checksum_t **checksum; metalink_checksum *chksum;
const metalink_digest_alias *digest_alias; const metalink_digest_alias *digest_alias;
int rv; int rv;
if(!mlfile->file->checksums) { if(mlfile->checksum == NULL) {
return -2; return -2;
} }
for(digest_alias = digest_aliases; digest_alias->alias_name; for(digest_alias = digest_aliases; digest_alias->alias_name;
++digest_alias) { ++digest_alias) {
for(checksum = mlfile->file->checksums; *checksum; ++checksum) { for(chksum = mlfile->checksum; chksum; chksum = chksum->next) {
if(Curl_raw_equal(digest_alias->alias_name, (*checksum)->type) && if(Curl_raw_equal(digest_alias->alias_name, chksum->hash_name) &&
strlen((*checksum)->hash) == strlen(chksum->hash_value) ==
digest_alias->digest_def->dparams->digest_resultlen*2) { digest_alias->digest_def->dparams->digest_resultlen*2) {
break; break;
} }
} }
if(*checksum) { if(chksum) {
break; break;
} }
} }
@@ -537,7 +605,7 @@ int metalink_check_hash(struct Configurable *config,
return -2; return -2;
} }
rv = check_hash(filename, digest_alias->digest_def, rv = check_hash(filename, digest_alias->digest_def,
(*checksum)->hash, config->errors); chksum->hash_value, config->errors);
if(rv == 1) { if(rv == 1) {
fprintf(config->errors, "Checksum matched\n"); fprintf(config->errors, "Checksum matched\n");
} }

View File

@@ -25,26 +25,31 @@
#include <metalink/metalink_parser.h> #include <metalink/metalink_parser.h>
#include "tool_cfgable.h" struct Configurable;
struct metalinkfile { typedef struct metalink_checksum {
struct metalink_checksum *next;
char *hash_name;
/* Hex-encoded hash value */
char *hash_value;
} metalink_checksum;
typedef struct metalink_resource {
struct metalink_resource *next;
char *url;
} metalink_resource;
typedef struct metalinkfile {
struct metalinkfile *next; struct metalinkfile *next;
metalink_file_t *file; char *filename;
}; metalink_checksum *checksum;
metalink_resource *resource;
struct metalink { } metalinkfile;
struct metalink *next;
metalink_t* metalink;
};
struct metalinkfile *new_metalinkfile(metalink_file_t *metalinkfile);
struct metalink *new_metalink(metalink_t *metalink);
/* /*
* Counts the resource in the metalinkfile. * Counts the resource in the metalinkfile.
*/ */
int count_next_metalink_resource(struct metalinkfile *mlfile); int count_next_metalink_resource(metalinkfile *mlfile);
void clean_metalink(struct Configurable *config); void clean_metalink(struct Configurable *config);
@@ -110,7 +115,7 @@ typedef struct {
* checksum. * checksum.
*/ */
int metalink_check_hash(struct Configurable *config, int metalink_check_hash(struct Configurable *config,
struct metalinkfile *mlfile, metalinkfile *mlfile,
const char *filename); const char *filename);
#endif /* HEADER_CURL_TOOL_METALINK_H */ #endif /* HEADER_CURL_TOOL_METALINK_H */

View File

@@ -130,7 +130,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
struct OutStruct heads; struct OutStruct heads;
#ifdef HAVE_LIBMETALINK #ifdef HAVE_LIBMETALINK
struct metalinkfile *mlfile_last = NULL; metalinkfile *mlfile_last = NULL;
#endif /* HAVE_LIBMETALINK */ #endif /* HAVE_LIBMETALINK */
CURL *curl = NULL; CURL *curl = NULL;
@@ -409,8 +409,8 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
int metalink = 0; /* nonzero for metalink download. Put outside of int metalink = 0; /* nonzero for metalink download. Put outside of
HAVE_LIBMETALINK to reduce #ifdef */ HAVE_LIBMETALINK to reduce #ifdef */
#ifdef HAVE_LIBMETALINK #ifdef HAVE_LIBMETALINK
struct metalinkfile *mlfile; metalinkfile *mlfile;
metalink_resource_t **mlres; metalink_resource *mlres;
#endif /* HAVE_LIBMETALINK */ #endif /* HAVE_LIBMETALINK */
outfiles = NULL; outfiles = NULL;
@@ -425,7 +425,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
} }
mlfile = mlfile_last; mlfile = mlfile_last;
mlfile_last = mlfile_last->next; mlfile_last = mlfile_last->next;
mlres = mlfile->file->resources; mlres = mlfile->resource;
} }
else { else {
mlfile = NULL; mlfile = NULL;
@@ -558,12 +558,12 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
if(metalink) { if(metalink) {
/* For Metalink download, use name in Metalink file as /* For Metalink download, use name in Metalink file as
filename. */ filename. */
outfile = strdup(mlfile->file->name); outfile = strdup(mlfile->filename);
if(!outfile) { if(!outfile) {
res = CURLE_OUT_OF_MEMORY; res = CURLE_OUT_OF_MEMORY;
goto show_error; goto show_error;
} }
this_url = strdup((*mlres)->url); this_url = strdup(mlres->url);
if(!this_url) { if(!this_url) {
res = CURLE_OUT_OF_MEMORY; res = CURLE_OUT_OF_MEMORY;
goto show_error; goto show_error;
@@ -1624,7 +1624,10 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
if(is_fatal_error(res)) { if(is_fatal_error(res)) {
break; break;
} }
if(!metalink_next_res || *(++mlres) == NULL) if(!metalink_next_res)
break;
mlres = mlres->next;
if(mlres == NULL)
/* TODO If metalink_next_res is 1 and mlres is NULL, /* TODO If metalink_next_res is 1 and mlres is NULL,
* set res to error code * set res to error code
*/ */