1 /* release.c - the opkg package management system
3 Copyright (C) 2010,2011 Javier Palacios
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2, or (at
8 your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
20 #include "opkg_utils.h"
21 #include "libbb/libbb.h"
23 #include "opkg_download.h"
24 #include "sprintf_alloc.h"
26 #include "release_parse.h"
28 #include "parse_util.h"
29 #include "file_util.h"
32 release_init(release_t *release)
35 release->datestring = NULL;
36 release->architectures = NULL;
37 release->architectures_count = 0;
38 release->components = NULL;
39 release->components_count = 0;
40 release->complist = NULL;
41 release->complist_count = 0;
49 release = xcalloc(1, sizeof(release_t));
50 release_init(release);
56 release_deinit(release_t *release)
61 free(release->datestring);
63 for(i = 0; i < release->architectures_count; i++){
64 free(release->architectures[i]);
66 free(release->architectures);
68 for(i = 0; i < release->components_count; i++){
69 free(release->components[i]);
71 free(release->components);
73 for(i = 0; i < release->complist_count; i++){
74 free(release->complist[i]);
76 free(release->complist);
81 release_init_from_file(release_t *release, const char *filename)
86 release_file = fopen(filename, "r");
87 if (release_file == NULL) {
88 opkg_perror(ERROR, "Failed to open %s", filename);
92 err=release_parse_from_stream(release, release_file);
94 if (!release_arch_supported(release)) {
95 opkg_msg(ERROR, "No valid architecture found on Release file.\n");
104 item_in_list(const char *comp, char **complist, const unsigned int count)
111 for(i = 0; i < count; i++){
112 if (strcmp(comp, complist[i]) == 0)
120 release_arch_supported(release_t *release)
122 nv_pair_list_elt_t *l;
124 list_for_each_entry(l , &conf->arch_list.head, node) {
125 nv_pair_t *nv = (nv_pair_t *)l->data;
126 if (item_in_list(nv->name, release->architectures, release->architectures_count)) {
127 opkg_msg(DEBUG, "Arch %s (priority %s) supported for dist %s.\n",
128 nv->name, nv->value, release->name);
137 release_comps_supported(release_t *release, const char *complist)
143 release->complist = parse_list(complist, &release->complist_count, ' ', 1);
144 for(i = 0; i < release->complist_count; i++){
145 if (!item_in_list(release->complist[i], release->components, release->components_count)) {
146 opkg_msg(ERROR, "Component %s not supported for dist %s.\n",
147 release->complist[i], release->name);
157 release_comps(release_t *release, unsigned int *count)
159 char **comps = release->complist;
162 comps = release->components;
163 *count = release->components_count;
165 *count = release->complist_count;
168 return (const char **)comps;
172 release_download(release_t *release, pkg_src_t *dist, char *lists_dir, char *tmpdir)
176 const char **comps = release_comps(release, &ncomp);
177 nv_pair_list_elt_t *l;
180 for(i = 0; i < ncomp; i++){
184 sprintf_alloc(&prefix, "%s/dists/%s/%s/binary", dist->value, dist->name,
187 list_for_each_entry(l , &conf->arch_list.head, node) {
189 char *tmp_file_name, *list_file_name;
190 char *subpath = NULL;
192 nv_pair_t *nv = (nv_pair_t *)l->data;
194 sprintf_alloc(&list_file_name, "%s/%s-%s-%s", lists_dir, dist->name, comps[i], nv->name);
196 sprintf_alloc(&tmp_file_name, "%s/%s-%s-%s%s", tmpdir, dist->name, comps[i], nv->name, ".gz");
198 sprintf_alloc(&subpath, "%s/binary-%s/%s", comps[i], nv->name, dist->gzip ? "Packages.gz" : "Packages");
201 sprintf_alloc(&url, "%s-%s/Packages.gz", prefix, nv->name);
202 err = opkg_download(url, tmp_file_name, NULL, NULL, 1);
204 err = release_verify_file(release, tmp_file_name, subpath);
206 unlink (tmp_file_name);
207 unlink (list_file_name);
212 opkg_msg(NOTICE, "Inflating %s.\n", url);
213 in = fopen (tmp_file_name, "r");
214 out = fopen (list_file_name, "w");
216 err = unzip (in, out);
218 opkg_msg(INFO, "Corrumpt file at %s.\n", url);
225 unlink (tmp_file_name);
231 sprintf_alloc(&url, "%s-%s/Packages", prefix, nv->name);
232 err = opkg_download(url, list_file_name, NULL, NULL, 1);
234 err = release_verify_file(release, tmp_file_name, subpath);
236 unlink (list_file_name);
242 free(list_file_name);
255 release_get_size(release_t *release, const char *pathname)
257 const cksum_t *cksum;
259 if (release->md5sums) {
260 cksum = cksum_list_find(release->md5sums, pathname);
265 if (release->sha256sums) {
266 cksum = cksum_list_find(release->sha256sums, pathname);
275 release_get_md5(release_t *release, const char *pathname)
277 const cksum_t *cksum;
279 if (release->md5sums) {
280 cksum = cksum_list_find(release->md5sums, pathname);
289 release_get_sha256(release_t *release, const char *pathname)
291 const cksum_t *cksum;
293 if (release->sha256sums) {
294 cksum = cksum_list_find(release->sha256sums, pathname);
303 release_verify_file(release_t *release, const char* file_name, const char *pathname)
307 const char *md5 = release_get_md5(release, pathname);
309 char *f_sha256 = NULL;
310 const char *sha256 = release_get_sha256(release, pathname);
314 if (stat(file_name, &f_info) || (f_info.st_size!=release_get_size(release, pathname))) {
315 opkg_msg(ERROR, "Size verification failed for %s - %s.\n", release->name, pathname);
319 f_md5 = file_md5sum_alloc(file_name);
321 f_sha256 = file_sha256sum_alloc(file_name);
324 if (md5 && strcmp(md5, f_md5)) {
325 opkg_msg(ERROR, "MD5 verification failed for %s - %s.\n", release->name, pathname);
328 } else if (sha256 && strcmp(sha256, f_sha256)) {
329 opkg_msg(ERROR, "SHA256 verification failed for %s - %s.\n", release->name, pathname);