From 0c17ba515c8d76f256dec1f8862024c7d19a0b54 Mon Sep 17 00:00:00 2001 From: Timo Teräs Date: Mon, 3 Jan 2011 21:06:41 +0200 Subject: pkg, db: allow index with unsupported features to be loaded Just disable installation of packages using the new stuff. Also flag lower case package info fields as non-critical and allow installation even if that features is not supported. (backported master commit d8ba07e484b0c838ce475202f03e041953b183e1) --- src/apk_database.h | 4 +++- src/apk_package.h | 2 ++ src/database.c | 51 ++++++++++++++++++++++++++++++++------------------- src/package.c | 16 +++++++++++++--- src/state.c | 11 ++++++++++- 5 files changed, 60 insertions(+), 24 deletions(-) diff --git a/src/apk_database.h b/src/apk_database.h index 7b36978..4dc7480 100644 --- a/src/apk_database.h +++ b/src/apk_database.h @@ -104,8 +104,10 @@ struct apk_database { int root_fd, lock_fd, cache_fd, cachetmp_fd, keys_fd; unsigned name_id, num_repos; const char *cache_dir; - int permanent; unsigned int local_repos; + int permanent : 1; + int compat_newfeatures : 1; + int compat_notinstallable : 1; struct apk_dependency_array *world; struct apk_string_array *protected_paths; diff --git a/src/apk_package.h b/src/apk_package.h index 55f6845..0488f55 100644 --- a/src/apk_package.h +++ b/src/apk_package.h @@ -81,6 +81,8 @@ struct apk_installed_package { struct apk_string_array *pending_triggers; }; +#define APK_PKG_UNINSTALLABLE ((char*) -1) + struct apk_package { apk_hash_node hash_node; unsigned repos; diff --git a/src/database.c b/src/database.c index a7cab34..600ee18 100644 --- a/src/database.c +++ b/src/database.c @@ -560,7 +560,7 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo) struct hlist_node **diri_node = NULL; struct hlist_node **file_diri_node = NULL; apk_blob_t token = APK_BLOB_STR("\n"), l; - int field; + int field, r; while (!APK_BLOB_IS_NULL(l = bs->read(bs, token))) { if (l.len < 2 || l.ptr[1] != ':') { @@ -587,27 +587,25 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo) /* If no package, create new */ if (pkg == NULL) { pkg = apk_pkg_new(); - ipkg = NULL; + ipkg = NULL; diri = NULL; file_diri_node = NULL; } /* Standard index line? */ - if (apk_pkg_add_info(db, pkg, field, l) == 0) { - if (repo == -1 && field == 'S') { - /* Instert to installed database; this needs to - * happen after package name has been read, but - * before first FDB entry. */ - ipkg = apk_pkg_install(db, pkg); - diri_node = hlist_tail_ptr(&ipkg->owned_dirs); - } + r = apk_pkg_add_info(db, pkg, field, l); + if (r == 0) { + if (repo == -1 && field == 'S') { + /* Instert to installed database; this needs to + * happen after package name has been read, but + * before first FDB entry. */ + ipkg = apk_pkg_install(db, pkg); + diri_node = hlist_tail_ptr(&ipkg->owned_dirs); + } continue; - } - - if (repo != -1 || ipkg == NULL) { - apk_error("Invalid index entry '%c'", field); - return -1; } + if (repo != -1 || ipkg == NULL) + continue; /* Check FDB special entries */ switch (field) { @@ -645,8 +643,14 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo) apk_blob_pull_csum(&l, &file->csum); break; default: - apk_error("FDB entry '%c' unsupported", field); - return -1; + if (r != 0 && !(apk_flags & APK_FORCE)) { + /* Installed db should not have unsupported fields */ + apk_error("This apk-tools is too old to handle installed packages"); + return -1; + } + /* Installed. So mark the package as installable. */ + pkg->filename = NULL; + continue; } if (APK_BLOB_IS_NULL(l)) { apk_error("FDB format error in entry '%c'", field); @@ -877,7 +881,7 @@ static int apk_db_read_state(struct apk_database *db, int flags) struct apk_istream *is; struct apk_bstream *bs; apk_blob_t blob; - int i; + int i, r; /* Read: * 1. installed repository @@ -901,8 +905,10 @@ static int apk_db_read_state(struct apk_database *db, int flags) if (!(flags & APK_OPENF_NO_INSTALLED)) { bs = apk_bstream_from_file(db->root_fd, "var/lib/apk/installed"); if (bs != NULL) { - apk_db_index_read(db, bs, -1); + r = apk_db_index_read(db, bs, -1); bs->close(bs, NULL); + if (r != 0) + return -1; } bs = apk_bstream_from_file(db->root_fd, "var/lib/apk/triggers"); @@ -1179,6 +1185,13 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts) goto ret_r; } + if (db->compat_newfeatures) { + apk_warning("This apk-tools is OLD! Some packages %s.", + db->compat_notinstallable ? + "are not installable" : + "might not function properly"); + } + return rr; ret_errno: diff --git a/src/package.c b/src/package.c index df53d93..25c6770 100644 --- a/src/package.c +++ b/src/package.c @@ -649,8 +649,17 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg, case 'I': pkg->installed_size = apk_blob_pull_uint(&value, 10); break; + case 'F': case 'M': case 'R': case 'Z': + /* installed db entries which are handled in database.c */ + return 1; default: - return -1; + /* lower case index entries are safe to be ignored */ + if (!islower(field)) { + pkg->filename = APK_PKG_UNINSTALLABLE; + db->compat_notinstallable = 1; + } + db->compat_newfeatures = 1; + return 1; } if (APK_BLOB_IS_NULL(value)) return -1; @@ -797,8 +806,9 @@ int apk_pkg_read(struct apk_database *db, const char *file, tar->close(tar); if (r < 0 && r != -ECANCELED) goto err; - if (ctx.pkg->name == NULL) { - r = -ENOMSG; + if (ctx.pkg->name == NULL || + ctx.pkg->filename == APK_PKG_UNINSTALLABLE) { + r = -ENOTSUP; goto err; } if (sctx->action != APK_SIGN_VERIFY) diff --git a/src/state.c b/src/state.c index 59315eb..b37adc7 100644 --- a/src/state.c +++ b/src/state.c @@ -119,6 +119,15 @@ static struct apk_name_choices *name_choices_new(struct apk_database *db, memcpy(nc->pkgs, name->pkgs->item, name->pkgs->num * sizeof(struct apk_package *)); + for (j = 0; j < nc->num; ) { + if (nc->pkgs[j]->filename != APK_PKG_UNINSTALLABLE) { + j++; + } else { + nc->pkgs[j] = nc->pkgs[nc->num - 1]; + nc->num--; + } + } + if (name->flags & APK_NAME_TOPLEVEL_OVERRIDE) return nc; @@ -132,7 +141,7 @@ static struct apk_name_choices *name_choices_new(struct apk_database *db, for (j = 0; j < nc->num; ) { if (apk_version_compare(nc->pkgs[j]->version, dep->version) & dep->result_mask) { - j++; + j++; } else { nc->pkgs[j] = nc->pkgs[nc->num - 1]; nc->num--; -- cgit v1.2.3-70-g09d2