aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Makefile4
-rw-r--r--src/adb_trust.c4
-rw-r--r--src/apk.c210
-rw-r--r--src/apk_applet.h15
-rw-r--r--src/apk_archive.h4
-rw-r--r--src/apk_context.h51
-rw-r--r--src/apk_database.h45
-rw-r--r--src/apk_defines.h3
-rw-r--r--src/apk_io.h2
-rw-r--r--src/apk_print.h37
-rw-r--r--src/app_adbdump.c3
-rw-r--r--src/app_adbsign.c5
-rw-r--r--src/app_add.c30
-rw-r--r--src/app_audit.c18
-rw-r--r--src/app_cache.c20
-rw-r--r--src/app_convndx.c2
-rw-r--r--src/app_del.c14
-rw-r--r--src/app_dot.c4
-rw-r--r--src/app_fetch.c33
-rw-r--r--src/app_fix.c5
-rw-r--r--src/app_index.c40
-rw-r--r--src/app_info.c67
-rw-r--r--src/app_list.c28
-rw-r--r--src/app_manifest.c62
-rw-r--r--src/app_mkndx.c24
-rw-r--r--src/app_policy.c9
-rw-r--r--src/app_search.c12
-rw-r--r--src/app_update.c11
-rw-r--r--src/app_upgrade.c26
-rw-r--r--src/app_verify.c7
-rw-r--r--src/app_version.c33
-rw-r--r--src/app_vertest.c4
-rw-r--r--src/applet.c (renamed from src/help.c)38
-rw-r--r--src/commit.c94
-rw-r--r--src/context.c27
-rw-r--r--src/database.c258
-rw-r--r--src/io_archive.c20
-rw-r--r--src/lua-apk.c6
-rw-r--r--src/meson.build3
-rw-r--r--src/package.c25
-rw-r--r--src/print.c249
-rw-r--r--src/solver.c2
-rwxr-xr-xtest/solver.sh2
43 files changed, 819 insertions, 737 deletions
diff --git a/src/Makefile b/src/Makefile
index 4360c48..e2b40ba 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -20,7 +20,7 @@ libapk_soname := 3.12.0
libapk_so := $(obj)/libapk.so.$(libapk_soname)
libapk.so.$(libapk_soname)-objs := \
adb.o adb_trust.o \
- common.o database.o package.o commit.o solver.o \
+ common.o context.o database.o package.o commit.o solver.o \
version.o atom.o blob.o hash.o print.o \
io.o io_url.o io_gunzip.o io_archive.o
@@ -60,7 +60,7 @@ endif
# Apk utility
progs-y += apk
-apk-objs := apk.o help.o \
+apk-objs := apk.o applet.o \
app_add.o app_del.o app_fix.o app_update.o app_upgrade.o \
app_info.o app_list.o app_search.o app_manifest.o \
app_policy.o app_stats.o \
diff --git a/src/adb_trust.c b/src/adb_trust.c
index 41c904f..4f08441 100644
--- a/src/adb_trust.c
+++ b/src/adb_trust.c
@@ -248,11 +248,11 @@ int adb_trust_verify_signature(struct adb_trust *trust, struct adb *db, struct a
APK_OPT_GROUP(options_signing, "Signing", SIGNING_OPTIONS);
-static int option_parse_signing(void *ctx, struct apk_db_options *dbopts, int optch, const char *optarg)
+static int option_parse_signing(void *ctx, struct apk_ctx *ac, int optch, const char *optarg)
{
switch (optch) {
case OPT_SIGN_sign_key:
- *apk_string_array_add(&dbopts->private_keys) = (char*) optarg;
+ *apk_string_array_add(&ac->private_keys) = (char*) optarg;
break;
default:
return -ENOTSUP;
diff --git a/src/apk.c b/src/apk.c
index a1085e9..7cbf22b 100644
--- a/src/apk.c
+++ b/src/apk.c
@@ -34,9 +34,6 @@
#include "apk_print.h"
#include "apk_io.h"
-static struct list_head apk_applet_list;
-#define foreach_applet(iter) list_for_each_entry(iter, &apk_applet_list, node)
-
#ifdef TEST_MODE
static const char *test_installed_db = NULL;
static const char *test_world = NULL;
@@ -54,13 +51,12 @@ time_t time(time_t *tloc)
}
#endif
-static void version(void)
+static void version(struct apk_out *out)
{
- printf("apk-tools " APK_VERSION ", compiled for " APK_DEFAULT_ARCH ".\n"
+ apk_out(out, "apk-tools " APK_VERSION ", compiled for " APK_DEFAULT_ARCH ".");
#ifdef TEST_MODE
- "TEST MODE BUILD. NOT FOR PRODUCTION USE.\n"
+ apk_out(out, "TEST MODE BUILD. NOT FOR PRODUCTION USE.");
#endif
- );
}
#define GLOBAL_OPTIONS(OPT) \
@@ -106,95 +102,96 @@ APK_OPT_GROUP2(optiondesc_global, "Global", GLOBAL_OPTIONS, TEST_OPTIONS);
APK_OPT_GROUP(optiondesc_global, "Global", GLOBAL_OPTIONS);
#endif
-static int option_parse_global(void *ctx, struct apk_db_options *dbopts, int opt, const char *optarg)
+static int option_parse_global(void *ctx, struct apk_ctx *ac, int opt, const char *optarg)
{
+ struct apk_out *out = &ac->out;
switch (opt) {
case OPT_GLOBAL_help:
return -EINVAL;
case OPT_GLOBAL_root:
- dbopts->root = optarg;
+ ac->root = optarg;
break;
case OPT_GLOBAL_keys_dir:
- dbopts->keys_dir = optarg;
+ ac->keys_dir = optarg;
break;
case OPT_GLOBAL_repositories_file:
- dbopts->repositories_file = optarg;
+ ac->repositories_file = optarg;
break;
case OPT_GLOBAL_repository:
- *apk_string_array_add(&dbopts->repository_list) = (char*) optarg;
+ *apk_string_array_add(&ac->repository_list) = (char*) optarg;
break;
case OPT_GLOBAL_quiet:
- apk_verbosity--;
+ if (ac->out.verbosity) ac->out.verbosity--;
break;
case OPT_GLOBAL_verbose:
- apk_verbosity++;
+ ac->out.verbosity++;
break;
case OPT_GLOBAL_version:
- version();
+ version(out);
return -ESHUTDOWN;
case OPT_GLOBAL_force:
- dbopts->force |= APK_FORCE_OVERWRITE | APK_FORCE_OLD_APK
+ ac->force |= APK_FORCE_OVERWRITE | APK_FORCE_OLD_APK
| APK_FORCE_BROKEN_WORLD | APK_FORCE_NON_REPOSITORY
| APK_FORCE_BINARY_STDOUT;
break;
case OPT_GLOBAL_force_overwrite:
- dbopts->force |= APK_FORCE_OVERWRITE;
+ ac->force |= APK_FORCE_OVERWRITE;
break;
case OPT_GLOBAL_force_old_apk:
- dbopts->force |= APK_FORCE_OLD_APK;
+ ac->force |= APK_FORCE_OLD_APK;
break;
case OPT_GLOBAL_force_broken_world:
- dbopts->force |= APK_FORCE_BROKEN_WORLD;
+ ac->force |= APK_FORCE_BROKEN_WORLD;
break;
case OPT_GLOBAL_force_refresh:
- dbopts->force |= APK_FORCE_REFRESH;
+ ac->force |= APK_FORCE_REFRESH;
break;
case OPT_GLOBAL_force_non_repository:
- dbopts->force |= APK_FORCE_NON_REPOSITORY;
+ ac->force |= APK_FORCE_NON_REPOSITORY;
break;
case OPT_GLOBAL_force_binary_stdout:
- dbopts->force |= APK_FORCE_BINARY_STDOUT;
+ ac->force |= APK_FORCE_BINARY_STDOUT;
break;
case OPT_GLOBAL_interactive:
- dbopts->flags |= APK_INTERACTIVE;
+ ac->flags |= APK_INTERACTIVE;
break;
case OPT_GLOBAL_progress:
- dbopts->progress.out = stdout;
+ ac->progress.out = &ac->out;
break;
case OPT_GLOBAL_no_progress:
- dbopts->progress.out = NULL;
+ ac->progress.out = NULL;
break;
case OPT_GLOBAL_progress_fd:
- dbopts->progress.fd = atoi(optarg);
+ ac->progress.fd = atoi(optarg);
break;
case OPT_GLOBAL_allow_untrusted:
- dbopts->flags |= APK_ALLOW_UNTRUSTED;
+ ac->flags |= APK_ALLOW_UNTRUSTED;
break;
case OPT_GLOBAL_purge:
- dbopts->flags |= APK_PURGE;
+ ac->flags |= APK_PURGE;
break;
case OPT_GLOBAL_wait:
- dbopts->lock_wait = atoi(optarg);
+ ac->lock_wait = atoi(optarg);
break;
case OPT_GLOBAL_no_network:
- dbopts->flags |= APK_NO_NETWORK;
+ ac->flags |= APK_NO_NETWORK;
break;
case OPT_GLOBAL_no_cache:
- dbopts->flags |= APK_NO_CACHE;
+ ac->flags |= APK_NO_CACHE;
break;
case OPT_GLOBAL_cache_dir:
- dbopts->cache_dir = optarg;
+ ac->cache_dir = optarg;
break;
case OPT_GLOBAL_update_cache:
/* Make it one minute, to avoid updating indexes twice
* when doing self-upgrade's re-exec */
- dbopts->cache_max_age = 60;
+ ac->cache_max_age = 60;
break;
case OPT_GLOBAL_cache_max_age:
- dbopts->cache_max_age = atoi(optarg) * 60;
+ ac->cache_max_age = atoi(optarg) * 60;
break;
case OPT_GLOBAL_arch:
- dbopts->arch = optarg;
+ ac->arch = optarg;
break;
case OPT_GLOBAL_print_arch:
puts(APK_DEFAULT_ARCH);
@@ -231,28 +228,28 @@ const struct apk_option_group optgroup_global = {
APK_OPT_GROUP(optiondesc_commit, "Commit", COMMIT_OPTIONS);
-static int option_parse_commit(void *ctx, struct apk_db_options *dbopts, int opt, const char *optarg)
+static int option_parse_commit(void *ctx, struct apk_ctx *ac, int opt, const char *optarg)
{
switch (opt) {
case OPT_COMMIT_simulate:
- dbopts->flags |= APK_SIMULATE;
+ ac->flags |= APK_SIMULATE;
break;
case OPT_COMMIT_clean_protected:
- dbopts->flags |= APK_CLEAN_PROTECTED;
+ ac->flags |= APK_CLEAN_PROTECTED;
break;
case OPT_COMMIT_overlay_from_stdin:
- dbopts->flags |= APK_OVERLAY_FROM_STDIN;
+ ac->flags |= APK_OVERLAY_FROM_STDIN;
break;
case OPT_COMMIT_no_scripts:
- dbopts->flags |= APK_NO_SCRIPTS;
+ ac->flags |= APK_NO_SCRIPTS;
break;
case OPT_COMMIT_no_commit_hooks:
- dbopts->flags |= APK_NO_COMMIT_HOOKS;
+ ac->flags |= APK_NO_COMMIT_HOOKS;
break;
case OPT_COMMIT_initramfs_diskless_boot:
- dbopts->open_flags |= APK_OPENF_CREATE;
- dbopts->flags |= APK_NO_COMMIT_HOOKS;
- dbopts->force |= APK_FORCE_OVERWRITE | APK_FORCE_OLD_APK
+ ac->open_flags |= APK_OPENF_CREATE;
+ ac->flags |= APK_NO_COMMIT_HOOKS;
+ ac->force |= APK_FORCE_OVERWRITE | APK_FORCE_OLD_APK
| APK_FORCE_BROKEN_WORLD | APK_FORCE_NON_REPOSITORY;
break;
default:
@@ -266,25 +263,13 @@ const struct apk_option_group optgroup_commit = {
.parse = option_parse_commit,
};
-static int usage(struct apk_applet *applet)
+static int usage(struct apk_out *out, struct apk_applet *applet)
{
- version();
- apk_help(applet);
+ version(out);
+ apk_applet_help(applet, out);
return 1;
}
-static struct apk_applet *find_applet(const char *name)
-{
- struct apk_applet *a;
-
- foreach_applet(a) {
- if (strcmp(name, a->name) == 0)
- return a;
- }
-
- return NULL;
-}
-
static struct apk_applet *deduce_applet(int argc, char **argv)
{
struct apk_applet *a;
@@ -298,19 +283,20 @@ static struct apk_applet *deduce_applet(int argc, char **argv)
prog++;
if (strncmp(prog, "apk_", 4) == 0)
- return find_applet(prog + 4);
+ return apk_applet_find(prog + 4);
for (i = 1; i < argc; i++) {
if (argv[i][0] == '-') continue;
- a = find_applet(argv[i]);
+ a = apk_applet_find(argv[i]);
if (a) return a;
}
return NULL;
}
-static int parse_options(int argc, char **argv, struct apk_applet *applet, void *ctx, struct apk_db_options *dbopts)
+static int parse_options(int argc, char **argv, struct apk_applet *applet, void *ctx, struct apk_ctx *ac)
{
+ struct apk_out *out = &ac->out;
const struct apk_option_group *default_optgroups[] = { &optgroup_global, NULL };
const struct apk_option_group *og, **optgroups = default_optgroups;
struct option all_options[80], *opt;
@@ -357,7 +343,7 @@ static int parse_options(int argc, char **argv, struct apk_applet *applet, void
while ((p = getopt_long(argc, argv, short_options, all_options, NULL)) != -1) {
if (p >= 64 && p < 128) p = short_option_val[p - 64];
og = optgroups[p >> 10];
- r = og->parse(ctx, dbopts, p & 0x3ff, optarg);
+ r = og->parse(ctx, ac, p & 0x3ff, optarg);
if (r == 0) continue;
if (r == -EINVAL) {
help_requested = 1;
@@ -367,7 +353,7 @@ static int parse_options(int argc, char **argv, struct apk_applet *applet, void
}
if (help_requested || r == -ENOTSUP)
- return usage(applet);
+ return usage(out, applet);
return 0;
}
@@ -391,66 +377,51 @@ static void init_openssl(void)
#endif
}
-static void on_sigwinch(int s)
-{
- apk_reset_screen_width();
-}
-
-static void setup_terminal(void)
-{
- signal(SIGWINCH, on_sigwinch);
- signal(SIGPIPE, SIG_IGN);
-}
-
-static void setup_automatic_flags(struct apk_db_options *dbopts)
+static void setup_automatic_flags(struct apk_ctx *ac)
{
const char *tmp;
if ((tmp = getenv("APK_PROGRESS_CHAR")) != NULL)
- dbopts->progress.progress_char = tmp;
+ ac->progress.progress_char = tmp;
else if ((tmp = getenv("LANG")) != NULL && strstr(tmp, "UTF-8") != NULL)
- dbopts->progress.progress_char = "\u2588";
+ ac->progress.progress_char = "\u2588";
else
- dbopts->progress.progress_char = "#";
+ ac->progress.progress_char = "#";
if (!isatty(STDOUT_FILENO) || !isatty(STDERR_FILENO) ||
!isatty(STDIN_FILENO))
return;
- dbopts->progress.out = stdout;
- if (!(dbopts->flags & APK_SIMULATE) &&
+ ac->progress.out = &ac->out;
+ if (!(ac->flags & APK_SIMULATE) &&
access("/etc/apk/interactive", F_OK) == 0)
- dbopts->flags |= APK_INTERACTIVE;
+ ac->flags |= APK_INTERACTIVE;
}
-void apk_applet_register(struct apk_applet *applet)
+static struct apk_ctx ctx;
+static struct apk_database db;
+
+static void on_sigint(int s)
{
- list_init(&applet->node);
- list_add_tail(&applet->node, &apk_applet_list);
+ apk_db_close(&db);
+ exit(128 + s);
}
-static void apk_applet_register_builtin(void)
+static void on_sigwinch(int s)
{
- extern apk_init_func_t __start_initapplets[], __stop_initapplets[];
- apk_init_func_t *p;
-
- list_init(&apk_applet_list);
- for (p = __start_initapplets; p < __stop_initapplets; p++)
- (*p)();
+ apk_out_reset(&ctx.out);
}
-static struct apk_database db;
-
-static void on_sigint(int s)
+static void setup_terminal(void)
{
- apk_db_close(&db);
- exit(128 + s);
+ signal(SIGWINCH, on_sigwinch);
+ signal(SIGPIPE, SIG_IGN);
}
int main(int argc, char **argv)
{
- void *ctx = NULL;
- struct apk_db_options dbopts;
+ void *applet_ctx = NULL;
+ struct apk_out *out = &ctx.out;
struct apk_string_array *args;
struct apk_applet *applet;
int r;
@@ -466,33 +437,31 @@ int main(int argc, char **argv)
apk_argv[argc] = NULL;
apk_argv[argc+1] = NULL;
- memset(&dbopts, 0, sizeof(dbopts));
- apk_string_array_init(&dbopts.repository_list);
- apk_string_array_init(&dbopts.private_keys);
+ apk_ctx_init(&ctx);
umask(0);
setup_terminal();
applet = deduce_applet(argc, argv);
if (applet != NULL) {
if (applet->context_size != 0)
- ctx = calloc(1, applet->context_size);
- dbopts.open_flags = applet->open_flags;
- dbopts.force |= applet->forced_force;
+ applet_ctx = calloc(1, applet->context_size);
+ ctx.open_flags = applet->open_flags;
+ ctx.force |= applet->forced_force;
}
init_openssl();
- setup_automatic_flags(&dbopts);
+ setup_automatic_flags(&ctx);
fetchConnectionCacheInit(32, 4);
- r = parse_options(argc, argv, applet, ctx, &dbopts);
+ r = parse_options(argc, argv, applet, applet_ctx, &ctx);
if (r != 0) goto err;
if (applet == NULL) {
if (argc > 1) {
- apk_error("'%s' is not an apk command. See 'apk --help'.", argv[1]);
+ apk_err(out, "'%s' is not an apk command. See 'apk --help'.", argv[1]);
return 1;
}
- return usage(NULL);
+ return usage(out, NULL);
}
argc -= optind;
@@ -506,15 +475,14 @@ int main(int argc, char **argv)
signal(SIGINT, on_sigint);
#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;
- dbopts.flags |= APK_SIMULATE;
- dbopts.flags &= ~APK_INTERACTIVE;
+ ctx.open_flags &= ~(APK_OPENF_WRITE | APK_OPENF_CACHE_WRITE | APK_OPENF_CREATE);
+ ctx.open_flags |= APK_OPENF_READ | APK_OPENF_NO_STATE | APK_OPENF_NO_REPOS;
+ ctx.flags |= APK_SIMULATE;
+ ctx.flags &= ~APK_INTERACTIVE;
#endif
- r = apk_db_open(&db, &dbopts);
+ r = apk_db_open(&db, &ctx);
if (r != 0) {
- apk_error("Failed to open apk database: %s",
- apk_error_str(r));
+ apk_err(out, "Failed to open apk database: %s", apk_error_str(r));
goto err;
}
@@ -544,12 +512,12 @@ int main(int argc, char **argv)
}
if (apk_db_index_read(&db, apk_istream_from_file(AT_FDCWD, name.ptr), repo) != 0) {
- apk_error("Failed to open repository: " BLOB_FMT, BLOB_PRINTF(name));
+ apk_err(out, "Failed to open repository: " BLOB_FMT, BLOB_PRINTF(name));
goto err;
}
if (repo != -2) {
- if (!(db.flags & APK_NO_NETWORK))
+ if (!(ctx.flags & APK_NO_NETWORK))
db.available_repos |= BIT(repo);
db.repo_tags[repo_tag].allowed_repos |= BIT(repo);
}
@@ -559,7 +527,7 @@ int main(int argc, char **argv)
apk_string_array_resize(&args, argc);
memcpy(args->item, argv, argc * sizeof(*argv));
- r = applet->main(ctx, &db, args);
+ r = applet->main(applet_ctx, &db, args);
apk_db_close(&db);
#ifdef TEST_MODE
@@ -569,11 +537,11 @@ int main(int argc, char **argv)
err:
if (r == -ESHUTDOWN) r = 0;
- if (ctx) free(ctx);
+ if (applet_ctx) free(applet_ctx);
fetchConnectionCacheClose();
+ apk_ctx_free(&ctx);
apk_string_array_free(&args);
- apk_string_array_free(&dbopts.private_keys);
free(apk_argv);
if (r < 0) r = 250;
diff --git a/src/apk_applet.h b/src/apk_applet.h
index 8e59390..2f4518b 100644
--- a/src/apk_applet.h
+++ b/src/apk_applet.h
@@ -15,13 +15,6 @@
#include "apk_defines.h"
#include "apk_database.h"
-#if 0
-#define APK_OPT1n(_opt) "\xf0" _opt "\x00"
-#define APK_OPT1R(_opt) "\xaf" "\xf0" _opt "\x00"
-#define APK_OPT2n(_opt, _short) _short _opt "\x00"
-#define APK_OPT2R(_opt, _short) "\xaf" _short _opt "\x00"
-#endif
-
#define __APK_OPTAPPLET "\x00"
#define __APK_OPTGROUP(_name) _name "\x00"
#define __APK_OPT_ENUM(_enum,__desc) _enum,
@@ -45,8 +38,7 @@
struct apk_option_group {
const char *desc;
- int (*parse)(void *ctx, struct apk_db_options *dbopts,
- int opt, const char *optarg);
+ int (*parse)(void *ctx, struct apk_ctx *ac, int opt, const char *optarg);
};
struct apk_applet {
@@ -63,10 +55,13 @@ struct apk_applet {
extern const struct apk_option_group optgroup_global, optgroup_commit, optgroup_signing;
-void apk_help(struct apk_applet *applet);
void apk_applet_register(struct apk_applet *);
+void apk_applet_register_builtin(void);
+struct apk_applet *apk_applet_find(const char *name);
+void apk_applet_help(struct apk_applet *applet, struct apk_out *out);
typedef void (*apk_init_func_t)(void);
+
#define APK_DEFINE_APPLET(x) \
static void __register_##x(void) { apk_applet_register(&x); } \
static apk_init_func_t __regfunc_##x __attribute__((__section__("initapplets"))) __attribute((used)) = __register_##x;
diff --git a/src/apk_archive.h b/src/apk_archive.h
index 708fd1a..fdce49e 100644
--- a/src/apk_archive.h
+++ b/src/apk_archive.h
@@ -12,6 +12,7 @@
#include <sys/types.h>
#include "apk_blob.h"
+#include "apk_print.h"
#include "apk_io.h"
#define APK_EXTRACTF_NO_CHOWN 0x0001
@@ -31,6 +32,7 @@ int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
const char *extract_name, const char *hardlink_name,
struct apk_istream *is,
apk_progress_cb cb, void *cb_ctx,
- unsigned int extract_flags);
+ unsigned int extract_flags,
+ struct apk_out *out);
#endif
diff --git a/src/apk_context.h b/src/apk_context.h
new file mode 100644
index 0000000..27f7c4d
--- /dev/null
+++ b/src/apk_context.h
@@ -0,0 +1,51 @@
+/* apk_context.h - Alpine Package Keeper (APK)
+ *
+ * Copyright (C) 2020 Timo Teräs <timo.teras@iki.fi>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#ifndef APK_CONTEXT_H
+#define APK_CONTEXT_H
+
+#include "apk_print.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)
+#define APK_FORCE_REFRESH BIT(3)
+#define APK_FORCE_NON_REPOSITORY BIT(4)
+#define APK_FORCE_BINARY_STDOUT BIT(5)
+
+struct apk_ctx {
+ unsigned int flags, force, lock_wait;
+ struct apk_out out;
+ struct apk_progress progress;
+ unsigned int cache_max_age;
+ unsigned long open_flags;
+ const char *root;
+ const char *arch;
+ const char *keys_dir;
+ const char *cache_dir;
+ const char *repositories_file;
+ struct apk_string_array *repository_list;
+ struct apk_string_array *private_keys;
+};
+
+void apk_ctx_init(struct apk_ctx *ac);
+void apk_ctx_free(struct apk_ctx *ac);
+
+#endif
diff --git a/src/apk_database.h b/src/apk_database.h
index 20d9169..e43f7ae 100644
--- a/src/apk_database.h
+++ b/src/apk_database.h
@@ -16,32 +16,13 @@
#include "apk_archive.h"
#include "apk_package.h"
#include "apk_io.h"
-#include "apk_print.h"
+#include "apk_context.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)
-#define APK_FORCE_REFRESH BIT(3)
-#define APK_FORCE_NON_REPOSITORY BIT(4)
-#define APK_FORCE_BINARY_STDOUT BIT(5)
-
struct apk_name;
APK_ARRAY(apk_name_array, struct apk_name *);
@@ -137,20 +118,6 @@ struct apk_repository {
apk_blob_t description;
};
-struct apk_db_options {
- unsigned int flags, force, lock_wait;
- struct apk_progress progress;
- unsigned int cache_max_age;
- unsigned long open_flags;
- const char *root;
- const char *arch;
- const char *keys_dir;
- const char *cache_dir;
- const char *repositories_file;
- struct apk_string_array *repository_list;
- struct apk_string_array *private_keys;
-};
-
#define APK_REPOSITORY_CACHED 0
#define APK_REPOSITORY_FIRST_CONFIGURED 1
@@ -163,16 +130,14 @@ struct apk_repository_tag {
};
struct apk_database {
- unsigned int flags, force;
- struct apk_progress progress;
- char *root;
+ struct apk_ctx *ctx;
int root_fd, lock_fd, cache_fd, keys_fd;
unsigned num_repos, num_repo_tags;
const char *cache_dir;
char *cache_remount_dir, *root_proc_dir;
unsigned long cache_remount_flags;
apk_blob_t *arch;
- unsigned int local_repos, available_repos, cache_max_age;
+ unsigned int local_repos, available_repos;
unsigned int repo_update_errors, repo_update_counter;
unsigned int pending_triggers;
unsigned int extract_flags;
@@ -245,7 +210,7 @@ struct apk_db_file *apk_db_file_query(struct apk_database *db,
APK_OPENF_NO_WORLD)
void apk_db_init(struct apk_database *db);
-int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts);
+int apk_db_open(struct apk_database *db, struct apk_ctx *ctx);
void apk_db_close(struct apk_database *db);
int apk_db_write_config(struct apk_database *db);
int apk_db_permanent(struct apk_database *db);
@@ -254,7 +219,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->force & APK_FORCE_REFRESH) ? APK_ISTREAM_FORCE_REFRESH : since;
+ return (db->ctx->force & APK_FORCE_REFRESH) ? APK_ISTREAM_FORCE_REFRESH : since;
}
struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *pkg);
diff --git a/src/apk_defines.h b/src/apk_defines.h
index 7445e03..1bc8db0 100644
--- a/src/apk_defines.h
+++ b/src/apk_defines.h
@@ -68,9 +68,6 @@ static inline int IS_ERR_OR_NULL(const void *ptr) { return IS_ERR(ptr) || !ptr;
#define ROUND_DOWN(x,a) ((x) & ~(a-1))
#define ROUND_UP(x,a) (((x)+(a)-1) & ~((a)-1))
-extern int apk_verbosity;
-extern char **apk_argv;
-
/* default architecture for APK packages. */
#if defined(__x86_64__)
#define APK_DEFAULT_ARCH "x86_64"
diff --git a/src/apk_io.h b/src/apk_io.h
index 2e70b53..adec003 100644
--- a/src/apk_io.h
+++ b/src/apk_io.h
@@ -147,7 +147,7 @@ struct apk_ostream *apk_ostream_to_fd(int fd);
struct apk_ostream *apk_ostream_to_file(int atfd, const char *file, mode_t mode);
struct apk_ostream *apk_ostream_to_file_gz(int atfd, const char *file, const char *tmpfile, mode_t mode);
size_t apk_ostream_write_string(struct apk_ostream *ostream, const char *string);
-static inline void apk_ostream_cancel(struct apk_ostream *os, int rc) { if (!os->rc) os->rc = rc; }
+static inline int apk_ostream_cancel(struct apk_ostream *os, int rc) { if (!os->rc) os->rc = rc; return rc; }
static inline ssize_t apk_ostream_write(struct apk_ostream *os, const void *buf, size_t size)
{
return os->ops->write(os, buf, size);
diff --git a/src/apk_print.h b/src/apk_print.h
index 0d001d8..ec766ed 100644
--- a/src/apk_print.h
+++ b/src/apk_print.h
@@ -12,6 +12,9 @@
#include "apk_blob.h"
+const char *apk_error_str(int error);
+const char *apk_get_human_size(off_t size, off_t *dest);
+
struct apk_url_print {
const char *url;
const char *pwmask;
@@ -24,22 +27,28 @@ void apk_url_parse(struct apk_url_print *, const char *);
#define URL_FMT "%.*s%s%s"
#define URL_PRINTF(u) u.len_before_pw, u.url, u.pwmask, u.url_or_host
-#define apk_error(args...) do { apk_log_err("ERROR: ", args); } while (0)
-#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)
+struct apk_out {
+ int verbosity;
+ unsigned int width, last_change;
+ FILE *out, *err;
+};
-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);
+static inline int apk_out_verbosity(struct apk_out *out) { return out->verbosity; }
-void apk_reset_screen_width(void);
-int apk_get_screen_width(void);
-const char *apk_get_human_size(off_t size, off_t *dest);
+#define apk_err(out, args...) do { apk_out_fmt(out, "ERROR: ", args); } while (0)
+#define apk_out(out, args...) do { apk_out_fmt(out, NULL, args); } while (0)
+#define apk_warn(out, args...) do { if (apk_out_verbosity(out) >= 0) { apk_out_fmt(out, "WARNING: ", args); } } while (0)
+#define apk_msg(out, args...) do { if (apk_out_verbosity(out) >= 1) { apk_out_fmt(out, NULL, args); } } while (0)
+#define apk_dbg(out, args...) do { if (apk_out_verbosity(out) >= 2) { apk_out_fmt(out, NULL, args); } } while (0)
+#define apk_dbg2(out, args...) do { if (apk_out_verbosity(out) >= 3) { apk_out_fmt(out, NULL, args); } } while (0)
+
+void apk_out_reset(struct apk_out *);
+void apk_out_fmt(struct apk_out *, const char *prefix, const char *format, ...);
struct apk_progress {
- int fd;
- FILE *out;
- int last_bar, last_percent;
+ struct apk_out *out;
+ int fd, last_bar, last_percent;
+ unsigned int last_out_change;
size_t last_done;
const char *progress_char;
};
@@ -47,8 +56,8 @@ struct apk_progress {
void apk_print_progress(struct apk_progress *p, size_t done, size_t total);
struct apk_indent {
- int x;
- int indent;
+ struct apk_out *out;
+ int x, indent;
};
int apk_print_indented(struct apk_indent *i, apk_blob_t blob);
diff --git a/src/app_adbdump.c b/src/app_adbdump.c
index 6e42a55..75cf048 100644
--- a/src/app_adbdump.c
+++ b/src/app_adbdump.c
@@ -223,13 +223,14 @@ static int mmap_and_dump_adb(struct adb_trust *trust, int fd)
static int adbdump_main(void *pctx, struct apk_database *db, struct apk_string_array *args)
{
+ struct apk_out *out = &db->ctx->out;
char **arg;
int r;
foreach_array_item(arg, args) {
r = mmap_and_dump_adb(&db->trust, open(*arg, O_RDONLY));
if (r) {
- apk_error("%s: %s", *arg, apk_error_str(r));
+ apk_err(out, "%s: %s", *arg, apk_error_str(r));
return r;
}
}
diff --git a/src/app_adbsign.c b/src/app_adbsign.c
index 918948f..ddcf0c1 100644
--- a/src/app_adbsign.c
+++ b/src/app_adbsign.c
@@ -19,7 +19,7 @@ struct sign_ctx {
APK_OPT_APPLET(option_desc, ADBSIGN_OPTIONS);
-static int option_parse_applet(void *pctx, struct apk_db_options *dbopts, int optch, const char *optarg)
+static int option_parse_applet(void *pctx, struct apk_ctx *ac, int optch, const char *optarg)
{
struct sign_ctx *ctx = (struct sign_ctx *) pctx;
@@ -64,6 +64,7 @@ static int update_signatures(struct adb_xfrm *xfrm, struct adb_block *blk, struc
static int adbsign_main(void *pctx, struct apk_database *db, struct apk_string_array *args)
{
+ struct apk_out *out = &db->ctx->out;
struct sign_ctx *ctx = pctx;
char **arg;
int r;
@@ -75,7 +76,7 @@ static int adbsign_main(void *pctx, struct apk_database *db, struct apk_string_a
adb_c_xfrm(&ctx->xfrm, update_signatures);
apk_istream_close(ctx->xfrm.is);
r = apk_ostream_close(ctx->xfrm.os);
- if (r) apk_error("%s: %s", *arg, apk_error_str(r));
+ if (r) apk_err(out, "%s: %s", *arg, apk_error_str(r));
}
return 0;
diff --git a/src/app_add.c b/src/app_add.c
index 93b376c..1eedcc6 100644
--- a/src/app_add.c
+++ b/src/app_add.c
@@ -30,13 +30,13 @@ struct add_ctx {
APK_OPT_APPLET(option_desc, ADD_OPTIONS);
-static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int opt, const char *optarg)
+static int option_parse_applet(void *ctx, struct apk_ctx *ac, int opt, const char *optarg)
{
struct add_ctx *actx = (struct add_ctx *) ctx;
switch (opt) {
case OPT_ADD_initdb:
- dbopts->open_flags |= APK_OPENF_CREATE;
+ ac->open_flags |= APK_OPENF_CREATE;
break;
case OPT_ADD_latest:
actx->solver_flags |= APK_SOLVERF_LATEST;
@@ -63,17 +63,18 @@ static const struct apk_option_group optgroup_applet = {
static int non_repository_check(struct apk_database *db)
{
- if (db->force & APK_FORCE_NON_REPOSITORY)
+ if (db->ctx->force & APK_FORCE_NON_REPOSITORY)
return 0;
if (apk_db_cache_active(db))
return 0;
if (apk_db_permanent(db))
return 0;
- apk_error("You tried to add a non-repository package to system, "
- "but it would be lost on next reboot. Enable package caching "
- "(apk cache --help) or use --force-non-repository "
- "if you know what you are doing.");
+ apk_err(&db->ctx->out,
+ "You tried to add a non-repository package to system, "
+ "but it would be lost on next reboot. Enable package caching "
+ "(apk cache --help) or use --force-non-repository "
+ "if you know what you are doing.");
return 1;
}
@@ -111,6 +112,7 @@ static struct apk_package *create_virtual_package(struct apk_database *db, struc
static int add_main(void *ctx, struct apk_database *db, struct apk_string_array *args)
{
+ struct apk_out *out = &db->ctx->out;
struct add_ctx *actx = (struct add_ctx *) ctx;
struct apk_package *virtpkg = NULL;
struct apk_dependency virtdep;
@@ -129,7 +131,7 @@ static int add_main(void *ctx, struct apk_database *db, struct apk_string_array
if (APK_BLOB_IS_NULL(b) || virtdep.conflict ||
virtdep.result_mask != APK_DEPMASK_ANY ||
virtdep.version != &apk_atom_null) {
- apk_error("%s: bad package specifier");
+ apk_err(out, "%s: bad package specifier");
return -1;
}
if (virtdep.name->name[0] != '.' && non_repository_check(db))
@@ -137,7 +139,7 @@ static int add_main(void *ctx, struct apk_database *db, struct apk_string_array
virtpkg = create_virtual_package(db, virtdep.name);
if (!virtpkg) {
- apk_error("Failed to allocate virtual meta package");
+ apk_err(out, "Failed to allocate virtual meta package");
return -1;
}
@@ -156,11 +158,11 @@ 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, db->flags & APK_ALLOW_UNTRUSTED);
+ NULL, db->keys_fd, db->ctx->flags & APK_ALLOW_UNTRUSTED);
r = apk_pkg_read(db, *parg, &sctx, &pkg);
apk_sign_ctx_free(&sctx);
if (r != 0) {
- apk_error("%s: %s", *parg, apk_error_str(r));
+ apk_err(out, "%s: %s", *parg, apk_error_str(r));
return -1;
}
apk_dep_from_pkg(&dep, db, pkg);
@@ -169,9 +171,9 @@ static int add_main(void *ctx, struct apk_database *db, struct apk_string_array
apk_blob_pull_dep(&b, db, &dep);
if (APK_BLOB_IS_NULL(b) || b.len > 0 || (virtpkg != NULL && dep.repository_tag)) {
- apk_error("'%s' is not a valid %s dependency, format is %s",
- *parg, virtpkg == NULL ? "world" : "child",
- virtpkg == NULL ? "name(@tag)([<>~=]version)" : "name([<>~=]version)");
+ apk_err(out, "'%s' is not a valid %s dependency, format is %s",
+ *parg, virtpkg == NULL ? "world" : "child",
+ virtpkg == NULL ? "name(@tag)([<>~=]version)" : "name([<>~=]version)");
return -1;
}
}
diff --git a/src/app_audit.c b/src/app_audit.c
index 9b410c5..acfca13 100644
--- a/src/app_audit.c
+++ b/src/app_audit.c
@@ -29,6 +29,7 @@ enum {
};
struct audit_ctx {
+ int verbosity;
unsigned mode : 1;
unsigned recursive : 1;
unsigned check_permissions : 1;
@@ -44,9 +45,9 @@ struct audit_ctx {
APK_OPT_APPLET(option_desc, AUDIT_OPTIONS);
-static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int opt, const char *optarg)
+static int option_parse_applet(void *applet_ctx, struct apk_ctx *ac, int opt, const char *optarg)
{
- struct audit_ctx *actx = (struct audit_ctx *) ctx;
+ struct audit_ctx *actx = (struct audit_ctx *) applet_ctx;
switch (opt) {
case OPT_AUDIT_backup:
@@ -146,18 +147,19 @@ static int audit_directory(struct audit_ctx *actx,
static void report_audit(struct audit_ctx *actx,
char reason, apk_blob_t bfull, struct apk_package *pkg)
{
- if (!reason)
- return;
+ int verbosity = actx->verbosity;
+
+ if (!reason) return;
if (actx->packages_only) {
if (pkg == NULL || pkg->state_int != 0)
return;
pkg->state_int = 1;
- if (apk_verbosity < 1)
+ if (verbosity < 1)
printf("%s\n", pkg->name->name);
else
printf(PKG_VER_FMT "\n", PKG_VER_PRINTF(pkg));
- } else if (apk_verbosity < 1) {
+ } else if (verbosity < 1) {
printf(BLOB_FMT "\n", BLOB_PRINTF(bfull));
} else
printf("%c " BLOB_FMT "\n", reason, BLOB_PRINTF(bfull));
@@ -307,11 +309,13 @@ static int audit_missing_files(apk_hash_item item, void *pctx)
static int audit_main(void *ctx, struct apk_database *db, struct apk_string_array *args)
{
+ struct apk_out *out = &db->ctx->out;
struct audit_tree_ctx atctx;
struct audit_ctx *actx = (struct audit_ctx *) ctx;
char **parg, *arg;
int r = 0;
+ actx->verbosity = apk_out_verbosity(&db->ctx->out);
atctx.db = db;
atctx.actx = actx;
atctx.pathlen = 0;
@@ -323,7 +327,7 @@ static int audit_main(void *ctx, struct apk_database *db, struct apk_string_arra
foreach_array_item(parg, args) {
arg = *parg;
if (arg[0] != '/') {
- apk_warning("%s: relative path skipped.\n", arg);
+ apk_warn(out, "%s: relative path skipped.\n", arg);
continue;
}
arg++;
diff --git a/src/app_cache.c b/src/app_cache.c
index 826ac1f..974690c 100644
--- a/src/app_cache.c
+++ b/src/app_cache.c
@@ -34,7 +34,7 @@ struct cache_ctx {
APK_OPT_APPLET(option_desc, CACHE_OPTIONS);
-static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int opt, const char *optarg)
+static int option_parse_applet(void *ctx, struct apk_ctx *ac, int opt, const char *optarg)
{
struct cache_ctx *cctx = (struct cache_ctx *) ctx;
@@ -69,16 +69,17 @@ static void progress_cb(void *ctx, size_t bytes_done)
static int cache_download(struct cache_ctx *cctx, struct apk_database *db)
{
+ struct apk_out *out = &db->ctx->out;
struct apk_changeset changeset = {};
struct apk_change *change;
struct apk_package *pkg;
struct apk_repository *repo;
- struct progress prog = { .prog = db->progress };
+ struct progress prog = { .prog = db->ctx->progress };
int r, ret = 0;
r = apk_solver_solve(db, cctx->solver_flags, db->world, &changeset);
if (r < 0) {
- apk_error("Unable to select packages. Run apk fix.");
+ apk_err(out, "Unable to select packages. Run apk fix.");
return r;
}
@@ -100,7 +101,7 @@ static int cache_download(struct cache_ctx *cctx, struct apk_database *db)
r = apk_cache_download(db, repo, pkg, APK_SIGN_VERIFY_IDENTITY, 0,
progress_cb, &prog);
if (r && r != -EALREADY) {
- apk_error(PKG_VER_FMT ": %s", PKG_VER_PRINTF(pkg), apk_error_str(r));
+ apk_err(out, PKG_VER_FMT ": %s", PKG_VER_PRINTF(pkg), apk_error_str(r));
ret++;
}
prog.done += pkg->size;
@@ -111,6 +112,7 @@ static int cache_download(struct cache_ctx *cctx, struct apk_database *db)
static void cache_clean_item(struct apk_database *db, int dirfd, const char *name, struct apk_package *pkg)
{
+ struct apk_out *out = &db->ctx->out;
char tmp[PATH_MAX];
apk_blob_t b;
int i;
@@ -118,7 +120,7 @@ static void cache_clean_item(struct apk_database *db, int dirfd, const char *nam
if (strcmp(name, "installed") == 0) return;
if (pkg) {
- if ((db->flags & APK_PURGE) && pkg->ipkg == NULL) goto delete;
+ if ((db->ctx->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;
@@ -132,9 +134,8 @@ 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 (!(db->flags & APK_SIMULATE)) {
+ apk_dbg(out, "deleting %s", name);
+ if (!(db->ctx->flags & APK_SIMULATE)) {
if (unlinkat(dirfd, name, 0) < 0 && errno == EISDIR)
unlinkat(dirfd, name, AT_REMOVEDIR);
}
@@ -147,6 +148,7 @@ static int cache_clean(struct apk_database *db)
static int cache_main(void *ctx, struct apk_database *db, struct apk_string_array *args)
{
+ struct apk_out *out = &db->ctx->out;
struct cache_ctx *cctx = (struct cache_ctx *) ctx;
char *arg;
int r = 0, actions = 0;
@@ -165,7 +167,7 @@ static int cache_main(void *ctx, struct apk_database *db, struct apk_string_arra
return -EINVAL;
if (!apk_db_cache_active(db)) {
- apk_error("Package cache is not enabled.\n");
+ apk_err(out, "Package cache is not enabled.\n");
r = 2;
goto err;
}
diff --git a/src/app_convndx.c b/src/app_convndx.c
index 924a1f6..393ca43 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, ctx->db->flags & APK_ALLOW_UNTRUSTED);
+ apk_sign_ctx_init(&ctx->sctx, APK_SIGN_VERIFY, NULL, ctx->db->keys_fd, ctx->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, &ctx->db->id_cache);
diff --git a/src/app_del.c b/src/app_del.c
index aa7ab4f..390a99a 100644
--- a/src/app_del.c
+++ b/src/app_del.c
@@ -24,7 +24,7 @@ struct del_ctx {
APK_OPT_APPLET(option_desc, DEL_OPTIONS);
-static int option_parse_applet(void *pctx, struct apk_db_options *dbopts, int opt, const char *optarg)
+static int option_parse_applet(void *pctx, struct apk_ctx *ac, int opt, const char *optarg)
{
struct del_ctx *ctx = (struct del_ctx *) pctx;
@@ -44,6 +44,7 @@ static const struct apk_option_group optgroup_applet = {
};
struct not_deleted_ctx {
+ struct apk_out *out;
struct apk_indent indent;
struct apk_name *name;
unsigned int matches;
@@ -54,12 +55,13 @@ static void print_not_deleted_pkg(struct apk_package *pkg0, struct apk_dependenc
struct apk_package *pkg, void *pctx)
{
struct not_deleted_ctx *ctx = (struct not_deleted_ctx *) pctx;
+ struct apk_out *out = ctx->out;
struct apk_dependency *d;
struct apk_provider *p;
if (pkg0->name != ctx->name) {
if (!ctx->header) {
- apk_message("World updated, but the following packages are not removed due to:");
+ apk_msg(out, "World updated, but the following packages are not removed due to:");
ctx->header = 1;
}
if (!ctx->indent.indent) {
@@ -83,10 +85,11 @@ static void print_not_deleted_pkg(struct apk_package *pkg0, struct apk_dependenc
static void print_not_deleted_name(struct apk_database *db, const char *match,
struct apk_name *name, void *pctx)
{
+ struct apk_out *out = &db->ctx->out;
struct not_deleted_ctx *ctx = (struct not_deleted_ctx *) pctx;
struct apk_provider *p;
- ctx->indent.indent = 0;
+ ctx->indent = (struct apk_indent) { .out = out };
ctx->name = name;
ctx->matches = apk_foreach_genid() | APK_FOREACH_MARKED | APK_DEP_SATISFIES;
foreach_array_item(p, name->providers)
@@ -111,11 +114,12 @@ static void delete_pkg(struct apk_package *pkg0, struct apk_dependency *dep0,
static void delete_name(struct apk_database *db, const char *match,
struct apk_name *name, void *pctx)
{
+ struct apk_out *out = &db->ctx->out;
struct del_ctx *ctx = (struct del_ctx *) pctx;
struct apk_package *pkg;
if (!name) {
- apk_error("No such package: %s", match);
+ apk_err(out, "No such package: %s", match);
ctx->errors++;
return;
}
@@ -130,7 +134,7 @@ static void delete_name(struct apk_database *db, const char *match,
static int del_main(void *pctx, struct apk_database *db, struct apk_string_array *args)
{
struct del_ctx *ctx = (struct del_ctx *) pctx;
- struct not_deleted_ctx ndctx = {};
+ struct not_deleted_ctx ndctx = { .out = &db->ctx->out };
struct apk_changeset changeset = {};
struct apk_change *change;
int r = 0;
diff --git a/src/app_dot.c b/src/app_dot.c
index ad9167c..15283fd 100644
--- a/src/app_dot.c
+++ b/src/app_dot.c
@@ -28,7 +28,7 @@ struct dot_ctx {
APK_OPT_APPLET(option_desc, DOT_OPTIONS);
-static int option_parse_applet(void *pctx, struct apk_db_options *dbopts, int opt, const char *optarg)
+static int option_parse_applet(void *pctx, struct apk_ctx *ac, int opt, const char *optarg)
{
struct dot_ctx *ctx = (struct dot_ctx *) pctx;
@@ -38,7 +38,7 @@ static int option_parse_applet(void *pctx, struct apk_db_options *dbopts, int op
break;
case OPT_DOT_installed:
ctx->installed_only = 1;
- dbopts->open_flags &= ~APK_OPENF_NO_INSTALLED;
+ ac->open_flags &= ~APK_OPENF_NO_INSTALLED;
break;
default:
return -ENOTSUP;
diff --git a/src/app_fetch.c b/src/app_fetch.c
index c1498e7..9a4faab 100644
--- a/src/app_fetch.c
+++ b/src/app_fetch.c
@@ -76,13 +76,13 @@ static int cup(void)
APK_OPT_APPLET(option_desc, FETCH_OPTIONS);
-static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int opt, const char *optarg)
+static int option_parse_applet(void *ctx, struct apk_ctx *ac, int opt, const char *optarg)
{
struct fetch_ctx *fctx = (struct fetch_ctx *) ctx;
switch (opt) {
case OPT_FETCH_simulate:
- dbopts->flags |= APK_SIMULATE;
+ ac->flags |= APK_SIMULATE;
break;
case OPT_FETCH_recursive:
fctx->flags |= FETCH_RECURSIVE;
@@ -117,6 +117,7 @@ static int fetch_package(apk_hash_item item, void *pctx)
{
struct fetch_ctx *ctx = (struct fetch_ctx *) pctx;
struct apk_database *db = ctx->db;
+ struct apk_out *out = &db->ctx->out;
struct apk_package *pkg = (struct apk_package *) item;
struct apk_istream *is;
struct apk_repository *repo;
@@ -144,8 +145,8 @@ static int fetch_package(apk_hash_item item, void *pctx)
return 0;
}
- apk_message("Downloading " PKG_VER_FMT, PKG_VER_PRINTF(pkg));
- if (db->flags & APK_SIMULATE)
+ apk_msg(out, "Downloading " PKG_VER_FMT, PKG_VER_PRINTF(pkg));
+ if (db->ctx->flags & APK_SIMULATE)
return 0;
r = apk_repo_format_item(db, repo, pkg, &urlfd, url, sizeof(url));
@@ -194,7 +195,7 @@ static int fetch_package(apk_hash_item item, void *pctx)
return 0;
err:
- apk_error(PKG_VER_FMT ": %s", PKG_VER_PRINTF(pkg), apk_error_str(r));
+ apk_err(out, PKG_VER_FMT ": %s", PKG_VER_PRINTF(pkg), apk_error_str(r));
ctx->errors++;
return 0;
}
@@ -209,10 +210,12 @@ static void mark_package(struct fetch_ctx *ctx, struct apk_package *pkg)
static void mark_error(struct fetch_ctx *ctx, const char *match, struct apk_name *name)
{
+ struct apk_out *out = &ctx->db->ctx->out;
+
if (strchr(match, '*') != NULL)
return;
- apk_message("%s: unable to select package (or its dependencies)", name ? name->name : match);
+ apk_msg(out, "%s: unable to select package (or its dependencies)", name ? name->name : match);
ctx->errors++;
}
@@ -276,6 +279,7 @@ static int purge_package(void *pctx, int dirfd, const char *filename)
char tmp[PATH_MAX];
struct fetch_ctx *ctx = (struct fetch_ctx *) pctx;
struct apk_database *db = ctx->db;
+ struct apk_out *out = &db->ctx->out;
struct apk_provider *p0;
struct apk_name *name;
apk_blob_t b = APK_BLOB_STR(filename), bname, bver;
@@ -294,8 +298,8 @@ static int purge_package(void *pctx, int dirfd, const char *filename)
break;
}
- apk_message("Purging %s", filename);
- if (db->flags & APK_SIMULATE)
+ apk_msg(out, "Purging %s", filename);
+ if (db->ctx->flags & APK_SIMULATE)
return 0;
unlinkat(dirfd, filename, 0);
@@ -304,21 +308,22 @@ static int purge_package(void *pctx, int dirfd, const char *filename)
static int fetch_main(void *pctx, struct apk_database *db, struct apk_string_array *args)
{
+ struct apk_out *out = &db->ctx->out;
struct fetch_ctx *ctx = (struct fetch_ctx *) pctx;
ctx->db = db;
- ctx->prog = db->progress;
+ ctx->prog = db->ctx->progress;
if (ctx->flags & FETCH_STDOUT) {
- ctx->prog.out = 0;
- apk_verbosity = 0;
+ db->ctx->progress.out = 0;
+ db->ctx->out.verbosity = 0;
}
if (ctx->outdir_fd == 0)
ctx->outdir_fd = AT_FDCWD;
if ((args->num == 1) && (strcmp(args->item[0], "coffee") == 0)) {
- if (db->force) return cup();
- apk_message("Go and fetch your own coffee.");
+ if (db->ctx->force) return cup();
+ apk_msg(out, "Go and fetch your own coffee.");
return 0;
}
@@ -335,7 +340,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 && (db->flags & APK_PURGE) &&
+ if (!ctx->errors && (db->ctx->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_fix.c b/src/app_fix.c
index ccd1e3c..311cfdd 100644
--- a/src/app_fix.c
+++ b/src/app_fix.c
@@ -31,7 +31,7 @@ struct fix_ctx {
APK_OPT_APPLET(option_desc, FIX_OPTIONS);
-static int option_parse_applet(void *pctx, struct apk_db_options *dbopts, int opt, const char *optarg)
+static int option_parse_applet(void *pctx, struct apk_ctx *ac, int opt, const char *optarg)
{
struct fix_ctx *ctx = (struct fix_ctx *) pctx;
switch (opt) {
@@ -76,10 +76,11 @@ static void mark_fix(struct fix_ctx *ctx, struct apk_name *name)
static void set_solver_flags(struct apk_database *db, const char *match, struct apk_name *name, void *pctx)
{
+ struct apk_out *out = &db->ctx->out;
struct fix_ctx *ctx = pctx;
if (!name) {
- apk_error("Package '%s' not found", match);
+ apk_err(out, "Package '%s' not found", match);
ctx->errors++;
} else
mark_fix(ctx, name);
diff --git a/src/app_index.c b/src/app_index.c
index 2a0a912..707bd94 100644
--- a/src/app_index.c
+++ b/src/app_index.c
@@ -20,6 +20,7 @@
#define APK_INDEXF_NO_WARNINGS 0x0001
struct counts {
+ struct apk_out *out;
int unsatisfied;
};
@@ -42,7 +43,7 @@ struct index_ctx {
APK_OPT_APPLET(option_desc, INDEX_OPTIONS);
-static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int opt, const char *optarg)
+static int option_parse_applet(void *ctx, struct apk_ctx *ac, int opt, const char *optarg)
{
struct index_ctx *ictx = (struct index_ctx *) ctx;
@@ -90,16 +91,15 @@ static int warn_if_no_providers(apk_hash_item item, void *ctx)
{
struct counts *counts = (struct counts *) ctx;
struct apk_name *name = (struct apk_name *) item;
+ struct apk_out *out = counts->out;
if (!name->is_dependency) return 0;
if (name->providers->num) return 0;
if (++counts->unsatisfied < 10) {
- apk_warning("No provider for dependency '%s'",
- name->name);
+ apk_warn(out, "No provider for dependency '%s'", name->name);
} else if (counts->unsatisfied == 10) {
- apk_warning("Too many unsatisfiable dependencies, "
- "not reporting the rest.");
+ apk_warn(out, "Too many unsatisfiable dependencies, not reporting the rest.");
}
return 0;
@@ -107,7 +107,8 @@ static int warn_if_no_providers(apk_hash_item item, void *ctx)
static int index_main(void *ctx, struct apk_database *db, struct apk_string_array *args)
{
- struct counts counts = {0};
+ struct apk_out *out = &db->ctx->out;
+ struct counts counts = { .out = out };
struct apk_ostream *os;
struct apk_file_info fi;
int total, r, found, newpkgs = 0, errors = 0;
@@ -117,9 +118,10 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
apk_blob_t *rewrite_arch = NULL;
if (isatty(STDOUT_FILENO) && ictx->output == NULL &&
- !(db->force & APK_FORCE_BINARY_STDOUT)) {
- apk_error("Will not write binary index to console. "
- "Use --force-binary-stdout to override.");
+ !(db->ctx->force & APK_FORCE_BINARY_STDOUT)) {
+ apk_err(out,
+ "Will not write binary index to console. "
+ "Use --force-binary-stdout to override.");
return -1;
}
@@ -127,7 +129,7 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
ictx->method = APK_SIGN_GENERATE;
if ((r = index_read_file(db, ictx)) < 0) {
- apk_error("%s: %s", ictx->index, apk_error_str(r));
+ apk_err(out, "%s: %s", ictx->index, apk_error_str(r));
return r;
}
@@ -136,7 +138,7 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
foreach_array_item(parg, args) {
if (apk_fileinfo_get(AT_FDCWD, *parg, APK_CHECKSUM_NONE, &fi, &db->atoms) < 0) {
- apk_warning("File '%s' is unaccessible", *parg);
+ apk_warn(out, "File '%s' is unaccessible", *parg);
continue;
}
@@ -183,10 +185,10 @@ 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, db->flags & APK_ALLOW_UNTRUSTED);
+ apk_sign_ctx_init(&sctx, ictx->method, NULL, db->keys_fd, db->ctx->flags & APK_ALLOW_UNTRUSTED);
r = apk_pkg_read(db, *parg, &sctx, &pkg);
if (r < 0) {
- apk_error("%s: %s", *parg, apk_error_str(r));
+ apk_err(out, "%s: %s", *parg, apk_error_str(r));
errors++;
} else {
newpkgs++;
@@ -237,7 +239,7 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
apk_ostream_close(os);
if (r < 0) {
- apk_error("Index generation failed: %s", apk_error_str(r));
+ apk_err(out, "Index generation failed: %s", apk_error_str(r));
return r;
}
@@ -247,11 +249,11 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
}
if (counts.unsatisfied != 0)
- apk_warning("Total of %d unsatisfiable package "
- "names. Your repository may be broken.",
- counts.unsatisfied);
- apk_message("Index has %d packages (of which %d are new)",
- total, newpkgs);
+ apk_warn(out,
+ "Total of %d unsatisfiable package names. Your repository may be broken.",
+ counts.unsatisfied);
+ apk_msg(out, "Index has %d packages (of which %d are new)",
+ total, newpkgs);
return 0;
}
diff --git a/src/app_info.c b/src/app_info.c
index 8454f0f..8f02f30 100644
--- a/src/app_info.c
+++ b/src/app_info.c
@@ -23,6 +23,8 @@ struct info_ctx {
int errors;
};
+static int verbosity = 0;
+
/* These need to stay in sync with the function pointer array in
* info_subaction() */
#define APK_INFO_DESC 0x01
@@ -40,18 +42,11 @@ struct info_ctx {
static void verbose_print_pkg(struct apk_package *pkg, int minimal_verbosity)
{
- int verbosity = apk_verbosity;
- if (verbosity < minimal_verbosity)
- verbosity = minimal_verbosity;
-
- if (pkg == NULL || verbosity < 1)
- return;
-
+ int v = min(verbosity, minimal_verbosity);
+ if (pkg == NULL || v < 1) return;
printf("%s", pkg->name->name);
- if (apk_verbosity > 1)
- printf("-" BLOB_FMT, BLOB_PRINTF(*pkg->version));
- if (apk_verbosity > 2)
- printf(" - %s", pkg->description);
+ if (v > 1) printf("-" BLOB_FMT, BLOB_PRINTF(*pkg->version));
+ if (v > 2) printf(" - %s", pkg->description);
printf("\n");
}
@@ -89,6 +84,7 @@ static void info_exists(struct info_ctx *ctx, struct apk_database *db,
static void info_who_owns(struct info_ctx *ctx, struct apk_database *db,
struct apk_string_array *args)
{
+ struct apk_out *out = &db->ctx->out;
struct apk_package *pkg;
struct apk_dependency_array *deps;
struct apk_dependency dep;
@@ -116,13 +112,13 @@ static void info_who_owns(struct info_ctx *ctx, struct apk_database *db,
}
if (pkg == NULL) {
- apk_error(BLOB_FMT ": Could not find owner package",
- BLOB_PRINTF(fn));
+ apk_err(out, BLOB_FMT ": Could not find owner package",
+ BLOB_PRINTF(fn));
ctx->errors++;
continue;
}
- if (apk_verbosity < 1) {
+ if (verbosity < 1) {
dep = (struct apk_dependency) {
.name = pkg->name,
.version = &apk_atom_null,
@@ -134,7 +130,7 @@ static void info_who_owns(struct info_ctx *ctx, struct apk_database *db,
BLOB_PRINTF(fn), via, PKG_VER_PRINTF(pkg));
}
}
- if (apk_verbosity < 1 && deps->num != 0) {
+ if (verbosity < 1 && deps->num != 0) {
os = apk_ostream_to_fd(STDOUT_FILENO);
if (!IS_ERR_OR_NULL(os)) {
apk_deps_write(db, deps, os, APK_BLOB_PTR_LEN(" ", 1));
@@ -147,7 +143,7 @@ static void info_who_owns(struct info_ctx *ctx, struct apk_database *db,
static void info_print_description(struct apk_database *db, struct apk_package *pkg)
{
- if (apk_verbosity > 1)
+ if (verbosity > 1)
printf("%s: %s", pkg->name->name, pkg->description);
else
printf(PKG_VER_FMT " description:\n%s\n",
@@ -157,7 +153,7 @@ static void info_print_description(struct apk_database *db, struct apk_package *
static void info_print_url(struct apk_database *db, struct apk_package *pkg)
{
- if (apk_verbosity > 1)
+ if (verbosity > 1)
printf("%s: %s", pkg->name->name, pkg->url);
else
printf(PKG_VER_FMT " webpage:\n%s\n",
@@ -167,7 +163,7 @@ static void info_print_url(struct apk_database *db, struct apk_package *pkg)
static void info_print_license(struct apk_database *db, struct apk_package *pkg)
{
- if (apk_verbosity > 1)
+ if (verbosity > 1)
printf("%s: " BLOB_FMT , pkg->name->name, BLOB_PRINTF(*pkg->license));
else
printf(PKG_VER_FMT " license:\n" BLOB_FMT "\n",
@@ -181,7 +177,7 @@ static void info_print_size(struct apk_database *db, struct apk_package *pkg)
const char *size_unit;
size_unit = apk_get_human_size(pkg->installed_size, &size);
- if (apk_verbosity > 1)
+ if (verbosity > 1)
printf("%s: %lld %s", pkg->name->name,
(long long)size, size_unit);
else
@@ -193,12 +189,12 @@ static void info_print_dep_array(struct apk_database *db, struct apk_package *pk
struct apk_dependency_array *deps, const char *dep_text)
{
struct apk_dependency *d;
- apk_blob_t separator = APK_BLOB_STR(apk_verbosity > 1 ? " " : "\n");
+ apk_blob_t separator = APK_BLOB_STR(verbosity > 1 ? " " : "\n");
char buf[256];
- if (apk_verbosity == 1)
+ if (verbosity == 1)
printf(PKG_VER_FMT " %s:\n", PKG_VER_PRINTF(pkg), dep_text);
- if (apk_verbosity > 1)
+ if (verbosity > 1)
printf("%s: ", pkg->name->name);
foreach_array_item(d, deps) {
apk_blob_t b = APK_BLOB_BUF(buf);
@@ -221,14 +217,14 @@ static void info_print_provides(struct apk_database *db, struct apk_package *pkg
static void print_rdep_pkg(struct apk_package *pkg0, struct apk_dependency *dep0, struct apk_package *pkg, void *pctx)
{
- printf(PKG_VER_FMT "%s", PKG_VER_PRINTF(pkg0), apk_verbosity > 1 ? " " : "\n");
+ printf(PKG_VER_FMT "%s", PKG_VER_PRINTF(pkg0), verbosity > 1 ? " " : "\n");
}
static void info_print_required_by(struct apk_database *db, struct apk_package *pkg)
{
- if (apk_verbosity == 1)
+ if (verbosity == 1)
printf(PKG_VER_FMT " is required by:\n", PKG_VER_PRINTF(pkg));
- if (apk_verbosity > 1)
+ if (verbosity > 1)
printf("%s: ", pkg->name->name);
apk_pkg_foreach_reverse_dependency(
pkg,
@@ -244,12 +240,12 @@ static void info_print_install_if(struct apk_database *db, struct apk_package *p
static void info_print_rinstall_if(struct apk_database *db, struct apk_package *pkg)
{
int i, j;
- char *separator = apk_verbosity > 1 ? " " : "\n";
+ char *separator = verbosity > 1 ? " " : "\n";
- if (apk_verbosity == 1)
+ if (verbosity == 1)
printf(PKG_VER_FMT " affects auto-installation of:\n",
PKG_VER_PRINTF(pkg));
- if (apk_verbosity > 1)
+ if (verbosity > 1)
printf("%s: ", pkg->name->name);
for (i = 0; i < pkg->name->rinstall_if->num; i++) {
struct apk_name *name0;
@@ -280,7 +276,7 @@ static void info_print_contents(struct apk_database *db, struct apk_package *pkg
struct apk_db_file *file;
struct hlist_node *dc, *dn, *fc, *fn;
- if (apk_verbosity == 1)
+ if (verbosity == 1)
printf(PKG_VER_FMT " contains:\n",
PKG_VER_PRINTF(pkg));
@@ -288,7 +284,7 @@ static void info_print_contents(struct apk_database *db, struct apk_package *pkg
pkg_dirs_list) {
hlist_for_each_entry_safe(file, fc, fn, &diri->owned_files,
diri_files_list) {
- if (apk_verbosity > 1)
+ if (verbosity > 1)
printf("%s: ", pkg->name->name);
printf(DIR_FILE_FMT "\n", DIR_FILE_PRINTF(diri->dir, file));
}
@@ -300,12 +296,12 @@ static void info_print_triggers(struct apk_database *db, struct apk_package *pkg
struct apk_installed_package *ipkg = pkg->ipkg;
char **trigger;
- if (apk_verbosity == 1)
+ if (verbosity == 1)
printf(PKG_VER_FMT " triggers:\n",
PKG_VER_PRINTF(pkg));
foreach_array_item(trigger, ipkg->triggers) {
- if (apk_verbosity > 1)
+ if (verbosity > 1)
printf("%s: trigger ", pkg->name->name);
printf("%s\n", *trigger);
}
@@ -383,7 +379,7 @@ static void print_name_info(struct apk_database *db, const char *match, struct a
APK_OPT_APPLET(option_desc, INFO_OPTIONS);
-static int option_parse_applet(void *pctx, struct apk_db_options *dbopts, int opt, const char *optarg)
+static int option_parse_applet(void *pctx, struct apk_ctx *ac, int opt, const char *optarg)
{
struct info_ctx *ctx = (struct info_ctx *) pctx;
@@ -391,11 +387,11 @@ static int option_parse_applet(void *pctx, struct apk_db_options *dbopts, int op
switch (opt) {
case OPT_INFO_installed:
ctx->action = info_exists;
- dbopts->open_flags |= APK_OPENF_NO_REPOS;
+ ac->open_flags |= APK_OPENF_NO_REPOS;
break;
case OPT_INFO_who_owns:
ctx->action = info_who_owns;
- dbopts->open_flags |= APK_OPENF_NO_REPOS;
+ ac->open_flags |= APK_OPENF_NO_REPOS;
break;
case OPT_INFO_webpage:
ctx->subaction_mask |= APK_INFO_URL;
@@ -447,6 +443,7 @@ static int info_main(void *ctx, struct apk_database *db, struct apk_string_array
struct info_ctx *ictx = (struct info_ctx *) ctx;
struct apk_installed_package *ipkg;
+ verbosity = apk_out_verbosity(&db->ctx->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 5606df0..a7e05b8 100644
--- a/src/app_list.c
+++ b/src/app_list.c
@@ -18,6 +18,7 @@
#include "apk_print.h"
struct list_ctx {
+ int verbosity;
unsigned int installed : 1;
unsigned int orphaned : 1;
unsigned int available : 1;
@@ -36,8 +37,7 @@ static int origin_matches(const struct list_ctx *ctx, const struct apk_package *
if (pkg->origin == NULL)
return 0;
- foreach_array_item(pmatch, ctx->filters)
- {
+ foreach_array_item(pmatch, ctx->filters) {
if (apk_blob_compare(APK_BLOB_STR(*pmatch), *pkg->origin) == 0)
return 1;
}
@@ -103,8 +103,7 @@ static void print_package(const struct apk_package *pkg, const struct list_ctx *
if (pkg->ipkg)
printf(" [installed]");
- else
- {
+ else {
const struct apk_package *u;
u = is_upgradable(pkg->name, pkg);
@@ -113,10 +112,9 @@ static void print_package(const struct apk_package *pkg, const struct list_ctx *
}
- if (apk_verbosity > 1)
- {
+ if (ctx->verbosity > 1) {
printf("\n %s\n", pkg->description);
- if (apk_verbosity > 2)
+ if (ctx->verbosity > 2)
printf(" <%s>\n", pkg->url);
}
@@ -147,8 +145,7 @@ static void iterate_providers(const struct apk_name *name, const struct list_ctx
{
struct apk_provider *p;
- foreach_array_item(p, name->providers)
- {
+ foreach_array_item(p, name->providers) {
if (!ctx->match_providers && p->pkg->name != name)
continue;
@@ -162,19 +159,17 @@ static void iterate_providers(const struct apk_name *name, const struct list_ctx
static void print_result(struct apk_database *db, const char *match, struct apk_name *name, void *pctx)
{
struct list_ctx *ctx = pctx;
+ struct apk_name **pname;
if (name == NULL)
return;
- if (ctx->match_depends)
- {
- struct apk_name **pname;
-
+ if (ctx->match_depends) {
foreach_array_item(pname, name->rdepends)
iterate_providers(*pname, ctx);
- }
- else
+ } else {
iterate_providers(name, ctx);
+ }
}
#define LIST_OPTIONS(OPT) \
@@ -188,7 +183,7 @@ static void print_result(struct apk_database *db, const char *match, struct apk_
APK_OPT_APPLET(option_desc, LIST_OPTIONS);
-static int option_parse_applet(void *pctx, struct apk_db_options *dbopts, int opt, const char *optarg)
+static int option_parse_applet(void *pctx, struct apk_ctx *ac, int opt, const char *optarg)
{
struct list_ctx *ctx = pctx;
@@ -235,6 +230,7 @@ static int list_main(void *pctx, struct apk_database *db, struct apk_string_arra
{
struct list_ctx *ctx = pctx;
+ ctx->verbosity = apk_out_verbosity(&db->ctx->out);
ctx->filters = args;
if (ctx->match_origin)
diff --git a/src/app_manifest.c b/src/app_manifest.c
index c2e20e8..9b9a2db 100644
--- a/src/app_manifest.c
+++ b/src/app_manifest.c
@@ -24,43 +24,50 @@ static char *csum_types[APK_CHECKSUM_SHA1 + 1] = {
[APK_CHECKSUM_SHA1] = "sha1",
};
-struct manifest_file_ctx {
- const char *file;
- struct apk_sign_ctx *sctx;
-};
-
static void process_package(struct apk_database *db, struct apk_package *pkg)
{
+ struct apk_out *out = &db->ctx->out;
struct apk_installed_package *ipkg = pkg->ipkg;
struct apk_db_dir_instance *diri;
struct apk_db_file *file;
struct hlist_node *dc, *dn, *fc, *fn;
+ const char *prefix1 = "", *prefix2 = "";
char csum_buf[APK_BLOB_CHECKSUM_BUF];
if (ipkg == NULL)
return;
+ if (apk_out_verbosity(out) > 1) {
+ prefix1 = pkg->name->name;
+ prefix2 = ": ";
+ }
+
hlist_for_each_entry_safe(diri, dc, dn, &ipkg->owned_dirs,
pkg_dirs_list) {
hlist_for_each_entry_safe(file, fc, fn, &diri->owned_files,
diri_files_list) {
apk_blob_t csum_blob = APK_BLOB_BUF(csum_buf);
-
memset(csum_buf, '\0', sizeof(csum_buf));
apk_blob_push_hexdump(&csum_blob, APK_BLOB_CSUM(file->csum));
- if (apk_verbosity > 1)
- printf("%s: ", pkg->name->name);
-
- printf("%s:%s " DIR_FILE_FMT "\n", csum_types[file->csum.type], csum_buf, DIR_FILE_PRINTF(diri->dir, file));
- }
+ apk_out(out, "%s%s%s:%s " DIR_FILE_FMT,
+ prefix1, prefix2,
+ csum_types[file->csum.type], csum_buf,
+ DIR_FILE_PRINTF(diri->dir, file));
+ }
}
}
-static int read_file_entry(void *ctx, const struct apk_file_info *ae,
- struct apk_istream *is)
+struct manifest_file_ctx {
+ struct apk_out *out;
+ struct apk_sign_ctx *sctx;
+ const char *prefix1, *prefix2;
+};
+
+static int read_file_entry(void *ctx, const struct apk_file_info *ae, struct apk_istream *is)
{
struct manifest_file_ctx *mctx = ctx;
+ struct apk_out *out = mctx->out;
char csum_buf[APK_BLOB_CHECKSUM_BUF];
apk_blob_t csum_blob = APK_BLOB_BUF(csum_buf);
int r;
@@ -78,34 +85,43 @@ static int read_file_entry(void *ctx, const struct apk_file_info *ae,
memset(csum_buf, '\0', sizeof(csum_buf));
apk_blob_push_hexdump(&csum_blob, APK_BLOB_CSUM(ae->csum));
- if (apk_verbosity > 1)
- printf("%s: ", mctx->file);
-
- printf("%s:%s %s\n", csum_types[ae->csum.type], csum_buf, ae->name);
+ apk_out(out, "%s%s%s:%s %s\n",
+ mctx->prefix1, mctx->prefix2,
+ csum_types[ae->csum.type], csum_buf, ae->name);
return 0;
}
static void process_file(struct apk_database *db, const char *match)
{
+ struct apk_out *out = &db->ctx->out;
struct apk_sign_ctx sctx;
- struct manifest_file_ctx ctx = {match, &sctx};
+ struct manifest_file_ctx ctx = {
+ .out = out,
+ .sctx = &sctx,
+ .prefix1 = "",
+ .prefix2 = "",
+ };
int r;
- apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd, db->flags & APK_ALLOW_UNTRUSTED);
+ if (apk_out_verbosity(out) > 1) {
+ ctx.prefix1 = match;
+ ctx.prefix2 = ": ";
+ }
+
+ 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);
apk_sign_ctx_free(&sctx);
- if (r < 0) apk_error("%s: %s", match, apk_error_str(r));
+ if (r < 0) apk_err(out, "%s: %s", match, apk_error_str(r));
}
static void process_match(struct apk_database *db, const char *match, struct apk_name *name, void *ctx)
{
struct apk_provider *p;
- if (name == NULL)
- {
+ if (name == NULL) {
process_file(db, match);
return;
}
@@ -114,7 +130,7 @@ static void process_match(struct apk_database *db, const char *match, struct apk
process_package(db, p->pkg);
}
-static int manifest_main(void *ctx, struct apk_database *db, struct apk_string_array *args)
+static int manifest_main(void *applet_ctx, struct apk_database *db, struct apk_string_array *args)
{
apk_name_foreach_matching(db, args, apk_foreach_genid(), process_match, NULL);
return 0;
diff --git a/src/app_mkndx.c b/src/app_mkndx.c
index d3c6143..beb4144 100644
--- a/src/app_mkndx.c
+++ b/src/app_mkndx.c
@@ -44,7 +44,7 @@ struct mkndx_ctx {
APK_OPT_APPLET(option_desc, MKNDX_OPTIONS);
-static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int optch, const char *optarg)
+static int option_parse_applet(void *ctx, struct apk_ctx *ac, int optch, const char *optarg)
{
struct mkndx_ctx *ictx = ctx;
@@ -188,6 +188,7 @@ static int mkndx_parse_v2_tar(void *pctx, const struct apk_file_info *ae, struct
static int mkndx_main(void *pctx, struct apk_database *db, struct apk_string_array *args)
{
+ struct apk_out *out = &db->ctx->out;
struct adb odb, tmpdb;
struct adb_obj oroot, opkgs, ndx, tmpl;
struct apk_file_info fi;
@@ -198,7 +199,7 @@ static int mkndx_main(void *pctx, struct apk_database *db, struct apk_string_arr
time_t index_mtime = 0;
if (ctx->output == NULL) {
- apk_error("Please specify --output FILE");
+ apk_err(out, "Please specify --output FILE");
return -1;
}
@@ -215,7 +216,7 @@ static int mkndx_main(void *pctx, struct apk_database *db, struct apk_string_arr
r = adb_m_map(&odb, open(ctx->index, O_RDONLY), ADB_SCHEMA_INDEX, &db->trust);
if (r) {
- apk_error("%s: %s", ctx->index, apk_error_str(r));
+ apk_err(out, "%s: %s", ctx->index, apk_error_str(r));
return r;
}
adb_ro_obj(adb_r_rootobj(&odb, &oroot, &schema_index), ADBI_NDX_PACKAGES, &opkgs);
@@ -225,7 +226,7 @@ static int mkndx_main(void *pctx, struct apk_database *db, struct apk_string_arr
r = apk_fileinfo_get(AT_FDCWD, *parg, APK_CHECKSUM_NONE, &fi, 0);
if (r < 0) {
err_pkg:
- apk_error("%s: %s", *parg, apk_error_str(r));
+ apk_err(out, "%s: %s", *parg, apk_error_str(r));
errors++;
continue;
}
@@ -273,7 +274,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, db->flags & APK_ALLOW_UNTRUSTED);
+ 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(apk_istream_from_file(AT_FDCWD, *parg), apk_sign_ctx_mpart_cb, &ctx->sctx),
mkndx_parse_v2_tar, ctx, &db->id_cache);
@@ -283,7 +284,7 @@ static int mkndx_main(void *pctx, struct apk_database *db, struct apk_string_arr
}
}
if (errors) {
- apk_error("%d errors, not creating index", errors);
+ apk_err(out, "%d errors, not creating index", errors);
return -1;
}
@@ -300,19 +301,18 @@ static int mkndx_main(void *pctx, struct apk_database *db, struct apk_string_arr
adb_free(&odb);
if (r == 0)
- apk_message("Index has %d packages (of which %d are new)",
- numpkgs, newpkgs);
+ apk_msg(out, "Index has %d packages (of which %d are new)", numpkgs, newpkgs);
else
- apk_error("Index creation failed: %s", apk_error_str(r));
+ apk_err(out, "Index creation failed: %s", apk_error_str(r));
#if 0
apk_hash_foreach(&db->available.names, warn_if_no_providers, &counts);
if (counts.unsatisfied != 0)
- apk_warning("Total of %d unsatisfiable package "
- "names. Your repository may be broken.",
- counts.unsatisfied);
+ apk_warn(out,
+ "Total of %d unsatisfiable package names. Your repository may be broken.",
+ counts.unsatisfied);
#endif
return r;
diff --git a/src/app_policy.c b/src/app_policy.c
index 954eb9d..91e97d0 100644
--- a/src/app_policy.c
+++ b/src/app_policy.c
@@ -17,6 +17,7 @@ extern const char * const apk_installed_file;
static void print_policy(struct apk_database *db, const char *match, struct apk_name *name, void *ctx)
{
+ struct apk_out *out = &db->ctx->out;
struct apk_provider *p;
struct apk_repository *repo;
int i, j, num = 0;
@@ -41,17 +42,17 @@ zlib1g policy:
if (p->pkg->name != name)
continue;
if (num++ == 0)
- printf("%s policy:\n", name->name);
- printf(" " BLOB_FMT ":\n", BLOB_PRINTF(*p->version));
+ apk_out(out, "%s policy:", name->name);
+ apk_out(out, " " BLOB_FMT ":", BLOB_PRINTF(*p->version));
if (p->pkg->ipkg != NULL)
- printf(" %s\n", apk_installed_file);
+ apk_out(out, " %s", apk_installed_file);
for (i = 0; i < db->num_repos; i++) {
repo = &db->repos[i];
if (!(BIT(i) & p->pkg->repos))
continue;
for (j = 0; j < db->num_repo_tags; j++) {
if (db->repo_tags[j].allowed_repos & p->pkg->repos)
- printf(" "BLOB_FMT"%s%s\n",
+ apk_out(out, " "BLOB_FMT"%s%s",
BLOB_PRINTF(db->repo_tags[j].tag),
j == 0 ? "" : " ",
repo->url);
diff --git a/src/app_search.c b/src/app_search.c
index 866bb7a..11b7108 100644
--- a/src/app_search.c
+++ b/src/app_search.c
@@ -18,6 +18,7 @@ struct search_ctx {
void (*print_result)(struct search_ctx *ctx, struct apk_package *pkg);
void (*print_package)(struct search_ctx *ctx, struct apk_package *pkg);
+ int verbosity;
int show_all : 1;
int search_exact : 1;
int search_description : 1;
@@ -38,9 +39,9 @@ static void print_package_name(struct search_ctx *ctx, struct apk_package *pkg)
{
if (!unique_match(pkg)) return;
printf("%s", pkg->name->name);
- if (apk_verbosity > 0)
+ if (ctx->verbosity > 0)
printf("-" BLOB_FMT, BLOB_PRINTF(*pkg->version));
- if (apk_verbosity > 1)
+ if (ctx->verbosity > 1)
printf(" - %s", pkg->description);
printf("\n");
}
@@ -52,7 +53,7 @@ static void print_origin_name(struct search_ctx *ctx, struct apk_package *pkg)
printf(BLOB_FMT, BLOB_PRINTF(*pkg->origin));
else
printf("%s", pkg->name->name);
- if (apk_verbosity > 0)
+ if (ctx->verbosity > 0)
printf("-" BLOB_FMT, BLOB_PRINTF(*pkg->version));
printf("\n");
}
@@ -65,7 +66,7 @@ static void print_rdep_pkg(struct apk_package *pkg0, struct apk_dependency *dep0
static void print_rdepends(struct search_ctx *ctx, struct apk_package *pkg)
{
- if (apk_verbosity > 0) {
+ if (ctx->verbosity > 0) {
ctx->matches = apk_foreach_genid() | APK_DEP_SATISFIES;
printf(PKG_VER_FMT " is required by:\n", PKG_VER_PRINTF(pkg));
}
@@ -82,7 +83,7 @@ static void print_rdepends(struct search_ctx *ctx, struct apk_package *pkg)
APK_OPT_APPLET(option_desc, SEARCH_OPTIONS);
-static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int opt, const char *optarg)
+static int option_parse_applet(void *ctx, struct apk_ctx *ac, int opt, const char *optarg)
{
struct search_ctx *ictx = (struct search_ctx *) ctx;
@@ -176,6 +177,7 @@ static int search_main(void *pctx, struct apk_database *db, struct apk_string_ar
struct search_ctx *ctx = (struct search_ctx *) pctx;
char *tmp, **pmatch;
+ ctx->verbosity = apk_out_verbosity(&db->ctx->out);
ctx->filter = args;
ctx->matches = apk_foreach_genid() | APK_DEP_SATISFIES;
if (ctx->print_package == NULL)
diff --git a/src/app_update.c b/src/app_update.c
index 70b7460..4fa24f8 100644
--- a/src/app_update.c
+++ b/src/app_update.c
@@ -16,11 +16,12 @@
static int update_main(void *ctx, struct apk_database *db, struct apk_string_array *args)
{
+ struct apk_out *out = &db->ctx->out;
struct apk_repository *repo;
int i;
char buf[32] = "OK:";
- if (apk_verbosity < 1)
+ if (apk_out_verbosity(out) < 1)
return db->repo_update_errors;
for (i = 0; i < db->num_repos; i++) {
@@ -29,15 +30,15 @@ static int update_main(void *ctx, struct apk_database *db, struct apk_string_arr
if (APK_BLOB_IS_NULL(repo->description))
continue;
- apk_message(BLOB_FMT " [%s]",
- BLOB_PRINTF(repo->description),
- db->repos[i].url);
+ apk_msg(out, BLOB_FMT " [%s]",
+ BLOB_PRINTF(repo->description),
+ db->repos[i].url);
}
if (db->repo_update_errors != 0)
snprintf(buf, sizeof(buf), "%d errors;",
db->repo_update_errors);
- apk_message("%s %d distinct packages available", buf,
+ apk_msg(out, "%s %d distinct packages available", buf,
db->available.packages.num_items);
return db->repo_update_errors;
diff --git a/src/app_upgrade.c b/src/app_upgrade.c
index 2c35d63..6d63b50 100644
--- a/src/app_upgrade.c
+++ b/src/app_upgrade.c
@@ -16,6 +16,8 @@
#include "apk_print.h"
#include "apk_solver.h"
+extern char **apk_argv;
+
struct upgrade_ctx {
unsigned short solver_flags;
int no_self_upgrade : 1;
@@ -35,7 +37,7 @@ struct upgrade_ctx {
APK_OPT_APPLET(option_desc, UPGRADE_OPTIONS);
-static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int opt, const char *optarg)
+static int option_parse_applet(void *ctx, struct apk_ctx *ac, int opt, const char *optarg)
{
struct upgrade_ctx *uctx = (struct upgrade_ctx *) ctx;
@@ -71,6 +73,7 @@ static const struct apk_option_group optgroup_applet = {
int apk_do_self_upgrade(struct apk_database *db, unsigned short solver_flags, unsigned int self_upgrade_only)
{
+ struct apk_out *out = &db->ctx->out;
struct apk_name *name;
struct apk_package *pkg;
struct apk_provider *p0;
@@ -102,7 +105,7 @@ int apk_do_self_upgrade(struct apk_database *db, unsigned short solver_flags, un
r = apk_solver_solve(db, 0, db->world, &changeset);
if (r != 0) {
- apk_warning("Failed to perform initial self-upgrade, continuing with full upgrade.");
+ apk_warn(out, "Failed to perform initial self-upgrade, continuing with full upgrade.");
r = 0;
goto ret;
}
@@ -110,24 +113,24 @@ 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 && db->flags & APK_SIMULATE) {
- apk_warning("This simulation is not reliable as apk-tools upgrade is available.");
+ if (!self_upgrade_only && db->ctx->flags & APK_SIMULATE) {
+ apk_warn(out, "This simulation is not reliable as apk-tools upgrade is available.");
goto ret;
}
- apk_message("Upgrading critical system libraries and apk-tools:");
+ apk_msg(out, "Upgrading critical system libraries and apk-tools:");
apk_solver_commit_changeset(db, &changeset, db->world);
if (self_upgrade_only) goto ret;
apk_db_close(db);
+ apk_msg(out, "Continuing the upgrade transaction with new apk-tools:");
- apk_message("Continuing the upgrade transaction with new apk-tools:");
for (r = 0; apk_argv[r] != NULL; r++)
;
apk_argv[r] = "--no-self-upgrade";
execvp(apk_argv[0], apk_argv);
- apk_error("PANIC! Failed to re-execute new apk-tools!");
+ apk_err(out, "PANIC! Failed to re-execute new apk-tools!");
exit(1);
ret:
@@ -138,10 +141,11 @@ ret:
static void set_upgrade_for_name(struct apk_database *db, const char *match, struct apk_name *name, void *pctx)
{
+ struct apk_out *out = &db->ctx->out;
struct upgrade_ctx *uctx = (struct upgrade_ctx *) pctx;
if (!name) {
- apk_error("Package '%s' not found", match);
+ apk_err(out, "Package '%s' not found", match);
uctx->errors++;
return;
}
@@ -151,6 +155,7 @@ static void set_upgrade_for_name(struct apk_database *db, const char *match, str
static int upgrade_main(void *ctx, struct apk_database *db, struct apk_string_array *args)
{
+ struct apk_out *out = &db->ctx->out;
struct upgrade_ctx *uctx = (struct upgrade_ctx *) ctx;
unsigned short solver_flags;
struct apk_dependency *dep;
@@ -159,8 +164,9 @@ static int upgrade_main(void *ctx, struct apk_database *db, struct apk_string_ar
int r = 0;
if (apk_db_check_world(db, db->world) != 0) {
- apk_error("Not continuing with upgrade due to missing repository tags. "
- "Use --force-broken-world to override.");
+ apk_err(out,
+ "Not continuing with upgrade due to missing repository tags. "
+ "Use --force-broken-world to override.");
return -1;
}
diff --git a/src/app_verify.c b/src/app_verify.c
index 8f78d82..0a18ea6 100644
--- a/src/app_verify.c
+++ b/src/app_verify.c
@@ -17,6 +17,7 @@
static int verify_main(void *ctx, struct apk_database *db, struct apk_string_array *args)
{
+ struct apk_out *out = &db->ctx->out;
struct apk_sign_ctx sctx;
char **parg;
int r, ok, rc = 0;
@@ -28,13 +29,13 @@ static int verify_main(void *ctx, struct apk_database *db, struct apk_string_arr
apk_sign_ctx_mpart_cb, &sctx),
apk_sign_ctx_verify_tar, &sctx, &db->id_cache);
ok = sctx.control_verified && sctx.data_verified;
- if (apk_verbosity >= 1)
- apk_message("%s: %d - %s", *parg, r,
+ if (apk_out_verbosity(out) >= 1)
+ apk_msg(out, "%s: %d - %s", *parg, r,
r < 0 ? apk_error_str(r) :
ok ? "OK" :
!sctx.control_verified ? "UNTRUSTED" : "FAILED");
else if (!ok)
- printf("%s\n", *parg);
+ apk_out(out, "%s", *parg);
if (!ok)
rc++;
diff --git a/src/app_version.c b/src/app_version.c
index d5d9c88..0e17493 100644
--- a/src/app_version.c
+++ b/src/app_version.c
@@ -22,6 +22,7 @@ struct ver_ctx {
static int ver_indexes(struct apk_database *db, struct apk_string_array *args)
{
+ struct apk_out *out = &db->ctx->out;
struct apk_repository *repo;
int i;
@@ -31,9 +32,9 @@ static int ver_indexes(struct apk_database *db, struct apk_string_array *args)
if (APK_BLOB_IS_NULL(repo->description))
continue;
- printf(BLOB_FMT " [%s]\n",
- BLOB_PRINTF(repo->description),
- db->repos[i].url);
+ apk_out(out, BLOB_FMT " [%s]",
+ BLOB_PRINTF(repo->description),
+ db->repos[i].url);
}
return 0;
@@ -41,25 +42,26 @@ static int ver_indexes(struct apk_database *db, struct apk_string_array *args)
static int ver_test(struct apk_database *db, struct apk_string_array *args)
{
+ struct apk_out *out = &db->ctx->out;
int r;
if (args->num != 2)
return 1;
r = apk_version_compare(args->item[0], args->item[1]);
- printf("%s\n", apk_version_op_string(r));
+ apk_out(out, "%s", apk_version_op_string(r));
return 0;
}
static int ver_validate(struct apk_database *db, struct apk_string_array *args)
{
+ struct apk_out *out = &db->ctx->out;
char **parg;
int errors = 0;
foreach_array_item(parg, args) {
if (!apk_version_validate(APK_BLOB_STR(*parg))) {
- if (apk_verbosity > 0)
- printf("%s\n", *parg);
+ apk_msg(out, "%s", *parg);
errors++;
}
}
@@ -75,7 +77,7 @@ static int ver_validate(struct apk_database *db, struct apk_string_array *args)
APK_OPT_APPLET(option_desc, VERSION_OPTIONS);
-static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int opt, const char *optarg)
+static int option_parse_applet(void *ctx, struct apk_ctx *ac, int opt, const char *optarg)
{
struct ver_ctx *ictx = (struct ver_ctx *) ctx;
switch (opt) {
@@ -84,7 +86,7 @@ static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int opt
break;
case OPT_VERSION_check:
ictx->action = ver_validate;
- dbopts->open_flags |= APK_OPENF_NO_STATE | APK_OPENF_NO_REPOS;
+ ac->open_flags |= APK_OPENF_NO_STATE | APK_OPENF_NO_REPOS;
break;
case OPT_VERSION_indexes:
ictx->action = ver_indexes;
@@ -94,7 +96,7 @@ static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int opt
break;
case OPT_VERSION_test:
ictx->action = ver_test;
- dbopts->open_flags |= APK_OPENF_NO_STATE | APK_OPENF_NO_REPOS;
+ ac->open_flags |= APK_OPENF_NO_STATE | APK_OPENF_NO_REPOS;
break;
default:
return -ENOTSUP;
@@ -109,6 +111,7 @@ static const struct apk_option_group optgroup_applet = {
static void ver_print_package_status(struct apk_database *db, const char *match, struct apk_name *name, void *pctx)
{
+ struct apk_out *out = &db->ctx->out;
struct ver_ctx *ctx = (struct ver_ctx *) pctx;
struct apk_package *pkg;
struct apk_provider *p0;
@@ -149,8 +152,8 @@ static void ver_print_package_status(struct apk_database *db, const char *match,
opstr = apk_version_op_string(r);
if ((ctx->limchars != NULL) && (strchr(ctx->limchars, *opstr) == NULL))
return;
- if (apk_verbosity <= 0) {
- printf("%s\n", pkg->name->name);
+ if (apk_out_verbosity(out) <= 0) {
+ apk_out(out, "%s", pkg->name->name);
return;
}
@@ -163,7 +166,7 @@ static void ver_print_package_status(struct apk_database *db, const char *match,
}
snprintf(pkgname, sizeof(pkgname), PKG_VER_FMT, PKG_VER_PRINTF(pkg));
- printf("%-40s%s " BLOB_FMT " " BLOB_FMT "\n",
+ apk_out(out, "%-40s%s " BLOB_FMT " " BLOB_FMT,
pkgname, opstr,
BLOB_PRINTF(*latest),
BLOB_PRINTF(db->repo_tags[tag].tag));
@@ -171,20 +174,20 @@ static void ver_print_package_status(struct apk_database *db, const char *match,
static int ver_main(void *pctx, struct apk_database *db, struct apk_string_array *args)
{
+ struct apk_out *out = &db->ctx->out;
struct ver_ctx *ctx = (struct ver_ctx *) pctx;
if (ctx->limchars) {
if (strlen(ctx->limchars) == 0)
ctx->limchars = NULL;
- } else if (args->num == 0 && apk_verbosity == 1) {
+ } else if (args->num == 0 && apk_out_verbosity(out) == 1) {
ctx->limchars = "<";
}
if (ctx->action != NULL)
return ctx->action(db, args);
- if (apk_verbosity > 0)
- printf("%-42sAvailable:\n", "Installed:");
+ apk_msg(out, "%-42s%s", "Installed:", "Available:");
apk_name_foreach_matching(
db, args, APK_FOREACH_NULL_MATCHES_ALL | apk_foreach_genid(),
diff --git a/src/app_vertest.c b/src/app_vertest.c
index 54d5f10..e6b3cae 100644
--- a/src/app_vertest.c
+++ b/src/app_vertest.c
@@ -16,6 +16,7 @@
static int vertest_main(void *pctx, struct apk_database *db, struct apk_string_array *args)
{
+ struct apk_out *out = &db->ctx->out;
apk_blob_t arg, ver, op, space = APK_BLOB_STRLIT(" ");
char **parg;
int errors = 0;
@@ -35,8 +36,7 @@ static int vertest_main(void *pctx, struct apk_database *db, struct apk_string_a
ok = apk_version_validate(arg);
}
if (!ok) {
- if (apk_verbosity > 0)
- printf("%s\n", *parg);
+ apk_msg(out, "%s", *parg);
errors++;
}
}
diff --git a/src/help.c b/src/applet.c
index 3034da2..1d47662 100644
--- a/src/help.c
+++ b/src/applet.c
@@ -10,6 +10,37 @@
#include "apk_applet.h"
#include "apk_print.h"
+static struct list_head apk_applet_list;
+
+#define apk_applet_foreach(iter) list_for_each_entry(iter, &apk_applet_list, node)
+
+void apk_applet_register(struct apk_applet *applet)
+{
+ list_init(&applet->node);
+ list_add_tail(&applet->node, &apk_applet_list);
+}
+
+void apk_applet_register_builtin(void)
+{
+ extern apk_init_func_t __start_initapplets[], __stop_initapplets[];
+ apk_init_func_t *p;
+
+ list_init(&apk_applet_list);
+ for (p = __start_initapplets; p < __stop_initapplets; p++)
+ (*p)();
+}
+
+struct apk_applet *apk_applet_find(const char *name)
+{
+ struct apk_applet *a;
+
+ apk_applet_foreach(a) {
+ if (strcmp(name, a->name) == 0)
+ return a;
+ }
+ return NULL;
+}
+
static inline int is_group(struct apk_applet *applet, const char *topic)
{
if (!applet) return strcasecmp(topic, "apk") == 0;
@@ -19,7 +50,7 @@ static inline int is_group(struct apk_applet *applet, const char *topic)
return 0;
}
-void apk_help(struct apk_applet *applet)
+void apk_applet_help(struct apk_applet *applet, struct apk_out *out)
{
#include "help.h"
@@ -31,16 +62,15 @@ void apk_help(struct apk_applet *applet)
uncompress((unsigned char*) buf, &len, compressed_help, sizeof compressed_help);
for (ptr = buf; *ptr && ptr < &buf[len]; ptr = msg + strlen(msg) + 1) {
msg = ptr + strlen(ptr) + 1;
-
if (is_group(applet, ptr)) {
fputc('\n', stdout);
fwrite(msg, strlen(msg), 1, stdout);
num++;
}
}
- if (num == 0) apk_error("Help not found");
+ if (num == 0) apk_err(out, "Help not found");
#else
fputc('\n', stdout);
- apk_error("This apk-tools has been built without help");
+ apk_err(out, "This apk-tools has been built without help");
#endif
}
diff --git a/src/commit.c b/src/commit.c
index 6cc60b7..640c135 100644
--- a/src/commit.c
+++ b/src/commit.c
@@ -28,6 +28,7 @@ static inline int pkg_available(struct apk_database *db, struct apk_package *pkg
static int print_change(struct apk_database *db, struct apk_change *change,
int cur, int total)
{
+ struct apk_out *out = &db->ctx->out;
struct apk_name *name;
struct apk_package *oldpkg = change->old_pkg;
struct apk_package *newpkg = change->new_pkg;
@@ -73,18 +74,18 @@ static int print_change(struct apk_database *db, struct apk_change *change,
return FALSE;
if (oneversion) {
- apk_message("%s %s %s" BLOB_FMT " (" BLOB_FMT ")",
- status, msg,
- name->name,
- BLOB_PRINTF(db->repo_tags[change->new_repository_tag].tag),
- BLOB_PRINTF(*oneversion));
+ apk_msg(out, "%s %s %s" BLOB_FMT " (" BLOB_FMT ")",
+ status, msg,
+ name->name,
+ BLOB_PRINTF(db->repo_tags[change->new_repository_tag].tag),
+ BLOB_PRINTF(*oneversion));
} else {
- apk_message("%s %s %s" BLOB_FMT " (" BLOB_FMT " -> " BLOB_FMT ")",
- status, msg,
- name->name,
- BLOB_PRINTF(db->repo_tags[change->new_repository_tag].tag),
- BLOB_PRINTF(*oldpkg->version),
- BLOB_PRINTF(*newpkg->version));
+ apk_msg(out, "%s %s %s" BLOB_FMT " (" BLOB_FMT " -> " BLOB_FMT ")",
+ status, msg,
+ name->name,
+ BLOB_PRINTF(db->repo_tags[change->new_repository_tag].tag),
+ BLOB_PRINTF(*oldpkg->version),
+ BLOB_PRINTF(*newpkg->version));
}
return TRUE;
}
@@ -126,13 +127,13 @@ static void progress_cb(void *ctx, size_t installed_bytes)
prog->total.bytes + prog->total.packages);
}
-static int dump_packages(struct apk_changeset *changeset,
+static int dump_packages(struct apk_out *out, struct apk_changeset *changeset,
int (*cmp)(struct apk_change *change),
const char *msg)
{
struct apk_change *change;
struct apk_name *name;
- struct apk_indent indent = { .indent = 2 };
+ struct apk_indent indent = { .out = out, .indent = 2 };
int match = 0;
foreach_array_item(change, changeset->changes) {
@@ -231,17 +232,18 @@ static int run_commit_hook(void *ctx, int dirfd, const char *file)
static char *const commit_hook_str[] = { "pre-commit", "post-commit" };
struct apk_commit_hook *hook = (struct apk_commit_hook *) ctx;
struct apk_database *db = hook->db;
+ struct apk_out *out = &db->ctx->out;
char fn[PATH_MAX], *argv[] = { fn, (char *) commit_hook_str[hook->type], NULL };
if (file[0] == '.') return 0;
- if ((db->flags & (APK_NO_SCRIPTS | APK_SIMULATE)) != 0) return 0;
+ if ((db->ctx->flags & (APK_NO_SCRIPTS | APK_SIMULATE)) != 0) return 0;
snprintf(fn, sizeof(fn), "etc/apk/commit_hooks.d" "/%s", file);
- if ((db->flags & APK_NO_COMMIT_HOOKS) != 0) {
- apk_message("Skipping: %s %s", fn, commit_hook_str[hook->type]);
+ if ((db->ctx->flags & APK_NO_COMMIT_HOOKS) != 0) {
+ apk_msg(out, "Skipping: %s %s", fn, commit_hook_str[hook->type]);
return 0;
}
- if (apk_verbosity >= 2) apk_message("Executing: %s %s", fn, commit_hook_str[hook->type]);
+ apk_dbg(out, "Executing: %s %s", fn, commit_hook_str[hook->type]);
if (apk_db_run_script(db, fn, argv) < 0 && hook->type == PRE_COMMIT_HOOK)
return -2;
@@ -260,7 +262,8 @@ int apk_solver_commit_changeset(struct apk_database *db,
struct apk_changeset *changeset,
struct apk_dependency_array *world)
{
- struct progress prog = { .prog = db->progress };
+ struct apk_out *out = &db->ctx->out;
+ struct progress prog = { .prog = db->ctx->progress };
struct apk_change *change;
char buf[32];
const char *size_unit;
@@ -269,8 +272,8 @@ int apk_solver_commit_changeset(struct apk_database *db,
assert(world);
if (apk_db_check_world(db, world) != 0) {
- apk_error("Not committing changes due to missing repository tags. "
- "Use --force-broken-world to override.");
+ apk_err(out, "Not committing changes due to missing repository tags. "
+ "Use --force-broken-world to override.");
return -1;
}
@@ -287,18 +290,18 @@ int apk_solver_commit_changeset(struct apk_database *db,
}
size_unit = apk_get_human_size(llabs(size_diff), &humanized);
- if ((apk_verbosity > 1 || (db->flags & APK_INTERACTIVE)) &&
- !(db->flags & APK_SIMULATE)) {
- r = dump_packages(changeset, cmp_remove,
+ if ((apk_out_verbosity(out) > 1 || (db->ctx->flags & APK_INTERACTIVE)) &&
+ !(db->ctx->flags & APK_SIMULATE)) {
+ r = dump_packages(out, changeset, cmp_remove,
"The following packages will be REMOVED");
- r += dump_packages(changeset, cmp_downgrade,
+ r += dump_packages(out, changeset, cmp_downgrade,
"The following packages will be DOWNGRADED");
- if (r || (db->flags & APK_INTERACTIVE) || apk_verbosity > 2) {
- r += dump_packages(changeset, cmp_new,
+ if (r || (db->ctx->flags & APK_INTERACTIVE) || apk_out_verbosity(out) > 2) {
+ r += dump_packages(out, changeset, cmp_new,
"The following NEW packages will be installed");
- r += dump_packages(changeset, cmp_upgrade,
+ r += dump_packages(out, changeset, cmp_upgrade,
"The following packages will be upgraded");
- r += dump_packages(changeset, cmp_reinstall,
+ r += dump_packages(out, changeset, cmp_reinstall,
"The following packages will be reinstalled");
printf("After this operation, %lld %s of %s.\n",
(long long)humanized,
@@ -307,7 +310,7 @@ int apk_solver_commit_changeset(struct apk_database *db,
"disk space will be freed" :
"additional disk space will be used");
}
- if (r > 0 && (db->flags & APK_INTERACTIVE)) {
+ if (r > 0 && (db->ctx->flags & APK_INTERACTIVE)) {
printf("Do you want to continue [Y/n]? ");
fflush(stdout);
r = fgetc(stdin);
@@ -328,7 +331,7 @@ int apk_solver_commit_changeset(struct apk_database *db,
prog.pkg = change->new_pkg;
progress_cb(&prog, 0);
- if (!(db->flags & APK_SIMULATE) &&
+ if (!(db->ctx->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,
@@ -357,18 +360,18 @@ all_done:
errors > 1 ? "s" : "");
else
strcpy(buf, "OK:");
- if (apk_verbosity > 1) {
- apk_message("%s %d packages, %d dirs, %d files, %zu MiB",
- buf,
- db->installed.stats.packages,
- db->installed.stats.dirs,
- db->installed.stats.files,
- db->installed.stats.bytes / (1024 * 1024));
+ if (apk_out_verbosity(out) > 1) {
+ apk_msg(out, "%s %d packages, %d dirs, %d files, %zu MiB",
+ buf,
+ db->installed.stats.packages,
+ db->installed.stats.dirs,
+ db->installed.stats.files,
+ db->installed.stats.bytes / (1024 * 1024));
} else {
- apk_message("%s %zu MiB in %d packages",
- buf,
- db->installed.stats.bytes / (1024 * 1024),
- db->installed.stats.packages);
+ apk_msg(out, "%s %zu MiB in %d packages",
+ buf,
+ db->installed.stats.bytes / (1024 * 1024),
+ db->installed.stats.packages);
}
}
return errors;
@@ -599,6 +602,7 @@ void apk_solver_print_errors(struct apk_database *db,
struct apk_changeset *changeset,
struct apk_dependency_array *world)
{
+ struct apk_out *out = &db->ctx->out;
struct print_state ps;
struct apk_change *change;
struct apk_dependency *p;
@@ -640,7 +644,7 @@ void apk_solver_print_errors(struct apk_database *db,
* any other selected version. or all of them with -v.
*/
- apk_error("unable to select packages:");
+ apk_err(out, "unable to select packages:");
/* Construct information about names */
foreach_array_item(change, changeset->changes) {
@@ -655,6 +659,7 @@ void apk_solver_print_errors(struct apk_database *db,
/* Analyze is package, and missing names referred to */
ps = (struct print_state) {
+ .i.out = out,
.db = db,
.world = world,
};
@@ -675,12 +680,13 @@ int apk_solver_commit(struct apk_database *db,
unsigned short solver_flags,
struct apk_dependency_array *world)
{
+ struct apk_out *out = &db->ctx->out;
struct apk_changeset changeset = {};
int r;
if (apk_db_check_world(db, world) != 0) {
- apk_error("Not committing changes due to missing repository tags. "
- "Use --force-broken-world to override.");
+ apk_err(out, "Not committing changes due to missing repository tags. "
+ "Use --force-broken-world to override.");
return -1;
}
diff --git a/src/context.c b/src/context.c
new file mode 100644
index 0000000..f7b745c
--- /dev/null
+++ b/src/context.c
@@ -0,0 +1,27 @@
+/* context.c - Alpine Package Keeper (APK)
+ *
+ * Copyright (C) 2005-2008 Natanael Copa <n@tanael.org>
+ * Copyright (C) 2008-2020 Timo Teräs <timo.teras@iki.fi>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#include "apk_context.h"
+
+void apk_ctx_init(struct apk_ctx *ac)
+{
+ memset(ac, 0, sizeof *ac);
+ apk_string_array_init(&ac->repository_list);
+ apk_string_array_init(&ac->private_keys);
+ apk_out_reset(&ac->out);
+ ac->out.out = stdout;
+ ac->out.err = stderr;
+ ac->out.verbosity = 1;
+}
+
+void apk_ctx_free(struct apk_ctx *ac)
+{
+ apk_string_array_free(&ac->repository_list);
+ apk_string_array_free(&ac->private_keys);
+}
diff --git a/src/database.c b/src/database.c
index 946155d..f31e840 100644
--- a/src/database.c
+++ b/src/database.c
@@ -47,10 +47,7 @@ enum {
APK_DIR_REMOVE
};
-int apk_verbosity = 1;
-
-static apk_blob_t tmpprefix = { .len=8, .ptr = ".apknew." };
-
+static apk_blob_t tmpprefix = APK_BLOB_STRLIT(".apknew.");
static const char * const apkindex_tar_gz = "APKINDEX.tar.gz";
static const char * const apk_static_cache_dir = "var/cache/apk";
static const char * const apk_world_file = "etc/apk/world";
@@ -242,7 +239,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 (!(db->flags & APK_SIMULATE))
+ if (!(db->ctx->flags & APK_SIMULATE))
mkdirat(db->root_fd, dir->name, newmode);
dir->created = 1;
dir->update_permissions = 1;
@@ -257,7 +254,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 (!(db->flags & APK_SIMULATE) &&
+ if (!(db->ctx->flags & APK_SIMULATE) &&
unlinkat(db->root_fd, dir->name, AT_REMOVEDIR) != 0)
;
}
@@ -609,6 +606,7 @@ int apk_cache_download(struct apk_database *db, struct apk_repository *repo,
struct apk_package *pkg, int verify, int autoupdate,
apk_progress_cb cb, void *cb_ctx)
{
+ struct apk_out *out = &db->ctx->out;
struct stat st = {0};
struct apk_url_print urlp;
struct apk_istream *is;
@@ -629,18 +627,18 @@ int apk_cache_download(struct apk_database *db, struct apk_repository *repo,
r = apk_repo_format_real_url(db->arch, repo, pkg, url, sizeof(url), &urlp);
if (r < 0) return r;
- if (autoupdate && !(db->force & APK_FORCE_REFRESH)) {
+ if (autoupdate && !(db->ctx->force & APK_FORCE_REFRESH)) {
if (fstatat(db->cache_fd, cacheitem, &st, 0) == 0 &&
- now - st.st_mtime <= db->cache_max_age)
+ now - st.st_mtime <= db->ctx->cache_max_age)
return -EALREADY;
}
- apk_message("fetch " URL_FMT, URL_PRINTF(urlp));
+ apk_msg(out, "fetch " URL_FMT, URL_PRINTF(urlp));
- if (db->flags & APK_SIMULATE) return 0;
+ if (db->ctx->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, db->flags & APK_ALLOW_UNTRUSTED);
+ apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd, db->ctx->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);
@@ -747,6 +745,7 @@ err:
int apk_db_index_read(struct apk_database *db, struct apk_istream *is, int repo)
{
+ struct apk_out *out = &db->ctx->out;
struct apk_package *pkg = NULL;
struct apk_installed_package *ipkg = NULL;
struct apk_db_dir_instance *diri = NULL;
@@ -782,7 +781,7 @@ int apk_db_index_read(struct apk_database *db, struct apk_istream *is, int repo)
}
if (apk_db_pkg_add(db, pkg) == NULL) {
- apk_error("Installed database load failed");
+ apk_err(out, "Installed database load failed");
return -1;
}
pkg = NULL;
@@ -870,13 +869,13 @@ int apk_db_index_read(struct apk_database *db, struct apk_istream *is, int repo)
case 's': ipkg->broken_script = 1; break;
case 'x': ipkg->broken_xattr = 1; break;
default:
- if (!(db->force & APK_FORCE_OLD_APK))
+ if (!(db->ctx->force & APK_FORCE_OLD_APK))
goto old_apk_tools;
}
}
break;
default:
- if (r != 0 && !(db->force & APK_FORCE_OLD_APK))
+ if (r != 0 && !(db->ctx->force & APK_FORCE_OLD_APK))
goto old_apk_tools;
/* Installed. So mark the package as installable. */
pkg->filename = NULL;
@@ -888,10 +887,10 @@ int apk_db_index_read(struct apk_database *db, struct apk_istream *is, int repo)
return 0;
old_apk_tools:
/* Installed db should not have unsupported fields */
- apk_error("This apk-tools is too old to handle installed packages");
+ apk_err(out, "This apk-tools is too old to handle installed packages");
goto err;
bad_entry:
- apk_error("FDB format error (line %d, entry '%c')", lineno, field);
+ apk_err(out, "FDB format error (line %d, entry '%c')", lineno, field);
err:
apk_istream_close(is);
return -1;
@@ -928,8 +927,9 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) {
pkg = ipkg->pkg;
r = apk_pkg_write_index_entry(pkg, os);
- if (r < 0)
+ if (r < 0) {
return r;
+ }
if (ipkg->replaces->num) {
apk_blob_push_blob(&bbuf, APK_BLOB_STR("r:"));
@@ -1192,7 +1192,7 @@ static int write_index_entry(apk_hash_item item, void *ctx)
return r;
if (apk_ostream_write(iwctx->os, "\n", 1) != 1)
- return -EIO;
+ return apk_ostream_cancel(iwctx->os, -EIO);
iwctx->count++;
return 0;
@@ -1390,6 +1390,7 @@ static void mark_in_cache(struct apk_database *db, int dirfd, const char *name,
static int add_repos_from_file(void *ctx, int dirfd, const char *file)
{
struct apk_database *db = (struct apk_database *) ctx;
+ struct apk_out *out = &db->ctx->out;
apk_blob_t blob;
if (dirfd != AT_FDCWD && dirfd != db->root_fd) {
@@ -1401,8 +1402,8 @@ static int add_repos_from_file(void *ctx, int dirfd, const char *file)
blob = apk_blob_from_file(dirfd, file);
if (APK_BLOB_IS_NULL(blob)) {
if (dirfd != AT_FDCWD) return 0;
- apk_error("failed to read repositories: %s", file);
- apk_message("NOTE: --repositories-file is relative to the startup directory since apk 2.12.0_rc2");
+ apk_err(out, "failed to read repositories: %s", file);
+ apk_msg(out, "NOTE: --repositories-file is relative to the startup directory since apk 2.12.0_rc2");
return -ENOENT;
}
@@ -1507,8 +1508,9 @@ void apk_db_init(struct apk_database *db)
db->root_fd = -1;
}
-int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
+int apk_db_open(struct apk_database *db, struct apk_ctx *ac)
{
+ struct apk_out *out = &ac->out;
const char *msg = NULL;
struct statfs stfs;
apk_blob_t blob;
@@ -1517,31 +1519,31 @@ 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 (dbopts->flags & APK_SIMULATE) {
- dbopts->open_flags &= ~(APK_OPENF_CREATE | APK_OPENF_WRITE);
- dbopts->open_flags |= APK_OPENF_READ;
- }
- if (dbopts->open_flags == 0) {
+ db->ctx = ac;
+ if (ac->open_flags == 0) {
msg = "Invalid open flags (internal error)";
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) &&
- !(dbopts->flags & APK_NO_NETWORK))
+ 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 (!dbopts->cache_dir) dbopts->cache_dir = "etc/apk/cache";
+ 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, dbopts->cache_dir);
+ apk_db_setup_repositories(db, ac->cache_dir);
- db->cache_max_age = dbopts->cache_max_age ?: 4*60*60; /* 4 hours default */
- db->root = strdup(dbopts->root ?: "/");
- db->root_fd = openat(AT_FDCWD, db->root, O_RDONLY | O_CLOEXEC);
- if (db->root_fd < 0 && (dbopts->open_flags & APK_OPENF_CREATE)) {
- mkdirat(AT_FDCWD, db->root, 0755);
- db->root_fd = openat(AT_FDCWD, db->root, O_RDONLY | O_CLOEXEC);
+ 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";
@@ -1551,8 +1553,8 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
stfs.f_type == TMPFS_MAGIC)
db->permanent = 0;
- if (dbopts->root && dbopts->arch) {
- db->arch = apk_atomize(&db->atoms, APK_BLOB_STR(dbopts->arch));
+ if (ac->root && ac->arch) {
+ db->arch = apk_atomize(&db->atoms, APK_BLOB_STR(ac->arch));
write_arch = TRUE;
} else {
apk_blob_t arch;
@@ -1568,11 +1570,11 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
apk_id_cache_init(&db->id_cache, db->root_fd);
- if (dbopts->open_flags & APK_OPENF_WRITE) {
+ if (ac->open_flags & APK_OPENF_WRITE) {
db->lock_fd = openat(db->root_fd, apk_lock_file,
O_CREAT | O_RDWR | O_CLOEXEC, 0600);
if (db->lock_fd < 0 && errno == ENOENT &&
- (dbopts->open_flags & APK_OPENF_CREATE)) {
+ (ac->open_flags & APK_OPENF_CREATE)) {
r = apk_db_create(db);
if (r != 0) {
msg = "Unable to create database";
@@ -1584,16 +1586,16 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
if (db->lock_fd < 0 ||
flock(db->lock_fd, LOCK_EX | LOCK_NB) < 0) {
msg = "Unable to lock database";
- if (dbopts->lock_wait) {
+ if (ac->lock_wait) {
struct sigaction sa, old_sa;
- apk_message("Waiting for repository lock");
+ apk_msg(out, "Waiting for repository lock");
memset(&sa, 0, sizeof sa);
sa.sa_handler = handle_alarm;
sa.sa_flags = SA_ONESHOT;
sigaction(SIGALRM, &sa, &old_sa);
- alarm(dbopts->lock_wait);
+ alarm(ac->lock_wait);
if (flock(db->lock_fd, LOCK_EX) < 0)
goto ret_errno;
@@ -1606,7 +1608,7 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
apk_blob_to_file(db->root_fd, apk_arch_file, *db->arch, APK_BTF_ADD_EOL);
/* mount /proc */
- if (asprintf(&db->root_proc_dir, "%s/proc", db->root) == -1)
+ if (asprintf(&db->root_proc_dir, "%s/proc", db->ctx->root) == -1)
goto ret_errno;
if (statfs(db->root_proc_dir, &stfs) != 0) {
if (errno == ENOENT) mkdir(db->root_proc_dir, 0555);
@@ -1628,21 +1630,21 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
add_protected_paths_from_file, db);
/* figure out where to have the cache */
- fd = openat(db->root_fd, dbopts->cache_dir, O_RDONLY | O_CLOEXEC);
+ fd = openat(db->root_fd, ac->cache_dir, O_RDONLY | O_CLOEXEC);
if (fd >= 0 && fstatfs(fd, &stfs) == 0) {
- db->cache_dir = dbopts->cache_dir;
+ db->cache_dir = ac->cache_dir;
db->cache_fd = fd;
db->cache_remount_flags = map_statfs_flags(stfs.f_flags);
- if ((dbopts->open_flags & (APK_OPENF_WRITE | APK_OPENF_CACHE_WRITE)) &&
+ if ((ac->open_flags & (APK_OPENF_WRITE | APK_OPENF_CACHE_WRITE)) &&
(db->cache_remount_flags & MS_RDONLY) != 0) {
/* remount cache read/write */
db->cache_remount_dir = find_mountpoint(db->root_fd, db->cache_dir);
if (db->cache_remount_dir == NULL) {
- apk_warning("Unable to find cache directory mount point");
+ apk_warn(out, "Unable to find cache directory mount point");
} else if (mount(0, db->cache_remount_dir, 0, MS_REMOUNT | (db->cache_remount_flags & ~MS_RDONLY), 0) != 0) {
free(db->cache_remount_dir);
db->cache_remount_dir = NULL;
- apk_error("Unable to remount cache read/write");
+ apk_err(out, "Unable to remount cache read/write");
r = EROFS;
goto ret_r;
}
@@ -1659,53 +1661,51 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
}
}
- db->keys_fd = openat(db->root_fd,
- dbopts->keys_dir ?: "etc/apk/keys",
- O_RDONLY | O_CLOEXEC);
+ db->keys_fd = openat(db->root_fd, ac->keys_dir, O_RDONLY | O_CLOEXEC);
- r = adb_trust_init(&db->trust, dup(db->keys_fd), dbopts->private_keys);
+ 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->flags & APK_OVERLAY_FROM_STDIN) {
- db->flags &= ~APK_OVERLAY_FROM_STDIN;
+ 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));
}
- r = apk_db_read_state(db, dbopts->open_flags);
- if (r == -ENOENT && (dbopts->open_flags & APK_OPENF_CREATE)) {
+ r = apk_db_read_state(db, ac->open_flags);
+ if (r == -ENOENT && (ac->open_flags & APK_OPENF_CREATE)) {
r = apk_db_create(db);
if (r != 0) {
msg = "Unable to create database";
goto ret_r;
}
- r = apk_db_read_state(db, dbopts->open_flags);
+ r = apk_db_read_state(db, ac->open_flags);
}
if (r != 0) {
msg = "Unable to read database state";
goto ret_r;
}
- if (!(dbopts->open_flags & APK_OPENF_NO_INSTALLED_REPO)) {
+ if (!(ac->open_flags & APK_OPENF_NO_INSTALLED_REPO)) {
if (apk_db_cache_active(db)) {
apk_db_index_read(db, apk_istream_from_file(db->cache_fd, "installed"), -2);
}
}
- if (!(dbopts->open_flags & APK_OPENF_NO_SYS_REPOS)) {
+ if (!(ac->open_flags & APK_OPENF_NO_SYS_REPOS)) {
char **repo;
- foreach_array_item(repo, dbopts->repository_list)
+ foreach_array_item(repo, ac->repository_list)
apk_db_add_repository(db, APK_BLOB_STR(*repo));
- if (dbopts->repositories_file == NULL) {
+ if (ac->repositories_file == NULL) {
add_repos_from_file(db, db->root_fd, "etc/apk/repositories");
apk_dir_foreach_file(openat(db->root_fd, "etc/apk/repositories.d", O_RDONLY | O_CLOEXEC),
add_repos_from_file, db);
} else {
- add_repos_from_file(db, AT_FDCWD, dbopts->repositories_file);
+ add_repos_from_file(db, AT_FDCWD, ac->repositories_file);
}
if (db->repo_update_counter)
@@ -1714,16 +1714,15 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
apk_hash_foreach(&db->available.names, apk_db_name_rdepends, db);
}
- if (apk_db_cache_active(db) && (dbopts->open_flags & (APK_OPENF_NO_REPOS|APK_OPENF_NO_INSTALLED)) == 0)
+ if (apk_db_cache_active(db) && (ac->open_flags & (APK_OPENF_NO_REPOS|APK_OPENF_NO_INSTALLED)) == 0)
apk_db_cache_foreach_item(db, mark_in_cache);
db->open_complete = 1;
if (db->compat_newfeatures) {
- apk_warning("This apk-tools is OLD! Some packages %s.",
- db->compat_notinstallable ?
- "are not installable" :
- "might not function properly");
+ apk_warn(out,
+ "This apk-tools is OLD! Some packages %s.",
+ db->compat_notinstallable ? "are not installable" : "might not function properly");
}
return 0;
@@ -1732,7 +1731,7 @@ ret_errno:
r = -errno;
ret_r:
if (msg != NULL)
- apk_error("%s: %s", msg, strerror(-r));
+ apk_err(out, "%s: %s", msg, strerror(-r));
apk_db_close(db);
return r;
@@ -1745,14 +1744,15 @@ struct write_ctx {
int apk_db_write_config(struct apk_database *db)
{
+ struct apk_out *out = &db->ctx->out;
struct apk_ostream *os;
int r;
- if ((db->flags & APK_SIMULATE) || db->root == NULL)
+ if ((db->ctx->flags & APK_SIMULATE) || db->ctx->root == NULL)
return 0;
if (db->lock_fd == 0) {
- apk_error("Refusing to write db without write lock!");
+ apk_err(out, "Refusing to write db without write lock!");
return -1;
}
@@ -1837,16 +1837,10 @@ void apk_db_close(struct apk_database *db)
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);
- if (db->root != NULL)
- free(db->root);
+ 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);
}
int apk_db_get_tag_id(struct apk_database *db, apk_blob_t tag)
@@ -1927,6 +1921,7 @@ int apk_db_fire_triggers(struct apk_database *db)
int apk_db_run_script(struct apk_database *db, char *fn, char **argv)
{
+ struct apk_out *out = &db->ctx->out;
int status;
pid_t pid;
static char * const environment[] = {
@@ -1936,7 +1931,7 @@ int apk_db_run_script(struct apk_database *db, char *fn, char **argv)
pid = fork();
if (pid == -1) {
- apk_error("%s: fork: %s", basename(fn), strerror(errno));
+ apk_err(out, "%s: fork: %s", basename(fn), strerror(errno));
return -2;
}
if (pid == 0) {
@@ -1947,7 +1942,7 @@ int apk_db_run_script(struct apk_database *db, char *fn, char **argv)
}
waitpid(pid, &status, 0);
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
- apk_error("%s: script exited with error %d", basename(fn), WEXITSTATUS(status));
+ apk_err(out, "%s: script exited with error %d", basename(fn), WEXITSTATUS(status));
return -1;
}
return 0;
@@ -1998,7 +1993,7 @@ void apk_db_update_directory_permissions(struct apk_database *db)
int apk_db_cache_active(struct apk_database *db)
{
- return db->cache_dir != apk_static_cache_dir;
+ return db->ctx->cache_dir != apk_static_cache_dir;
}
struct foreach_cache_item_ctx {
@@ -2052,10 +2047,11 @@ int apk_db_permanent(struct apk_database *db)
int apk_db_check_world(struct apk_database *db, struct apk_dependency_array *world)
{
+ struct apk_out *out = &db->ctx->out;
struct apk_dependency *dep;
int bad = 0, tag;
- if (db->force & APK_FORCE_BROKEN_WORLD)
+ if (db->ctx->force & APK_FORCE_BROKEN_WORLD)
return 0;
foreach_array_item(dep, world) {
@@ -2064,8 +2060,8 @@ int apk_db_check_world(struct apk_database *db, struct apk_dependency_array *wor
continue;
if (tag < 0)
tag = 0;
- apk_warning("The repository tag for world dependency '%s" BLOB_FMT "' does not exist",
- dep->name->name, BLOB_PRINTF(db->repo_tags[tag].tag));
+ apk_warn(out, "The repository tag for world dependency '%s" BLOB_FMT "' does not exist",
+ dep->name->name, BLOB_PRINTF(db->repo_tags[tag].tag));
bad++;
}
@@ -2138,14 +2134,15 @@ 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_out *out = &db->ctx->out;
struct apk_url_print urlp;
- int r, verify = (db->flags & APK_ALLOW_UNTRUSTED) ? APK_SIGN_NONE : APK_SIGN_VERIFY;
+ int r, verify = (db->ctx->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;
if (r != 0) {
apk_url_parse(&urlp, repo->url);
- apk_error(URL_FMT ": %s", URL_PRINTF(urlp), apk_error_str(r));
+ apk_err(out, URL_FMT ": %s", URL_PRINTF(urlp), apk_error_str(r));
db->repo_update_errors++;
} else {
db->repo_update_counter++;
@@ -2196,7 +2193,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, db->flags & APK_ALLOW_UNTRUSTED);
+ 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);
apk_sign_ctx_free(&ctx.sctx);
@@ -2221,6 +2218,7 @@ int apk_db_index_read_file(struct apk_database *db, const char *file, int repo)
int apk_db_add_repository(apk_database_t _db, apk_blob_t _repository)
{
struct apk_database *db = _db.db;
+ struct apk_out *out = &db->ctx->out;
struct apk_repository *repo;
struct apk_url_print urlp;
apk_blob_t brepo, btag;
@@ -2262,11 +2260,11 @@ 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 (!(db->flags & APK_NO_NETWORK))
+ if (!(db->ctx->flags & APK_NO_NETWORK))
db->available_repos |= BIT(repo_num);
- if (db->flags & APK_NO_CACHE) {
+ if (db->ctx->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));
+ if (r == 0) apk_msg(out, "fetch " URL_FMT, URL_PRINTF(urlp));
} else {
if (db->autoupdate) apk_repository_update(db, repo);
r = apk_repo_format_cache_index(APK_BLOB_BUF(buf), repo);
@@ -2282,7 +2280,7 @@ int apk_db_add_repository(apk_database_t _db, apk_blob_t _repository)
if (r != 0) {
apk_url_parse(&urlp, repo->url);
- apk_warning("Ignoring " URL_FMT ": %s", URL_PRINTF(urlp), apk_error_str(r));
+ apk_warn(out, "Ignoring " URL_FMT ": %s", URL_PRINTF(urlp), apk_error_str(r));
db->available_repos &= ~BIT(repo_num);
r = 0;
} else {
@@ -2394,6 +2392,7 @@ static int apk_db_install_archive_entry(void *_ctx,
static const char dot1[] = "/./", dot2[] = "/../";
struct install_ctx *ctx = (struct install_ctx *) _ctx;
struct apk_database *db = ctx->db;
+ struct apk_out *out = &db->ctx->out;
struct apk_package *pkg = ctx->pkg, *opkg;
struct apk_dependency *dep;
struct apk_installed_package *ipkg = pkg->ipkg;
@@ -2437,8 +2436,8 @@ static int apk_db_install_archive_entry(void *_ctx,
strncmp(ae->name, &dot1[1], 2) == 0 ||
strncmp(ae->name, &dot2[1], 3) == 0 ||
strstr(ae->name, dot1) || strstr(ae->name, dot2)) {
- apk_warning(PKG_VER_FMT": ignoring malicious file %s",
- PKG_VER_PRINTF(pkg), ae->name);
+ apk_warn(out, PKG_VER_FMT": ignoring malicious file %s",
+ PKG_VER_PRINTF(pkg), ae->name);
ipkg->broken_files = 1;
return 0;
}
@@ -2458,8 +2457,8 @@ static int apk_db_install_archive_entry(void *_ctx,
diri = ctx->diri = find_diri(ipkg, bdir, diri, &ctx->file_diri_node);
if (diri == NULL) {
if (!APK_BLOB_IS_NULL(bdir)) {
- apk_error(PKG_VER_FMT": "BLOB_FMT": no dirent in archive",
- PKG_VER_PRINTF(pkg), BLOB_PRINTF(name));
+ apk_err(out, PKG_VER_FMT": "BLOB_FMT": no dirent in archive",
+ PKG_VER_PRINTF(pkg), BLOB_PRINTF(name));
ipkg->broken_files = 1;
return 0;
}
@@ -2493,8 +2492,8 @@ static int apk_db_install_archive_entry(void *_ctx,
} while (0);
if (!link_target_file) {
- apk_error(PKG_VER_FMT": "BLOB_FMT": no hard link target (%s) in archive",
- PKG_VER_PRINTF(pkg), BLOB_PRINTF(name), ae->link_target);
+ apk_err(out, PKG_VER_FMT": "BLOB_FMT": no hard link target (%s) in archive",
+ PKG_VER_PRINTF(pkg), BLOB_PRINTF(name), ae->link_target);
ipkg->broken_files = 1;
return 0;
}
@@ -2539,14 +2538,14 @@ static int apk_db_install_archive_entry(void *_ctx,
if (pkg_prio >= 0)
break;
- if (!(db->force & APK_FORCE_OVERWRITE)) {
- apk_error(PKG_VER_FMT": trying to overwrite %s owned by "PKG_VER_FMT".",
- PKG_VER_PRINTF(pkg), ae->name, PKG_VER_PRINTF(opkg));
+ if (!(db->ctx->force & APK_FORCE_OVERWRITE)) {
+ apk_err(out, PKG_VER_FMT": trying to overwrite %s owned by "PKG_VER_FMT".",
+ PKG_VER_PRINTF(pkg), ae->name, PKG_VER_PRINTF(opkg));
ipkg->broken_files = 1;
return 0;
}
- apk_warning(PKG_VER_FMT": overwriting %s owned by "PKG_VER_FMT".",
- PKG_VER_PRINTF(pkg), ae->name, PKG_VER_PRINTF(opkg));
+ apk_warn(out, PKG_VER_FMT": overwriting %s owned by "PKG_VER_FMT".",
+ PKG_VER_PRINTF(pkg), ae->name, PKG_VER_PRINTF(opkg));
} while (0);
}
@@ -2555,8 +2554,7 @@ static int apk_db_install_archive_entry(void *_ctx,
file = apk_db_file_new(diri, bfile, &ctx->file_diri_node);
}
- if (apk_verbosity >= 3)
- apk_message("%s", ae->name);
+ apk_dbg2(out, "%s", ae->name);
/* Extract the file with temporary name */
file->acl = apk_db_acl_atomize(db, ae->mode, ae->uid, ae->gid, &ae->xattr_csum);
@@ -2564,7 +2562,7 @@ static int apk_db_install_archive_entry(void *_ctx,
db->root_fd, ae,
format_tmpname(pkg, file, tmpname_file),
format_tmpname(pkg, link_target_file, tmpname_link_target),
- is, extract_cb, ctx, db->extract_flags);
+ is, extract_cb, ctx, db->extract_flags, out);
switch (r) {
case 0:
@@ -2575,9 +2573,10 @@ static int apk_db_install_archive_entry(void *_ctx,
memcpy(&file->csum, &ae->csum, sizeof file->csum);
/* only warn once per package */
if (file->csum.type == APK_CHECKSUM_NONE && !ctx->missing_checksum) {
- apk_warning(PKG_VER_FMT": support for packages without embedded "
- "checksums will be dropped in apk-tools 3.",
- PKG_VER_PRINTF(pkg));
+ apk_warn(out,
+ PKG_VER_FMT": support for packages without embedded "
+ "checksums will be dropped in apk-tools 3.",
+ PKG_VER_PRINTF(pkg));
ipkg->broken_files = 1;
ctx->missing_checksum = 1;
}
@@ -2592,8 +2591,7 @@ static int apk_db_install_archive_entry(void *_ctx,
break;
}
} else {
- if (apk_verbosity >= 3)
- apk_message("%s (dir)", ae->name);
+ apk_dbg2(out, "%s (dir)", ae->name);
if (name.ptr[name.len-1] == '/')
name.len--;
@@ -2614,6 +2612,7 @@ static void apk_db_purge_pkg(struct apk_database *db,
struct apk_installed_package *ipkg,
int is_installed)
{
+ struct apk_out *out = &db->ctx->out;
struct apk_db_dir_instance *diri;
struct apk_db_file *file;
struct apk_db_file_hash_key key;
@@ -2637,13 +2636,12 @@ 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) ||
- (db->flags & APK_PURGE) ||
+ (db->ctx->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))
unlinkat(db->root_fd, name, 0);
- if (apk_verbosity >= 3)
- apk_message("%s", name);
+ apk_dbg2(out, "%s", name);
__hlist_del(fc, &diri->owned_files.first);
if (is_installed) {
apk_hash_delete_hashed(&db->installed.files, APK_BLOB_BUF(&key), hash);
@@ -2659,6 +2657,7 @@ static void apk_db_purge_pkg(struct apk_database *db,
static void apk_db_migrate_files(struct apk_database *db,
struct apk_installed_package *ipkg)
{
+ struct apk_out *out = &db->ctx->out;
struct apk_db_dir_instance *diri;
struct apk_db_dir *dir;
struct apk_db_file *file, *ofile;
@@ -2715,7 +2714,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 ((db->flags & APK_CLEAN_PROTECTED) ||
+ if ((db->ctx->flags & APK_CLEAN_PROTECTED) ||
(file->csum.type != APK_CHECKSUM_NONE &&
apk_checksum_compare(&file->csum, &fi.csum) == 0)) {
unlinkat(db->root_fd, tmpname, 0);
@@ -2725,9 +2724,9 @@ static void apk_db_migrate_files(struct apk_database *db,
DIR_FILE_PRINTF(diri->dir, file));
if (renameat(db->root_fd, tmpname,
db->root_fd, name) != 0) {
- apk_error(PKG_VER_FMT": failed to rename %s to %s.",
- PKG_VER_PRINTF(ipkg->pkg),
- tmpname, name);
+ apk_err(out, PKG_VER_FMT": failed to rename %s to %s.",
+ PKG_VER_PRINTF(ipkg->pkg),
+ tmpname, name);
ipkg->broken_files = 1;
}
}
@@ -2736,8 +2735,8 @@ static void apk_db_migrate_files(struct apk_database *db,
/* Overwrite the old file */
if (renameat(db->root_fd, tmpname,
db->root_fd, name) != 0) {
- apk_error(PKG_VER_FMT": failed to rename %s to %s.",
- PKG_VER_PRINTF(ipkg->pkg), tmpname, name);
+ apk_err(out, PKG_VER_FMT": failed to rename %s to %s.",
+ PKG_VER_PRINTF(ipkg->pkg), tmpname, name);
ipkg->broken_files = 1;
}
}
@@ -2763,6 +2762,7 @@ static int apk_db_unpack_pkg(struct apk_database *db,
int upgrade, apk_progress_cb cb, void *cb_ctx,
char **script_args)
{
+ struct apk_out *out = &db->ctx->out;
struct install_ctx ctx;
struct apk_istream *is = NULL, *cache_is;
struct apk_repository *repo;
@@ -2807,8 +2807,8 @@ static int apk_db_unpack_pkg(struct apk_database *db,
if (!IS_ERR_OR_NULL(cache_is))
is = cache_is;
else
- apk_warning(PKG_VER_FMT": unable to cache: %s",
- PKG_VER_PRINTF(pkg), apk_error_str(errno));
+ apk_warn(out, PKG_VER_FMT": unable to cache: %s",
+ PKG_VER_PRINTF(pkg), apk_error_str(errno));
}
ctx = (struct install_ctx) {
@@ -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, db->flags & APK_ALLOW_UNTRUSTED);
+ 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);
apk_sign_ctx_free(&ctx.sctx);
@@ -2839,7 +2839,7 @@ static int apk_db_unpack_pkg(struct apk_database *db,
apk_db_run_pending_script(&ctx);
return 0;
err_msg:
- apk_error(PKG_VER_FMT": %s", PKG_VER_PRINTF(pkg), apk_error_str(r));
+ apk_err(out, PKG_VER_FMT": %s", PKG_VER_PRINTF(pkg), apk_error_str(r));
return r;
}
diff --git a/src/io_archive.c b/src/io_archive.c
index 79cfd74..de4741e 100644
--- a/src/io_archive.c
+++ b/src/io_archive.c
@@ -336,7 +336,8 @@ int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
const char *extract_name, const char *link_target,
struct apk_istream *is,
apk_progress_cb cb, void *cb_ctx,
- unsigned int apk_extract_flags)
+ unsigned int apk_extract_flags,
+ struct apk_out *out)
{
struct apk_xattr *xattr;
const char *fn = extract_name ?: ae->name;
@@ -380,15 +381,15 @@ int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
break;
}
if (ret) {
- apk_error("Failed to create %s: %s", ae->name, strerror(-ret));
+ apk_err(out, "Failed to create %s: %s", ae->name, strerror(-ret));
return ret;
}
if (!(apk_extract_flags & APK_EXTRACTF_NO_CHOWN)) {
r = fchownat(atfd, fn, ae->uid, ae->gid, atflags);
if (r < 0) {
- apk_error("Failed to set ownership on %s: %s",
- fn, strerror(errno));
+ apk_err(out, "Failed to set ownership on %s: %s",
+ fn, strerror(errno));
if (!ret) ret = -errno;
}
@@ -396,9 +397,8 @@ int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
if (ae->mode & 07000) {
r = fchmodat(atfd, fn, ae->mode & 07777, atflags);
if (r < 0) {
- apk_error("Failed to set file permissions "
- "on %s: %s",
- fn, strerror(errno));
+ apk_err(out, "Failed to set file permissions on %s: %s",
+ fn, strerror(errno));
if (!ret) ret = -errno;
}
}
@@ -421,8 +421,8 @@ int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
}
if (r) {
if (r != -ENOTSUP)
- apk_error("Failed to set xattrs on %s: %s",
- fn, strerror(-r));
+ apk_err(out, "Failed to set xattrs on %s: %s",
+ fn, strerror(-r));
if (!ret) ret = r;
}
}
@@ -435,7 +435,7 @@ int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
times[0].tv_nsec = times[1].tv_nsec = 0;
r = utimensat(atfd, fn, times, atflags);
if (r < 0) {
- apk_error("Failed to preserve modification time on %s: %s",
+ apk_err(out, "Failed to preserve modification time on %s: %s",
fn, strerror(errno));
if (!ret || ret == -ENOTSUP) ret = -errno;
}
diff --git a/src/lua-apk.c b/src/lua-apk.c
index 6cd0208..10d34eb 100644
--- a/src/lua-apk.c
+++ b/src/lua-apk.c
@@ -140,7 +140,7 @@ static int get_boolean_field(lua_State *L, int index, const char *key)
return value;
}
-static int get_dbopts(lua_State *L, int i, struct apk_db_options *o)
+static int get_ctx(lua_State *L, int i, struct apk_ctx *o)
{
struct flagmap *f;
o->root = (char *)get_opt_string_field(L, i, "root", NULL);
@@ -165,14 +165,14 @@ static struct apk_database *checkdb(lua_State *L, int index)
static int Papk_db_open(lua_State *L)
{
- struct apk_db_options opts;
+ struct apk_ctx opts;
struct apk_database *db;
int r;
memset(&opts, 0, sizeof(opts));
apk_string_array_init(&opts.repository_list);
if (lua_istable(L, 1))
- get_dbopts(L, 1, &opts);
+ get_ctx(L, 1, &opts);
else
opts.open_flags |= APK_OPENF_READ;
diff --git a/src/meson.build b/src/meson.build
index f2b8cc9..4f3d435 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -7,6 +7,7 @@ libapk_src = [
'blob.c',
'commit.c',
'common.c',
+ 'context.c',
'database.c',
'hash.c',
'io.c',
@@ -63,7 +64,7 @@ apk_src = [
'app_verify.c',
'app_version.c',
'app_vertest.c',
- 'help.c',
+ 'applet.c',
]
if lua_bin.found()
diff --git a/src/package.c b/src/package.c
index 8376275..b63fae0 100644
--- a/src/package.c
+++ b/src/package.c
@@ -908,8 +908,9 @@ static int read_info_entry(void *ctx, const struct apk_file_info *ae,
while (!APK_BLOB_IS_NULL(l = apk_istream_get_delim(is, token)))
read_info_line(ctx, l);
} else if (strcmp(ae->name, ".INSTALL") == 0) {
- apk_warning("Package '%s-%s' contains deprecated .INSTALL",
- pkg->name->name, pkg->version);
+ apk_warn(&ri->db->ctx->out,
+ "Package '%s-%s' contains deprecated .INSTALL",
+ pkg->name->name, pkg->version);
}
return 0;
@@ -1004,6 +1005,7 @@ void apk_ipkg_run_script(struct apk_installed_package *ipkg,
struct apk_database *db,
unsigned int type, char **argv)
{
+ struct apk_out *out = &db->ctx->out;
struct apk_package *pkg = ipkg->pkg;
char fn[PATH_MAX];
int fd, root_fd = db->root_fd;
@@ -1018,10 +1020,10 @@ void apk_ipkg_run_script(struct apk_installed_package *ipkg,
PKG_VER_PRINTF(pkg),
apk_script_types[type]);
- if ((db->flags & (APK_NO_SCRIPTS | APK_SIMULATE)) != 0)
+ if ((db->ctx->flags & (APK_NO_SCRIPTS | APK_SIMULATE)) != 0)
return;
- apk_message("Executing %s", &fn[15]);
+ apk_msg(out, "Executing %s", &fn[15]);
fd = openat(root_fd, fn, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, 0755);
if (fd < 0) {
mkdirat(root_fd, "var/cache/misc", 0755);
@@ -1043,7 +1045,7 @@ void apk_ipkg_run_script(struct apk_installed_package *ipkg,
goto cleanup;
err_log:
- apk_error("%s: failed to execute: %s", &fn[15], apk_error_str(errno));
+ apk_err(out, "%s: failed to execute: %s", &fn[15], apk_error_str(errno));
err:
ipkg->broken_script = 1;
cleanup:
@@ -1063,6 +1065,7 @@ static int parse_index_line(void *ctx, apk_blob_t line)
struct apk_package *apk_pkg_parse_index_entry(struct apk_database *db, apk_blob_t blob)
{
+ struct apk_out *out = &db->ctx->out;
struct read_info_ctx ctx;
ctx.pkg = apk_pkg_new();
@@ -1075,8 +1078,7 @@ struct apk_package *apk_pkg_parse_index_entry(struct apk_database *db, apk_blob_
if (ctx.pkg->name == NULL) {
apk_pkg_free(ctx.pkg);
- apk_error("Failed to parse index entry: " BLOB_FMT,
- BLOB_PRINTF(blob));
+ apk_err(out, "Failed to parse index entry: " BLOB_FMT, BLOB_PRINTF(blob));
ctx.pkg = NULL;
}
@@ -1143,18 +1145,15 @@ int apk_pkg_write_index_entry(struct apk_package *info,
}
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n"));
- if (APK_BLOB_IS_NULL(bbuf)) {
- apk_error("Metadata for package " PKG_VER_FMT " is too long.",
- PKG_VER_PRINTF(info));
- return -ENOBUFS;
- }
+ if (APK_BLOB_IS_NULL(bbuf))
+ return apk_ostream_cancel(os, -ENOBUFS);
bbuf = apk_blob_pushed(APK_BLOB_BUF(buf), bbuf);
if (apk_ostream_write(os, bbuf.ptr, bbuf.len) != bbuf.len ||
write_depends(os, "D:", info->depends) ||
write_depends(os, "p:", info->provides) ||
write_depends(os, "i:", info->install_if))
- return -EIO;
+ return apk_ostream_cancel(os, -EIO);
return 0;
}
diff --git a/src/print.c b/src/print.c
index 84c8ed1..829f7f5 100644
--- a/src/print.c
+++ b/src/print.c
@@ -19,43 +19,125 @@
#include "apk_defines.h"
#include "apk_print.h"
-static int apk_screen_width = 0;
-static int apk_progress_force = 1;
-static const char *apk_size_units[] = {"B", "KiB", "MiB", "GiB", "TiB"};
-
-void apk_reset_screen_width(void)
-{
- apk_screen_width = 0;
- apk_progress_force = 1;
-}
-
-int apk_get_screen_width(void)
+const char *apk_error_str(int error)
{
- struct winsize w;
-
- if (apk_screen_width == 0) {
- apk_screen_width = 50;
- if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == 0 &&
- w.ws_col > 25)
- apk_screen_width = w.ws_col;
+ if (error < 0)
+ error = -error;
+ switch (error) {
+ case ENOKEY:
+ return "UNTRUSTED signature";
+ case EKEYREJECTED:
+ return "BAD signature";
+ case EIO:
+ return "IO ERROR";
+ case EBADMSG:
+ return "BAD archive";
+ case ENOMSG:
+ return "archive does not contain expected data";
+ case ENOPKG:
+ return "could not find a repo which provides this package (check repositories file and run 'apk update')";
+ case ECONNABORTED:
+ return "network connection aborted";
+ case ECONNREFUSED:
+ return "could not connect to server (check repositories file)";
+ case ENETUNREACH:
+ return "network error (check Internet connection and firewall)";
+ case ENXIO:
+ return "DNS lookup error";
+ case EREMOTEIO:
+ return "remote server returned error (try 'apk update')";
+ case ETIMEDOUT:
+ return "operation timed out";
+ case EAGAIN:
+ return "temporary error (try again later)";
+ case EAPKBADURL:
+ return "invalid URL (check your repositories file)";
+ case EAPKSTALEINDEX:
+ return "package mentioned in index not found (try 'apk update')";
+ case EAPKFORMAT:
+ return "package file format error";
+ case EAPKDEPFORMAT:
+ return "package dependency format error";
+ default:
+ return strerror(error);
}
-
- return apk_screen_width;
}
const char *apk_get_human_size(off_t size, off_t *dest)
{
+ static const char *size_units[] = {"B", "KiB", "MiB", "GiB", "TiB"};
size_t i;
off_t s;
assert(size >= 0);
- for (i = 0, s = size; s >= 10000 &&
- i < ARRAY_SIZE(apk_size_units); i++)
+ for (i = 0, s = size; s >= 10000 && i < ARRAY_SIZE(size_units); i++)
s /= 1024;
if (dest) *dest = s;
- return apk_size_units[min(i, ARRAY_SIZE(apk_size_units) - 1)];
+ return size_units[min(i, ARRAY_SIZE(size_units) - 1)];
+}
+
+void apk_url_parse(struct apk_url_print *urlp, const char *url)
+{
+ const char *authority, *path_or_host, *pw;
+
+ *urlp = (struct apk_url_print) {
+ .url = "",
+ .pwmask = "",
+ .url_or_host = url,
+ };
+
+ if (!(authority = strstr(url, "://"))) return;
+ authority += 3;
+ path_or_host = strpbrk(authority, "/@");
+ if (!path_or_host || *path_or_host == '/') return;
+ pw = strpbrk(authority, "@:");
+ if (!pw || *pw == '@') return;
+ *urlp = (struct apk_url_print) {
+ .url = url,
+ .pwmask = "*",
+ .url_or_host = path_or_host,
+ .len_before_pw = pw - url + 1,
+ };
+}
+
+void apk_out_reset(struct apk_out *out)
+{
+ out->width = 0;
+ out->last_change++;
+}
+
+static int apk_out_get_width(struct apk_out *out)
+{
+ struct winsize w;
+
+ if (out->width == 0) {
+ out->width = 50;
+ if (ioctl(fileno(out->out), TIOCGWINSZ, &w) == 0 &&
+ w.ws_col > 25)
+ out->width = w.ws_col;
+ }
+
+ return out->width;
+}
+
+static void log_internal(FILE *dest, const char *prefix, const char *format, va_list va)
+{
+ if (dest != stdout) fflush(stdout);
+ if (prefix != NULL) fprintf(dest, "%s", prefix);
+ vfprintf(dest, format, va);
+ fprintf(dest, "\n");
+ fflush(dest);
+}
+
+void apk_out_fmt(struct apk_out *out, const char *prefix, const char *format, ...)
+{
+ va_list va;
+ va_start(va, format);
+ log_internal(prefix ? out->err : out->out, prefix, format, va);
+ out->last_change++;
+ va_end(va);
}
void apk_print_progress(struct apk_progress *p, size_t done, size_t total)
@@ -64,31 +146,31 @@ void apk_print_progress(struct apk_progress *p, size_t done, size_t total)
int bar = 0;
char buf[64]; /* enough for petabytes... */
int i, percent = 0;
- FILE *out = p->out;
-
- if (p->last_done == done && !apk_progress_force)
- return;
+ FILE *out;
+ if (p->last_done == done && (!p->out || p->last_out_change == p->out->last_change)) return;
if (p->fd != 0) {
i = snprintf(buf, sizeof(buf), "%zu/%zu\n", done, total);
write(p->fd, buf, i);
}
p->last_done = done;
+ if (!p->out) return;
+ out = p->out->out;
if (!out) return;
- bar_width = apk_get_screen_width() - 6;
+ bar_width = apk_out_get_width(p->out) - 6;
if (total > 0) {
bar = muldiv(bar_width, done, total);
percent = muldiv(100, done, total);
}
- if (bar == p->last_bar && percent == p->last_percent && !apk_progress_force)
+ if (bar == p->last_bar && percent == p->last_percent && p->last_out_change == p->out->last_change)
return;
p->last_bar = bar;
p->last_percent = percent;
- apk_progress_force = 0;
+ p->last_out_change = p->out->last_change;
fprintf(out, "\e7%3i%% ", percent);
@@ -103,13 +185,14 @@ void apk_print_progress(struct apk_progress *p, size_t done, size_t total)
int apk_print_indented(struct apk_indent *i, apk_blob_t blob)
{
+ FILE *out = i->out->out;
if (i->x <= i->indent)
- i->x += printf("%*s" BLOB_FMT, i->indent - i->x, "", BLOB_PRINTF(blob));
- else if (i->x + blob.len + 1 >= apk_get_screen_width())
- i->x = printf("\n%*s" BLOB_FMT, i->indent, "", BLOB_PRINTF(blob)) - 1;
+ i->x += fprintf(out, "%*s" BLOB_FMT, i->indent - i->x, "", BLOB_PRINTF(blob));
+ else if (i->x + blob.len + 1 >= apk_out_get_width(i->out))
+ i->x = fprintf(out, "\n%*s" BLOB_FMT, i->indent, "", BLOB_PRINTF(blob)) - 1;
else
- i->x += printf(" " BLOB_FMT, BLOB_PRINTF(blob));
- apk_progress_force = 1;
+ i->x += fprintf(out, " " BLOB_FMT, BLOB_PRINTF(blob));
+ i->out->last_change++;
return 0;
}
@@ -130,99 +213,3 @@ void apk_print_indented_fmt(struct apk_indent *i, const char *fmt, ...)
apk_print_indented(i, APK_BLOB_PTR_LEN(tmp, n));
va_end(va);
}
-
-const char *apk_error_str(int error)
-{
- if (error < 0)
- error = -error;
- switch (error) {
- case ENOKEY:
- return "UNTRUSTED signature";
- case EKEYREJECTED:
- return "BAD signature";
- case EIO:
- return "IO ERROR";
- case EBADMSG:
- return "BAD archive";
- case ENOMSG:
- return "archive does not contain expected data";
- case ENOPKG:
- return "could not find a repo which provides this package (check repositories file and run 'apk update')";
- case ECONNABORTED:
- return "network connection aborted";
- case ECONNREFUSED:
- return "could not connect to server (check repositories file)";
- case ENETUNREACH:
- return "network error (check Internet connection and firewall)";
- case ENXIO:
- return "DNS lookup error";
- case EREMOTEIO:
- return "remote server returned error (try 'apk update')";
- case ETIMEDOUT:
- return "operation timed out";
- case EAGAIN:
- return "temporary error (try again later)";
- case EAPKBADURL:
- return "invalid URL (check your repositories file)";
- case EAPKSTALEINDEX:
- return "package mentioned in index not found (try 'apk update')";
- case EAPKFORMAT:
- return "package file format error";
- case EAPKDEPFORMAT:
- return "package dependency format error";
- default:
- return strerror(error);
- }
-}
-
-static void log_internal(FILE *dest, const char *prefix, const char *format, va_list va)
-{
- if (dest != stdout)
- fflush(stdout);
- if (prefix != NULL)
- fprintf(dest, "%s", prefix);
- vfprintf(dest, format, va);
- fprintf(dest, "\n");
- fflush(dest);
- apk_progress_force = 1;
-}
-
-void apk_log(const char *prefix, const char *format, ...)
-{
- va_list va;
- va_start(va, format);
- log_internal(stdout, prefix, format, va);
- va_end(va);
-}
-
-void apk_log_err(const char *prefix, const char *format, ...)
-{
- va_list va;
- va_start(va, format);
- log_internal(stderr, prefix, format, va);
- va_end(va);
-}
-
-void apk_url_parse(struct apk_url_print *urlp, const char *url)
-{
- const char *authority, *path_or_host, *pw;
-
- *urlp = (struct apk_url_print) {
- .url = "",
- .pwmask = "",
- .url_or_host = url,
- };
-
- if (!(authority = strstr(url, "://"))) return;
- authority += 3;
- path_or_host = strpbrk(authority, "/@");
- if (!path_or_host || *path_or_host == '/') return;
- pw = strpbrk(authority, "@:");
- if (!pw || *pw == '@') return;
- *urlp = (struct apk_url_print) {
- .url = url,
- .pwmask = "*",
- .url_or_host = path_or_host,
- .len_before_pw = pw - url + 1,
- };
-}
diff --git a/src/solver.c b/src/solver.c
index be9240a..faa20b0 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -1097,7 +1097,7 @@ restart:
generate_changeset(ss, world);
- if (ss->errors && (db->force & APK_FORCE_BROKEN_WORLD)) {
+ if (ss->errors && (db->ctx->force & APK_FORCE_BROKEN_WORLD)) {
foreach_array_item(d, world) {
name = d->name;
pkg = name->ss.chosen.pkg;
diff --git a/test/solver.sh b/test/solver.sh
index bc230c6..d14d89d 100755
--- a/test/solver.sh
+++ b/test/solver.sh
@@ -4,7 +4,7 @@ get_block() {
awk '/^@'$1'/{p=1;next} /^@/{p=0} p{print}'
}
-APK_TEST="../src/apk-test"
+APK_TEST="$VALGRIND ../src/apk-test"
TEST_TO_RUN="$@"
fail=0