Commit ecdacd15 authored by Timo Teräs's avatar Timo Teräs

all: implement database open options

so user can override trusted keys directory and repositories file.
parent fac43e2d
......@@ -16,17 +16,17 @@
#include "apk_state.h"
struct add_ctx {
unsigned int open_flags;
const char *virtpkg;
};
static int add_parse(void *ctx, int optch, int optindex, const char *optarg)
static int add_parse(void *ctx, struct apk_db_options *dbopts,
int optch, int optindex, const char *optarg)
{
struct add_ctx *actx = (struct add_ctx *) ctx;
switch (optch) {
case 0x10000:
actx->open_flags |= APK_OPENF_CREATE;
dbopts->open_flags |= APK_OPENF_CREATE;
break;
case 'u':
apk_flags |= APK_UPGRADE;
......@@ -57,22 +57,17 @@ static int non_repository_check(struct apk_database *db)
}
static int add_main(void *ctx, int argc, char **argv)
static int add_main(void *ctx, struct apk_database *db, int argc, char **argv)
{
struct add_ctx *actx = (struct add_ctx *) ctx;
struct apk_database db;
struct apk_state *state = NULL;
struct apk_dependency_array *pkgs = NULL;
struct apk_package *virtpkg = NULL;
struct apk_dependency virtdep;
int i, r;
r = apk_db_open(&db, apk_root, actx->open_flags | APK_OPENF_WRITE);
if (r != 0)
return r;
int i, r = 0;
if (actx->virtpkg) {
if (non_repository_check(&db))
if (non_repository_check(db))
goto err;
virtpkg = apk_pkg_new();
......@@ -80,14 +75,14 @@ static int add_main(void *ctx, int argc, char **argv)
apk_error("Failed to allocate virtual meta package");
goto err;
}
virtpkg->name = apk_db_get_name(&db, APK_BLOB_STR(actx->virtpkg));
virtpkg->name = apk_db_get_name(db, APK_BLOB_STR(actx->virtpkg));
apk_blob_checksum(APK_BLOB_STR(virtpkg->name->name),
apk_default_checksum(), &virtpkg->csum);
virtpkg->version = strdup("0");
virtpkg->description = strdup("virtual meta package");
apk_dep_from_pkg(&virtdep, &db, virtpkg);
apk_dep_from_pkg(&virtdep, db, virtpkg);
virtdep.name->flags |= APK_NAME_TOPLEVEL;
virtpkg = apk_db_pkg_add(&db, virtpkg);
virtpkg = apk_db_pkg_add(db, virtpkg);
}
for (i = 0; i < argc; i++) {
......@@ -97,21 +92,21 @@ static int add_main(void *ctx, int argc, char **argv)
struct apk_package *pkg = NULL;
struct apk_sign_ctx sctx;
if (non_repository_check(&db))
if (non_repository_check(db))
goto err;
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY_AND_GENERATE,
NULL, db.keys_fd);
r = apk_pkg_read(&db, argv[i], &sctx, &pkg);
NULL, db->keys_fd);
r = apk_pkg_read(db, argv[i], &sctx, &pkg);
apk_sign_ctx_free(&sctx);
if (r != 0) {
apk_error("%s: %s", argv[i], apk_error_str(r));
goto err;
}
apk_dep_from_pkg(&dep, &db, pkg);
apk_dep_from_pkg(&dep, db, pkg);
} else {
r = apk_dep_from_blob(&dep, &db, APK_BLOB_STR(argv[i]));
r = apk_dep_from_blob(&dep, db, APK_BLOB_STR(argv[i]));
if (r != 0)
goto err;
}
......@@ -126,10 +121,10 @@ static int add_main(void *ctx, int argc, char **argv)
if (virtpkg) {
apk_deps_add(&pkgs, &virtdep);
apk_deps_add(&db.world, &virtdep);
apk_deps_add(&db->world, &virtdep);
}
state = apk_state_new(&db);
state = apk_state_new(db);
if (state == NULL)
goto err;
......@@ -141,13 +136,12 @@ static int add_main(void *ctx, int argc, char **argv)
goto err;
}
if (!virtpkg)
apk_deps_add(&db.world, &pkgs->item[i]);
apk_deps_add(&db->world, &pkgs->item[i]);
}
r = apk_state_commit(state, &db);
r = apk_state_commit(state, db);
err:
if (state != NULL)
apk_state_unref(state);
apk_db_close(&db);
return r;
}
......@@ -166,6 +160,7 @@ static struct apk_applet apk_add = {
.help = "Add (or update) PACKAGEs to main dependencies and install "
"them, while ensuring that all dependencies are met.",
.arguments = "PACKAGE...",
.open_flags = APK_OPENF_WRITE,
.context_size = sizeof(struct add_ctx),
.num_options = ARRAY_SIZE(add_options),
.options = add_options,
......
......@@ -21,11 +21,10 @@
#include <openssl/engine.h>
#include "apk_defines.h"
#include "apk_database.h"
#include "apk_applet.h"
#include "apk_blob.h"
const char *apk_root;
struct apk_repository_url apk_repository_list;
int apk_verbosity = 1, apk_wait;
unsigned int apk_flags = 0;
......@@ -53,6 +52,10 @@ static struct apk_option generic_options[] = {
{ 0x105, "wait", "Wait for TIME seconds to get an exclusive "
"repository lock before failing",
required_argument, "TIME" },
{ 0x107, "keys-dir", "Override directory of trusted keys",
required_argument, "KEYSDIR" },
{ 0x108, "repositories-file", "Override repositories file",
required_argument, "REPOFILE" }
};
const char *apk_error_str(int error)
......@@ -239,10 +242,10 @@ static struct apk_applet *deduce_applet(int argc, char **argv)
return NULL;
}
static struct apk_repository_url *apk_repository_new(const char *url)
static struct apk_repository_list *apk_repository_new(const char *url)
{
struct apk_repository_url *r = calloc(1,
sizeof(struct apk_repository_url));
struct apk_repository_list *r = calloc(1,
sizeof(struct apk_repository_list));
if (r) {
r->url = url;
list_init(&r->list);
......@@ -289,11 +292,13 @@ int main(int argc, char **argv)
struct option *opt, *all_options;
int r, optindex, num_options;
void *ctx = NULL;
struct apk_repository_url *repo = NULL;
struct apk_repository_list *repo = NULL;
struct apk_database db;
struct apk_db_options dbopts;
memset(&dbopts, 0, sizeof(dbopts));
list_init(&dbopts.repository_list);
umask(0);
apk_root = getenv("ROOT");
list_init(&apk_repository_list.list);
applet = deduce_applet(argc, argv);
num_options = ARRAY_SIZE(generic_options) + 1;
......@@ -307,6 +312,8 @@ int main(int argc, char **argv)
applet->options, applet->num_options);
if (applet->context_size != 0)
ctx = calloc(1, applet->context_size);
dbopts.open_flags = applet->open_flags;
apk_flags |= applet->forced_flags;
}
for (opt = all_options, sopt = short_options; opt->name != NULL; opt++) {
......@@ -330,12 +337,18 @@ int main(int argc, char **argv)
return usage(applet);
break;
case 'p':
apk_root = optarg;
dbopts.root = optarg;
break;
case 0x107:
dbopts.keys_dir = optarg;
break;
case 0x108:
dbopts.repositories_file = optarg;
break;
case 'X':
repo = apk_repository_new(optarg);
if (repo)
list_add(&repo->list, &apk_repository_list.list);
list_add(&repo->list, &dbopts.repository_list);
break;
case 'q':
apk_verbosity--;
......@@ -374,7 +387,7 @@ int main(int argc, char **argv)
break;
default:
if (applet == NULL || applet->parse == NULL ||
applet->parse(ctx, r,
applet->parse(ctx, &dbopts, r,
optindex - ARRAY_SIZE(generic_options),
optarg) != 0)
return usage(applet);
......@@ -385,9 +398,6 @@ int main(int argc, char **argv)
if (applet == NULL)
return usage(NULL);
if (apk_root == NULL)
apk_root = "/";
argc -= optind;
argv += optind;
if (argc >= 1 && strcmp(argv[0], applet->name) == 0) {
......@@ -395,7 +405,16 @@ int main(int argc, char **argv)
argv++;
}
r = applet->main(ctx, argc, argv);
r = apk_db_open(&db, &dbopts);
if (r != 0) {
apk_error("Failed to open apk database: %s",
apk_error_str(r));
return r;
}
r = applet->main(ctx, &db, argc, argv);
apk_db_close(&db);
if (r == -EINVAL)
return usage(applet);
return r;
......
......@@ -14,15 +14,7 @@
#include <getopt.h>
#include "apk_defines.h"
extern const char *apk_root;
struct apk_repository_url {
struct list_head list;
const char *url;
};
extern struct apk_repository_url apk_repository_list;
#include "apk_database.h"
struct apk_option {
int val;
......@@ -37,12 +29,14 @@ struct apk_applet {
const char *arguments;
const char *help;
unsigned int open_flags, forced_flags;
int context_size;
int num_options;
struct apk_option *options;
int (*parse)(void *ctx, int optch, int optindex, const char *optarg);
int (*main)(void *ctx, int argc, char **argv);
int (*parse)(void *ctx, struct apk_db_options *dbopts,
int optch, int optindex, const char *optarg);
int (*main)(void *ctx, struct apk_database *db, int argc, char **argv);
};
extern struct apk_applet *__start_apkapplets, *__stop_apkapplets;
......
......@@ -79,6 +79,19 @@ struct apk_repository {
struct apk_checksum csum;
};
struct apk_repository_list {
struct list_head list;
const char *url;
};
struct apk_db_options {
unsigned long open_flags;
char *root;
char *keys_dir;
char *repositories_file;
struct list_head repository_list;
};
struct apk_database {
char *root;
int root_fd, lock_fd, cache_fd, cachetmp_fd, keys_fd;
......@@ -120,9 +133,9 @@ struct apk_db_file *apk_db_file_query(struct apk_database *db,
apk_blob_t dir,
apk_blob_t name);
#define APK_OPENF_READ 0x0000
#define APK_OPENF_WRITE 0x0001
#define APK_OPENF_CREATE 0x0002
#define APK_OPENF_READ 0x0001
#define APK_OPENF_WRITE 0x0002
#define APK_OPENF_CREATE 0x0004
#define APK_OPENF_NO_INSTALLED 0x0010
#define APK_OPENF_NO_SCRIPTS 0x0020
#define APK_OPENF_NO_WORLD 0x0040
......@@ -132,7 +145,7 @@ struct apk_db_file *apk_db_file_query(struct apk_database *db,
APK_OPENF_NO_SCRIPTS | \
APK_OPENF_NO_WORLD)
int apk_db_open(struct apk_database *db, const char *root, unsigned int flags);
int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts);
int apk_db_write_config(struct apk_database *db);
void apk_db_close(struct apk_database *db);
int apk_db_permanent(struct apk_database *db);
......
......@@ -144,7 +144,8 @@ static int audit_system(struct apk_database *db)
return 0;
}
static int audit_parse(void *ctx, int optch, int optindex, const char *optarg)
static int audit_parse(void *ctx, struct apk_db_options *dbopts,
int optch, int optindex, const char *optarg)
{
struct audit_ctx *actx = (struct audit_ctx *) ctx;
......@@ -161,26 +162,14 @@ static int audit_parse(void *ctx, int optch, int optindex, const char *optarg)
return 0;
}
static int audit_main(void *ctx, int argc, char **argv)
static int audit_main(void *ctx, struct apk_database *db, int argc, char **argv)
{
struct audit_ctx *actx = (struct audit_ctx *) ctx;
struct apk_database db;
int r;
if (actx->audit == NULL)
return -EINVAL;
r = apk_db_open(&db, apk_root,
APK_OPENF_READ | APK_OPENF_NO_SCRIPTS |
APK_OPENF_NO_REPOS);
if (r != 0) {
apk_error("Unable to open db: %s", apk_error_str(r));
return r;
}
r = actx->audit(&db);
apk_db_close(&db);
return r;
return actx->audit(db);
}
static struct apk_option audit_options[] = {
......@@ -194,6 +183,7 @@ static struct apk_applet apk_audit = {
.name = "audit",
.help = "Audit the filesystem for changes compared to installed "
"database.",
.open_flags = APK_OPENF_READ|APK_OPENF_NO_SCRIPTS|APK_OPENF_NO_REPOS,
.context_size = sizeof(struct audit_ctx),
.num_options = ARRAY_SIZE(audit_options),
.options = audit_options,
......
......@@ -141,11 +141,9 @@ static int cache_clean(struct apk_database *db)
return 0;
}
static int cache_main(void *ctx, int argc, char **argv)
static int cache_main(void *ctx, struct apk_database *db, int argc, char **argv)
{
struct apk_database db;
int actions = 0;
int r;
int r = 0, actions = 0;
if (argc != 1)
return -EINVAL;
......@@ -159,24 +157,18 @@ static int cache_main(void *ctx, int argc, char **argv)
else
return -EINVAL;
r = apk_db_open(&db, apk_root, APK_OPENF_READ |
APK_OPENF_NO_SCRIPTS | APK_OPENF_NO_INSTALLED);
if (r != 0)
return r;
if (!apk_db_cache_active(&db)) {
if (!apk_db_cache_active(db)) {
apk_error("Package cache is not enabled.\n");
r = 2;
goto err;
}
if (r == 0 && (actions & CACHE_CLEAN))
r = cache_clean(&db);
r = cache_clean(db);
if (r == 0 && (actions & CACHE_DOWNLOAD))
r = cache_download(&db);
r = cache_download(db);
err:
apk_db_close(&db);
return r;
}
......@@ -187,6 +179,7 @@ static struct apk_applet apk_cache = {
"making /etc/apk/cache a symlink to the directory (on boot "
"media) that will be used as package cache.",
.arguments = "sync | clean | download",
.open_flags = APK_OPENF_READ|APK_OPENF_NO_SCRIPTS|APK_OPENF_NO_INSTALLED,
.main = cache_main,
};
......
......@@ -878,15 +878,21 @@ static void handle_alarm(int sig)
{
}
int apk_db_open(struct apk_database *db, const char *root, unsigned int flags)
int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
{
const char *apk_repos = getenv("APK_REPOS"), *msg = NULL;
struct apk_repository_url *repo = NULL;
const char *msg = NULL;
struct apk_repository_list *repo = NULL;
struct stat64 st;
apk_blob_t blob;
int r, rr = 0;
memset(db, 0, sizeof(*db));
if (dbopts->open_flags == 0) {
msg = "Invalid open flags (internal error)";
r = -1;
goto ret_r;
}
apk_hash_init(&db->available.names, &pkg_name_hash_ops, 1000);
apk_hash_init(&db->available.packages, &pkg_info_hash_ops, 4000);
apk_hash_init(&db->installed.dirs, &dir_hash_ops, 2000);
......@@ -895,11 +901,11 @@ int apk_db_open(struct apk_database *db, const char *root, unsigned int flags)
db->cache_dir = apk_static_cache_dir;
db->permanent = 1;
db->root = strdup(root);
db->root = strdup(dbopts->root ?: "/");
db->root_fd = openat(AT_FDCWD, db->root, O_RDONLY);
if (db->root_fd < 0 && (flags & APK_OPENF_CREATE)) {
if (db->root_fd < 0 && (dbopts->open_flags & APK_OPENF_CREATE)) {
mkdirat(AT_FDCWD, db->root, 0755);
db->root_fd = openat(AT_FDCWD, root, O_RDONLY);
db->root_fd = openat(AT_FDCWD, db->root, O_RDONLY);
}
if (db->root_fd < 0) {
msg = "Unable to open root";
......@@ -912,11 +918,11 @@ int apk_db_open(struct apk_database *db, const char *root, unsigned int flags)
S_ISDIR(st.st_mode))
db->cache_dir = apk_linked_cache_dir;
if (flags & APK_OPENF_WRITE) {
if (dbopts->open_flags & APK_OPENF_WRITE) {
db->lock_fd = openat(db->root_fd, "var/lib/apk/lock",
O_CREAT | O_RDWR, 0400);
if (db->lock_fd < 0 && errno == ENOENT &&
(flags & APK_OPENF_CREATE)) {
(dbopts->open_flags & APK_OPENF_CREATE)) {
r = apk_db_create(db);
if (r != 0) {
msg = "Unable to create database";
......@@ -954,30 +960,32 @@ int apk_db_open(struct apk_database *db, const char *root, unsigned int flags)
db->cache_fd = openat(db->root_fd, db->cache_dir, O_RDONLY);
mkdirat(db->cache_fd, "tmp", 0644);
db->cachetmp_fd = openat(db->cache_fd, "tmp", O_RDONLY);
db->keys_fd = openat(db->root_fd, "etc/apk/keys", O_RDONLY);
db->keys_fd = openat(db->root_fd,
dbopts->keys_dir ?: "etc/apk/keys",
O_RDONLY);
r = apk_db_read_state(db, flags);
if (r == -ENOENT && (flags & APK_OPENF_CREATE)) {
r = apk_db_read_state(db, dbopts->open_flags);
if (r == -ENOENT && (dbopts->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, flags);
r = apk_db_read_state(db, dbopts->open_flags);
}
if (r != 0) {
msg = "Unable to read database state";
goto ret_r;
}
if (!(flags & APK_OPENF_NO_REPOS)) {
list_for_each_entry(repo, &apk_repository_list.list, list) {
if (!(dbopts->open_flags & APK_OPENF_NO_REPOS)) {
list_for_each_entry(repo, &dbopts->repository_list, list) {
r = apk_db_add_repository(db, APK_BLOB_STR(repo->url));
rr = r ?: rr;
}
if (apk_repos == NULL)
apk_repos = "etc/apk/repositories";
blob = apk_blob_from_file(db->root_fd, apk_repos);
blob = apk_blob_from_file(
db->root_fd,
dbopts->repositories_file ?: "etc/apk/repositories");
if (!APK_BLOB_IS_NULL(blob)) {
r = apk_blob_for_each_segment(
blob, "\n",
......
......@@ -14,7 +14,8 @@
#include "apk_state.h"
#include "apk_database.h"
static int del_parse(void *ctx, int optch, int optindex, const char *optarg)
static int del_parse(void *ctx, struct apk_db_options *db,
int optch, int optindex, const char *optarg)
{
switch (optch) {
case 'r':
......@@ -26,33 +27,29 @@ static int del_parse(void *ctx, int optch, int optindex, const char *optarg)
return 0;
}
static int del_main(void *ctx, int argc, char **argv)
static int del_main(void *ctx, struct apk_database *db, int argc, char **argv)
{
struct apk_database db;
struct apk_state *state;
struct apk_name *name;
int i, r = 0;
if (apk_db_open(&db, apk_root, APK_OPENF_WRITE) < 0)
return -1;
if (db.world == NULL)
goto out;
if (db->world == NULL)
return 0;
for (i = 0; i < argc; i++) {
name = apk_db_get_name(&db, APK_BLOB_STR(argv[i]));
name = apk_db_get_name(db, APK_BLOB_STR(argv[i]));
name->flags &= ~APK_NAME_TOPLEVEL;
apk_deps_del(&db.world, name);
apk_deps_del(&db->world, name);
}
state = apk_state_new(&db);
state = apk_state_new(db);
if (state == NULL)
goto err;
for (i = 0; i < argc; i++) {
struct apk_dependency dep;
name = apk_db_get_name(&db, APK_BLOB_STR(argv[i]));
name = apk_db_get_name(db, APK_BLOB_STR(argv[i]));
dep = (struct apk_dependency) {
.name = name,
.result_mask = APK_DEPMASK_CONFLICT,
......@@ -64,12 +61,10 @@ static int del_main(void *ctx, int argc, char **argv)
goto err;
}
}
r = apk_state_commit(state, &db);
r = apk_state_commit(state, db);
err:
if (state != NULL)
apk_state_unref(state);
out:
apk_db_close(&db);
return r;
}
......@@ -83,6 +78,7 @@ static struct apk_applet apk_del = {
.name = "del",
.help = "Remove PACKAGEs from the main dependencies and uninstall them.",
.arguments = "PACKAGE...",
.open_flags = APK_OPENF_WRITE,
.num_options = ARRAY_SIZE(del_options),
.options = del_options,
.parse = del_parse,
......
......@@ -66,7 +66,8 @@ static int cup(void)
return 0;
}
static int fetch_parse(void *ctx, int optch, int optindex, const char *optarg)
static int fetch_parse(void *ctx, struct apk_db_options *dbopts,
int optch, int optindex, const char *optarg)
{
struct fetch_ctx *fctx = (struct fetch_ctx *) ctx;
......@@ -95,7 +96,7 @@ static int fetch_package(struct fetch_ctx *fctx,
{
struct apk_istream *is;
char pkgfile[PATH_MAX], url[PATH_MAX];
int i, r, fd;
int r, i, fd;
apk_pkg_format_plain(pkg, APK_BLOB_BUF(pkgfile));
......@@ -162,11 +163,10 @@ static int fetch_package(struct fetch_ctx *fctx,
return 0;
}
static int fetch_main(void *ctx, int argc, char **argv)
static int fetch_main(void *ctx, struct apk_database *db, int argc, char **argv)
{
struct fetch_ctx *fctx = (struct fetch_ctx *) ctx;
struct apk_database db;
int i, j, r;
int r = 0, i, j;
if (fctx->outdir_fd == 0)
fctx->outdir_fd = AT_FDCWD;
......@@ -178,13 +178,9 @@ static int fetch_main(void *ctx, int argc, char **argv)
return 0;
}
r = apk_db_open(&db, apk_root, APK_OPENF_NO_STATE);
if (r != 0)
return r;
for (i = 0; i < argc; i++) {
struct apk_dependency dep = (struct apk_dependency) {
.name = apk_db_get_name(&db, APK_BLOB_STR(argv[i])),
.name = apk_db_get_name(db, APK_BLOB_STR(argv[i])),
.result_mask = APK_DEPMASK_REQUIRE,
};
......@@ -192,7 +188,7 @@ static int fetch_main(void *ctx, int argc, char **argv)
struct apk_state *state;
struct apk_change *change;
state = apk_state_new(&db);
state = apk_state_new(db);
if (state == NULL)
goto err;
......@@ -205,7 +201,7 @@ static int fetch_main(void *ctx, int argc, char **argv)
}
list_for_each_entry(change, &state->change_list_head, change_list) {
r = fetch_package(fctx, &db, change->newpkg);
r = fetch_package(fctx, db, change->newpkg);
if (r != 0)
goto err;
}
......@@ -221,7 +217,7 @@ static int fetch_main(void *ctx, int argc, char **argv)
== APK_VERSION_GREATER)
pkg = dep.name->pkgs->item[j];
r = fetch_package(fctx, &db, pkg);
r = fetch_package(fctx, db, pkg);
if (r != 0)
goto err;
} else {
......@@ -232,7 +228,6 @@ static int fetch_main(void *ctx, int argc, char **argv)
}
err:
apk_db_close(&db);
return r;
}
......@@ -250,6 +245,7 @@ static struct apk_applet apk_fetch = {
.help = "Download PACKAGEs from repositories to a local directory from "
"which a local mirror repository can be created.",
.arguments = "PACKAGE...",
.open_flags = APK_OPENF_READ|APK_OPENF_NO_STATE,
.context_size = sizeof(struct fetch_ctx),
.num_options = ARRAY_SIZE(fetch_options),
.options = fetch_options,
......
......@@ -19,7 +19,8 @@ struct fix_ctx {
unsigned int reinstall : 1;
};
static int fix_parse(void *pctx, int optch, int optindex, const char *optarg)
static int fix_parse(void *pctx, struct apk_db_options *dbopts,
int optch, int optindex, const char *optarg)
{
struct fix_ctx *ctx = (struct fix_ctx *) pctx;
switch (optch) {
......@@ -35,24 +36,19 @@ static int fix_parse(void *pctx, int optch, int optindex, const char *optarg)
return 0;
}
static int fix_main(void *pctx, int argc, char **argv)
static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv)
{
struct fix_ctx *ctx = (struct fix_ctx *) pctx;
struct apk_database db;
struct apk_state *state = NULL;
struct apk_name *name;
int r, i, j;
int r = 0, i, j;
r = apk_db_open(&db, apk_root, APK_OPENF_WRITE);
if (r != 0)
return r;
state = apk_state_new(&db);
state = apk_state_new(db);
if (state == NULL)
goto err;
return -1;
for (i = 0; i < argc; i++) {
name = apk_db_get_name(&db, APK_BLOB_STR(argv[i]));
name = apk_db_get_name(db, APK_BLOB_STR(argv[i]));
if (name == NULL)
goto err;
......@@ -72,7 +68,7 @@ static int fix_main(void *pctx, int argc, char **argv)
for (i = 0; i < argc; i++) {
struct apk_dependency dep;
r = apk_dep_from_blob(&dep, &db, APK_BLOB_STR(argv[i]));
r = apk_dep_from_blob(&dep, db, APK_BLOB_STR(argv[i]));
if (r != 0)
goto err;
......@@ -82,13 +78,12 @@ static int fix_main(void *pctx, int argc, char **argv)
goto err;
}
}
r = apk_state_commit(state, &db);
r = apk_state_commit(state, db);
err:
if (r != 0 && i < argc)
apk_error("Error while processing '%s'", argv[i]);
if (state != NULL)
apk_state_unref(state);
apk_db_close(&db);
return r;
}
......@@ -102,6 +97,7 @@ static struct apk_applet apk_fix = {
.help = "Repair package or upgrade it without modifying main "
"dependencies.",
.arguments = "PACKAGE...",
.open_flags = APK_OPENF_WRITE,
.context_size = sizeof(struct fix_ctx),
.num_options = ARRAY_SIZE(fix_options),
.options = fix_options,
......
......@@ -29,7 +29,8 @@ struct index_ctx {
int method;