summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/apk.c6
-rw-r--r--src/apk_database.h3
-rw-r--r--src/apk_defines.h1
-rw-r--r--src/apk_state.h3
-rw-r--r--src/cache.c17
-rw-r--r--src/database.c45
-rw-r--r--src/fetch.c16
-rw-r--r--src/state.c5
8 files changed, 67 insertions, 29 deletions
diff --git a/src/apk.c b/src/apk.c
index bbb33fb..6c4acd7 100644
--- a/src/apk.c
+++ b/src/apk.c
@@ -55,7 +55,8 @@ static struct apk_option generic_options[] = {
{ 0x107, "keys-dir", "Override directory of trusted keys",
required_argument, "KEYSDIR" },
{ 0x108, "repositories-file", "Override repositories file",
- required_argument, "REPOFILE" }
+ required_argument, "REPOFILE" },
+ { 0x109, "no-network", "Do not use network (cache is still used)" },
};
const char *apk_error_str(int error)
@@ -380,6 +381,9 @@ int main(int argc, char **argv)
case 0x105:
apk_wait = atoi(optarg);
break;
+ case 0x109:
+ apk_flags |= APK_NO_NETWORK;
+ break;
default:
if (applet == NULL || applet->parse == NULL ||
applet->parse(ctx, &dbopts, r,
diff --git a/src/apk_database.h b/src/apk_database.h
index 09f9ef7..f2b5ca7 100644
--- a/src/apk_database.h
+++ b/src/apk_database.h
@@ -98,6 +98,7 @@ struct apk_database {
unsigned name_id, num_repos;
const char *cache_dir;
int permanent;
+ unsigned int local_repos;
struct apk_dependency_array *world;
struct apk_string_array *protected_paths;
@@ -159,6 +160,8 @@ int apk_db_index_read_file(struct apk_database *db, const char *file, int repo);
int apk_db_index_write(struct apk_database *db, struct apk_ostream *os);
int apk_db_add_repository(apk_database_t db, apk_blob_t repository);
+struct apk_repository *apk_db_select_repo(struct apk_database *db,
+ struct apk_package *pkg);
int apk_repository_update(struct apk_database *db, struct apk_repository *repo);
int apk_db_cache_active(struct apk_database *db);
diff --git a/src/apk_defines.h b/src/apk_defines.h
index 27d4ee4..0ecade4 100644
--- a/src/apk_defines.h
+++ b/src/apk_defines.h
@@ -63,6 +63,7 @@ extern unsigned int apk_flags;
#define APK_PURGE 0x0200
#define APK_INTERACTIVE 0x0400
#define APK_RECURSIVE_DELETE 0x0800
+#define APK_NO_NETWORK 0x1000
#define apk_error(args...) do { apk_log("ERROR: ", args); } while (0)
#define apk_warning(args...) do { if (apk_verbosity > 0) { apk_log("WARNING: ", args); } } while (0)
diff --git a/src/apk_state.h b/src/apk_state.h
index 88a5ad0..72c02b9 100644
--- a/src/apk_state.h
+++ b/src/apk_state.h
@@ -4,7 +4,7 @@
* Copyright (C) 2008 Timo Teräs <timo.teras@iki.fi>
* All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
+ * This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation. See http://www.gnu.org/ for details.
*/
@@ -24,6 +24,7 @@ struct apk_change {
struct apk_state {
unsigned int refs, num_names;
+ struct apk_database *db;
struct list_head change_list_head;
apk_name_state_t name[];
};
diff --git a/src/cache.c b/src/cache.c
index d4509e1..f9bcb6f 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -28,6 +28,7 @@ static int cache_download(struct apk_database *db)
struct apk_state *state;
struct apk_change *change;
struct apk_package *pkg;
+ struct apk_repository *repo;
char item[PATH_MAX], cacheitem[PATH_MAX];
int i, r = 0;
@@ -54,17 +55,13 @@ static int cache_download(struct apk_database *db)
if (faccessat(db->cache_fd, cacheitem, R_OK, 0) == 0)
continue;
- for (i = 0; i < db->num_repos; i++) {
- if (!(pkg->repos & BIT(i)))
- continue;
+ repo = apk_db_select_repo(db, pkg);
+ if (repo == NULL)
+ continue;
- apk_pkg_format_plain(pkg, APK_BLOB_BUF(item));
- r = apk_cache_download(db, db->repos[i].url,
- item, cacheitem,
- APK_SIGN_VERIFY_IDENTITY);
- if (r != 0)
- return r;
- }
+ apk_pkg_format_plain(pkg, APK_BLOB_BUF(item));
+ apk_cache_download(db, repo->url, item, cacheitem,
+ APK_SIGN_VERIFY_IDENTITY);
}
err:
diff --git a/src/database.c b/src/database.c
index ab43ea2..d7bcb2d 100644
--- a/src/database.c
+++ b/src/database.c
@@ -1156,6 +1156,37 @@ static struct apk_bstream *apk_repository_file_open(struct apk_repository *repo,
return apk_bstream_from_url(tmp);
}
+struct apk_repository *apk_db_select_repo(struct apk_database *db,
+ struct apk_package *pkg)
+{
+ unsigned int repos = pkg->repos;
+ int i;
+
+ /* Always prefer local repositories */
+ if ((repos & db->local_repos) != 0)
+ repos &= db->local_repos;
+
+ /* Pick first repository providing this package */
+ for (i = 0; i < APK_MAX_REPOS; i++)
+ if (repos & BIT(i))
+ break;
+
+ if (i >= APK_MAX_REPOS)
+ return NULL;
+
+ /* If this is a remote repository, and we have no network,
+ * check that we have it in cache */
+ if ((db->local_repos & BIT(i)) == 0 && (apk_flags & APK_NO_NETWORK)) {
+ char cacheitem[PATH_MAX];
+
+ apk_pkg_format_cache(pkg, APK_BLOB_BUF(cacheitem));
+ if (faccessat(db->cache_fd, cacheitem, R_OK, 0) != 0)
+ return NULL;
+ }
+
+ return &db->repos[i];
+}
+
int apk_repository_update(struct apk_database *db, struct apk_repository *repo)
{
char cacheitem[PATH_MAX];
@@ -1282,6 +1313,8 @@ int apk_db_add_repository(apk_database_t _db, apk_blob_t repository)
targz = 0;
}
} else {
+ db->local_repos |= BIT(r);
+
bs = apk_repository_file_open(repo, apkindex_tar_gz);
if (bs == NULL) {
bs = apk_repository_file_open(repo, apk_index_gz);
@@ -1686,22 +1719,18 @@ static int apk_db_unpack_pkg(struct apk_database *db,
struct apk_bstream *bs = NULL;
struct apk_istream *tar;
char file[PATH_MAX];
- int r, i, need_copy = FALSE;
+ int r, need_copy = FALSE;
if (newpkg->filename == NULL) {
struct apk_repository *repo;
- for (i = 0; i < APK_MAX_REPOS; i++)
- if (newpkg->repos & BIT(i))
- break;
-
- if (i >= APK_MAX_REPOS) {
- apk_error("%s-%s: not present in any repository",
+ repo = apk_db_select_repo(db, newpkg);
+ if (repo == NULL) {
+ apk_error("%s-%s: package is not currently available",
newpkg->name->name, newpkg->version);
return -1;
}
- repo = &db->repos[i];
if (apk_db_cache_active(db) &&
repo->csum.type != APK_CHECKSUM_NONE) {
apk_pkg_format_cache(newpkg, APK_BLOB_BUF(file));
diff --git a/src/fetch.c b/src/fetch.c
index 9d10f7c..f827d95 100644
--- a/src/fetch.c
+++ b/src/fetch.c
@@ -95,8 +95,9 @@ static int fetch_package(struct fetch_ctx *fctx,
struct apk_package *pkg)
{
struct apk_istream *is;
+ struct apk_repository *repo;
char pkgfile[PATH_MAX], url[PATH_MAX];
- int r, i, fd;
+ int r, fd;
apk_pkg_format_plain(pkg, APK_BLOB_BUF(pkgfile));
@@ -110,12 +111,9 @@ static int fetch_package(struct fetch_ctx *fctx,
}
apk_message("Downloading %s-%s", pkg->name->name, pkg->version);
- for (i = 0; i < APK_MAX_REPOS; i++)
- if (pkg->repos & BIT(i))
- break;
-
- if (i >= APK_MAX_REPOS) {
- apk_error("%s-%s: not present in any repository",
+ repo = apk_db_select_repo(db, pkg);
+ if (repo == NULL) {
+ apk_error("%s-%s: package is not currently available",
pkg->name->name, pkg->version);
return -1;
}
@@ -123,8 +121,8 @@ static int fetch_package(struct fetch_ctx *fctx,
if (apk_flags & APK_SIMULATE)
return 0;
- snprintf(url, sizeof(url), "%s%s%s", db->repos[i].url,
- db->repos[i].url[strlen(db->repos[i].url)-1] == '/' ? "" : "/",
+ snprintf(url, sizeof(url), "%s%s%s", repo->url,
+ repo->url[strlen(repo->url)-1] == '/' ? "" : "/",
pkgfile);
if (fctx->flags & FETCH_STDOUT) {
diff --git a/src/state.c b/src/state.c
index ff1a2bb..f18b005 100644
--- a/src/state.c
+++ b/src/state.c
@@ -142,6 +142,7 @@ struct apk_state *apk_state_new(struct apk_database *db)
state = (struct apk_state*) calloc(1, num_bytes);
state->refs = 1;
state->num_names = db->name_id;
+ state->db = db;
list_init(&state->change_list_head);
/* Instantiate each 'name' target in world, and lockout incompatible
@@ -292,6 +293,10 @@ int apk_state_lock_dependency(struct apk_state *state,
if (apk_pkg_get_state(c->pkgs[i]) == APK_PKG_INSTALLED)
installed = pkg;
+ if (pkg->filename == NULL &&
+ apk_db_select_repo(state->db, pkg) == NULL)
+ continue;
+
if (latest == NULL) {
latest = pkg;
continue;