From a627ab8eb8387ebf5735cf525ae72bfa159aa39a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Fri, 9 Oct 2020 12:44:32 +0300 Subject: [PATCH] make apk_database optional for applets that don't need it The new v3 applets don't use it, and eventually all applets will use the new formats only. This prepares the code for this, and moves trust, id_cache, and root_fd to apk_ctx which is enough for v3 applets at this time. The generic code is made to not initialize apk_database if it's not needed. --- src/apk.c | 16 ++++++++++----- src/apk_applet.h | 2 +- src/apk_context.h | 36 ++++++++++++++++++++++++++++++++ src/apk_database.h | 25 ++--------------------- src/app_adbdump.c | 7 +++---- src/app_adbsign.c | 12 +++++------ src/app_add.c | 5 +++-- src/app_audit.c | 5 +++-- src/app_cache.c | 5 +++-- src/app_convdb.c | 21 ++++++++++--------- src/app_convndx.c | 17 ++++++++-------- src/app_del.c | 3 ++- src/app_dot.c | 3 ++- src/app_fetch.c | 5 +++-- src/app_fix.c | 3 ++- src/app_index.c | 5 +++-- src/app_info.c | 6 ++++-- src/app_list.c | 6 ++++-- src/app_manifest.c | 7 ++++--- src/app_mkndx.c | 15 +++++++------- src/app_policy.c | 4 ++-- src/app_search.c | 3 ++- src/app_stats.c | 7 +++++-- src/app_update.c | 5 +++-- src/app_upgrade.c | 5 +++-- src/app_verify.c | 10 ++++----- src/app_version.c | 5 +++-- src/app_vertest.c | 5 ++--- src/context.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++ src/database.c | 42 +++++++------------------------------- src/io.c | 8 ++++---- src/package.c | 4 ++-- 32 files changed, 209 insertions(+), 144 deletions(-) diff --git a/src/apk.c b/src/apk.c index 7cbf22b..f84d4aa 100644 --- a/src/apk.c +++ b/src/apk.c @@ -480,10 +480,16 @@ int main(int argc, char **argv) ctx.flags |= APK_SIMULATE; ctx.flags &= ~APK_INTERACTIVE; #endif - r = apk_db_open(&db, &ctx); - if (r != 0) { - apk_err(out, "Failed to open apk database: %s", apk_error_str(r)); - goto err; + + r = apk_ctx_prepare(&ctx); + if (r != 0) goto err; + + if (ctx.open_flags) { + r = apk_db_open(&db, &ctx); + if (r != 0) { + apk_err(out, "Failed to open apk database: %s", apk_error_str(r)); + goto err; + } } #ifdef TEST_MODE @@ -527,7 +533,7 @@ int main(int argc, char **argv) apk_string_array_resize(&args, argc); memcpy(args->item, argv, argc * sizeof(*argv)); - r = applet->main(applet_ctx, &db, args); + r = applet->main(applet_ctx, &ctx, args); apk_db_close(&db); #ifdef TEST_MODE diff --git a/src/apk_applet.h b/src/apk_applet.h index 2f4518b..c3d5978 100644 --- a/src/apk_applet.h +++ b/src/apk_applet.h @@ -50,7 +50,7 @@ struct apk_applet { unsigned int open_flags, forced_force; int context_size; - int (*main)(void *ctx, struct apk_database *db, struct apk_string_array *args); + int (*main)(void *ctx, struct apk_ctx *ac, struct apk_string_array *args); }; extern const struct apk_option_group optgroup_global, optgroup_commit, optgroup_signing; diff --git a/src/apk_context.h b/src/apk_context.h index 27f7c4d..41cc361 100644 --- a/src/apk_context.h +++ b/src/apk_context.h @@ -10,6 +10,8 @@ #define APK_CONTEXT_H #include "apk_print.h" +#include "apk_io.h" +#include "adb.h" #define APK_SIMULATE BIT(0) #define APK_CLEAN_PROTECTED BIT(1) @@ -30,6 +32,25 @@ #define APK_FORCE_NON_REPOSITORY BIT(4) #define APK_FORCE_BINARY_STDOUT BIT(5) +struct apk_database; + +#define APK_OPENF_READ 0x0001 +#define APK_OPENF_WRITE 0x0002 +#define APK_OPENF_CREATE 0x0004 +#define APK_OPENF_NO_INSTALLED 0x0010 +#define APK_OPENF_NO_SCRIPTS 0x0020 +#define APK_OPENF_NO_WORLD 0x0040 +#define APK_OPENF_NO_SYS_REPOS 0x0100 +#define APK_OPENF_NO_INSTALLED_REPO 0x0200 +#define APK_OPENF_CACHE_WRITE 0x0400 +#define APK_OPENF_NO_AUTOUPDATE 0x0800 + +#define APK_OPENF_NO_REPOS (APK_OPENF_NO_SYS_REPOS | \ + APK_OPENF_NO_INSTALLED_REPO) +#define APK_OPENF_NO_STATE (APK_OPENF_NO_INSTALLED | \ + APK_OPENF_NO_SCRIPTS | \ + APK_OPENF_NO_WORLD) + struct apk_ctx { unsigned int flags, force, lock_wait; struct apk_out out; @@ -43,9 +64,24 @@ struct apk_ctx { const char *repositories_file; struct apk_string_array *repository_list; struct apk_string_array *private_keys; + + struct adb_trust trust; + struct apk_id_cache id_cache; + struct apk_database *db; + int root_fd, keys_fd; }; void apk_ctx_init(struct apk_ctx *ac); void apk_ctx_free(struct apk_ctx *ac); +int apk_ctx_prepare(struct apk_ctx *ac); + +int apk_ctx_fd_keys(struct apk_ctx *ac); +struct adb_trust *apk_ctx_get_trust(struct apk_ctx *ac); +struct apk_id_cache *apk_ctx_get_id_cache(struct apk_ctx *ac); + +static inline int apk_ctx_fd_root(struct apk_ctx *ac) { return ac->root_fd; } +static inline time_t apk_ctx_since(struct apk_ctx *ac, time_t since) { + return (ac->force & APK_FORCE_REFRESH) ? APK_ISTREAM_FORCE_REFRESH : since; +} #endif diff --git a/src/apk_database.h b/src/apk_database.h index e43f7ae..7373b99 100644 --- a/src/apk_database.h +++ b/src/apk_database.h @@ -21,8 +21,6 @@ #include "apk_provider_data.h" #include "apk_solver_data.h" -#include "adb.h" - struct apk_name; APK_ARRAY(apk_name_array, struct apk_name *); @@ -148,13 +146,11 @@ struct apk_database { int compat_newfeatures : 1; int compat_notinstallable : 1; - struct adb_trust trust; - struct apk_dependency_array *world; + struct apk_id_cache *id_cache; struct apk_protected_path_array *protected_paths; struct apk_repository repos[APK_MAX_REPOS]; struct apk_repository_tag repo_tags[APK_MAX_TAGS]; - struct apk_id_cache id_cache; struct apk_atom_pool atoms; struct { @@ -192,23 +188,6 @@ struct apk_db_dir *apk_db_dir_query(struct apk_database *db, apk_blob_t name); struct apk_db_file *apk_db_file_query(struct apk_database *db, apk_blob_t dir, apk_blob_t name); -#define APK_OPENF_READ 0x0001 -#define APK_OPENF_WRITE 0x0002 -#define APK_OPENF_CREATE 0x0004 -#define APK_OPENF_NO_INSTALLED 0x0010 -#define APK_OPENF_NO_SCRIPTS 0x0020 -#define APK_OPENF_NO_WORLD 0x0040 -#define APK_OPENF_NO_SYS_REPOS 0x0100 -#define APK_OPENF_NO_INSTALLED_REPO 0x0200 -#define APK_OPENF_CACHE_WRITE 0x0400 -#define APK_OPENF_NO_AUTOUPDATE 0x0800 - -#define APK_OPENF_NO_REPOS (APK_OPENF_NO_SYS_REPOS | \ - APK_OPENF_NO_INSTALLED_REPO) -#define APK_OPENF_NO_STATE (APK_OPENF_NO_INSTALLED | \ - APK_OPENF_NO_SCRIPTS | \ - APK_OPENF_NO_WORLD) - void apk_db_init(struct apk_database *db); int apk_db_open(struct apk_database *db, struct apk_ctx *ctx); void apk_db_close(struct apk_database *db); @@ -219,7 +198,7 @@ int apk_db_fire_triggers(struct apk_database *db); int apk_db_run_script(struct apk_database *db, char *fn, char **argv); void apk_db_update_directory_permissions(struct apk_database *db); static inline time_t apk_db_url_since(struct apk_database *db, time_t since) { - return (db->ctx->force & APK_FORCE_REFRESH) ? APK_ISTREAM_FORCE_REFRESH : since; + return apk_ctx_since(db->ctx, since); } struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *pkg); diff --git a/src/app_adbdump.c b/src/app_adbdump.c index 75cf048..c101752 100644 --- a/src/app_adbdump.c +++ b/src/app_adbdump.c @@ -221,14 +221,14 @@ static int mmap_and_dump_adb(struct adb_trust *trust, int fd) return 0; } -static int adbdump_main(void *pctx, struct apk_database *db, struct apk_string_array *args) +static int adbdump_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *args) { - struct apk_out *out = &db->ctx->out; + struct apk_out *out = &ac->out; char **arg; int r; foreach_array_item(arg, args) { - r = mmap_and_dump_adb(&db->trust, open(*arg, O_RDONLY)); + r = mmap_and_dump_adb(apk_ctx_get_trust(ac), open(*arg, O_RDONLY)); if (r) { apk_err(out, "%s: %s", *arg, apk_error_str(r)); return r; @@ -240,7 +240,6 @@ static int adbdump_main(void *pctx, struct apk_database *db, struct apk_string_a static struct apk_applet apk_adbdump = { .name = "adbdump", - .open_flags = APK_OPENF_READ | APK_OPENF_NO_STATE | APK_OPENF_NO_REPOS, .main = adbdump_main, }; APK_DEFINE_APPLET(apk_adbdump); diff --git a/src/app_adbsign.c b/src/app_adbsign.c index ddcf0c1..120f702 100644 --- a/src/app_adbsign.c +++ b/src/app_adbsign.c @@ -8,8 +8,8 @@ #include "apk_print.h" struct sign_ctx { + struct apk_ctx *ac; struct adb_xfrm xfrm; - struct apk_database *db; int reset_signatures : 1; int signatures_written : 1; }; @@ -41,6 +41,7 @@ static const struct apk_option_group optgroup_applet = { static int update_signatures(struct adb_xfrm *xfrm, struct adb_block *blk, struct apk_istream *is) { struct sign_ctx *ctx = container_of(xfrm, struct sign_ctx, xfrm); + struct adb_trust *trust = apk_ctx_get_trust(ctx->ac); int r; switch (blk ? ADB_BLOCK_TYPE(blk) : -1) { @@ -53,7 +54,7 @@ static int update_signatures(struct adb_xfrm *xfrm, struct adb_block *blk, struc default: if (!ctx->signatures_written) { ctx->signatures_written = 1; - r = adb_trust_write_signatures(&ctx->db->trust, &xfrm->db, &xfrm->vfy, xfrm->os); + r = adb_trust_write_signatures(trust, &xfrm->db, &xfrm->vfy, xfrm->os); if (r) return r; } if (!blk) break; @@ -62,14 +63,14 @@ static int update_signatures(struct adb_xfrm *xfrm, struct adb_block *blk, struc return 0; } -static int adbsign_main(void *pctx, struct apk_database *db, struct apk_string_array *args) +static int adbsign_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *args) { - struct apk_out *out = &db->ctx->out; + struct apk_out *out = &ac->out; struct sign_ctx *ctx = pctx; char **arg; int r; - ctx->db = db; + ctx->ac = ac; foreach_array_item(arg, args) { ctx->xfrm.is = apk_istream_from_file(AT_FDCWD, *arg); ctx->xfrm.os = apk_ostream_to_file(AT_FDCWD, *arg, 0644); @@ -84,7 +85,6 @@ static int adbsign_main(void *pctx, struct apk_database *db, struct apk_string_a static struct apk_applet apk_adbsign = { .name = "adbsign", - .open_flags = APK_OPENF_READ | APK_OPENF_NO_STATE | APK_OPENF_NO_REPOS, .context_size = sizeof(struct sign_ctx), .optgroups = { &optgroup_global, &optgroup_signing, &optgroup_applet }, .main = adbsign_main, diff --git a/src/app_add.c b/src/app_add.c index 1eedcc6..42e4cd9 100644 --- a/src/app_add.c +++ b/src/app_add.c @@ -110,9 +110,10 @@ static struct apk_package *create_virtual_package(struct apk_database *db, struc return virtpkg; } -static int add_main(void *ctx, struct apk_database *db, struct apk_string_array *args) +static int add_main(void *ctx, struct apk_ctx *ac, struct apk_string_array *args) { - struct apk_out *out = &db->ctx->out; + struct apk_out *out = &ac->out; + struct apk_database *db = ac->db; struct add_ctx *actx = (struct add_ctx *) ctx; struct apk_package *virtpkg = NULL; struct apk_dependency virtdep; diff --git a/src/app_audit.c b/src/app_audit.c index acfca13..2d4925d 100644 --- a/src/app_audit.c +++ b/src/app_audit.c @@ -307,9 +307,10 @@ static int audit_missing_files(apk_hash_item item, void *pctx) return 0; } -static int audit_main(void *ctx, struct apk_database *db, struct apk_string_array *args) +static int audit_main(void *ctx, struct apk_ctx *ac, struct apk_string_array *args) { - struct apk_out *out = &db->ctx->out; + struct apk_out *out = &ac->out; + struct apk_database *db = ac->db; struct audit_tree_ctx atctx; struct audit_ctx *actx = (struct audit_ctx *) ctx; char **parg, *arg; diff --git a/src/app_cache.c b/src/app_cache.c index 974690c..db562cb 100644 --- a/src/app_cache.c +++ b/src/app_cache.c @@ -146,9 +146,10 @@ static int cache_clean(struct apk_database *db) return apk_db_cache_foreach_item(db, cache_clean_item); } -static int cache_main(void *ctx, struct apk_database *db, struct apk_string_array *args) +static int cache_main(void *ctx, struct apk_ctx *ac, struct apk_string_array *args) { - struct apk_out *out = &db->ctx->out; + struct apk_out *out = &ac->out; + struct apk_database *db = ac->db; struct cache_ctx *cctx = (struct cache_ctx *) ctx; char *arg; int r = 0, actions = 0; diff --git a/src/app_convdb.c b/src/app_convdb.c index fb89402..4871f67 100644 --- a/src/app_convdb.c +++ b/src/app_convdb.c @@ -18,7 +18,7 @@ struct conv_script { }; struct conv_ctx { - struct apk_database *db; + struct apk_atom_pool atoms; struct adb_obj pkgs; struct list_head script_head; @@ -91,7 +91,7 @@ static int read_triggers(struct conv_ctx *ctx, struct apk_istream *is) s = find_pkg(ctx, l, ADBI_SCRPT_TRIGGER); if (!s) continue; - s->triggers = apk_atomize_dup(&ctx->db->atoms, r); + s->triggers = apk_atomize_dup(&ctx->atoms, r); } apk_istream_close(is); @@ -189,14 +189,15 @@ static void convert_idb(struct conv_ctx *ctx, struct apk_istream *is) } } -static int conv_main(void *pctx, struct apk_database *db, struct apk_string_array *args) +static int conv_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *args) { struct conv_ctx *ctx = pctx; struct adb_obj idb; int r; + int root_fd = apk_ctx_fd_root(ac); - ctx->db = db; list_init(&ctx->script_head); + apk_atom_init(&ctx->atoms); adb_w_init_alloca(&ctx->dbi, ADB_SCHEMA_INSTALLED_DB, 10); adb_w_init_alloca(&ctx->dbp, ADB_SCHEMA_PACKAGE, 1000); @@ -204,12 +205,12 @@ static int conv_main(void *pctx, struct apk_database *db, struct apk_string_arra adb_wo_alloca(&ctx->pkgs, &schema_package_adb_array, &ctx->dbi); apk_tar_parse( - apk_istream_from_file(db->root_fd, "lib/apk/db/scripts.tar"), - read_script, ctx, &db->id_cache); + apk_istream_from_file(root_fd, "lib/apk/db/scripts.tar"), + read_script, ctx, apk_ctx_get_id_cache(ac)); - read_triggers(ctx, apk_istream_from_file(db->root_fd, "lib/apk/db/triggers")); + read_triggers(ctx, apk_istream_from_file(root_fd, "lib/apk/db/triggers")); - convert_idb(ctx, apk_istream_from_file(db->root_fd, "lib/apk/db/installed")); + convert_idb(ctx, apk_istream_from_file(root_fd, "lib/apk/db/installed")); adb_wo_obj(&idb, ADBI_IDB_PACKAGES, &ctx->pkgs); adb_w_rootobj(&idb); @@ -217,20 +218,20 @@ static int conv_main(void *pctx, struct apk_database *db, struct apk_string_arra r = adb_c_create( //apk_ostream_to_file(db->root_fd, "lib/apk/db/installed.adb", 0644), apk_ostream_to_file(AT_FDCWD, "installed.adb", 0644), - &ctx->dbi, &db->trust); + &ctx->dbi, apk_ctx_get_trust(ac)); if (r == 0) { // unlink old files } adb_free(&ctx->dbi); adb_free(&ctx->dbp); + apk_atom_free(&ctx->atoms); return r; } static struct apk_applet apk_convdb = { .name = "convdb", - .open_flags = APK_OPENF_READ | APK_OPENF_NO_STATE | APK_OPENF_NO_REPOS, .context_size = sizeof(struct conv_ctx), .optgroups = { &optgroup_global, &optgroup_signing }, .main = conv_main, diff --git a/src/app_convndx.c b/src/app_convndx.c index 393ca43..9f687ac 100644 --- a/src/app_convndx.c +++ b/src/app_convndx.c @@ -7,7 +7,7 @@ #include "apk_applet.h" struct conv_ctx { - struct apk_database *db; + struct apk_ctx *ac; struct adb_obj pkgs; struct adb dbi; struct apk_sign_ctx sctx; @@ -52,35 +52,37 @@ static int load_apkindex(void *sctx, const struct apk_file_info *fi, static int load_index(struct conv_ctx *ctx, struct apk_istream *is) { + struct apk_id_cache *idc = apk_ctx_get_id_cache(ctx->ac); int r = 0; if (IS_ERR_OR_NULL(is)) return is ? PTR_ERR(is) : -EINVAL; ctx->found = 0; - apk_sign_ctx_init(&ctx->sctx, APK_SIGN_VERIFY, NULL, ctx->db->keys_fd, ctx->db->ctx->flags & APK_ALLOW_UNTRUSTED); + apk_sign_ctx_init(&ctx->sctx, APK_SIGN_VERIFY, NULL, apk_ctx_fd_keys(ctx->ac), ctx->ac->flags & APK_ALLOW_UNTRUSTED); r = apk_tar_parse( apk_istream_gunzip_mpart(is, apk_sign_ctx_mpart_cb, &ctx->sctx), - load_apkindex, ctx, &ctx->db->id_cache); + load_apkindex, ctx, idc); apk_sign_ctx_free(&ctx->sctx); if (r >= 0 && ctx->found == 0) r = -ENOMSG; return r; } -static int conv_main(void *pctx, struct apk_database *db, struct apk_string_array *args) +static int conv_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *args) { char **arg; struct conv_ctx *ctx = pctx; + struct adb_trust *trust = apk_ctx_get_trust(ac); struct adb_obj ndx; int r; - ctx->db = db; + ctx->ac = ac; adb_w_init_alloca(&ctx->dbi, ADB_SCHEMA_INDEX, 1000); adb_wo_alloca(&ndx, &schema_index, &ctx->dbi); adb_wo_alloca(&ctx->pkgs, &schema_pkginfo_array, &ctx->dbi); foreach_array_item(arg, args) { - r = load_index(ctx, apk_istream_from_url(*arg, apk_db_url_since(db, 0))); + r = load_index(ctx, apk_istream_from_url(*arg, apk_ctx_since(ac, 0))); if (r) goto err; fprintf(stderr, "%s: %u packages\n", *arg, adb_ra_num(&ctx->pkgs)); } @@ -88,7 +90,7 @@ static int conv_main(void *pctx, struct apk_database *db, struct apk_string_arra adb_wo_obj(&ndx, ADBI_NDX_PACKAGES, &ctx->pkgs); adb_w_rootobj(&ndx); - r = adb_c_create(apk_ostream_to_fd(STDOUT_FILENO), &ctx->dbi, &db->trust); + r = adb_c_create(apk_ostream_to_fd(STDOUT_FILENO), &ctx->dbi, trust); err: adb_free(&ctx->dbi); @@ -97,7 +99,6 @@ err: static struct apk_applet apk_convndx = { .name = "convndx", - .open_flags = APK_OPENF_READ | APK_OPENF_NO_STATE | APK_OPENF_NO_REPOS, .context_size = sizeof(struct conv_ctx), .optgroups = { &optgroup_global, &optgroup_signing }, .main = conv_main, diff --git a/src/app_del.c b/src/app_del.c index 390a99a..f8fd524 100644 --- a/src/app_del.c +++ b/src/app_del.c @@ -131,8 +131,9 @@ static void delete_name(struct apk_database *db, const char *match, apk_deps_del(&ctx->world, name); } -static int del_main(void *pctx, struct apk_database *db, struct apk_string_array *args) +static int del_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *args) { + struct apk_database *db = ac->db; struct del_ctx *ctx = (struct del_ctx *) pctx; struct not_deleted_ctx ndctx = { .out = &db->ctx->out }; struct apk_changeset changeset = {}; diff --git a/src/app_dot.c b/src/app_dot.c index 15283fd..ab20700 100644 --- a/src/app_dot.c +++ b/src/app_dot.c @@ -138,8 +138,9 @@ static int foreach_pkg(apk_hash_item item, void *ctx) return 0; } -static int dot_main(void *pctx, struct apk_database *db, struct apk_string_array *args) +static int dot_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *args) { + struct apk_database *db = ac->db; struct dot_ctx *ctx = (struct dot_ctx *) pctx; struct apk_provider *p; char **parg; diff --git a/src/app_fetch.c b/src/app_fetch.c index 9a4faab..9963503 100644 --- a/src/app_fetch.c +++ b/src/app_fetch.c @@ -306,9 +306,10 @@ static int purge_package(void *pctx, int dirfd, const char *filename) return 0; } -static int fetch_main(void *pctx, struct apk_database *db, struct apk_string_array *args) +static int fetch_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *args) { - struct apk_out *out = &db->ctx->out; + struct apk_out *out = &ac->out; + struct apk_database *db = ac->db; struct fetch_ctx *ctx = (struct fetch_ctx *) pctx; ctx->db = db; diff --git a/src/app_fix.c b/src/app_fix.c index 311cfdd..170f2c2 100644 --- a/src/app_fix.c +++ b/src/app_fix.c @@ -86,8 +86,9 @@ static void set_solver_flags(struct apk_database *db, const char *match, struct mark_fix(ctx, name); } -static int fix_main(void *pctx, struct apk_database *db, struct apk_string_array *args) +static int fix_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *args) { + struct apk_database *db = ac->db; struct fix_ctx *ctx = (struct fix_ctx *) pctx; struct apk_installed_package *ipkg; diff --git a/src/app_index.c b/src/app_index.c index 707bd94..896474b 100644 --- a/src/app_index.c +++ b/src/app_index.c @@ -105,9 +105,10 @@ static int warn_if_no_providers(apk_hash_item item, void *ctx) return 0; } -static int index_main(void *ctx, struct apk_database *db, struct apk_string_array *args) +static int index_main(void *ctx, struct apk_ctx *ac, struct apk_string_array *args) { - struct apk_out *out = &db->ctx->out; + struct apk_out *out = &ac->out; + struct apk_database *db = ac->db; struct counts counts = { .out = out }; struct apk_ostream *os; struct apk_file_info fi; diff --git a/src/app_info.c b/src/app_info.c index 8f02f30..beb32d9 100644 --- a/src/app_info.c +++ b/src/app_info.c @@ -438,12 +438,14 @@ static int option_parse_applet(void *pctx, struct apk_ctx *ac, int opt, const ch return 0; } -static int info_main(void *ctx, struct apk_database *db, struct apk_string_array *args) +static int info_main(void *ctx, struct apk_ctx *ac, struct apk_string_array *args) { + struct apk_out *out = &ac->out; + struct apk_database *db = ac->db; struct info_ctx *ictx = (struct info_ctx *) ctx; struct apk_installed_package *ipkg; - verbosity = apk_out_verbosity(&db->ctx->out); + verbosity = apk_out_verbosity(out); ictx->db = db; if (ictx->subaction_mask == 0) ictx->subaction_mask = APK_INFO_DESC | APK_INFO_URL | APK_INFO_SIZE; diff --git a/src/app_list.c b/src/app_list.c index a7e05b8..620c3ad 100644 --- a/src/app_list.c +++ b/src/app_list.c @@ -226,11 +226,13 @@ static const struct apk_option_group optgroup_applet = { .parse = option_parse_applet, }; -static int list_main(void *pctx, struct apk_database *db, struct apk_string_array *args) +static int list_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *args) { + struct apk_out *out = &ac->out; + struct apk_database *db = ac->db; struct list_ctx *ctx = pctx; - ctx->verbosity = apk_out_verbosity(&db->ctx->out); + ctx->verbosity = apk_out_verbosity(out); ctx->filters = args; if (ctx->match_origin) diff --git a/src/app_manifest.c b/src/app_manifest.c index 9b9a2db..19d02f4 100644 --- a/src/app_manifest.c +++ b/src/app_manifest.c @@ -94,6 +94,7 @@ static int read_file_entry(void *ctx, const struct apk_file_info *ae, struct apk static void process_file(struct apk_database *db, const char *match) { + struct apk_id_cache *idc = apk_ctx_get_id_cache(db->ctx); struct apk_out *out = &db->ctx->out; struct apk_sign_ctx sctx; struct manifest_file_ctx ctx = { @@ -112,7 +113,7 @@ static void process_file(struct apk_database *db, const char *match) apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd, db->ctx->flags & APK_ALLOW_UNTRUSTED); r = apk_tar_parse( apk_istream_gunzip_mpart(apk_istream_from_file(AT_FDCWD, match), apk_sign_ctx_mpart_cb, &sctx), - read_file_entry, &ctx, &db->id_cache); + read_file_entry, &ctx, idc); apk_sign_ctx_free(&sctx); if (r < 0) apk_err(out, "%s: %s", match, apk_error_str(r)); } @@ -130,9 +131,9 @@ static void process_match(struct apk_database *db, const char *match, struct apk process_package(db, p->pkg); } -static int manifest_main(void *applet_ctx, struct apk_database *db, struct apk_string_array *args) +static int manifest_main(void *applet_ctx, struct apk_ctx *ac, struct apk_string_array *args) { - apk_name_foreach_matching(db, args, apk_foreach_genid(), process_match, NULL); + apk_name_foreach_matching(ac->db, args, apk_foreach_genid(), process_match, NULL); return 0; } diff --git a/src/app_mkndx.c b/src/app_mkndx.c index beb4144..2dc6f81 100644 --- a/src/app_mkndx.c +++ b/src/app_mkndx.c @@ -186,9 +186,11 @@ static int mkndx_parse_v2_tar(void *pctx, const struct apk_file_info *ae, struct return 0; } -static int mkndx_main(void *pctx, struct apk_database *db, struct apk_string_array *args) +static int mkndx_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *args) { - struct apk_out *out = &db->ctx->out; + struct apk_out *out = &ac->out; + struct apk_id_cache *idc = apk_ctx_get_id_cache(ac); + struct adb_trust *trust = apk_ctx_get_trust(ac); struct adb odb, tmpdb; struct adb_obj oroot, opkgs, ndx, tmpl; struct apk_file_info fi; @@ -214,7 +216,7 @@ static int mkndx_main(void *pctx, struct apk_database *db, struct apk_string_arr apk_fileinfo_get(AT_FDCWD, ctx->index, APK_CHECKSUM_NONE, &fi, 0); index_mtime = fi.mtime; - r = adb_m_map(&odb, open(ctx->index, O_RDONLY), ADB_SCHEMA_INDEX, &db->trust); + r = adb_m_map(&odb, open(ctx->index, O_RDONLY), ADB_SCHEMA_INDEX, trust); if (r) { apk_err(out, "%s: %s", ctx->index, apk_error_str(r)); return r; @@ -274,10 +276,10 @@ static int mkndx_main(void *pctx, struct apk_database *db, struct apk_string_arr } if (!found) { do_file: - apk_sign_ctx_init(&ctx->sctx, APK_SIGN_VERIFY, NULL, db->keys_fd, db->ctx->flags & APK_ALLOW_UNTRUSTED); + apk_sign_ctx_init(&ctx->sctx, APK_SIGN_VERIFY, NULL, apk_ctx_fd_keys(ac), ac->flags & APK_ALLOW_UNTRUSTED); r = apk_tar_parse( apk_istream_gunzip_mpart(apk_istream_from_file(AT_FDCWD, *parg), apk_sign_ctx_mpart_cb, &ctx->sctx), - mkndx_parse_v2_tar, ctx, &db->id_cache); + mkndx_parse_v2_tar, ctx, idc); apk_sign_ctx_free(&ctx->sctx); if (r < 0 && r != -ECANCELED) goto err_pkg; newpkgs++; @@ -295,7 +297,7 @@ static int mkndx_main(void *pctx, struct apk_database *db, struct apk_string_arr r = adb_c_create( apk_ostream_to_file(AT_FDCWD, ctx->output, 0644), - &ctx->db, &db->trust); + &ctx->db, trust); adb_free(&ctx->db); adb_free(&odb); @@ -320,7 +322,6 @@ static int mkndx_main(void *pctx, struct apk_database *db, struct apk_string_arr static struct apk_applet apk_mkndx = { .name = "mkndx", - .open_flags = APK_OPENF_READ | APK_OPENF_NO_STATE | APK_OPENF_NO_REPOS, .context_size = sizeof(struct mkndx_ctx), .optgroups = { &optgroup_global, &optgroup_signing, &optgroup_applet }, .main = mkndx_main, diff --git a/src/app_policy.c b/src/app_policy.c index 91e97d0..c026337 100644 --- a/src/app_policy.c +++ b/src/app_policy.c @@ -61,9 +61,9 @@ zlib1g policy: } } -static int policy_main(void *ctx, struct apk_database *db, struct apk_string_array *args) +static int policy_main(void *ctx, struct apk_ctx *ac, struct apk_string_array *args) { - apk_name_foreach_matching(db, args, apk_foreach_genid(), print_policy, NULL); + apk_name_foreach_matching(ac->db, args, apk_foreach_genid(), print_policy, NULL); return 0; } diff --git a/src/app_search.c b/src/app_search.c index 11b7108..4ac4243 100644 --- a/src/app_search.c +++ b/src/app_search.c @@ -172,8 +172,9 @@ static int print_pkg(apk_hash_item item, void *pctx) return 0; } -static int search_main(void *pctx, struct apk_database *db, struct apk_string_array *args) +static int search_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *args) { + struct apk_database *db = ac->db; struct search_ctx *ctx = (struct search_ctx *) pctx; char *tmp, **pmatch; diff --git a/src/app_stats.c b/src/app_stats.c index 7e60494..317edc7 100644 --- a/src/app_stats.c +++ b/src/app_stats.c @@ -22,9 +22,12 @@ static int list_count(struct list_head *h) return c; } -static int stats_main(void *ctx, struct apk_database *db, struct apk_string_array *args) +static int stats_main(void *ctx, struct apk_ctx *ac, struct apk_string_array *args) { - printf( + struct apk_out *out = &ac->out; + struct apk_database *db = ac->db; + + apk_out(out, "installed:\n" " packages: %d\n" " dirs: %d\n" diff --git a/src/app_update.c b/src/app_update.c index 4fa24f8..3a01381 100644 --- a/src/app_update.c +++ b/src/app_update.c @@ -14,9 +14,10 @@ #include "apk_version.h" #include "apk_print.h" -static int update_main(void *ctx, struct apk_database *db, struct apk_string_array *args) +static int update_main(void *ctx, struct apk_ctx *ac, struct apk_string_array *args) { - struct apk_out *out = &db->ctx->out; + struct apk_out *out = &ac->out; + struct apk_database *db = ac->db; struct apk_repository *repo; int i; char buf[32] = "OK:"; diff --git a/src/app_upgrade.c b/src/app_upgrade.c index 6d63b50..3edd0b1 100644 --- a/src/app_upgrade.c +++ b/src/app_upgrade.c @@ -153,9 +153,10 @@ static void set_upgrade_for_name(struct apk_database *db, const char *match, str apk_solver_set_name_flags(name, uctx->ignore ? APK_SOLVERF_INSTALLED : APK_SOLVERF_UPGRADE, 0); } -static int upgrade_main(void *ctx, struct apk_database *db, struct apk_string_array *args) +static int upgrade_main(void *ctx, struct apk_ctx *ac, struct apk_string_array *args) { - struct apk_out *out = &db->ctx->out; + struct apk_out *out = &ac->out; + struct apk_database *db = ac->db; struct upgrade_ctx *uctx = (struct upgrade_ctx *) ctx; unsigned short solver_flags; struct apk_dependency *dep; diff --git a/src/app_verify.c b/src/app_verify.c index 0a18ea6..e36f3e9 100644 --- a/src/app_verify.c +++ b/src/app_verify.c @@ -15,19 +15,20 @@ #include "apk_database.h" #include "apk_print.h" -static int verify_main(void *ctx, struct apk_database *db, struct apk_string_array *args) +static int verify_main(void *ctx, struct apk_ctx *ac, struct apk_string_array *args) { - struct apk_out *out = &db->ctx->out; + struct apk_out *out = &ac->out; struct apk_sign_ctx sctx; + struct apk_id_cache *idc = apk_ctx_get_id_cache(ac); char **parg; int r, ok, rc = 0; foreach_array_item(parg, args) { - apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd, 1); + apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, apk_ctx_fd_keys(ac), 1); r = apk_tar_parse( apk_istream_gunzip_mpart(apk_istream_from_file(AT_FDCWD, *parg), apk_sign_ctx_mpart_cb, &sctx), - apk_sign_ctx_verify_tar, &sctx, &db->id_cache); + apk_sign_ctx_verify_tar, &sctx, idc); ok = sctx.control_verified && sctx.data_verified; if (apk_out_verbosity(out) >= 1) apk_msg(out, "%s: %d - %s", *parg, r, @@ -47,7 +48,6 @@ static int verify_main(void *ctx, struct apk_database *db, struct apk_string_arr static struct apk_applet apk_verify = { .name = "verify", - .open_flags = APK_OPENF_READ | APK_OPENF_NO_STATE, .main = verify_main, }; diff --git a/src/app_version.c b/src/app_version.c index 0e17493..a42ab63 100644 --- a/src/app_version.c +++ b/src/app_version.c @@ -172,9 +172,10 @@ static void ver_print_package_status(struct apk_database *db, const char *match, BLOB_PRINTF(db->repo_tags[tag].tag)); } -static int ver_main(void *pctx, struct apk_database *db, struct apk_string_array *args) +static int ver_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *args) { - struct apk_out *out = &db->ctx->out; + struct apk_out *out = &ac->out; + struct apk_database *db = ac->db; struct ver_ctx *ctx = (struct ver_ctx *) pctx; if (ctx->limchars) { diff --git a/src/app_vertest.c b/src/app_vertest.c index e6b3cae..b933dd1 100644 --- a/src/app_vertest.c +++ b/src/app_vertest.c @@ -14,9 +14,9 @@ #include "apk_version.h" #include "apk_print.h" -static int vertest_main(void *pctx, struct apk_database *db, struct apk_string_array *args) +static int vertest_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *args) { - struct apk_out *out = &db->ctx->out; + struct apk_out *out = &ac->out; apk_blob_t arg, ver, op, space = APK_BLOB_STRLIT(" "); char **parg; int errors = 0; @@ -45,7 +45,6 @@ static int vertest_main(void *pctx, struct apk_database *db, struct apk_string_a } static struct apk_applet apk_vertest = { - .open_flags = APK_OPENF_READ | APK_OPENF_NO_STATE | APK_OPENF_NO_REPOS, .name = "vertest", .main = vertest_main, }; diff --git a/src/context.c b/src/context.c index f7b745c..6f953b0 100644 --- a/src/context.c +++ b/src/context.c @@ -7,6 +7,9 @@ * SPDX-License-Identifier: GPL-2.0-only */ +#include +#include +#include #include "apk_context.h" void apk_ctx_init(struct apk_ctx *ac) @@ -22,6 +25,54 @@ void apk_ctx_init(struct apk_ctx *ac) void apk_ctx_free(struct apk_ctx *ac) { + apk_id_cache_free(&ac->id_cache); + adb_trust_free(&ac->trust); apk_string_array_free(&ac->repository_list); apk_string_array_free(&ac->private_keys); } + +int apk_ctx_prepare(struct apk_ctx *ac) +{ + if (ac->flags & APK_SIMULATE && + ac->open_flags & (APK_OPENF_CREATE | APK_OPENF_WRITE)) { + ac->open_flags &= ~(APK_OPENF_CREATE | APK_OPENF_WRITE); + ac->open_flags |= APK_OPENF_READ; + } + if (!ac->cache_dir) ac->cache_dir = "etc/apk/cache"; + if (!ac->keys_dir) ac->keys_dir = "etc/apk/keys"; + if (!ac->root) ac->root = "/"; + if (!ac->cache_max_age) ac->cache_max_age = 4*60*60; /* 4 hours default */ + + ac->root_fd = openat(AT_FDCWD, ac->root, O_RDONLY | O_CLOEXEC); + if (ac->root_fd < 0 && (ac->open_flags & APK_OPENF_CREATE)) { + mkdirat(AT_FDCWD, ac->root, 0755); + ac->root_fd = openat(AT_FDCWD, ac->root, O_RDONLY | O_CLOEXEC); + } + if (ac->root_fd < 0) { + apk_err(&ac->out, "Unable to open root: %s", apk_error_str(errno)); + return -errno; + } + return 0; +} + +int apk_ctx_fd_keys(struct apk_ctx *ac) +{ + if (ac->keys_fd <= 0) ac->keys_fd = openat(ac->root_fd, ac->keys_dir, O_RDONLY | O_CLOEXEC); + return ac->keys_fd; +} + +struct adb_trust *apk_ctx_get_trust(struct apk_ctx *ac) +{ + if (!ac->trust.mdctx) { + int r = adb_trust_init(&ac->trust, dup(apk_ctx_fd_keys(ac)), ac->private_keys); + if (r) return ERR_PTR(r); + } + return &ac->trust; +} + +struct apk_id_cache *apk_ctx_get_id_cache(struct apk_ctx *ac) +{ + if (!ac->id_cache.root_fd) + apk_id_cache_init(&ac->id_cache, apk_ctx_fd_root(ac)); + return &ac->id_cache; +} diff --git a/src/database.c b/src/database.c index f31e840..5fd1c82 100644 --- a/src/database.c +++ b/src/database.c @@ -642,7 +642,7 @@ int apk_cache_download(struct apk_database *db, struct apk_repository *repo, is = apk_istream_from_url(url, apk_db_url_since(db, st.st_mtime)); is = apk_istream_tee(is, db->cache_fd, tmpcacheitem, !autoupdate, cb, cb_ctx); is = apk_istream_gunzip_mpart(is, apk_sign_ctx_mpart_cb, &sctx); - r = apk_tar_parse(is, apk_sign_ctx_verify_tar, &sctx, &db->id_cache); + r = apk_tar_parse(is, apk_sign_ctx_verify_tar, &sctx, db->id_cache); apk_sign_ctx_free(&sctx); } else { is = apk_istream_from_url(url, apk_db_url_since(db, st.st_mtime)); @@ -1165,7 +1165,7 @@ static int apk_db_read_state(struct apk_database *db, int flags) if (!(flags & APK_OPENF_NO_SCRIPTS)) { r = apk_tar_parse(apk_istream_from_file(db->root_fd, apk_scripts_file), - apk_read_script_archive_entry, db, &db->id_cache); + apk_read_script_archive_entry, db, db->id_cache); if (r && r != -ENOENT) return r; } @@ -1525,30 +1525,14 @@ int apk_db_open(struct apk_database *db, struct apk_ctx *ac) r = -1; goto ret_r; } - if (ac->flags & APK_SIMULATE) { - ac->open_flags &= ~(APK_OPENF_CREATE | APK_OPENF_WRITE); - ac->open_flags |= APK_OPENF_READ; - } if ((ac->open_flags & APK_OPENF_WRITE) && !(ac->open_flags & APK_OPENF_NO_AUTOUPDATE) && !(ac->flags & APK_NO_NETWORK)) db->autoupdate = 1; - if (!ac->cache_dir) ac->cache_dir = "etc/apk/cache"; - if (!ac->keys_dir) ac->keys_dir = "etc/apk/keys"; - if (!ac->root) ac->root = "/"; - if (!ac->cache_max_age) ac->cache_max_age = 4*60*60; /* 4 hours default */ apk_db_setup_repositories(db, ac->cache_dir); + db->root_fd = apk_ctx_fd_root(ac); - db->root_fd = openat(AT_FDCWD, db->ctx->root, O_RDONLY | O_CLOEXEC); - if (db->root_fd < 0 && (ac->open_flags & APK_OPENF_CREATE)) { - mkdirat(AT_FDCWD, db->ctx->root, 0755); - db->root_fd = openat(AT_FDCWD, db->ctx->root, O_RDONLY | O_CLOEXEC); - } - if (db->root_fd < 0) { - msg = "Unable to open root"; - goto ret_errno; - } if (fstatfs(db->root_fd, &stfs) == 0 && stfs.f_type == TMPFS_MAGIC) db->permanent = 0; @@ -1568,7 +1552,7 @@ int apk_db_open(struct apk_database *db, struct apk_ctx *ac) } } - apk_id_cache_init(&db->id_cache, db->root_fd); + db->id_cache = apk_ctx_get_id_cache(ac); if (ac->open_flags & APK_OPENF_WRITE) { db->lock_fd = openat(db->root_fd, apk_lock_file, @@ -1663,12 +1647,6 @@ int apk_db_open(struct apk_database *db, struct apk_ctx *ac) db->keys_fd = openat(db->root_fd, ac->keys_dir, O_RDONLY | O_CLOEXEC); - r = adb_trust_init(&db->trust, dup(db->keys_fd), ac->private_keys); - if (r) { - msg = "Unable to read trusted keys"; - goto ret_r; - } - if (db->ctx->flags & APK_OVERLAY_FROM_STDIN) { db->ctx->flags &= ~APK_OVERLAY_FROM_STDIN; apk_db_read_overlay(db, apk_istream_from_fd(STDIN_FILENO)); @@ -1725,6 +1703,7 @@ int apk_db_open(struct apk_database *db, struct apk_ctx *ac) db->compat_notinstallable ? "are not installable" : "might not function properly"); } + ac->db = db; return 0; ret_errno: @@ -1794,10 +1773,6 @@ void apk_db_close(struct apk_database *db) struct hlist_node *dc, *dn; int i; - /* the id cache was never initialized if root_fd failed */ - if (db->root_fd >= 0) - apk_id_cache_free(&db->id_cache); - /* Cleaning up the directory tree will cause mode, uid and gid * of all modified (package providing that directory got removed) * directories to be reset. */ @@ -1835,11 +1810,8 @@ void apk_db_close(struct apk_database *db) db->cache_remount_dir = NULL; } - adb_trust_free(&db->trust); - if (db->keys_fd) close(db->keys_fd); if (db->cache_fd) close(db->cache_fd); - if (db->root_fd) close(db->root_fd); if (db->lock_fd) close(db->lock_fd); } @@ -2194,7 +2166,7 @@ static int load_index(struct apk_database *db, struct apk_istream *is, ctx.repo = repo; ctx.found = 0; apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY, NULL, db->keys_fd, db->ctx->flags & APK_ALLOW_UNTRUSTED); - r = apk_tar_parse(apk_istream_gunzip_mpart(is, apk_sign_ctx_mpart_cb, &ctx.sctx), load_apkindex, &ctx, &db->id_cache); + r = apk_tar_parse(apk_istream_gunzip_mpart(is, apk_sign_ctx_mpart_cb, &ctx.sctx), load_apkindex, &ctx, db->id_cache); apk_sign_ctx_free(&ctx.sctx); if (r >= 0 && ctx.found == 0) @@ -2822,7 +2794,7 @@ static int apk_db_unpack_pkg(struct apk_database *db, .cb_ctx = cb_ctx, }; apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY_IDENTITY, &pkg->csum, db->keys_fd, db->ctx->flags & APK_ALLOW_UNTRUSTED); - r = apk_tar_parse(apk_istream_gunzip_mpart(is, apk_sign_ctx_mpart_cb, &ctx.sctx), apk_db_install_archive_entry, &ctx, &db->id_cache); + r = apk_tar_parse(apk_istream_gunzip_mpart(is, apk_sign_ctx_mpart_cb, &ctx.sctx), apk_db_install_archive_entry, &ctx, db->id_cache); apk_sign_ctx_free(&ctx.sctx); if (need_copy) { diff --git a/src/io.c b/src/io.c index e6d94f7..97b0d57 100644 --- a/src/io.c +++ b/src/io.c @@ -1078,8 +1078,10 @@ void apk_id_cache_init(struct apk_id_cache *idc, int root_fd) void apk_id_cache_free(struct apk_id_cache *idc) { + if (!idc->root_fd) return; apk_hash_free(&idc->uid_cache); apk_hash_free(&idc->gid_cache); + idc->root_fd = 0; } void apk_id_cache_reset(struct apk_id_cache *idc) @@ -1100,8 +1102,7 @@ uid_t apk_resolve_uid(struct apk_id_cache *idc, const char *username, uid_t defa FILE *in; ci = resolve_cache_item(&idc->uid_cache, APK_BLOB_STR(username)); - if (ci == NULL) - return default_uid; + if (ci == NULL) return default_uid; if (ci->genid != idc->genid) { ci->genid = idc->genid; @@ -1143,8 +1144,7 @@ uid_t apk_resolve_gid(struct apk_id_cache *idc, const char *groupname, uid_t def FILE *in; ci = resolve_cache_item(&idc->gid_cache, APK_BLOB_STR(groupname)); - if (ci == NULL) - return default_gid; + if (ci == NULL) return default_gid; if (ci->genid != idc->genid) { ci->genid = idc->genid; diff --git a/src/package.c b/src/package.c index b63fae0..b9fcc34 100644 --- a/src/package.c +++ b/src/package.c @@ -939,7 +939,7 @@ int apk_pkg_read(struct apk_database *db, const char *file, r = apk_tar_parse( apk_istream_gunzip_mpart(apk_istream_from_file(AT_FDCWD, file), apk_sign_ctx_mpart_cb, sctx), - read_info_entry, &ctx, &db->id_cache); + read_info_entry, &ctx, db->id_cache); if (r < 0 && r != -ECANCELED) goto err; if (ctx.pkg->name == NULL || ctx.pkg->uninstallable) { @@ -1040,7 +1040,7 @@ void apk_ipkg_run_script(struct apk_installed_package *ipkg, goto err; /* Script may have done something that changes id cache contents */ - apk_id_cache_reset(&db->id_cache); + apk_id_cache_reset(db->id_cache); goto cleanup;