summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2011-10-19 11:38:23 -0400
committerTimo Teräs <timo.teras@iki.fi>2011-10-19 11:38:23 -0400
commit89d003f8c2e5a92655ee778f7bfa5c0e85ddbed4 (patch)
tree371afd4062af10e81e8d909abc5613ee964d100a /src
parenta787038dbe643a7169a4b3610e104ac94b175ed0 (diff)
downloadapk-tools-89d003f8c2e5a92655ee778f7bfa5c0e85ddbed4.tar.gz
apk-tools-89d003f8c2e5a92655ee778f7bfa5c0e85ddbed4.tar.bz2
apk-tools-89d003f8c2e5a92655ee778f7bfa5c0e85ddbed4.tar.xz
apk-tools-89d003f8c2e5a92655ee778f7bfa5c0e85ddbed4.zip
pkg: introduce "replaces_priority"
If two packages replace each other, the one with highes priority will keep the file. Additionally, if we have a package overriding another's file it's remembered and handled properly. This is essentially to allow "policy packages" which just overwrite certain (configuration) files from other package(s).
Diffstat (limited to 'src')
-rw-r--r--src/apk_package.h1
-rw-r--r--src/database.c40
-rw-r--r--src/package.c2
3 files changed, 32 insertions, 11 deletions
diff --git a/src/apk_package.h b/src/apk_package.h
index f58954f..83bbd70 100644
--- a/src/apk_package.h
+++ b/src/apk_package.h
@@ -68,6 +68,7 @@ APK_ARRAY(apk_dependency_array, struct apk_dependency);
struct apk_installed_package {
struct apk_package *pkg;
unsigned int flags;
+ unsigned short replaces_priority;
struct list_head installed_pkgs_list;
struct list_head trigger_pkgs_list;
struct hlist_head owned_dirs;
diff --git a/src/database.c b/src/database.c
index 5662f7a..fee8788 100644
--- a/src/database.c
+++ b/src/database.c
@@ -671,6 +671,10 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
if (ipkg != NULL)
apk_blob_pull_deps(&l, db, &ipkg->replaces);
break;
+ case 'q':
+ if (ipkg != NULL)
+ ipkg->replaces_priority = apk_blob_pull_uint(&l, 10);
+ break;
default:
if (r != 0 && !(apk_flags & APK_FORCE)) {
/* Installed db should not have unsupported fields */
@@ -712,6 +716,11 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
apk_blob_push_deps(&bbuf, ipkg->replaces);
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n"));
}
+ if (ipkg->replaces_priority) {
+ apk_blob_push_blob(&bbuf, APK_BLOB_STR("q:"));
+ apk_blob_push_uint(&bbuf, ipkg->replaces_priority, 10);
+ apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n"));
+ }
hlist_for_each_entry(diri, c1, &ipkg->owned_dirs, pkg_dirs_list) {
apk_blob_push_blob(&bbuf, APK_BLOB_STR("F:"));
@@ -1780,7 +1789,9 @@ static int read_info_line(void *_ctx, apk_blob_t line)
return 0;
if (apk_blob_compare(APK_BLOB_STR("replaces"), l) == 0) {
- apk_blob_pull_deps(&r, db, &ctx->ipkg->replaces);
+ apk_blob_pull_deps(&r, db, &ipkg->replaces);
+ } else if (apk_blob_compare(APK_BLOB_STR("replaces_priority"), l) == 0) {
+ ipkg->replaces_priority = apk_blob_pull_uint(&r, 10);
} else if (apk_blob_compare(APK_BLOB_STR("triggers"), l) == 0) {
apk_string_array_resize(&ipkg->triggers, 0);
apk_blob_for_each_segment(r, " ", parse_triggers, ctx->ipkg);
@@ -1870,26 +1881,35 @@ static int apk_db_install_archive_entry(void *_ctx,
opkg = file->diri->pkg;
do {
+ int opkg_prio = -1, pkg_prio = -1;
+
/* Overlay file? */
if (opkg->name == NULL)
break;
/* Upgrading package? */
if (opkg->name == pkg->name)
break;
- /* If we have been replaced, skip file silently. */
+ /* Does the original package replace the new one? */
for (i = 0; i < opkg->ipkg->replaces->num; i++) {
if (apk_dep_is_satisfied(&opkg->ipkg->replaces->item[i], pkg)) {
- apk_warning("%s: Dropping silently %s owned by %s.",
- pkg->name->name, ae->name,
- opkg->name->name);
- return 0;
+ opkg_prio = opkg->ipkg->replaces_priority;
+ break;
}
}
- /* Overwriting with permission? */
- for (i = 0; i < ctx->ipkg->replaces->num; i++)
- if (apk_dep_is_satisfied(&ctx->ipkg->replaces->item[i], opkg))
+ /* Does the new package replace the original one? */
+ for (i = 0; i < ctx->ipkg->replaces->num; i++) {
+ if (apk_dep_is_satisfied(&ctx->ipkg->replaces->item[i], opkg)) {
+ pkg_prio = ctx->ipkg->replaces_priority;
break;
- if (i < ctx->ipkg->replaces->num)
+ }
+ }
+ /* If the original package is more important,
+ * skip this file */
+ if (opkg_prio > pkg_prio)
+ return 0;
+ /* If the new package has valid 'replaces', we
+ * will overwrite the file without warnings. */
+ if (pkg_prio >= 0)
break;
if (!(apk_flags & APK_FORCE)) {
diff --git a/src/package.c b/src/package.c
index 76b6550..cc4c141 100644
--- a/src/package.c
+++ b/src/package.c
@@ -708,7 +708,7 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
case 'c':
pkg->commit = apk_blob_cstr(value);
break;
- case 'F': case 'M': case 'R': case 'Z': case 'r':
+ case 'F': case 'M': case 'R': case 'Z': case 'r': case 'q':
/* installed db entries which are handled in database.c */
return 1;
default: