rename apk_db_options to apk_ctx, rework logging

makes apk_verbosity non-global

fixes #10682
cute-signatures
Timo Teräs 2020-10-05 18:52:51 +03:00
parent 7a7eca8670
commit 354713d2f7
43 changed files with 824 additions and 742 deletions

View File

@ -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 \

View File

@ -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;

212
src/apk.c
View File

@ -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,54 +377,28 @@ 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;
}
void apk_applet_register(struct apk_applet *applet)
{
list_init(&applet->node);
list_add_tail(&applet->node, &apk_applet_list);
}
static 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)();
ac->flags |= APK_INTERACTIVE;
}
static struct apk_ctx ctx;
static struct apk_database db;
static void on_sigint(int s)
@ -447,10 +407,21 @@ static void on_sigint(int s)
exit(128 + s);
}
static void on_sigwinch(int s)
{
apk_out_reset(&ctx.out);
}
static void setup_terminal(void)
{
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;

View File

@ -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;

View File

@ -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

51
src/apk_context.h Normal file
View File

@ -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

View File

@ -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);

View File

@ -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"

View File

@ -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);

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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++;

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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;
}

View File

@ -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++;

View File

@ -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(),

View File

@ -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++;
}
}

View File

@ -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
}

View File

@ -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;
}

27
src/context.c Normal file
View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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()

View File

@ -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;
}

View File

@ -19,118 +19,6 @@
#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)
{
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;
}
return apk_screen_width;
}
const char *apk_get_human_size(off_t size, off_t *dest)
{
size_t i;
off_t s;
assert(size >= 0);
for (i = 0, s = size; s >= 10000 &&
i < ARRAY_SIZE(apk_size_units); i++)
s /= 1024;
if (dest) *dest = s;
return apk_size_units[min(i, ARRAY_SIZE(apk_size_units) - 1)];
}
void apk_print_progress(struct apk_progress *p, size_t done, size_t total)
{
int bar_width;
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;
if (p->fd != 0) {
i = snprintf(buf, sizeof(buf), "%zu/%zu\n", done, total);
write(p->fd, buf, i);
}
p->last_done = done;
if (!out) return;
bar_width = apk_get_screen_width() - 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)
return;
p->last_bar = bar;
p->last_percent = percent;
apk_progress_force = 0;
fprintf(out, "\e7%3i%% ", percent);
for (i = 0; i < bar; i++)
fputs(p->progress_char, out);
for (; i < bar_width; i++)
fputc(' ', out);
fflush(out);
fputs("\e8\e[0K", out);
}
int apk_print_indented(struct apk_indent *i, apk_blob_t blob)
{
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;
else
i->x += printf(" " BLOB_FMT, BLOB_PRINTF(blob));
apk_progress_force = 1;
return 0;
}
void apk_print_indented_words(struct apk_indent *i, const char *text)
{
apk_blob_for_each_segment(APK_BLOB_STR(text), " ",
(apk_blob_cb) apk_print_indented, i);
}
void apk_print_indented_fmt(struct apk_indent *i, const char *fmt, ...)
{
char tmp[256];
size_t n;
va_list va;
va_start(va, fmt);
n = vsnprintf(tmp, sizeof(tmp), fmt, va);
apk_print_indented(i, APK_BLOB_PTR_LEN(tmp, n));
va_end(va);
}
const char *apk_error_str(int error)
{
if (error < 0)
@ -175,32 +63,19 @@ const char *apk_error_str(int error)
}
}
static void log_internal(FILE *dest, const char *prefix, const char *format, va_list va)
const char *apk_get_human_size(off_t size, off_t *dest)
{
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;
}
static const char *size_units[] = {"B", "KiB", "MiB", "GiB", "TiB"};
size_t i;
off_t s;
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);
}
assert(size >= 0);
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);
for (i = 0, s = size; s >= 10000 && i < ARRAY_SIZE(size_units); i++)
s /= 1024;
if (dest) *dest = s;
return size_units[min(i, ARRAY_SIZE(size_units) - 1)];
}
void apk_url_parse(struct apk_url_print *urlp, const char *url)
@ -226,3 +101,115 @@ void apk_url_parse(struct apk_url_print *urlp, const char *url)
.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)
{
int bar_width;
int bar = 0;
char buf[64]; /* enough for petabytes... */
int i, percent = 0;
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_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 && p->last_out_change == p->out->last_change)
return;
p->last_bar = bar;
p->last_percent = percent;
p->last_out_change = p->out->last_change;
fprintf(out, "\e7%3i%% ", percent);
for (i = 0; i < bar; i++)
fputs(p->progress_char, out);
for (; i < bar_width; i++)
fputc(' ', out);
fflush(out);
fputs("\e8\e[0K", out);
}
int apk_print_indented(struct apk_indent *i, apk_blob_t blob)
{
FILE *out = i->out->out;
if (i->x <= i->indent)
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 += fprintf(out, " " BLOB_FMT, BLOB_PRINTF(blob));
i->out->last_change++;
return 0;
}
void apk_print_indented_words(struct apk_indent *i, const char *text)
{
apk_blob_for_each_segment(APK_BLOB_STR(text), " ",
(apk_blob_cb) apk_print_indented, i);
}
void apk_print_indented_fmt(struct apk_indent *i, const char *fmt, ...)
{
char tmp[256];
size_t n;
va_list va;
va_start(va, fmt);
n = vsnprintf(tmp, sizeof(tmp), fmt, va);
apk_print_indented(i, APK_BLOB_PTR_LEN(tmp, n));
va_end(va);
}

View File

@ -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;

View File

@ -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