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

make the atom functions not use global state

This greatly helps with memory management on applications that
may want to daemonize and open/close database several times.

Also the lifetime and "owner" of memory for all data is now
explicitly bound to owning struct apk_database, which might
be helpful when writing language bindings. As side effect, the
interned "atoms" are unique only within what apk_database, so
comparing packages from different apk_database may not work
as expected.

Fixes #10697
parent 12fdf6fc
Pipeline #18642 passed with stage
in 47 seconds
......@@ -18,7 +18,7 @@ ZLIB_LIBS := $(shell $(PKG_CONFIG) --libs zlib)
# Dynamic library
libapk.so.$(VERSION)-objs := \
common.o database.o package.o commit.o solver.o \
version.o blob.o hash.o print.o \
version.o atom.o blob.o hash.o print.o \
io.o io_url.o io_gunzip.o io_archive.o
libapk.so.$(VERSION)-libs := libfetch/libfetch.a
......
......@@ -518,7 +518,6 @@ int main(int argc, char **argv)
memset(&dbopts, 0, sizeof(dbopts));
list_init(&dbopts.repository_list);
apk_atom_init();
umask(0);
setup_terminal();
......
/* apk_atom.h - 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
*/
#ifndef APK_ATOM_H
#define APK_ATOM_H
#include "apk_hash.h"
#include "apk_blob.h"
extern apk_blob_t apk_atom_null;
struct apk_atom_pool {
struct apk_hash hash;
};
void apk_atom_init(struct apk_atom_pool *);
void apk_atom_free(struct apk_atom_pool *);
apk_blob_t *apk_atom_get(struct apk_atom_pool *atoms, apk_blob_t blob, int duplicate);
static inline apk_blob_t *apk_atomize(struct apk_atom_pool *atoms, apk_blob_t blob) {
return apk_atom_get(atoms, blob, 0);
}
static inline apk_blob_t *apk_atomize_dup(struct apk_atom_pool *atoms, apk_blob_t blob) {
return apk_atom_get(atoms, blob, 1);
}
#endif
......@@ -25,7 +25,6 @@ struct apk_blob {
};
typedef struct apk_blob apk_blob_t;
typedef int (*apk_blob_cb)(void *ctx, apk_blob_t blob);
extern apk_blob_t apk_null_blob;
#define BLOB_FMT "%.*s"
#define BLOB_PRINTF(b) (int)(b).len, (b).ptr
......@@ -130,10 +129,6 @@ void apk_blob_pull_base64(apk_blob_t *b, apk_blob_t to);
void apk_blob_pull_hexdump(apk_blob_t *b, apk_blob_t to);
int apk_blob_pull_blob_match(apk_blob_t *b, apk_blob_t match);
void apk_atom_init(void);
apk_blob_t *apk_blob_atomize(apk_blob_t blob);
apk_blob_t *apk_blob_atomize_dup(apk_blob_t blob);
#if defined(__GLIBC__) && !defined(__UCLIBC__)
extern size_t strlcpy(char *dest, const char *src, size_t size);
#endif
......
......@@ -12,6 +12,7 @@
#include "apk_version.h"
#include "apk_hash.h"
#include "apk_atom.h"
#include "apk_archive.h"
#include "apk_package.h"
#include "apk_io.h"
......@@ -166,6 +167,7 @@ struct apk_database {
struct apk_repository repos[APK_MAX_REPOS];
struct apk_repository_tag repo_tags[APK_MAX_TAGS];
struct apk_id_cache id_cache;
struct apk_atom_pool atoms;
struct {
struct apk_hash names;
......
......@@ -16,6 +16,7 @@
#include "apk_defines.h"
#include "apk_blob.h"
#include "apk_hash.h"
#include "apk_atom.h"
struct apk_id_cache {
int root_fd;
......@@ -167,7 +168,7 @@ int apk_blob_to_file(int atfd, const char *file, apk_blob_t b, unsigned int flag
#define APK_FI_XATTR_CSUM(x) (((x) & 0xff) << 8)
#define APK_FI_CSUM(x) (((x) & 0xff))
int apk_fileinfo_get(int atfd, const char *filename, unsigned int flags,
struct apk_file_info *fi);
struct apk_file_info *fi, struct apk_atom_pool *atoms);
void apk_fileinfo_hash_xattr(struct apk_file_info *fi);
void apk_fileinfo_free(struct apk_file_info *fi);
......
......@@ -100,9 +100,9 @@ static struct apk_package *create_virtual_package(struct apk_database *db, struc
if (virtpkg == NULL) return 0;
virtpkg->name = name;
virtpkg->version = apk_blob_atomize_dup(APK_BLOB_STR(ver));
virtpkg->version = apk_atomize_dup(&db->atoms, APK_BLOB_STR(ver));
virtpkg->description = strdup("virtual meta package");
virtpkg->arch = apk_blob_atomize(APK_BLOB_STR("noarch"));
virtpkg->arch = apk_atomize(&db->atoms, APK_BLOB_STR("noarch"));
mdctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(mdctx, apk_checksum_default(), NULL);
......@@ -135,7 +135,7 @@ static int add_main(void *ctx, struct apk_database *db, struct apk_string_array
apk_blob_pull_dep(&b, db, &virtdep);
if (APK_BLOB_IS_NULL(b) || virtdep.conflict ||
virtdep.result_mask != APK_DEPMASK_ANY ||
virtdep.version != &apk_null_blob) {
virtdep.version != &apk_atom_null) {
apk_error("%s: bad package specifier");
return -1;
}
......
......@@ -107,7 +107,7 @@ static int audit_file(struct audit_ctx *actx,
APK_FI_NOFOLLOW |
APK_FI_XATTR_CSUM(dbf->acl->xattr_csum.type ?: APK_CHECKSUM_DEFAULT) |
APK_FI_CSUM(dbf->csum.type),
&fi) != 0)
&fi, &db->atoms) != 0)
return -EPERM;
if (dbf->csum.type != APK_CHECKSUM_NONE &&
......@@ -183,7 +183,7 @@ static int audit_directory_tree_item(void *ctx, int dirfd, const char *name)
int reason = 0;
if (bdir.len + bent.len + 1 >= sizeof(atctx->path)) return 0;
if (apk_fileinfo_get(dirfd, name, APK_FI_NOFOLLOW, &fi) < 0) return 0;
if (apk_fileinfo_get(dirfd, name, APK_FI_NOFOLLOW, &fi, &db->atoms) < 0) return 0;
memcpy(&atctx->path[atctx->pathlen], bent.ptr, bent.len);
atctx->pathlen += bent.len;
......
......@@ -145,7 +145,7 @@ static int fetch_package(apk_hash_item item, void *pctx)
}
if (!(ctx->flags & FETCH_STDOUT)) {
if (apk_fileinfo_get(ctx->outdir_fd, filename, APK_CHECKSUM_NONE, &fi) == 0 &&
if (apk_fileinfo_get(ctx->outdir_fd, filename, APK_CHECKSUM_NONE, &fi, &db->atoms) == 0 &&
fi.size == pkg->size)
return 0;
}
......@@ -227,7 +227,7 @@ static void mark_name_flags(struct apk_database *db, const char *match, struct a
struct fetch_ctx *ctx = (struct fetch_ctx *) pctx;
struct apk_dependency dep = (struct apk_dependency) {
.name = name,
.version = &apk_null_blob,
.version = &apk_atom_null,
.result_mask = APK_DEPMASK_ANY,
};
......
......@@ -27,7 +27,7 @@ struct index_ctx {
const char *index;
const char *output;
const char *description;
apk_blob_t *rewrite_arch;
const char *rewrite_arch;
time_t index_mtime;
int method;
unsigned short index_flags;
......@@ -64,7 +64,7 @@ static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int opt
ictx->output = optarg;
break;
case OPT_INDEX_rewrite_arch:
ictx->rewrite_arch = apk_blob_atomize(APK_BLOB_STR(optarg));
ictx->rewrite_arch = optarg;
break;
case OPT_INDEX_no_warnings:
ictx->index_flags |= APK_INDEXF_NO_WARNINGS;
......@@ -86,7 +86,7 @@ static int index_read_file(struct apk_database *db, struct index_ctx *ictx)
if (ictx->index == NULL)
return 0;
if (apk_fileinfo_get(AT_FDCWD, ictx->index, APK_CHECKSUM_NONE, &fi) < 0)
if (apk_fileinfo_get(AT_FDCWD, ictx->index, APK_CHECKSUM_NONE, &fi, &db->atoms) < 0)
return 0;
ictx->index_mtime = fi.mtime;
......@@ -121,6 +121,7 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
struct index_ctx *ictx = (struct index_ctx *) ctx;
struct apk_package *pkg;
char **parg;
apk_blob_t *rewrite_arch = NULL;
if (isatty(STDOUT_FILENO) && ictx->output == NULL &&
!(apk_force & APK_FORCE_BINARY_STDOUT)) {
......@@ -137,8 +138,11 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
return r;
}
if (ictx->rewrite_arch)
rewrite_arch = apk_atomize(&db->atoms, APK_BLOB_STR(ictx->rewrite_arch));
foreach_array_item(parg, args) {
if (apk_fileinfo_get(AT_FDCWD, *parg, APK_CHECKSUM_NONE, &fi) < 0) {
if (apk_fileinfo_get(AT_FDCWD, *parg, APK_CHECKSUM_NONE, &fi, &db->atoms) < 0) {
apk_warning("File '%s' is unaccessible", *parg);
continue;
}
......@@ -174,15 +178,11 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
foreach_array_item(p, name->providers) {
pkg = p->pkg;
if (pkg->name != name)
continue;
if (apk_blob_compare(bver, *pkg->version) != 0)
continue;
if (pkg->size != fi.size)
continue;
if (pkg->name != name) continue;
if (apk_blob_compare(bver, *pkg->version) != 0) continue;
if (pkg->size != fi.size) continue;
pkg->filename = strdup(*parg);
if (ictx->rewrite_arch != NULL)
pkg->arch = ictx->rewrite_arch;
if (rewrite_arch) pkg->arch = rewrite_arch;
found = TRUE;
break;
}
......@@ -197,8 +197,7 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
errors++;
} else {
newpkgs++;
if (ictx->rewrite_arch != NULL)
pkg->arch = ictx->rewrite_arch;
if (rewrite_arch) pkg->arch = rewrite_arch;
}
apk_sign_ctx_free(&sctx);
}
......
......@@ -125,7 +125,7 @@ static void info_who_owns(struct info_ctx *ctx, struct apk_database *db,
if (apk_verbosity < 1) {
dep = (struct apk_dependency) {
.name = pkg->name,
.version = apk_blob_atomize(APK_BLOB_NULL),
.version = &apk_atom_null,
.result_mask = APK_DEPMASK_ANY,
};
apk_deps_add(&deps, &dep);
......
......@@ -67,33 +67,25 @@ static const struct apk_package *is_upgradable(struct apk_name *name, const stru
{
struct apk_provider *p;
struct apk_package *ipkg;
apk_blob_t *latest = apk_blob_atomize(APK_BLOB_STR(""));
apk_blob_t no_version = APK_BLOB_STR("");
apk_blob_t *latest = &no_version;
int r;
if (name == NULL)
return NULL;
if (!name) return NULL;
ipkg = apk_pkg_get_installed(name);
if (ipkg == NULL)
return NULL;
if (!ipkg) return NULL;
if (pkg0 == NULL)
{
foreach_array_item(p, name->providers)
{
if (!pkg0) {
foreach_array_item(p, name->providers) {
pkg0 = p->pkg;
int r;
if (pkg0 == ipkg)
continue;
if (pkg0 == ipkg) continue;
r = apk_version_compare_blob(*pkg0->version, *latest);
if (r == APK_VERSION_GREATER)
latest = pkg0->version;
if (r == APK_VERSION_GREATER) latest = pkg0->version;
}
}
else
} else {
latest = pkg0->version;
}
return apk_version_compare_blob(*ipkg->version, *latest) == APK_VERSION_LESS ? ipkg : NULL;
}
......
......@@ -24,8 +24,6 @@ static int list_count(struct list_head *h)
static int stats_main(void *ctx, struct apk_database *db, struct apk_string_array *args)
{
extern struct apk_hash atom_hash;
printf(
"installed:\n"
" packages: %d\n"
......@@ -46,7 +44,7 @@ static int stats_main(void *ctx, struct apk_database *db, struct apk_string_arra
list_count(&db->installed.triggers),
db->available.names.num_items,
db->available.packages.num_items,
atom_hash.num_items
db->atoms.hash.num_items
);
return 0;
}
......
......@@ -174,7 +174,7 @@ static int upgrade_main(void *ctx, struct apk_database *db, struct apk_string_ar
foreach_array_item(dep, world) {
if (dep->result_mask == APK_DEPMASK_CHECKSUM) {
dep->result_mask = APK_DEPMASK_ANY;
dep->version = apk_blob_atomize(APK_BLOB_NULL);
dep->version = &apk_atom_null;
}
}
} else {
......
......@@ -121,7 +121,7 @@ static void ver_print_package_status(struct apk_database *db, const char *match,
struct apk_provider *p0;
char pkgname[41];
const char *opstr;
apk_blob_t *latest = apk_blob_atomize(APK_BLOB_STR(""));
apk_blob_t *latest = apk_atomize(&db->atoms, APK_BLOB_STR(""));
unsigned int latest_repos = 0;
int i, r = -1;
unsigned short tag, allowed_repos;
......
/* apk_atom.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_atom.h"
apk_blob_t apk_atom_null = APK_BLOB_NULL;
struct apk_atom_hashnode {
struct hlist_node hash_node;
apk_blob_t blob;
};
static apk_blob_t atom_hash_get_key(apk_hash_item item)
{
return ((struct apk_atom_hashnode *) item)->blob;
}
static struct apk_hash_ops atom_ops = {
.node_offset = offsetof(struct apk_atom_hashnode, hash_node),
.get_key = atom_hash_get_key,
.hash_key = apk_blob_hash,
.compare = apk_blob_compare,
.delete_item = (apk_hash_delete_f) free,
};
void apk_atom_init(struct apk_atom_pool *atoms)
{
apk_hash_init(&atoms->hash, &atom_ops, 10000);
}
void apk_atom_free(struct apk_atom_pool *atoms)
{
apk_hash_free(&atoms->hash);
}
apk_blob_t *apk_atom_get(struct apk_atom_pool *atoms, apk_blob_t blob, int duplicate)
{
struct apk_atom_hashnode *atom;
unsigned long hash = apk_hash_from_key(&atoms->hash, blob);
if (blob.len < 0 || !blob.ptr) return &apk_atom_null;
atom = (struct apk_atom_hashnode *) apk_hash_get_hashed(&atoms->hash, blob, hash);
if (atom) return &atom->blob;
if (duplicate) {
char *ptr;
atom = malloc(sizeof(*atom) + blob.len);
ptr = (char*) (atom + 1);
memcpy(ptr, blob.ptr, blob.len);
atom->blob = APK_BLOB_PTR_LEN(ptr, blob.len);
} else {
atom = malloc(sizeof(*atom));
atom->blob = blob;
}
apk_hash_insert_hashed(&atoms->hash, atom, hash);
return &atom->blob;
}
......@@ -15,11 +15,6 @@
#include "apk_blob.h"
#include "apk_hash.h"
struct apk_blob_atom {
struct hlist_node hash_node;
apk_blob_t blob;
};
char *apk_blob_cstr(apk_blob_t blob)
{
char *cstr;
......@@ -640,77 +635,6 @@ err:
*b = APK_BLOB_NULL;
}
static apk_blob_t atom_hash_get_key(apk_hash_item item)
{
return ((struct apk_blob_atom *) item)->blob;
}
struct apk_hash atom_hash;
static struct apk_hash_ops atom_ops = {
.node_offset = offsetof(struct apk_blob_atom, hash_node),
.get_key = atom_hash_get_key,
.hash_key = apk_blob_hash,
.compare = apk_blob_compare,
.delete_item = (apk_hash_delete_f) free,
};
apk_blob_t apk_null_blob = {0,0};
#ifdef VALGRIND
static void apk_atom_fini(void)
{
apk_hash_free(&atom_hash);
}
#endif
void apk_atom_init(void)
{
#ifdef VALGRIND
atexit(apk_atom_fini);
#endif
apk_hash_init(&atom_hash, &atom_ops, 10000);
}
apk_blob_t *apk_blob_atomize(apk_blob_t blob)
{
struct apk_blob_atom *atom;
unsigned long hash = apk_hash_from_key(&atom_hash, blob);
if (blob.len < 0 || blob.ptr == NULL)
return &apk_null_blob;
atom = (struct apk_blob_atom *) apk_hash_get_hashed(&atom_hash, blob, hash);
if (atom != NULL)
return &atom->blob;
atom = malloc(sizeof(*atom));
atom->blob = blob;
apk_hash_insert_hashed(&atom_hash, atom, hash);
return &atom->blob;
}
apk_blob_t *apk_blob_atomize_dup(apk_blob_t blob)
{
struct apk_blob_atom *atom;
unsigned long hash = apk_hash_from_key(&atom_hash, blob);
char *ptr;
if (blob.len < 0 || blob.ptr == NULL)
return &apk_null_blob;
atom = (struct apk_blob_atom *) apk_hash_get_hashed(&atom_hash, blob, hash);
if (atom != NULL)
return &atom->blob;
atom = malloc(sizeof(*atom) + blob.len);
ptr = (char*) (atom + 1);
memcpy(ptr, blob.ptr, blob.len);
atom->blob = APK_BLOB_PTR_LEN(ptr, blob.len);
apk_hash_insert_hashed(&atom_hash, atom, hash);
return &atom->blob;
}
#if defined(__GLIBC__) && !defined(__UCLIBC__)
size_t strlcpy(char *dst, const char *src, size_t size)
{
......
......@@ -453,8 +453,8 @@ static void print_conflicts(struct print_state *ps, struct apk_package *pkg)
foreach_array_item(p, d->name->providers) {
if (!p->pkg->marked)
continue;
if (d->version == &apk_null_blob &&
p->version == &apk_null_blob)
if (d->version == &apk_atom_null &&
p->version == &apk_atom_null)
continue;
if (once && p->pkg == pkg &&
p->version == d->version) {
......
......@@ -225,7 +225,7 @@ struct apk_name *apk_db_get_name(struct apk_database *db, apk_blob_t name)
return pn;
}
static struct apk_db_acl *apk_db_acl_atomize(mode_t mode, uid_t uid, gid_t gid, const struct apk_checksum *xattr_csum)
static struct apk_db_acl *apk_db_acl_atomize(struct apk_database *db, mode_t mode, uid_t uid, gid_t gid, const struct apk_checksum *xattr_csum)
{
struct apk_db_acl acl = { .mode = mode & 07777, .uid = uid, .gid = gid };
apk_blob_t *b;
......@@ -233,7 +233,7 @@ static struct apk_db_acl *apk_db_acl_atomize(mode_t mode, uid_t uid, gid_t gid,
if (xattr_csum && xattr_csum->type != APK_CHECKSUM_NONE)
acl.xattr_csum = *xattr_csum;
b = apk_blob_atomize_dup(APK_BLOB_STRUCT(acl));
b = apk_atomize_dup(&db->atoms, APK_BLOB_STRUCT(acl));
return (struct apk_db_acl *) b->ptr;
}
......@@ -518,8 +518,7 @@ struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *
struct apk_package *idb;
struct apk_dependency *dep;
if (pkg->license == NULL)
pkg->license = apk_blob_atomize(APK_BLOB_NULL);
if (!pkg->license) pkg->license = &apk_atom_null;
/* Set as "cached" if installing from specified file, and
* for virtual packages */
......@@ -848,7 +847,7 @@ int apk_db_index_read(struct apk_database *db, struct apk_istream *is, int repo)
else
xattr_csum.type = APK_CHECKSUM_NONE;
acl = apk_db_acl_atomize(mode, uid, gid, &xattr_csum);
acl = apk_db_acl_atomize(db, mode, uid, gid, &xattr_csum);
if (field == 'M')
diri->acl = acl;
else
......@@ -1501,6 +1500,7 @@ void apk_db_init(struct apk_database *db)
apk_hash_init(&db->available.packages, &pkg_info_hash_ops, 10000);
apk_hash_init(&db->installed.dirs, &dir_hash_ops, 20000);
apk_hash_init(&db->installed.files, &file_hash_ops, 200000);
apk_atom_init(&db->atoms);
list_init(&db->installed.packages);
list_init(&db->installed.triggers);
apk_dependency_array_init(&db->world);
......@@ -1517,8 +1517,8 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
apk_blob_t blob;
int r, fd, write_arch = FALSE;
apk_default_acl_dir = apk_db_acl_atomize(0755, 0, 0, NULL);
apk_default_acl_file = apk_db_acl_atomize(0644, 0, 0, NULL);
apk_default_acl_dir = apk_db_acl_atomize(db, 0755, 0, 0, NULL);
apk_default_acl_file = apk_db_acl_atomize(db, 0644, 0, 0, NULL);
if (apk_flags & APK_SIMULATE) {
dbopts->open_flags &= ~(APK_OPENF_CREATE | APK_OPENF_WRITE);
......@@ -1553,16 +1553,16 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
db->permanent = 0;
if (dbopts->root && dbopts->arch) {
db->arch = apk_blob_atomize(APK_BLOB_STR(dbopts->arch));
db->arch = apk_atomize(&db->atoms, APK_BLOB_STR(dbopts->arch));
write_arch = TRUE;
} else {
apk_blob_t arch;
arch = apk_blob_from_file(db->root_fd, apk_arch_file);
if (!APK_BLOB_IS_NULL(arch)) {
db->arch = apk_blob_atomize_dup(apk_blob_trim(arch));
db->arch = apk_atomize_dup(&db->atoms, apk_blob_trim(arch));
free(arch.ptr);
} else {
db->arch = apk_blob_atomize(APK_BLOB_STR(APK_DEFAULT_ARCH));
db->arch = apk_atomize(&db->atoms, APK_BLOB_STR(APK_DEFAULT_ARCH));
write_arch = TRUE;
}
}
......@@ -1820,6 +1820,7 @@ void apk_db_close(struct apk_database *db)
apk_hash_free(&db->available.names);
apk_hash_free(&db->installed.files);
apk_hash_free(&db->installed.dirs);
apk_atom_free(&db->atoms);
if (db->root_proc_dir) {
umount2(db->root_proc_dir, MNT_DETACH|UMOUNT_NOFOLLOW);
......@@ -1867,12 +1868,12 @@ int apk_db_get_tag_id(struct apk_database *db, apk_blob_t tag)
db->num_repo_tags++;
if (tag.ptr[0] == '@') {
db->repo_tags[i].tag = *apk_blob_atomize_dup(tag);
db->repo_tags[i].tag = *apk_atomize_dup(&db->atoms, tag);
} else {
char *tmp = alloca(tag.len + 1);
tmp[0] = '@';
memcpy(&tmp[1], tag.ptr, tag.len);
db->repo_tags[i].tag = *apk_blob_atomize_dup(APK_BLOB_PTR_LEN(tmp, tag.len+1));
db->repo_tags[i].tag = *apk_atomize_dup(&db->atoms, APK_BLOB_PTR_LEN(tmp, tag.len+1));
}
db->repo_tags[i].plain_name = db->repo_tags[i].tag;
......@@ -2551,7 +2552,7 @@ static int apk_db_install_archive_entry(void *_ctx,
apk_message("%s", ae->name);
/* Extract the file with temporary name */
file->acl = apk_db_acl_atomize(ae->mode, ae->uid, ae->gid, &ae->xattr_csum);
file->acl = apk_db_acl_atomize(db, ae->mode, ae->uid, ae->gid, &ae->xattr_csum);
r = apk_archive_entry_extract(
db->root_fd, ae,
format_tmpname(pkg, file, tmpname_file),
......@@ -2592,7 +2593,7 @@ static int apk_db_install_archive_entry(void *_ctx,
diri = apk_db_install_directory_entry(ctx, name);
apk_db_dir_prepare(db, diri->dir, ae->mode);
}
apk_db_diri_set(diri, apk_db_acl_atomize(ae->mode, ae->uid, ae->gid, &ae->xattr_csum));
apk_db_diri_set(diri, apk_db_acl_atomize(db, ae->mode, ae->uid, ae->gid, &ae->xattr_csum));
}
ctx->installed_size += ctx->current_file_size;
......@@ -2628,7 +2629,7 @@ static void apk_db_purge_pkg(struct apk_database *db,
if ((diri->dir->protect_mode == APK_PROTECT_NONE) ||
(apk_flags & APK_PURGE) ||
(file->csum.type != APK_CHECKSUM_NONE &&
apk_fileinfo_get(db->root_fd, name, APK_FI_NOFOLLOW | file->csum.type, &fi) == 0 &&
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)
......@@ -2684,7 +2685,7 @@ static void apk_db_migrate_files(struct apk_database *db,
cstype = ofile->csum.type;
cstype |= APK_FI_NOFOLLOW;
r = apk_fileinfo_get(db->root_fd, name, cstype, &fi);
r = apk_fileinfo_get(db->root_fd, name, cstype, &fi, &db->atoms);
if (ofile && ofile->diri->pkg->name == NULL) {
/* File was from overlay, delete the
* packages version */
......@@ -2702,7 +2703,8 @@ static void apk_db_migrate_files(struct apk_database *db,
if (ofile == NULL ||
ofile->csum.type != file->csum.type)
apk_fileinfo_get(db->root_fd, name,
APK_FI_NOFOLLOW | file->csum.type, &fi);
APK_FI_NOFOLLOW | file->csum.type,
&fi, &db->atoms);
if ((apk_flags & APK_CLEAN_PROTECTED) ||
(file->csum.type != APK_CHECKSUM_NONE &&
apk_checksum_compare(&file->csum, &fi.csum) == 0)) {
......
......@@ -93,6 +93,7 @@ void apk_hash_delete_hashed(struct apk_hash *h, apk_blob_t key, unsigned long ha
if (h->ops->compare_item(item, key