diff --git a/src/apk.c b/src/apk.c index 266886f..a1085e9 100644 --- a/src/apk.c +++ b/src/apk.c @@ -156,31 +156,31 @@ static int option_parse_global(void *ctx, struct apk_db_options *dbopts, int opt dbopts->force |= APK_FORCE_BINARY_STDOUT; break; case OPT_GLOBAL_interactive: - apk_flags |= APK_INTERACTIVE; + dbopts->flags |= APK_INTERACTIVE; break; case OPT_GLOBAL_progress: - apk_flags |= APK_PROGRESS; + dbopts->progress.out = stdout; break; case OPT_GLOBAL_no_progress: - apk_flags &= ~APK_PROGRESS; + dbopts->progress.out = NULL; break; case OPT_GLOBAL_progress_fd: - apk_progress_fd = atoi(optarg); + dbopts->progress.fd = atoi(optarg); break; case OPT_GLOBAL_allow_untrusted: - apk_flags |= APK_ALLOW_UNTRUSTED; + dbopts->flags |= APK_ALLOW_UNTRUSTED; break; case OPT_GLOBAL_purge: - apk_flags |= APK_PURGE; + dbopts->flags |= APK_PURGE; break; case OPT_GLOBAL_wait: dbopts->lock_wait = atoi(optarg); break; case OPT_GLOBAL_no_network: - apk_flags |= APK_NO_NETWORK; + dbopts->flags |= APK_NO_NETWORK; break; case OPT_GLOBAL_no_cache: - apk_flags |= APK_NO_CACHE; + dbopts->flags |= APK_NO_CACHE; break; case OPT_GLOBAL_cache_dir: dbopts->cache_dir = optarg; @@ -235,23 +235,23 @@ static int option_parse_commit(void *ctx, struct apk_db_options *dbopts, int opt { switch (opt) { case OPT_COMMIT_simulate: - apk_flags |= APK_SIMULATE; + dbopts->flags |= APK_SIMULATE; break; case OPT_COMMIT_clean_protected: - apk_flags |= APK_CLEAN_PROTECTED; + dbopts->flags |= APK_CLEAN_PROTECTED; break; case OPT_COMMIT_overlay_from_stdin: - apk_flags |= APK_OVERLAY_FROM_STDIN; + dbopts->flags |= APK_OVERLAY_FROM_STDIN; break; case OPT_COMMIT_no_scripts: - apk_flags |= APK_NO_SCRIPTS; + dbopts->flags |= APK_NO_SCRIPTS; break; case OPT_COMMIT_no_commit_hooks: - apk_flags |= APK_NO_COMMIT_HOOKS; + dbopts->flags |= APK_NO_COMMIT_HOOKS; break; case OPT_COMMIT_initramfs_diskless_boot: dbopts->open_flags |= APK_OPENF_CREATE; - apk_flags |= APK_NO_COMMIT_HOOKS; + dbopts->flags |= APK_NO_COMMIT_HOOKS; dbopts->force |= APK_FORCE_OVERWRITE | APK_FORCE_OLD_APK | APK_FORCE_BROKEN_WORLD | APK_FORCE_NON_REPOSITORY; break; @@ -402,16 +402,25 @@ static void setup_terminal(void) signal(SIGPIPE, SIG_IGN); } -static void setup_automatic_flags(void) +static void setup_automatic_flags(struct apk_db_options *dbopts) { + const char *tmp; + + if ((tmp = getenv("APK_PROGRESS_CHAR")) != NULL) + dbopts->progress.progress_char = tmp; + else if ((tmp = getenv("LANG")) != NULL && strstr(tmp, "UTF-8") != NULL) + dbopts->progress.progress_char = "\u2588"; + else + dbopts->progress.progress_char = "#"; + if (!isatty(STDOUT_FILENO) || !isatty(STDERR_FILENO) || !isatty(STDIN_FILENO)) return; - apk_flags |= APK_PROGRESS; - if (!(apk_flags & APK_SIMULATE) && + dbopts->progress.out = stdout; + if (!(dbopts->flags & APK_SIMULATE) && access("/etc/apk/interactive", F_OK) == 0) - apk_flags |= APK_INTERACTIVE; + dbopts->flags |= APK_INTERACTIVE; } void apk_applet_register(struct apk_applet *applet) @@ -468,12 +477,11 @@ int main(int argc, char **argv) if (applet->context_size != 0) ctx = calloc(1, applet->context_size); dbopts.open_flags = applet->open_flags; - apk_flags |= applet->forced_flags; dbopts.force |= applet->forced_force; } init_openssl(); - setup_automatic_flags(); + setup_automatic_flags(&dbopts); fetchConnectionCacheInit(32, 4); r = parse_options(argc, argv, applet, ctx, &dbopts); @@ -500,8 +508,8 @@ int main(int argc, char **argv) #ifdef TEST_MODE dbopts.open_flags &= ~(APK_OPENF_WRITE | APK_OPENF_CACHE_WRITE | APK_OPENF_CREATE); dbopts.open_flags |= APK_OPENF_READ | APK_OPENF_NO_STATE | APK_OPENF_NO_REPOS; - apk_flags |= APK_SIMULATE; - apk_flags &= ~APK_INTERACTIVE; + dbopts.flags |= APK_SIMULATE; + dbopts.flags &= ~APK_INTERACTIVE; #endif r = apk_db_open(&db, &dbopts); if (r != 0) { @@ -541,7 +549,7 @@ int main(int argc, char **argv) } if (repo != -2) { - if (!(apk_flags & APK_NO_NETWORK)) + if (!(db.flags & APK_NO_NETWORK)) db.available_repos |= BIT(repo); db.repo_tags[repo_tag].allowed_repos |= BIT(repo); } diff --git a/src/apk_applet.h b/src/apk_applet.h index 30fdc06..8e59390 100644 --- a/src/apk_applet.h +++ b/src/apk_applet.h @@ -55,7 +55,7 @@ struct apk_applet { const char *name; const struct apk_option_group *optgroups[4]; - unsigned int open_flags, forced_flags, forced_force; + unsigned int open_flags, forced_force; int context_size; int (*main)(void *ctx, struct apk_database *db, struct apk_string_array *args); diff --git a/src/apk_database.h b/src/apk_database.h index b69e3b5..20d9169 100644 --- a/src/apk_database.h +++ b/src/apk_database.h @@ -16,12 +16,25 @@ #include "apk_archive.h" #include "apk_package.h" #include "apk_io.h" +#include "apk_print.h" #include "apk_provider_data.h" #include "apk_solver_data.h" #include "adb.h" +#define APK_SIMULATE BIT(0) +#define APK_CLEAN_PROTECTED BIT(1) +#define APK_RECURSIVE BIT(2) +#define APK_ALLOW_UNTRUSTED BIT(3) +#define APK_PURGE BIT(4) +#define APK_INTERACTIVE BIT(5) +#define APK_NO_NETWORK BIT(6) +#define APK_OVERLAY_FROM_STDIN BIT(7) +#define APK_NO_SCRIPTS BIT(8) +#define APK_NO_CACHE BIT(9) +#define APK_NO_COMMIT_HOOKS BIT(10) + #define APK_FORCE_OVERWRITE BIT(0) #define APK_FORCE_OLD_APK BIT(1) #define APK_FORCE_BROKEN_WORLD BIT(2) @@ -125,7 +138,8 @@ struct apk_repository { }; struct apk_db_options { - unsigned int force, lock_wait; + unsigned int flags, force, lock_wait; + struct apk_progress progress; unsigned int cache_max_age; unsigned long open_flags; const char *root; @@ -149,7 +163,8 @@ struct apk_repository_tag { }; struct apk_database { - unsigned int force; + unsigned int flags, force; + struct apk_progress progress; char *root; int root_fd, lock_fd, cache_fd, keys_fd; unsigned num_repos, num_repo_tags; diff --git a/src/apk_defines.h b/src/apk_defines.h index 187b455..7445e03 100644 --- a/src/apk_defines.h +++ b/src/apk_defines.h @@ -69,22 +69,8 @@ static inline int IS_ERR_OR_NULL(const void *ptr) { return IS_ERR(ptr) || !ptr; #define ROUND_UP(x,a) (((x)+(a)-1) & ~((a)-1)) extern int apk_verbosity; -extern unsigned int apk_flags; extern char **apk_argv; -#define APK_SIMULATE 0x0002 -#define APK_CLEAN_PROTECTED 0x0004 -#define APK_PROGRESS 0x0008 -#define APK_RECURSIVE 0x0020 -#define APK_ALLOW_UNTRUSTED 0x0100 -#define APK_PURGE 0x0200 -#define APK_INTERACTIVE 0x0400 -#define APK_NO_NETWORK 0x1000 -#define APK_OVERLAY_FROM_STDIN 0x2000 -#define APK_NO_SCRIPTS 0x4000 -#define APK_NO_CACHE 0x8000 -#define APK_NO_COMMIT_HOOKS 0x00010000 - /* default architecture for APK packages. */ #if defined(__x86_64__) #define APK_DEFAULT_ARCH "x86_64" diff --git a/src/apk_package.h b/src/apk_package.h index 6e428e4..6fbf0c7 100644 --- a/src/apk_package.h +++ b/src/apk_package.h @@ -54,6 +54,7 @@ struct apk_sign_ctx { int has_data_checksum : 1; int control_verified : 1; int data_verified : 1; + int allow_untrusted : 1; char data_checksum[EVP_MAX_MD_SIZE]; struct apk_checksum identity; EVP_MD_CTX *mdctx; @@ -131,7 +132,7 @@ APK_ARRAY(apk_package_array, struct apk_package *); extern const char *apk_script_types[]; void apk_sign_ctx_init(struct apk_sign_ctx *ctx, int action, - struct apk_checksum *identity, int keys_fd); + struct apk_checksum *identity, int keys_fd, int allow_untrusted); void apk_sign_ctx_free(struct apk_sign_ctx *ctx); int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx, const struct apk_file_info *fi, diff --git a/src/apk_print.h b/src/apk_print.h index 8e4dd46..0d001d8 100644 --- a/src/apk_print.h +++ b/src/apk_print.h @@ -28,8 +28,6 @@ void apk_url_parse(struct apk_url_print *, const char *); #define apk_warning(args...) do { if (apk_verbosity > 0) { apk_log_err("WARNING: ", args); } } while (0) #define apk_message(args...) do { if (apk_verbosity > 0) { apk_log(NULL, args); } } while (0) -extern int apk_progress_fd; - void apk_log(const char *prefix, const char *format, ...); void apk_log_err(const char *prefix, const char *format, ...); const char *apk_error_str(int error); @@ -38,12 +36,21 @@ void apk_reset_screen_width(void); int apk_get_screen_width(void); const char *apk_get_human_size(off_t size, off_t *dest); +struct apk_progress { + int fd; + FILE *out; + int last_bar, last_percent; + size_t last_done; + const char *progress_char; +}; + +void apk_print_progress(struct apk_progress *p, size_t done, size_t total); + struct apk_indent { int x; int indent; }; -void apk_print_progress(size_t done, size_t total); int apk_print_indented(struct apk_indent *i, apk_blob_t blob); void apk_print_indented_words(struct apk_indent *i, const char *text); void apk_print_indented_fmt(struct apk_indent *i, const char *fmt, ...); diff --git a/src/app_add.c b/src/app_add.c index 4f2a9a6..93b376c 100644 --- a/src/app_add.c +++ b/src/app_add.c @@ -156,7 +156,7 @@ static int add_main(void *ctx, struct apk_database *db, struct apk_string_array return -1; apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY_AND_GENERATE, - NULL, db->keys_fd); + NULL, db->keys_fd, db->flags & APK_ALLOW_UNTRUSTED); r = apk_pkg_read(db, *parg, &sctx, &pkg); apk_sign_ctx_free(&sctx); if (r != 0) { diff --git a/src/app_cache.c b/src/app_cache.c index f4dd951..826ac1f 100644 --- a/src/app_cache.c +++ b/src/app_cache.c @@ -57,13 +57,14 @@ static const struct apk_option_group optgroup_applet = { }; struct progress { + struct apk_progress prog; size_t done, total; }; static void progress_cb(void *ctx, size_t bytes_done) { struct progress *prog = (struct progress *) ctx; - apk_print_progress(prog->done + bytes_done, prog->total); + apk_print_progress(&prog->prog, prog->done + bytes_done, prog->total); } static int cache_download(struct cache_ctx *cctx, struct apk_database *db) @@ -72,7 +73,7 @@ static int cache_download(struct cache_ctx *cctx, struct apk_database *db) struct apk_change *change; struct apk_package *pkg; struct apk_repository *repo; - struct progress prog = { 0, 0 }; + struct progress prog = { .prog = db->progress }; int r, ret = 0; r = apk_solver_solve(db, cctx->solver_flags, db->world, &changeset); @@ -117,7 +118,7 @@ static void cache_clean_item(struct apk_database *db, int dirfd, const char *nam if (strcmp(name, "installed") == 0) return; if (pkg) { - if ((apk_flags & APK_PURGE) && pkg->ipkg == NULL) goto delete; + if ((db->flags & APK_PURGE) && pkg->ipkg == NULL) goto delete; if (pkg->repos & db->local_repos & ~BIT(APK_REPOSITORY_CACHED)) goto delete; if (pkg->ipkg == NULL && !(pkg->repos & ~BIT(APK_REPOSITORY_CACHED))) goto delete; return; @@ -133,7 +134,7 @@ static void cache_clean_item(struct apk_database *db, int dirfd, const char *nam delete: if (apk_verbosity >= 2) apk_message("deleting %s", name); - if (!(apk_flags & APK_SIMULATE)) { + if (!(db->flags & APK_SIMULATE)) { if (unlinkat(dirfd, name, 0) < 0 && errno == EISDIR) unlinkat(dirfd, name, AT_REMOVEDIR); } diff --git a/src/app_convndx.c b/src/app_convndx.c index e20f673..924a1f6 100644 --- a/src/app_convndx.c +++ b/src/app_convndx.c @@ -57,7 +57,7 @@ static int load_index(struct conv_ctx *ctx, struct apk_istream *is) 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); + apk_sign_ctx_init(&ctx->sctx, APK_SIGN_VERIFY, NULL, ctx->db->keys_fd, ctx->db->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); diff --git a/src/app_fetch.c b/src/app_fetch.c index 7b32ab4..c1498e7 100644 --- a/src/app_fetch.c +++ b/src/app_fetch.c @@ -28,6 +28,7 @@ struct fetch_ctx { unsigned int flags; int outdir_fd, errors; struct apk_database *db; + struct apk_progress prog; size_t done, total; struct apk_dependency_array *world; }; @@ -81,7 +82,7 @@ static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int opt switch (opt) { case OPT_FETCH_simulate: - apk_flags |= APK_SIMULATE; + dbopts->flags |= APK_SIMULATE; break; case OPT_FETCH_recursive: fctx->flags |= FETCH_RECURSIVE; @@ -109,7 +110,7 @@ static const struct apk_option_group optgroup_applet = { static void progress_cb(void *pctx, size_t bytes_done) { struct fetch_ctx *ctx = (struct fetch_ctx *) pctx; - apk_print_progress(ctx->done + bytes_done, ctx->total); + apk_print_progress(&ctx->prog, ctx->done + bytes_done, ctx->total); } static int fetch_package(apk_hash_item item, void *pctx) @@ -144,7 +145,7 @@ static int fetch_package(apk_hash_item item, void *pctx) } apk_message("Downloading " PKG_VER_FMT, PKG_VER_PRINTF(pkg)); - if (apk_flags & APK_SIMULATE) + if (db->flags & APK_SIMULATE) return 0; r = apk_repo_format_item(db, repo, pkg, &urlfd, url, sizeof(url)); @@ -294,7 +295,7 @@ static int purge_package(void *pctx, int dirfd, const char *filename) } apk_message("Purging %s", filename); - if (apk_flags & APK_SIMULATE) + if (db->flags & APK_SIMULATE) return 0; unlinkat(dirfd, filename, 0); @@ -305,8 +306,10 @@ static int fetch_main(void *pctx, struct apk_database *db, struct apk_string_arr { struct fetch_ctx *ctx = (struct fetch_ctx *) pctx; + ctx->db = db; + ctx->prog = db->progress; if (ctx->flags & FETCH_STDOUT) { - apk_flags &= ~APK_PROGRESS; + ctx->prog.out = 0; apk_verbosity = 0; } @@ -319,8 +322,6 @@ static int fetch_main(void *pctx, struct apk_database *db, struct apk_string_arr return 0; } - ctx->db = db; - if (ctx->flags & FETCH_RECURSIVE) { apk_dependency_array_init(&ctx->world); apk_name_foreach_matching(db, args, apk_foreach_genid(), mark_name_flags, ctx); @@ -334,7 +335,7 @@ static int fetch_main(void *pctx, struct apk_database *db, struct apk_string_arr apk_hash_foreach(&db->available.packages, fetch_package, ctx); /* Remove packages not matching download spec from the output directory */ - if (!ctx->errors && (apk_flags & APK_PURGE) && + if (!ctx->errors && (db->flags & APK_PURGE) && !(ctx->flags & FETCH_STDOUT) && ctx->outdir_fd > 0) apk_dir_foreach_file(ctx->outdir_fd, purge_package, ctx); diff --git a/src/app_index.c b/src/app_index.c index b8c3461..2a0a912 100644 --- a/src/app_index.c +++ b/src/app_index.c @@ -183,7 +183,7 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra if (!found) { struct apk_sign_ctx sctx; - apk_sign_ctx_init(&sctx, ictx->method, NULL, db->keys_fd); + apk_sign_ctx_init(&sctx, ictx->method, NULL, db->keys_fd, db->flags & APK_ALLOW_UNTRUSTED); r = apk_pkg_read(db, *parg, &sctx, &pkg); if (r < 0) { apk_error("%s: %s", *parg, apk_error_str(r)); diff --git a/src/app_manifest.c b/src/app_manifest.c index cd5b2ef..c2e20e8 100644 --- a/src/app_manifest.c +++ b/src/app_manifest.c @@ -92,7 +92,7 @@ static void process_file(struct apk_database *db, const char *match) struct manifest_file_ctx ctx = {match, &sctx}; int r; - apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd); + apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd, db->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); diff --git a/src/app_mkndx.c b/src/app_mkndx.c index 7f136fc..d3c6143 100644 --- a/src/app_mkndx.c +++ b/src/app_mkndx.c @@ -273,7 +273,7 @@ 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); + apk_sign_ctx_init(&ctx->sctx, APK_SIGN_VERIFY, NULL, db->keys_fd, db->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); diff --git a/src/app_upgrade.c b/src/app_upgrade.c index 8645d21..2c35d63 100644 --- a/src/app_upgrade.c +++ b/src/app_upgrade.c @@ -110,7 +110,7 @@ int apk_do_self_upgrade(struct apk_database *db, unsigned short solver_flags, un if (changeset.num_total_changes == 0) goto ret; - if (!self_upgrade_only && apk_flags & APK_SIMULATE) { + if (!self_upgrade_only && db->flags & APK_SIMULATE) { apk_warning("This simulation is not reliable as apk-tools upgrade is available."); goto ret; } diff --git a/src/app_verify.c b/src/app_verify.c index 7975268..8f78d82 100644 --- a/src/app_verify.c +++ b/src/app_verify.c @@ -22,7 +22,7 @@ static int verify_main(void *ctx, struct apk_database *db, struct apk_string_arr int r, ok, rc = 0; foreach_array_item(parg, args) { - apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd); + apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd, 1); r = apk_tar_parse( apk_istream_gunzip_mpart(apk_istream_from_file(AT_FDCWD, *parg), apk_sign_ctx_mpart_cb, &sctx), @@ -47,7 +47,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, - .forced_flags = APK_ALLOW_UNTRUSTED, .main = verify_main, }; diff --git a/src/commit.c b/src/commit.c index fe9b1ad..6cc60b7 100644 --- a/src/commit.c +++ b/src/commit.c @@ -112,6 +112,7 @@ static void count_change(struct apk_change *change, struct apk_stats *stats) } struct progress { + struct apk_progress prog; struct apk_stats done; struct apk_stats total; struct apk_package *pkg; @@ -120,7 +121,8 @@ struct progress { static void progress_cb(void *ctx, size_t installed_bytes) { struct progress *prog = (struct progress *) ctx; - apk_print_progress(prog->done.bytes + prog->done.packages + installed_bytes, + apk_print_progress(&prog->prog, + prog->done.bytes + prog->done.packages + installed_bytes, prog->total.bytes + prog->total.packages); } @@ -232,10 +234,10 @@ static int run_commit_hook(void *ctx, int dirfd, const char *file) char fn[PATH_MAX], *argv[] = { fn, (char *) commit_hook_str[hook->type], NULL }; if (file[0] == '.') return 0; - if ((apk_flags & (APK_NO_SCRIPTS | APK_SIMULATE)) != 0) return 0; + if ((db->flags & (APK_NO_SCRIPTS | APK_SIMULATE)) != 0) return 0; snprintf(fn, sizeof(fn), "etc/apk/commit_hooks.d" "/%s", file); - if ((apk_flags & APK_NO_COMMIT_HOOKS) != 0) { + if ((db->flags & APK_NO_COMMIT_HOOKS) != 0) { apk_message("Skipping: %s %s", fn, commit_hook_str[hook->type]); return 0; } @@ -258,7 +260,7 @@ int apk_solver_commit_changeset(struct apk_database *db, struct apk_changeset *changeset, struct apk_dependency_array *world) { - struct progress prog; + struct progress prog = { .prog = db->progress }; struct apk_change *change; char buf[32]; const char *size_unit; @@ -276,7 +278,6 @@ int apk_solver_commit_changeset(struct apk_database *db, goto all_done; /* Count what needs to be done */ - memset(&prog, 0, sizeof(prog)); foreach_array_item(change, changeset->changes) { count_change(change, &prog.total); if (change->new_pkg) @@ -286,13 +287,13 @@ int apk_solver_commit_changeset(struct apk_database *db, } size_unit = apk_get_human_size(llabs(size_diff), &humanized); - if ((apk_verbosity > 1 || (apk_flags & APK_INTERACTIVE)) && - !(apk_flags & APK_SIMULATE)) { + if ((apk_verbosity > 1 || (db->flags & APK_INTERACTIVE)) && + !(db->flags & APK_SIMULATE)) { r = dump_packages(changeset, cmp_remove, "The following packages will be REMOVED"); r += dump_packages(changeset, cmp_downgrade, "The following packages will be DOWNGRADED"); - if (r || (apk_flags & APK_INTERACTIVE) || apk_verbosity > 2) { + if (r || (db->flags & APK_INTERACTIVE) || apk_verbosity > 2) { r += dump_packages(changeset, cmp_new, "The following NEW packages will be installed"); r += dump_packages(changeset, cmp_upgrade, @@ -306,7 +307,7 @@ int apk_solver_commit_changeset(struct apk_database *db, "disk space will be freed" : "additional disk space will be used"); } - if (r > 0 && (apk_flags & APK_INTERACTIVE)) { + if (r > 0 && (db->flags & APK_INTERACTIVE)) { printf("Do you want to continue [Y/n]? "); fflush(stdout); r = fgetc(stdin); @@ -327,7 +328,7 @@ int apk_solver_commit_changeset(struct apk_database *db, prog.pkg = change->new_pkg; progress_cb(&prog, 0); - if (!(apk_flags & APK_SIMULATE) && + if (!(db->flags & APK_SIMULATE) && ((change->old_pkg != change->new_pkg) || (change->reinstall && pkg_available(db, change->new_pkg)))) { r = apk_db_install_pkg(db, change->old_pkg, change->new_pkg, @@ -339,7 +340,7 @@ int apk_solver_commit_changeset(struct apk_database *db, errors += r; count_change(change, &prog.done); } - apk_print_progress(prog.total.bytes + prog.total.packages, + apk_print_progress(&prog.prog, prog.total.bytes + prog.total.packages, prog.total.bytes + prog.total.packages); apk_db_update_directory_permissions(db); diff --git a/src/database.c b/src/database.c index 045d6c7..946155d 100644 --- a/src/database.c +++ b/src/database.c @@ -48,7 +48,6 @@ enum { }; int apk_verbosity = 1; -unsigned int apk_flags = 0; static apk_blob_t tmpprefix = { .len=8, .ptr = ".apknew." }; @@ -243,7 +242,7 @@ static void apk_db_dir_prepare(struct apk_database *db, struct apk_db_dir *dir, (st.st_mode & 07777) == (dir->mode & 07777) && st.st_uid == dir->uid && st.st_gid == dir->gid; } else if (newmode) { - if (!(apk_flags & APK_SIMULATE)) + if (!(db->flags & APK_SIMULATE)) mkdirat(db->root_fd, dir->name, newmode); dir->created = 1; dir->update_permissions = 1; @@ -258,7 +257,7 @@ void apk_db_dir_unref(struct apk_database *db, struct apk_db_dir *dir, int rmdir if (dir->namelen != 0) { if (rmdir_mode == APK_DIR_REMOVE) { dir->modified = 1; - if (!(apk_flags & APK_SIMULATE) && + if (!(db->flags & APK_SIMULATE) && unlinkat(db->root_fd, dir->name, AT_REMOVEDIR) != 0) ; } @@ -637,11 +636,11 @@ int apk_cache_download(struct apk_database *db, struct apk_repository *repo, } apk_message("fetch " URL_FMT, URL_PRINTF(urlp)); - if (apk_flags & APK_SIMULATE) return 0; + if (db->flags & APK_SIMULATE) return 0; if (cb) cb(cb_ctx, 0); if (verify != APK_SIGN_NONE) { - apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd); + apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd, db->flags & APK_ALLOW_UNTRUSTED); 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); @@ -1518,7 +1517,7 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts) apk_default_acl_dir = apk_db_acl_atomize(db, 0755, 0, 0, NULL); apk_default_acl_file = apk_db_acl_atomize(db, 0644, 0, 0, NULL); - if (apk_flags & APK_SIMULATE) { + if (dbopts->flags & APK_SIMULATE) { dbopts->open_flags &= ~(APK_OPENF_CREATE | APK_OPENF_WRITE); dbopts->open_flags |= APK_OPENF_READ; } @@ -1527,10 +1526,11 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts) r = -1; goto ret_r; } + db->flags = dbopts->flags; db->force = dbopts->force; if ((dbopts->open_flags & APK_OPENF_WRITE) && !(dbopts->open_flags & APK_OPENF_NO_AUTOUPDATE) && - !(apk_flags & APK_NO_NETWORK)) + !(dbopts->flags & APK_NO_NETWORK)) db->autoupdate = 1; if (!dbopts->cache_dir) dbopts->cache_dir = "etc/apk/cache"; @@ -1669,8 +1669,8 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts) goto ret_r; } - if (apk_flags & APK_OVERLAY_FROM_STDIN) { - apk_flags &= ~APK_OVERLAY_FROM_STDIN; + if (db->flags & APK_OVERLAY_FROM_STDIN) { + db->flags &= ~APK_OVERLAY_FROM_STDIN; apk_db_read_overlay(db, apk_istream_from_fd(STDIN_FILENO)); } @@ -1748,7 +1748,7 @@ int apk_db_write_config(struct apk_database *db) struct apk_ostream *os; int r; - if ((apk_flags & APK_SIMULATE) || db->root == NULL) + if ((db->flags & APK_SIMULATE) || db->root == NULL) return 0; if (db->lock_fd == 0) { @@ -2139,7 +2139,7 @@ struct apk_repository *apk_db_select_repo(struct apk_database *db, static int apk_repository_update(struct apk_database *db, struct apk_repository *repo) { struct apk_url_print urlp; - int r, verify = (apk_flags & APK_ALLOW_UNTRUSTED) ? APK_SIGN_NONE : APK_SIGN_VERIFY; + int r, verify = (db->flags & APK_ALLOW_UNTRUSTED) ? APK_SIGN_NONE : APK_SIGN_VERIFY; r = apk_cache_download(db, repo, NULL, verify, 1, NULL, NULL); if (r == -EALREADY) return 0; @@ -2196,7 +2196,7 @@ static int load_index(struct apk_database *db, struct apk_istream *is, ctx.db = db; ctx.repo = repo; ctx.found = 0; - apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY, NULL, db->keys_fd); + apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY, NULL, db->keys_fd, db->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); apk_sign_ctx_free(&ctx.sctx); @@ -2262,9 +2262,9 @@ int apk_db_add_repository(apk_database_t _db, apk_blob_t _repository) apk_blob_checksum(brepo, apk_checksum_default(), &repo->csum); if (apk_url_local_file(repo->url) == NULL) { - if (!(apk_flags & APK_NO_NETWORK)) + if (!(db->flags & APK_NO_NETWORK)) db->available_repos |= BIT(repo_num); - if (apk_flags & APK_NO_CACHE) { + if (db->flags & APK_NO_CACHE) { r = apk_repo_format_real_url(db->arch, repo, NULL, buf, sizeof(buf), &urlp); if (r == 0) apk_message("fetch " URL_FMT, URL_PRINTF(urlp)); } else { @@ -2637,7 +2637,7 @@ static void apk_db_purge_pkg(struct apk_database *db, }; hash = apk_blob_hash_seed(key.filename, diri->dir->hash); if ((diri->dir->protect_mode == APK_PROTECT_NONE) || - (apk_flags & APK_PURGE) || + (db->flags & APK_PURGE) || (file->csum.type != APK_CHECKSUM_NONE && apk_fileinfo_get(db->root_fd, name, APK_FI_NOFOLLOW | file->csum.type, &fi, &db->atoms) == 0 && apk_checksum_compare(&file->csum, &fi.csum) == 0)) @@ -2715,7 +2715,7 @@ static void apk_db_migrate_files(struct apk_database *db, apk_fileinfo_get(db->root_fd, name, APK_FI_NOFOLLOW | file->csum.type, &fi, &db->atoms); - if ((apk_flags & APK_CLEAN_PROTECTED) || + if ((db->flags & APK_CLEAN_PROTECTED) || (file->csum.type != APK_CHECKSUM_NONE && apk_checksum_compare(&file->csum, &fi.csum) == 0)) { unlinkat(db->root_fd, tmpname, 0); @@ -2821,7 +2821,7 @@ static int apk_db_unpack_pkg(struct apk_database *db, .cb = cb, .cb_ctx = cb_ctx, }; - apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY_IDENTITY, &pkg->csum, db->keys_fd); + apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY_IDENTITY, &pkg->csum, db->keys_fd, db->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); apk_sign_ctx_free(&ctx.sctx); diff --git a/src/package.c b/src/package.c index 4fca548..8376275 100644 --- a/src/package.c +++ b/src/package.c @@ -465,11 +465,13 @@ int apk_script_type(const char *name) } void apk_sign_ctx_init(struct apk_sign_ctx *ctx, int action, - struct apk_checksum *identity, int keys_fd) + struct apk_checksum *identity, int keys_fd, + int allow_untrusted) { memset(ctx, 0, sizeof(struct apk_sign_ctx)); ctx->keys_fd = keys_fd; ctx->action = action; + ctx->allow_untrusted = !!allow_untrusted; switch (action) { case APK_SIGN_VERIFY: /* If we're only verifing, we're going to start with a @@ -514,7 +516,7 @@ static int check_signing_key_trust(struct apk_sign_ctx *sctx) case APK_SIGN_VERIFY: case APK_SIGN_VERIFY_AND_GENERATE: if (sctx->signature.pkey == NULL) { - if (apk_flags & APK_ALLOW_UNTRUSTED) + if (sctx->allow_untrusted) break; return -ENOKEY; } @@ -697,8 +699,7 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data) EVP_MD_CTX_size(sctx->mdctx)) != 0) return -EKEYREJECTED; sctx->data_verified = 1; - if (!(apk_flags & APK_ALLOW_UNTRUSTED) && - !sctx->control_verified) + if (!sctx->allow_untrusted && !sctx->control_verified) return -ENOKEY; return 0; } @@ -718,11 +719,11 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data) (unsigned char *) sctx->signature.data.ptr, sctx->signature.data.len, sctx->signature.pkey); - if (r != 1 && !(apk_flags & APK_ALLOW_UNTRUSTED)) + if (r != 1 && !sctx->allow_untrusted) return -EKEYREJECTED; } else { r = 0; - if (!(apk_flags & APK_ALLOW_UNTRUSTED)) + if (!sctx->allow_untrusted) return -ENOKEY; } if (r == 1) { @@ -1017,7 +1018,7 @@ void apk_ipkg_run_script(struct apk_installed_package *ipkg, PKG_VER_PRINTF(pkg), apk_script_types[type]); - if ((apk_flags & (APK_NO_SCRIPTS | APK_SIMULATE)) != 0) + if ((db->flags & (APK_NO_SCRIPTS | APK_SIMULATE)) != 0) return; apk_message("Executing %s", &fn[15]); diff --git a/src/print.c b/src/print.c index 7be181e..84c8ed1 100644 --- a/src/print.c +++ b/src/print.c @@ -19,10 +19,8 @@ #include "apk_defines.h" #include "apk_print.h" -int apk_progress_fd; static int apk_screen_width = 0; static int apk_progress_force = 1; -static const char *apk_progress_char = "#"; static const char *apk_size_units[] = {"B", "KiB", "MiB", "GiB", "TiB"}; void apk_reset_screen_width(void) @@ -34,8 +32,6 @@ void apk_reset_screen_width(void) int apk_get_screen_width(void) { struct winsize w; - const char *lang; - const char *progress_char; if (apk_screen_width == 0) { apk_screen_width = 50; @@ -44,13 +40,6 @@ int apk_get_screen_width(void) apk_screen_width = w.ws_col; } - lang = getenv("LANG"); - if (lang != NULL && strstr(lang, "UTF-8") != NULL) - apk_progress_char = "\u2588"; - - if ((progress_char = getenv("APK_PROGRESS_CHAR")) != NULL) - apk_progress_char = progress_char; - return apk_screen_width; } @@ -69,26 +58,24 @@ const char *apk_get_human_size(off_t size, off_t *dest) return apk_size_units[min(i, ARRAY_SIZE(apk_size_units) - 1)]; } -void apk_print_progress(size_t done, size_t total) +void apk_print_progress(struct apk_progress *p, size_t done, size_t total) { - static size_t last_done = 0; - static int last_bar = 0, last_percent = 0; int bar_width; int bar = 0; char buf[64]; /* enough for petabytes... */ int i, percent = 0; + FILE *out = p->out; - if (last_done == done && !apk_progress_force) + if (p->last_done == done && !apk_progress_force) return; - if (apk_progress_fd != 0) { + if (p->fd != 0) { i = snprintf(buf, sizeof(buf), "%zu/%zu\n", done, total); - write(apk_progress_fd, buf, i); + write(p->fd, buf, i); } - last_done = done; + p->last_done = done; - if (!(apk_flags & APK_PROGRESS)) - return; + if (!out) return; bar_width = apk_get_screen_width() - 6; if (total > 0) { @@ -96,22 +83,22 @@ void apk_print_progress(size_t done, size_t total) percent = muldiv(100, done, total); } - if (bar == last_bar && percent == last_percent && !apk_progress_force) + if (bar == p->last_bar && percent == p->last_percent && !apk_progress_force) return; - last_bar = bar; - last_percent = percent; + p->last_bar = bar; + p->last_percent = percent; apk_progress_force = 0; - fprintf(stdout, "\e7%3i%% ", percent); + fprintf(out, "\e7%3i%% ", percent); for (i = 0; i < bar; i++) - fputs(apk_progress_char, stdout); + fputs(p->progress_char, out); for (; i < bar_width; i++) - fputc(' ', stdout); + fputc(' ', out); - fflush(stdout); - fputs("\e8\e[0K", stdout); + fflush(out); + fputs("\e8\e[0K", out); } int apk_print_indented(struct apk_indent *i, apk_blob_t blob)