summaryrefslogtreecommitdiff
path: root/pkgtools/pkg_install/files/lib/pkg_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'pkgtools/pkg_install/files/lib/pkg_io.c')
-rw-r--r--pkgtools/pkg_install/files/lib/pkg_io.c185
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;
}