diff options
Diffstat (limited to 'pkgtools/pkg_install/files/lib/pkg_io.c')
-rw-r--r-- | pkgtools/pkg_install/files/lib/pkg_io.c | 185 |
1 files changed, 157 insertions, 28 deletions
diff --git a/pkgtools/pkg_install/files/lib/pkg_io.c b/pkgtools/pkg_install/files/lib/pkg_io.c index 643262e0221..0a87bfc5a64 100644 --- a/pkgtools/pkg_install/files/lib/pkg_io.c +++ b/pkgtools/pkg_install/files/lib/pkg_io.c @@ -1,4 +1,4 @@ -/* $NetBSD: pkg_io.c,v 1.1 2008/04/04 15:21:32 joerg Exp $ */ +/* $NetBSD: pkg_io.c,v 1.2 2008/04/26 14:56:34 joerg Exp $ */ /*- * Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>. * All rights reserved. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #endif -__RCSID("$NetBSD: pkg_io.c,v 1.1 2008/04/04 15:21:32 joerg Exp $"); +__RCSID("$NetBSD: pkg_io.c,v 1.2 2008/04/26 14:56:34 joerg Exp $"); #include <archive.h> #include <archive_entry.h> @@ -52,7 +52,7 @@ __RCSID("$NetBSD: pkg_io.c,v 1.1 2008/04/04 15:21:32 joerg Exp $"); #include "lib.h" struct fetch_archive { - const char *url; + struct url *url; fetchIO *fetch; char buffer[32768]; }; @@ -62,7 +62,7 @@ fetch_archive_open(struct archive *a, void *client_data) { struct fetch_archive *f = client_data; - f->fetch = fetchGetURL(f->url, ""); + f->fetch = fetchGet(f->url, ""); if (f->fetch == NULL) return ENOENT; return 0; @@ -88,52 +88,181 @@ fetch_archive_close(struct archive *a, void *client_data) return 0; } -struct archive * -open_remote_archive(const char *url, void **cookie) +static struct archive * +open_archive_by_url(struct url *url, void **cookie) { struct fetch_archive *f; - struct archive *archive; + struct archive *a; f = malloc(sizeof(*f)); if (f == NULL) err(2, "cannot allocate memory for remote archive"); f->url = url; - archive = archive_read_new(); - archive_read_support_compression_all(archive); - archive_read_support_format_all(archive); - if (archive_read_open(archive, f, fetch_archive_open, fetch_archive_read, - fetch_archive_close)) - errx(2, "cannot open archive: %s", archive_error_string(archive)); + a = archive_read_new(); + archive_read_support_compression_all(a); + archive_read_support_format_all(a); + if (archive_read_open(a, f, fetch_archive_open, fetch_archive_read, + fetch_archive_close)) { + archive_read_close(a); + free(f); + return NULL; + } *cookie = f; + return a; +} + +struct archive * +open_archive(const char *url, void **cookie) +{ + struct url *u; + struct archive *a; + + if (!IS_URL(url)) { + a = archive_read_new(); + archive_read_support_compression_all(a); + archive_read_support_format_all(a); + if (archive_read_open_filename(a, url, 1024)) { + archive_read_close(a); + return NULL; + } + *cookie = NULL; + return a; + } + + if ((u = fetchParseURL(url)) == NULL) + return NULL; - return archive; + a = open_archive_by_url(u, cookie); + + fetchFreeURL(u); + return a; } void -close_remote_archive(void *cookie) +close_archive(void *cookie) { free(cookie); } -struct archive * -open_local_archive(const char *path, void **cookie) +static int +strip_suffix(char *filename) { - struct archive *archive; + size_t len; - archive = archive_read_new(); - archive_read_support_compression_all(archive); - archive_read_support_format_all(archive); - if (archive_read_open_filename(archive, path, 1024)) - errx(2, "cannot open archive: %s", - archive_error_string(archive)); - *cookie = NULL; + len = strlen(filename); + if (len <= 4) + return 0; + if (strcmp(filename + len - 4, ".tgz") == 0 || + strcmp(filename + len - 4, ".tbz") == 0) { + filename[len - 4] = '\0'; + return 1; + } else + return 0; +} - return archive; +static int +find_best_package(struct url *url, const char *pattern, struct url **best_url) +{ + char *cur_match, *best_match = NULL; + struct url_list ue; + size_t i; + + if (*best_url) { + if ((best_match = fetchUnquoteFilename(*best_url)) == NULL) + return -1; + } else + best_match = NULL; + + if (best_match && strip_suffix(best_match) == 0) { + free(best_match); + return -1; + } + + fetchInitURLList(&ue); + if (fetchList(&ue, url, NULL, "")) { + fetchFreeURLList(&ue); + return -1; + } + for (i = 0; i < ue.length; ++i) { + cur_match = fetchUnquoteFilename(ue.urls + i); + + if (cur_match == NULL) { + free(best_match); + fetchFreeURLList(&ue); + return -1; + } + if (strip_suffix(cur_match) == 0) { + free(cur_match); + continue; + } + if (pkg_order(pattern, cur_match, best_match) == 1) { + if (*best_url) + fetchFreeURL(*best_url); + *best_url = fetchCopyURL(ue.urls + i); + free(best_match); + best_match = cur_match; + cur_match = NULL; + if (*best_url == NULL) { + free(best_match); + return -1; + } + } + free(cur_match); + } + free(best_match); + fetchFreeURLList(&ue); + return 0; } -void -close_local_archive(void *cookie) +struct archive * +find_archive(const char *fname, void **cookie) { + struct archive *a; + struct path *path; + const char *cur_path; + struct url *url, *best_match; + char tmp[MaxPathSize]; + + best_match = NULL; + + a = open_archive(fname, cookie); + if (a != NULL) + return a; + + if (strchr(fname, '/') != NULL) { + const char *last_slash; + + last_slash = strrchr(fname, '/'); + snprintf(tmp, sizeof(tmp), "%s%.*s", + IS_URL(fname) ? "" : "file://", + (int)(last_slash - fname + 1), fname); + url = fetchParseURL(tmp); + if (url == NULL) + return NULL; + fname = last_slash + 1; /* XXX fetchUnquoteFilename */ + find_best_package(url, fname, &best_match); + fetchFreeURL(url); + } else { + TAILQ_FOREACH(path, &PkgPath, pl_entry) { + cur_path = path->pl_path; + if (!IS_URL(cur_path)) { + snprintf(tmp, sizeof(tmp), "file://%s", cur_path); + cur_path = tmp; + } + url = fetchParseURL(cur_path); + if (url == NULL) + continue; + find_best_package(url, fname, &best_match); + /* XXX Check return value and complain */ + fetchFreeURL(url); + } + } + + if (best_match == NULL) + return NULL; + a = open_archive_by_url(best_match, cookie); + fetchFreeURL(best_match); + return a; } |