summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teras <timo.teras@iki.fi>2009-07-24 14:00:57 +0300
committerTimo Teras <timo.teras@iki.fi>2009-07-24 14:00:57 +0300
commite5be34335ca8ff9df4ec53c2ab421522a6ca02c3 (patch)
tree62d9f11702abf9bcded4c0aec6db101e0e17b429
parent8806ce875e4e1d3dabbfd6a6cf12a3b5a6257ed9 (diff)
downloadapk-tools-e5be34335ca8ff9df4ec53c2ab421522a6ca02c3.tar.bz2
apk-tools-e5be34335ca8ff9df4ec53c2ab421522a6ca02c3.tar.xz
db: create cache index with non-repository packages
this enables virtual packages and files specified from command line to work on non-harddisk installs.
-rw-r--r--src/add.c27
-rw-r--r--src/apk_database.h1
-rw-r--r--src/database.c161
3 files changed, 122 insertions, 67 deletions
diff --git a/src/add.c b/src/add.c
index 03fc96a..d147fa6 100644
--- a/src/add.c
+++ b/src/add.c
@@ -77,6 +77,22 @@ static int cup(void)
return 0;
}
+static int non_repository_check(struct apk_database *db)
+{
+ if (apk_flags & APK_FORCE)
+ return 0;
+ if (apk_db_cache_active(db))
+ return 0;
+ if (apk_db_permanent(db))
+ return 0;
+
+ apk_error("You tried to add a non-repository package to system, "
+ "but it would be lost on next reboot. Enable package caching "
+ "(apk cache --help) or use --force if you know what you are "
+ "doing.");
+ return 1;
+}
+
static int add_main(void *ctx, int argc, char **argv)
{
@@ -97,6 +113,9 @@ static int add_main(void *ctx, int argc, char **argv)
return r;
if (actx->virtpkg) {
+ if (non_repository_check(&db))
+ goto err;
+
virtpkg = apk_pkg_new();
if (virtpkg == NULL) {
apk_error("Failed to allocate virtual meta package");
@@ -119,14 +138,8 @@ static int add_main(void *ctx, int argc, char **argv)
struct apk_package *pkg = NULL;
struct apk_sign_ctx sctx;
- if (!apk_db_cache_active(&db) &&
- !apk_db_permanent(&db) &&
- !(apk_flags & APK_FORCE)) {
- apk_error("Use --force or enable package "
- "caching to install non-repository "
- "packages.");
+ if (non_repository_check(&db))
goto err;
- }
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY_AND_GENERATE,
NULL);
diff --git a/src/apk_database.h b/src/apk_database.h
index 46e6152..d2f27eb 100644
--- a/src/apk_database.h
+++ b/src/apk_database.h
@@ -83,6 +83,7 @@ struct apk_database {
int root_fd, lock_fd;
unsigned name_id, num_repos;
const char *cache_dir;
+ int permanent;
struct apk_dependency_array *world;
struct apk_string_array *protected_paths;
diff --git a/src/database.c b/src/database.c
index bf0a0a6..ce90aea 100644
--- a/src/database.c
+++ b/src/database.c
@@ -1,7 +1,7 @@
/* database.c - Alpine Package Keeper (APK)
*
* Copyright (C) 2005-2008 Natanael Copa <n@tanael.org>
- * Copyright (C) 2008 Timo Teräs <timo.teras@iki.fi>
+ * Copyright (C) 2008-2009 Timo Teräs <timo.teras@iki.fi>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
@@ -395,6 +395,23 @@ struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *
return idb;
}
+static void apk_db_cache_get_name(char *buf, size_t bufsz,
+ struct apk_database *db,
+ struct apk_checksum *csum,
+ const char *file, int temp)
+{
+ char csumstr[APK_CACHE_CSUM_BYTES*2+1];
+ apk_blob_t bbuf = APK_BLOB_BUF(csumstr);
+
+ apk_blob_push_hexdump(&bbuf,
+ APK_BLOB_PTR_LEN((char *) csum->data,
+ APK_CACHE_CSUM_BYTES));
+ apk_blob_push_blob(&bbuf, APK_BLOB_PTR_LEN("", 1));
+
+ snprintf(buf, bufsz, "%s/%s/%s.%s%s",
+ db->root, db->cache_dir, csumstr, file, temp ? ".new" : "");
+}
+
int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
{
struct apk_package *pkg = NULL;
@@ -410,9 +427,9 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
if (pkg == NULL)
continue;
- if (repo != -1)
+ if (repo >= 0)
pkg->repos |= BIT(repo);
- else
+ else if (repo == -1)
apk_pkg_set_state(db, pkg, APK_PKG_INSTALLED);
if (apk_db_pkg_add(db, pkg) != pkg && repo == -1) {
@@ -678,6 +695,12 @@ static int apk_db_read_state(struct apk_database *db, int flags)
apk_db_index_read(db, bs, -1);
bs->close(bs, NULL);
}
+
+ bs = apk_bstream_from_file("etc/apk/cache/installed");
+ if (bs != NULL) {
+ apk_db_index_read(db, bs, -2);
+ bs->close(bs, NULL);
+ }
}
if (!(flags & APK_OPENF_NO_SCRIPTS)) {
@@ -696,6 +719,73 @@ static int apk_db_read_state(struct apk_database *db, int flags)
return 0;
}
+struct index_write_ctx {
+ struct apk_ostream *os;
+ int count;
+ int force;
+};
+
+static int write_index_entry(apk_hash_item item, void *ctx)
+{
+ struct index_write_ctx *iwctx = (struct index_write_ctx *) ctx;
+ struct apk_package *pkg = (struct apk_package *) item;
+ int r;
+
+ if (!iwctx->force && pkg->filename == NULL)
+ return 0;
+
+ r = apk_pkg_write_index_entry(pkg, iwctx->os);
+ if (r < 0)
+ return r;
+
+ if (iwctx->os->write(iwctx->os, "\n", 1) != 1)
+ return -1;
+
+ iwctx->count++;
+ return 0;
+}
+
+static int apk_db_index_write_nr_cache(struct apk_database *db)
+{
+ struct index_write_ctx ctx = { NULL, 0, TRUE };
+ struct apk_package *pkg;
+ struct apk_ostream *os;
+ int r;
+
+ if (!apk_db_cache_active(db))
+ return 0;
+
+ /* Write list of installed non-repository packages to
+ * cached index file */
+ ctx.os = os = apk_ostream_to_file("etc/apk/cache/installed.new", 0644);
+ if (os == NULL)
+ return -1;
+
+ list_for_each_entry(pkg, &db->installed.packages, installed_pkgs_list) {
+ if (pkg->repos != 0)
+ continue;
+ r = write_index_entry(pkg, &ctx);
+ if (r != 0)
+ return r;
+ }
+
+ os->close(os);
+ if (rename("etc/apk/cache/installed.new",
+ "etc/apk/cache/installed") < 0)
+ return -errno;
+
+ return ctx.count;
+}
+
+int apk_db_index_write(struct apk_database *db, struct apk_ostream *os)
+{
+ struct index_write_ctx ctx = { os, 0, FALSE };
+
+ apk_hash_foreach(&db->available.packages, write_index_entry, &ctx);
+
+ return ctx.count;
+}
+
static int add_protected_path(void *ctx, apk_blob_t blob)
{
struct apk_database *db = (struct apk_database *) ctx;
@@ -746,6 +836,7 @@ int apk_db_open(struct apk_database *db, const char *root, unsigned int flags)
apk_hash_init(&db->installed.files, &file_hash_ops, 10000);
list_init(&db->installed.packages);
db->cache_dir = apk_static_cache_dir;
+ db->permanent = 1;
if (root != NULL) {
fchdir(apk_cwd_fd);
@@ -759,6 +850,8 @@ int apk_db_open(struct apk_database *db, const char *root, unsigned int flags)
msg = "Unable to open root";
goto ret_errno;
}
+ if (fstat(db->root_fd, &st) != 0 || major(st.st_dev) == 0)
+ db->permanent = 0;
fchdir(db->root_fd);
if (stat(apk_linked_cache_dir, &st) == 0 && S_ISDIR(st.st_mode))
@@ -834,6 +927,9 @@ int apk_db_open(struct apk_database *db, const char *root, unsigned int flags)
if (!(flags & APK_OPENF_NO_REPOS)) {
list_for_each_entry(repo, &apk_repository_list.list, list)
apk_db_add_repository(db, APK_BLOB_STR(repo->url));
+
+ if (apk_flags & APK_UPDATE_CACHE)
+ apk_db_index_write_nr_cache(db);
}
fchdir(apk_cwd_fd);
@@ -895,6 +991,7 @@ int apk_db_write_config(struct apk_database *db)
return -errno;
unlink("var/lib/apk/scripts");
+ apk_db_index_write_nr_cache(db);
return 0;
}
@@ -943,13 +1040,7 @@ int apk_db_cache_active(struct apk_database *db)
int apk_db_permanent(struct apk_database *db)
{
- struct stat st;
-
- if (fstat(db->root_fd, &st) != 0)
- return 0;
- if (major(st.st_dev) == 0)
- return 0;
- return 1;
+ return db->permanent;
}
struct apk_package *apk_db_get_pkg(struct apk_database *db,
@@ -978,56 +1069,6 @@ struct apk_package *apk_db_get_file_owner(struct apk_database *db,
return dbf->diri->pkg;
}
-struct index_write_ctx {
- struct apk_ostream *os;
- int count;
-};
-
-static int write_index_entry(apk_hash_item item, void *ctx)
-{
- struct index_write_ctx *iwctx = (struct index_write_ctx *) ctx;
- struct apk_package *pkg = (struct apk_package *) item;
- int r;
-
- if (pkg->filename == NULL)
- return 0;
-
- r = apk_pkg_write_index_entry(pkg, iwctx->os);
- if (r < 0)
- return r;
-
- if (iwctx->os->write(iwctx->os, "\n", 1) != 1)
- return -1;
-
- iwctx->count++;
- return 0;
-}
-
-int apk_db_index_write(struct apk_database *db, struct apk_ostream *os)
-{
- struct index_write_ctx ctx = { os, 0 };
-
- apk_hash_foreach(&db->available.packages, write_index_entry, &ctx);
-
- return ctx.count;
-}
-
-static void apk_db_cache_get_name(char *buf, size_t bufsz,
- struct apk_database *db,
- struct apk_checksum *csum,
- const char *file, int temp)
-{
- char csumstr[APK_CACHE_CSUM_BYTES*2+1];
- apk_blob_t bbuf = APK_BLOB_BUF(csumstr);
-
- apk_blob_push_hexdump(&bbuf,
- APK_BLOB_PTR_LEN((char *) csum->data, APK_CACHE_CSUM_BYTES));
- apk_blob_push_blob(&bbuf, APK_BLOB_PTR_LEN("", 1));
-
- snprintf(buf, bufsz, "%s/%s/%s.%s%s",
- db->root, db->cache_dir, csumstr, file, temp ? ".new" : "");
-}
-
static struct apk_bstream *apk_db_cache_open(struct apk_database *db,
struct apk_checksum *csum,
const char *file)