diff options
-rw-r--r-- | src/apk_database.h | 4 | ||||
-rw-r--r-- | src/apk_package.h | 2 | ||||
-rw-r--r-- | src/database.c | 51 | ||||
-rw-r--r-- | src/package.c | 16 | ||||
-rw-r--r-- | src/state.c | 11 |
5 files changed, 60 insertions, 24 deletions
diff --git a/src/apk_database.h b/src/apk_database.h index 349ea7d..070b3a6 100644 --- a/src/apk_database.h +++ b/src/apk_database.h @@ -105,8 +105,10 @@ struct apk_database { unsigned name_id, num_repos; const char *cache_dir; apk_blob_t *arch; - 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 3e50979..8998c7c 100644 --- a/src/apk_package.h +++ b/src/apk_package.h @@ -76,6 +76,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; struct apk_name *name; diff --git a/src/database.c b/src/database.c index f87123b..d7692cd 100644 --- a/src/database.c +++ b/src/database.c @@ -562,7 +562,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] != ':') { @@ -589,27 +589,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) { @@ -647,8 +645,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); @@ -879,7 +883,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 @@ -903,8 +907,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"); @@ -1182,6 +1188,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 37e4357..ae34f79 100644 --- a/src/package.c +++ b/src/package.c @@ -654,8 +654,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; @@ -755,8 +764,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 408df72..4a4641d 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; @@ -131,7 +140,7 @@ static struct apk_name_choices *name_choices_new(struct apk_database *db, for (j = 0; j < nc->num; ) { if (apk_dep_is_satisfied(dep, nc->pkgs[j])) { - j++; + j++; } else { nc->pkgs[j] = nc->pkgs[nc->num - 1]; nc->num--; |