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;