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 #10697cute-signatures
parent
12fdf6fc21
commit
d0edeec8fb
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
76
src/blob.c
76
src/blob.c
|
@ -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) == 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
11
src/io.c
11
src/io.c
|
@ -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)) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
24
src/solver.c
24
src/solver.c
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue