1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at http://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
22 #include "tool_setup.h"
26 #include "tool_metalink.h"
27 #include "tool_getparam.h"
28 #include "tool_paramhlp.h"
30 #include "memdebug.h" /* keep this as LAST include */
32 /* Copied from tool_getparam.c */
33 #define GetStr(str,val) do { \
39 *(str) = strdup((val)); \
41 return PARAM_NO_MEM; \
44 struct metalinkfile *new_metalinkfile(metalink_file_t *metalinkfile) {
45 struct metalinkfile *f;
46 f = (struct metalinkfile*)malloc(sizeof(struct metalinkfile));
47 f->file = metalinkfile;
52 struct metalink *new_metalink(metalink_t *metalink) {
54 ml = (struct metalink*)malloc(sizeof(struct metalink));
55 ml->metalink = metalink;
60 int count_next_metalink_resource(struct metalinkfile *mlfile)
63 metalink_resource_t **mlres;
64 for(mlres = mlfile->file->resources; *mlres; ++mlres, ++count);
68 void clean_metalink(struct Configurable *config)
70 while(config->metalinkfile_list) {
71 struct metalinkfile *mlfile = config->metalinkfile_list;
72 config->metalinkfile_list = config->metalinkfile_list->next;
73 Curl_safefree(mlfile);
75 config->metalinkfile_last = 0;
76 while(config->metalink_list) {
77 struct metalink *ml = config->metalink_list;
78 config->metalink_list = config->metalink_list->next;
79 metalink_delete(ml->metalink);
82 config->metalink_last = 0;
85 int parse_metalink(struct Configurable *config, const char *infile)
89 metalink_file_t **files;
92 r = metalink_parse_file(infile, &metalink);
97 if(metalink->files == NULL) {
98 fprintf(config->errors, "\nMetalink does not contain any file.\n");
101 ml = new_metalink(metalink);
103 if(config->metalink_list) {
104 config->metalink_last->next = ml;
105 config->metalink_last = ml;
108 config->metalink_list = config->metalink_last = ml;
111 for(files = metalink->files; *files; ++files) {
113 /* Skip an entry which has no resource. */
114 if(!(*files)->resources) {
115 fprintf(config->errors, "\nFile %s does not have any resource.\n",
119 if(config->url_get ||
120 ((config->url_get = config->url_list) != NULL)) {
121 /* there's a node here, if it already is filled-in continue to
122 find an "empty" node */
123 while(config->url_get && (config->url_get->flags & GETOUT_URL))
124 config->url_get = config->url_get->next;
127 /* now there might or might not be an available node to fill in! */
131 url = config->url_get;
133 /* there was no free node, create one! */
134 url=new_getout(config);
137 struct metalinkfile *mlfile;
138 /* Set name as url */
139 GetStr(&url->url, (*files)->name);
141 /* set flag metalink here */
142 url->flags |= GETOUT_URL | GETOUT_METALINK;
143 mlfile = new_metalinkfile(*files);
145 if(config->metalinkfile_list) {
146 config->metalinkfile_last->next = mlfile;
147 config->metalinkfile_last = mlfile;
150 config->metalinkfile_list = config->metalinkfile_last = mlfile;
158 * Returns nonzero if content_type includes mediatype.
160 static int check_content_type(const char *content_type, const char *media_type)
162 const char *ptr = content_type;
163 size_t media_type_len = strlen(media_type);
164 for(; *ptr && (*ptr == ' ' || *ptr == '\t'); ++ptr);
168 return Curl_raw_nequal(ptr, media_type, media_type_len) &&
169 (*(ptr+media_type_len) == '\0' || *(ptr+media_type_len) == ' ' ||
170 *(ptr+media_type_len) == '\t' || *(ptr+media_type_len) == ';');
173 int check_metalink_content_type(const char *content_type)
175 return check_content_type(content_type, "application/metalink+xml");