1 /* <!-- copyright */
2 /*
3  * libmetalink
4  *
5  * Copyright (c) 2008 Tatsuhiro Tsujikawa
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  */
25 /* copyright --> */
26 #include <metalink/metalink_types.h>
27 #include "metalink_config.h"
28 
29 #include <string.h>
30 #include <stdlib.h>
31 #include <assert.h>
32 #include <stdio.h>
33 
allocate_copy_string(char ** dest,const char * src)34 static metalink_error_t allocate_copy_string(char** dest, const char* src)
35 {
36   free(*dest);
37   if(src) {
38     size_t length;
39     length = strlen(src)+1;
40     *dest = malloc(length);
41     if(*dest == NULL) {
42       return METALINK_ERR_BAD_ALLOC;
43     }
44     memcpy(*dest, src, length);
45     return 0;
46   } else {
47     *dest = NULL;
48     return 0;
49   }
50 }
51 
52 metalink_file_t
53 METALINK_PUBLIC
metalink_file_new(void)54 * metalink_file_new(void)
55 {
56   metalink_file_t* file;
57   file = malloc(sizeof(metalink_file_t));
58   if(file) {
59     memset(file, 0, sizeof(metalink_file_t));
60   }
61   return file;
62 }
63 
64 void
65 METALINK_PUBLIC
metalink_file_delete(metalink_file_t * file)66 metalink_file_delete(metalink_file_t* file)
67 {
68   metalink_resource_t** res;
69   metalink_metaurl_t** metaurls;
70   metalink_checksum_t** checksums;
71   char** language;
72   char** os;
73 
74   if(file) {
75     free(file->name);
76     free(file->version);
77     free(file->description);
78     free(file->copyright);
79     free(file->identity);
80     free(file->logo);
81     free(file->publisher_name);
82     free(file->publisher_url);
83 
84     if(file->signature) {
85       metalink_signature_delete(file->signature);
86     }
87 
88     if(file->languages) {
89       language = file->languages;
90       while(*language) {
91 	free(*language);
92 	++language;
93       }
94       free(file->languages);
95     }
96 
97     if(file->oses) {
98       os = file->oses;
99       while(*os) {
100 	free(*os);
101 	++os;
102       }
103       free(file->oses);
104     }
105 
106     if(file->resources) {
107       res = file->resources;
108       while(*res) {
109 	metalink_resource_delete(*res);
110 	++res;
111       }
112       free(file->resources);
113     }
114 
115     if(file->metaurls) {
116       metaurls = file->metaurls;
117       while(*metaurls) {
118 	metalink_metaurl_delete(*metaurls);
119 	 ++metaurls;
120       }
121       free(file->metaurls);
122     }
123 
124     if(file->checksums) {
125       checksums = file->checksums;
126       while(*checksums) {
127 	metalink_checksum_delete(*checksums);
128 	++checksums;
129       }
130       free(file->checksums);
131     }
132 
133     metalink_chunk_checksum_delete(file->chunk_checksum);
134 
135     free(file);
136   }
137 }
138 
139 metalink_error_t
140 METALINK_PUBLIC
metalink_file_set_name(metalink_file_t * file,const char * name)141 metalink_file_set_name(metalink_file_t* file, const char* name)
142 {
143   return allocate_copy_string(&file->name, name);
144 }
145 
146 metalink_error_t
147 METALINK_PUBLIC
metalink_file_set_description(metalink_file_t * file,const char * description)148 metalink_file_set_description(metalink_file_t* file, const char* description)
149 {
150   return allocate_copy_string(&file->description, description);
151 }
152 
153 void
154 METALINK_PUBLIC
metalink_file_set_size(metalink_file_t * file,long long int size)155 metalink_file_set_size(metalink_file_t* file, long long int size)
156 {
157   file->size = size;
158 }
159 
160 metalink_error_t
161 METALINK_PUBLIC
metalink_file_set_version(metalink_file_t * file,const char * version)162 metalink_file_set_version(metalink_file_t* file, const char* version)
163 {
164   return allocate_copy_string(&file->version, version);
165 }
166 
167 metalink_error_t
168 METALINK_PUBLIC
metalink_file_set_copyright(metalink_file_t * file,const char * copyright)169 metalink_file_set_copyright(metalink_file_t* file, const char* copyright)
170 {
171   return allocate_copy_string(&file->copyright, copyright);
172 }
173 
174 metalink_error_t
175 METALINK_PUBLIC
metalink_file_set_identity(metalink_file_t * file,const char * identity)176 metalink_file_set_identity(metalink_file_t* file, const char* identity)
177 {
178   return allocate_copy_string(&file->identity, identity);
179 }
180 
181 metalink_error_t
182 METALINK_PUBLIC
metalink_file_set_logo(metalink_file_t * file,const char * logo)183 metalink_file_set_logo(metalink_file_t* file, const char* logo)
184 {
185   return allocate_copy_string(&file->logo, logo);
186 }
187 
188 metalink_error_t
189 METALINK_PUBLIC
metalink_file_set_publisher_name(metalink_file_t * file,const char * name)190 metalink_file_set_publisher_name(metalink_file_t* file, const char* name)
191 {
192   return allocate_copy_string(&file->publisher_name, name);
193 }
194 
195 metalink_error_t
196 METALINK_PUBLIC
metalink_file_set_publisher_url(metalink_file_t * file,const char * url)197 metalink_file_set_publisher_url(metalink_file_t* file, const char* url)
198 {
199   return allocate_copy_string(&file->publisher_url, url);
200 }
201 
202 void
203 METALINK_PUBLIC
metalink_file_set_maxconnections(metalink_file_t * file,int maxconnections)204 metalink_file_set_maxconnections(metalink_file_t* file, int maxconnections)
205 {
206   file->maxconnections = maxconnections;
207 }
208 
209 /* for metalink_resource_t */
210 
211 metalink_resource_t
212 METALINK_PUBLIC
metalink_resource_new(void)213 * metalink_resource_new(void)
214 {
215   metalink_resource_t* resource;
216   resource = malloc(sizeof(metalink_resource_t));
217   if(resource) {
218     memset(resource, 0, sizeof(metalink_resource_t));
219   }
220   return resource;
221 }
222 
223 void
224 METALINK_PUBLIC
metalink_resource_delete(metalink_resource_t * resource)225 metalink_resource_delete(metalink_resource_t* resource)
226 {
227   if(resource) {
228     free(resource->url);
229     free(resource->type);
230     free(resource->location);
231     free(resource);
232   }
233 }
234 
235 metalink_error_t
236 METALINK_PUBLIC
metalink_set_identity(metalink_t * metalink,const char * identity)237 metalink_set_identity(metalink_t* metalink, const char* identity)
238 {
239   return allocate_copy_string(&metalink->identity, identity);
240 }
241 
242 metalink_error_t
243 METALINK_PUBLIC
metalink_set_tags(metalink_t * metalink,const char * tags)244 metalink_set_tags(metalink_t* metalink, const char* tags)
245 {
246   return allocate_copy_string(&metalink->tags, tags);
247 }
248 
249 metalink_error_t
250 METALINK_PUBLIC
metalink_set_generator(metalink_t * metalink,const char * generator)251 metalink_set_generator(metalink_t* metalink, const char* generator)
252 {
253   return allocate_copy_string(&metalink->generator, generator);
254 }
255 
256 metalink_error_t
257 METALINK_PUBLIC
metalink_set_origin(metalink_t * metalink,const char * origin)258 metalink_set_origin(metalink_t* metalink, const char* origin)
259 {
260   return allocate_copy_string(&metalink->origin, origin);
261 }
262 
263 void
264 METALINK_PUBLIC
metalink_set_origin_dynamic(metalink_t * metalink,int origin_dynamic)265 metalink_set_origin_dynamic(metalink_t* metalink, int origin_dynamic)
266 {
267   metalink->origin_dynamic = origin_dynamic;
268 }
269 
270 void
271 METALINK_PUBLIC
metalink_set_published(metalink_t * metalink,time_t published)272 metalink_set_published(metalink_t* metalink, time_t published)
273 {
274   metalink->published = published;
275 }
276 
277 void
278 METALINK_PUBLIC
metalink_set_updated(metalink_t * metalink,time_t updated)279 metalink_set_updated(metalink_t* metalink, time_t updated)
280 {
281   metalink->updated = updated;
282 }
283 
284 void
285 METALINK_PUBLIC
metalink_set_version(metalink_t * metalink,metalink_version_t version)286 metalink_set_version(metalink_t* metalink, metalink_version_t version)
287 {
288   metalink->version = version;
289 }
290 
291 metalink_error_t
292 METALINK_PUBLIC
metalink_resource_set_type(metalink_resource_t * resource,const char * type)293 metalink_resource_set_type(metalink_resource_t* resource, const char* type)
294 {
295   return allocate_copy_string(&resource->type, type);
296 }
297 
298 metalink_error_t
299 METALINK_PUBLIC
metalink_resource_set_location(metalink_resource_t * resource,const char * location)300 metalink_resource_set_location(metalink_resource_t* resource,
301 				   const char* location)
302 {
303   return allocate_copy_string(&resource->location, location);
304 }
305 
306 void
307 METALINK_PUBLIC
metalink_resource_set_preference(metalink_resource_t * resource,int preference)308 metalink_resource_set_preference(metalink_resource_t* resource,
309 				 int preference)
310 {
311   resource->preference = preference;
312   resource->priority = 1000000 - preference;
313 }
314 
315 void
316 METALINK_PUBLIC
metalink_resource_set_priority(metalink_resource_t * resource,int priority)317 metalink_resource_set_priority(metalink_resource_t* resource,
318 			       int priority)
319 {
320   resource->priority = priority;
321   resource->preference = 1000000 - priority;
322 }
323 
324 void
325 METALINK_PUBLIC
metalink_resource_set_maxconnections(metalink_resource_t * resource,int maxconnections)326 metalink_resource_set_maxconnections(metalink_resource_t* resource,
327 					  int maxconnections)
328 {
329   resource->maxconnections = maxconnections;
330 }
331 
332 metalink_error_t
333 METALINK_PUBLIC
metalink_resource_set_url(metalink_resource_t * resource,const char * url)334 metalink_resource_set_url(metalink_resource_t* resource, const char* url)
335 {
336   return allocate_copy_string(&resource->url, url);
337 }
338 
339 /* for metalink_metaurl_t */
340 metalink_metaurl_t
341 METALINK_PUBLIC
metalink_metaurl_new(void)342 * metalink_metaurl_new(void)
343 {
344   metalink_metaurl_t* metaurl;
345   metaurl = malloc(sizeof(metalink_metaurl_t));
346   if(metaurl) {
347     memset(metaurl, 0, sizeof(metalink_metaurl_t));
348   }
349   return metaurl;
350 }
351 
352 void
353 METALINK_PUBLIC
metalink_metaurl_delete(metalink_metaurl_t * metaurl)354 metalink_metaurl_delete(metalink_metaurl_t* metaurl)
355 {
356   if(metaurl) {
357     free(metaurl->url);
358     free(metaurl->mediatype);
359     free(metaurl->name);
360     free(metaurl);
361   }
362 }
363 
364 metalink_error_t
365 METALINK_PUBLIC
metalink_metaurl_set_url(metalink_metaurl_t * metaurl,const char * url)366 metalink_metaurl_set_url(metalink_metaurl_t* metaurl,
367 			 const char* url)
368 {
369   return allocate_copy_string(&metaurl->url, url);
370 }
371 
372 metalink_error_t
373 METALINK_PUBLIC
metalink_metaurl_set_mediatype(metalink_metaurl_t * metaurl,const char * mediatype)374 metalink_metaurl_set_mediatype(metalink_metaurl_t* metaurl,
375 			       const char* mediatype)
376 {
377   return allocate_copy_string(&metaurl->mediatype, mediatype);
378 }
379 
380 metalink_error_t
381 METALINK_PUBLIC
metalink_metaurl_set_name(metalink_metaurl_t * metaurl,const char * name)382 metalink_metaurl_set_name(metalink_metaurl_t* metaurl,
383 			  const char* name)
384 {
385   return allocate_copy_string(&metaurl->name, name);
386 }
387 
388 void
389 METALINK_PUBLIC
metalink_metaurl_set_priority(metalink_metaurl_t * metaurl,int priority)390 metalink_metaurl_set_priority(metalink_metaurl_t* metaurl,
391 			      int priority)
392 {
393   metaurl->priority = priority;
394 }
395 
396 /* for metalink_checksum_t */
397 metalink_checksum_t
398 METALINK_PUBLIC
metalink_checksum_new(void)399 * metalink_checksum_new(void)
400 {
401   metalink_checksum_t* checksum;
402   checksum = malloc(sizeof(metalink_checksum_t));
403   if(checksum) {
404     memset(checksum, 0, sizeof(metalink_checksum_t));
405   }
406   return checksum;
407 }
408 
409 void
410 METALINK_PUBLIC
metalink_checksum_delete(metalink_checksum_t * checksum)411 metalink_checksum_delete(metalink_checksum_t* checksum)
412 {
413   if(checksum) {
414     free(checksum->type);
415     free(checksum->hash);
416     free(checksum);
417   }
418 }
419 
420 metalink_error_t
421 METALINK_PUBLIC
metalink_checksum_set_type(metalink_checksum_t * checksum,const char * type)422 metalink_checksum_set_type(metalink_checksum_t* checksum, const char* type)
423 {
424   return allocate_copy_string(&checksum->type, type);
425 }
426 
427 metalink_error_t
428 METALINK_PUBLIC
metalink_checksum_set_hash(metalink_checksum_t * checksum,const char * hash)429 metalink_checksum_set_hash(metalink_checksum_t* checksum, const char* hash)
430 {
431   return allocate_copy_string(&checksum->hash, hash);
432 }
433 
434 /* for metalink_piece_hash_t */
435 metalink_piece_hash_t
436 METALINK_PUBLIC
metalink_piece_hash_new(void)437 * metalink_piece_hash_new(void)
438 {
439   metalink_piece_hash_t* piece_hash;
440   piece_hash = malloc(sizeof(metalink_piece_hash_t));
441   if(piece_hash) {
442     memset(piece_hash, 0, sizeof(metalink_piece_hash_t));
443   }
444   return piece_hash;
445 }
446 
447 void
448 METALINK_PUBLIC
metalink_piece_hash_delete(metalink_piece_hash_t * piece_hash)449 metalink_piece_hash_delete(metalink_piece_hash_t* piece_hash)
450 {
451   if(!piece_hash) {
452     return;
453   }
454   free(piece_hash->hash);
455   free(piece_hash);
456 }
457 
458 void
459 METALINK_PUBLIC
metalink_piece_hash_set_piece(metalink_piece_hash_t * piece_hash,int piece)460 metalink_piece_hash_set_piece(metalink_piece_hash_t* piece_hash, int piece)
461 {
462   piece_hash->piece = piece;
463 }
464 
465 metalink_error_t
466 METALINK_PUBLIC
metalink_piece_hash_set_hash(metalink_piece_hash_t * piece_hash,const char * hash)467 metalink_piece_hash_set_hash(metalink_piece_hash_t* piece_hash, const char* hash)
468 {
469   return allocate_copy_string(&piece_hash->hash, hash);
470 }
471 
472 /* for metalink_chunk_checksum_t */
473 metalink_chunk_checksum_t
474 METALINK_PUBLIC
metalink_chunk_checksum_new(void)475 * metalink_chunk_checksum_new(void)
476 {
477   metalink_chunk_checksum_t* chunk_checksum;
478   chunk_checksum = malloc(sizeof(metalink_chunk_checksum_t));
479   if(chunk_checksum) {
480     memset(chunk_checksum, 0, sizeof(metalink_chunk_checksum_t));
481   }
482   return chunk_checksum;
483 }
484 
485 void
486 METALINK_PUBLIC
metalink_chunk_checksum_delete(metalink_chunk_checksum_t * chunk_checksum)487 metalink_chunk_checksum_delete(metalink_chunk_checksum_t* chunk_checksum)
488 {
489   metalink_piece_hash_t** p;
490   if(!chunk_checksum) {
491     return;
492   }
493   free(chunk_checksum->type);
494   if(chunk_checksum->piece_hashes) {
495     p = chunk_checksum->piece_hashes;
496     while(*p) {
497       metalink_piece_hash_delete(*p);
498       ++p;
499     }
500     free(chunk_checksum->piece_hashes);
501   }
502   free(chunk_checksum);
503 }
504 
505 metalink_error_t
506 METALINK_PUBLIC
metalink_chunk_checksum_set_type(metalink_chunk_checksum_t * chunk_checksum,const char * type)507 metalink_chunk_checksum_set_type(metalink_chunk_checksum_t* chunk_checksum,
508 				     const char* type)
509 {
510   return allocate_copy_string(&chunk_checksum->type, type);
511 }
512 
513 void
514 METALINK_PUBLIC
metalink_chunk_checksum_set_length(metalink_chunk_checksum_t * chunk_checksum,int length)515 metalink_chunk_checksum_set_length(metalink_chunk_checksum_t* chunk_checksum,
516 					int length)
517 {
518   chunk_checksum->length = length;
519 }
520 
521 void
522 METALINK_PUBLIC
metalink_chunk_checksum_set_piece_hashes(metalink_chunk_checksum_t * chunk_checksum,metalink_piece_hash_t ** piece_hashes)523 metalink_chunk_checksum_set_piece_hashes
524 (metalink_chunk_checksum_t* chunk_checksum,
525  metalink_piece_hash_t** piece_hashes)
526 {
527   if(chunk_checksum->piece_hashes) {
528     metalink_piece_hash_t** p;
529     p = chunk_checksum->piece_hashes;
530     while(*p) {
531       metalink_piece_hash_delete(*p);
532       ++p;
533     }
534     free(chunk_checksum->piece_hashes);
535   }
536   chunk_checksum->piece_hashes = piece_hashes;
537 }
538 
539 /* for metalink_signature_t */
540 metalink_signature_t
541 METALINK_PUBLIC
metalink_signature_new(void)542 * metalink_signature_new(void)
543 {
544   metalink_signature_t* signature;
545   signature = malloc(sizeof(metalink_signature_t));
546   if(signature) {
547     memset(signature, 0, sizeof(metalink_signature_t));
548   }
549   return signature;
550 }
551 
552 void
553 METALINK_PUBLIC
metalink_signature_delete(metalink_signature_t * signature)554 metalink_signature_delete(metalink_signature_t* signature)
555 {
556   if(signature) {
557     free(signature->mediatype);
558     free(signature->signature);
559     free(signature);
560   }
561 }
562 
563 metalink_error_t
564 METALINK_PUBLIC
metalink_signature_set_mediatype(metalink_signature_t * signature,const char * mediatype)565 metalink_signature_set_mediatype(metalink_signature_t* signature,
566 				 const char* mediatype)
567 {
568   return allocate_copy_string(&signature->mediatype, mediatype);
569 }
570 
571 metalink_error_t
572 METALINK_PUBLIC
metalink_signature_set_signature(metalink_signature_t * signature,const char * value)573 metalink_signature_set_signature(metalink_signature_t* signature,
574 				 const char* value)
575 {
576   return allocate_copy_string(&signature->signature, value);
577 }
578 
579 /* for metalink_t */
580 metalink_t
581 METALINK_PUBLIC
metalink_new(void)582 * metalink_new(void)
583 {
584   metalink_t* metalink;
585   metalink = malloc(sizeof(metalink_t));
586   if(metalink) {
587     memset(metalink, 0, sizeof(metalink_t));
588   }
589   return metalink;
590 }
591 
592 void
593 METALINK_PUBLIC
metalink_delete(metalink_t * metalink)594 metalink_delete(metalink_t* metalink)
595 {
596   metalink_file_t** filepp;
597   if(!metalink) {
598     return;
599   }
600 
601   if(metalink->generator) {
602     free(metalink->generator);
603   }
604   if(metalink->origin) {
605     free(metalink->origin);
606   }
607 
608   if(metalink->files) {
609     filepp = metalink->files;
610     while(*filepp) {
611       metalink_file_delete(*filepp);
612       ++filepp;
613     }
614     free(metalink->files);
615   }
616   if(metalink->identity){
617     free(metalink->identity);
618   }
619   if(metalink->tags){
620     free(metalink->tags);
621   }
622   free(metalink);
623 }
624