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
cute-signatures
Timo Teräs 2020-05-19 11:39:21 +03:00
parent 12fdf6fc21
commit d0edeec8fb
24 changed files with 185 additions and 179 deletions

View File

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

View File

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

33
src/apk_atom.h Normal file
View File

@ -0,0 +1,33 @@
/* 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

64
src/atom.c Normal file
View File

@ -0,0 +1,64 @@
/* 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;
}

View File

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

View File

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

View File

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

View File

@ -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) == 0) {
hlist_del(pos, &h->buckets->item[hash]);
h->ops->delete_item(item);
h->num_items--;
break;
}
}
@ -103,9 +104,9 @@ void apk_hash_delete_hashed(struct apk_hash *h, apk_blob_t key, unsigned long ha
if (h->ops->compare(key, itemkey) == 0) {
hlist_del(pos, &h->buckets->item[hash]);
h->ops->delete_item(item);
h->num_items--;
break;
}
}
}
}

View File

@ -692,7 +692,7 @@ void apk_fileinfo_hash_xattr(struct apk_file_info *fi)
}
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)
{
struct stat64 st;
unsigned int checksum = flags & 0xff;
@ -735,7 +735,7 @@ int apk_fileinfo_get(int atfd, const char *filename, unsigned int flags,
}
*apk_xattr_array_add(&xattrs) = (struct apk_xattr) {
.name = &buf[i],
.value = *apk_blob_atomize_dup(APK_BLOB_PTR_LEN(val, vlen)),
.value = *apk_atomize_dup(atoms, APK_BLOB_PTR_LEN(val, vlen)),
};
}
apk_fileinfo_hash_xattr_array(xattrs, apk_checksum_evp(xattr_checksum), &fi->xattr_csum);
@ -747,11 +747,8 @@ int apk_fileinfo_get(int atfd, const char *filename, unsigned int flags,
if (r && r != ENOTSUP) return -r;
}
if (checksum == APK_CHECKSUM_NONE)
return 0;
if (S_ISDIR(st.st_mode))
return 0;
if (checksum == APK_CHECKSUM_NONE) return 0;
if (S_ISDIR(st.st_mode)) return 0;
/* Checksum file content */
if ((flags & APK_FI_NOFOLLOW) && S_ISLNK(st.st_mode)) {

View File

@ -171,7 +171,6 @@ static int Papk_db_open(lua_State *L)
memset(&opts, 0, sizeof(opts));
list_init(&opts.repository_list);
apk_atom_init();
if (lua_istable(L, 1))
get_dbopts(L, 1, &opts);
else

View File

@ -259,7 +259,7 @@ void apk_blob_pull_dep(apk_blob_t *b, struct apk_database *db, struct apk_depend
*dep = (struct apk_dependency){
.name = name,
.version = apk_blob_atomize_dup(bver),
.version = apk_atomize_dup(&db->atoms, bver),
.repository_tag = tag,
.result_mask = mask,
.conflict = conflict,
@ -295,7 +295,7 @@ void apk_dep_from_pkg(struct apk_dependency *dep, struct apk_database *db,
*dep = (struct apk_dependency) {
.name = pkg->name,
.version = apk_blob_atomize_dup(b),
.version = apk_atomize_dup(&db->atoms, b),
.result_mask = APK_DEPMASK_CHECKSUM,
};
}
@ -323,7 +323,7 @@ int apk_dep_is_provided(struct apk_dependency *dep, struct apk_provider *p)
case APK_DEPMASK_ANY:
return !dep->conflict;
default:
if (p->version == &apk_null_blob)
if (p->version == &apk_atom_null)
return dep->conflict;
if (apk_version_compare_blob_fuzzy(*p->version, *dep->version, dep->fuzzy)
& dep->result_mask)
@ -779,7 +779,7 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
pkg->name = apk_db_get_name(db, value);
break;
case 'V':
pkg->version = apk_blob_atomize_dup(value);
pkg->version = apk_atomize_dup(&db->atoms, value);
break;
case 'T':
pkg->description = apk_blob_cstr(value);
@ -788,10 +788,10 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
pkg->url = apk_blob_cstr(value);
break;
case 'L':
pkg->license = apk_blob_atomize_dup(value);
pkg->license = apk_atomize_dup(&db->atoms, value);
break;
case 'A':
pkg->arch = apk_blob_atomize_dup(value);
pkg->arch = apk_atomize_dup(&db->atoms, value);
break;
case 'D':
apk_blob_pull_deps(&value, db, &pkg->depends);
@ -812,10 +812,10 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
apk_blob_pull_deps(&value, db, &pkg->install_if);
break;
case 'o':
pkg->origin = apk_blob_atomize_dup(value);
pkg->origin = apk_atomize_dup(&db->atoms, value);
break;
case 'm':
pkg->maintainer = apk_blob_atomize_dup(value);
pkg->maintainer = apk_atomize_dup(&db->atoms, value);
break;
case 't':
pkg->build_time = apk_blob_pull_uint(&value, 10);
@ -921,7 +921,7 @@ int apk_pkg_read(struct apk_database *db, const char *file,
struct apk_file_info fi;
int r;
r = apk_fileinfo_get(AT_FDCWD, file, APK_CHECKSUM_NONE, &fi);
r = apk_fileinfo_get(AT_FDCWD, file, APK_CHECKSUM_NONE, &fi, &db->atoms);
if (r != 0)
return r;

View File

@ -42,7 +42,7 @@ struct apk_solver_state {
static struct apk_provider provider_none = {
.pkg = NULL,
.version = &apk_null_blob
.version = &apk_atom_null
};
void apk_solver_set_name_flags(struct apk_name *name,
@ -321,10 +321,10 @@ static void exclude_non_providers(struct apk_solver_state *ss, struct apk_name *
foreach_array_item(p, name->providers) {
if (p->pkg->name == must_provide || !p->pkg->ss.pkg_selectable ||
(skip_virtuals && p->version == &apk_null_blob))
(skip_virtuals && p->version == &apk_atom_null))
goto next;
foreach_array_item(d, p->pkg->provides)
if (d->name == must_provide || (skip_virtuals && d->version == &apk_null_blob))
if (d->name == must_provide || (skip_virtuals && d->version == &apk_atom_null))
goto next;
disqualify_package(ss, p->pkg, "provides transitivity");
next: ;
@ -425,10 +425,10 @@ static void reconsider_name(struct apk_solver_state *ss, struct apk_name *name)
merge_index(&dep->name->ss.merge_depends, num_options);
if (merge_index(&pkg->name->ss.merge_provides, num_options))
pkg->name->ss.has_virtual_provides |= (p->version == &apk_null_blob);
pkg->name->ss.has_virtual_provides |= (p->version == &apk_atom_null);
foreach_array_item(dep, pkg->provides)
if (merge_index(&dep->name->ss.merge_provides, num_options))
dep->name->ss.has_virtual_provides |= (dep->version == &apk_null_blob);
dep->name->ss.has_virtual_provides |= (dep->version == &apk_atom_null);
num_tag_not_ok += !pkg->ss.tag_ok;
num_options++;
@ -630,8 +630,8 @@ static void assign_name(struct apk_solver_state *ss, struct apk_name *name, stru
if (name->ss.locked) {
/* If both are providing this name without version, it's ok */
if (p.version == &apk_null_blob &&
name->ss.chosen.version == &apk_null_blob)
if (p.version == &apk_atom_null &&
name->ss.chosen.version == &apk_atom_null)
return;
if (ss->ignore_conflict)
return;
@ -656,8 +656,8 @@ static void assign_name(struct apk_solver_state *ss, struct apk_name *name, stru
foreach_array_item(p0, name->providers) {
if (p0->pkg == p.pkg)
continue;
if (p.version == &apk_null_blob &&
p0->version == &apk_null_blob)
if (p.version == &apk_atom_null &&
p0->version == &apk_atom_null)
continue;
disqualify_package(ss, p0->pkg, "conflicting provides");
}
@ -668,7 +668,7 @@ static void assign_name(struct apk_solver_state *ss, struct apk_name *name, stru
static void select_package(struct apk_solver_state *ss, struct apk_name *name)
{
struct apk_provider chosen = { NULL, &apk_null_blob }, *p;
struct apk_provider chosen = { NULL, &apk_atom_null }, *p;
struct apk_package *pkg = NULL;
struct apk_dependency *d;
@ -689,7 +689,7 @@ static void select_package(struct apk_solver_state *ss, struct apk_name *name)
continue;
/* Virtual packages without provider_priority cannot be autoselected,
* unless there is only one provider */
if (p->version == &apk_null_blob &&
if (p->version == &apk_atom_null &&
p->pkg->name->auto_select_virtual == 0 &&
p->pkg->name->ss.requirers == 0 &&
(p->pkg->provider_priority == 0 && name->providers->num > 1))
@ -934,7 +934,7 @@ static void generate_changeset(struct apk_solver_state *ss, struct apk_dependenc
pkg->name->ss.installed_pkg = pkg;
pkg->name->ss.installed_name = pkg->name;
foreach_array_item(d, pkg->provides)
if (d->version != &apk_null_blob)
if (d->version != &apk_atom_null)
d->name->ss.installed_name = pkg->name;
}
list_for_each_entry(ipkg, &ss->db->installed.packages, installed_pkgs_list)