From d0909569c639a033a6f1c47a95745886ebe3e093 Mon Sep 17 00:00:00 2001 From: Timo Teras Date: Mon, 21 Dec 2009 14:14:02 +0200 Subject: apk: --overlay-from-stdin get list of overlay files from stdin, so those do not get overwritten. --- src/apk.c | 4 ++++ src/apk_defines.h | 1 + src/database.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- src/package.c | 9 +++++++-- 4 files changed, 61 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/apk.c b/src/apk.c index eff31ac..ee6690f 100644 --- a/src/apk.c +++ b/src/apk.c @@ -58,6 +58,7 @@ static struct apk_option generic_options[] = { required_argument, "REPOFILE" }, { 0x109, "no-network", "Do not use network (cache is still used)" }, { 0x110, "never-overwrite", "Never overwrite existing files" }, + { 0x111, "overlay-from-stdin", "Read list of overlay files from stdin" }, }; const char *apk_error_str(int error) @@ -388,6 +389,9 @@ int main(int argc, char **argv) case 0x110: apk_flags |= APK_NEVER_OVERWRITE; break; + case 0x111: + apk_flags |= APK_OVERLAY_FROM_STDIN; + break; default: if (applet == NULL || applet->parse == NULL || applet->parse(ctx, &dbopts, r, diff --git a/src/apk_defines.h b/src/apk_defines.h index c0f4b0f..2e93151 100644 --- a/src/apk_defines.h +++ b/src/apk_defines.h @@ -65,6 +65,7 @@ extern unsigned int apk_flags; #define APK_RECURSIVE_DELETE 0x0800 #define APK_NO_NETWORK 0x1000 #define APK_NEVER_OVERWRITE 0x2000 +#define APK_OVERLAY_FROM_STDIN 0x4000 #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/database.c b/src/database.c index 2e3ed61..3bfefeb 100644 --- a/src/database.c +++ b/src/database.c @@ -481,6 +481,40 @@ int apk_cache_download(struct apk_database *db, const char *url, return 0; } +int apk_db_read_overlay(struct apk_database *db, struct apk_bstream *bs) +{ + struct apk_db_dir_instance *diri = NULL; + struct hlist_node **diri_node = NULL, **file_diri_node = NULL; + struct apk_package *pkg; + struct apk_installed_package *ipkg; + struct apk_db_file *file; + apk_blob_t token = APK_BLOB_STR("\n"), line, bdir, bfile; + + pkg = apk_pkg_new(); + if (pkg == NULL) + return -1; + + ipkg = apk_pkg_install(db, pkg); + if (ipkg == NULL) + return -1; + + diri_node = hlist_tail_ptr(&ipkg->owned_dirs); + + while (!APK_BLOB_IS_NULL(line = bs->read(bs, token))) { + if (!apk_blob_rsplit(line, '/', &bdir, &bfile)) + break; + + if (bfile.len == 0) { + diri = apk_db_diri_new(db, pkg, bdir, &diri_node); + file_diri_node = &diri->owned_files.first; + } else { + file = apk_db_file_get(db, diri, bfile, &file_diri_node); + } + } + + return 0; +} + int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo) { struct apk_package *pkg = NULL; @@ -1050,6 +1084,12 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts) dbopts->keys_dir ?: "etc/apk/keys", O_RDONLY); + if (apk_flags & APK_OVERLAY_FROM_STDIN) { + apk_flags &= ~APK_OVERLAY_FROM_STDIN; + apk_db_read_overlay(db, apk_bstream_from_istream( + apk_istream_from_fd(STDIN_FILENO))); + } + r = apk_db_read_state(db, dbopts->open_flags); if (r == -ENOENT && (dbopts->open_flags & APK_OPENF_CREATE)) { r = apk_db_create(db); @@ -1701,8 +1741,13 @@ static int apk_db_install_archive_entry(void *_ctx, opkg = file->diri->pkg; do { + /* Overlay file? */ + if (opkg->name == NULL) + break; + /* Upgrading package? */ if (opkg->name == pkg->name) break; + /* Overwriting with permission? */ for (i = 0; ctx->replaces && i < ctx->replaces->num; i++) if (opkg->name == ctx->replaces->item[i]) break; @@ -1893,9 +1938,10 @@ static void apk_db_migrate_files(struct apk_database *db, unlinkat(db->root_fd, tmpname, 0); } else { /* check if want keep existing files */ - if ((apk_flags & APK_NEVER_OVERWRITE) && - (faccessat(db->root_fd, name, F_OK, - AT_SYMLINK_NOFOLLOW) == 0)) { + if ((ofile->name == NULL) || + ((apk_flags & APK_NEVER_OVERWRITE) && + (faccessat(db->root_fd, name, F_OK, + AT_SYMLINK_NOFOLLOW) == 0))) { unlinkat(db->root_fd, tmpname, 0); } else { /* Overwrite the old file */ diff --git a/src/package.c b/src/package.c index ee3f40e..b265468 100644 --- a/src/package.c +++ b/src/package.c @@ -66,8 +66,13 @@ struct apk_installed_package *apk_pkg_install(struct apk_database *db, pkg->ipkg = ipkg = calloc(1, sizeof(struct apk_installed_package)); ipkg->pkg = pkg; - db->installed.stats.packages++; - list_add_tail(&ipkg->installed_pkgs_list, &db->installed.packages); + + /* Overlay override information resides in a nameless package */ + if (pkg->name != NULL) { + db->installed.stats.packages++; + list_add_tail(&ipkg->installed_pkgs_list, + &db->installed.packages); + } return ipkg; } -- cgit v1.2.3