db, add: support adding v3 package files
parent
9bd1e95e5b
commit
40f0866367
|
@ -253,11 +253,11 @@ static int __adb_m_stream(struct adb *db, struct apk_istream *is, uint32_t expec
|
|||
} while (1);
|
||||
err:
|
||||
if (r > 0) r = -APKE_ADB_BLOCK;
|
||||
if (r == 0) {
|
||||
if (r == 0 || r == -ECANCELED) {
|
||||
if (!trusted) r = -APKE_SIGNATURE_UNTRUSTED;
|
||||
else if (!db->adb.ptr) r = -APKE_ADB_BLOCK;
|
||||
}
|
||||
if (r != 0) {
|
||||
if (r != 0 && r != -ECANCELED) {
|
||||
free(db->adb.ptr);
|
||||
db->adb = APK_BLOB_NULL;
|
||||
}
|
||||
|
|
|
@ -120,8 +120,12 @@ static inline int apk_digest_cmp_csum(const struct apk_digest *d, const struct a
|
|||
}
|
||||
static inline void apk_checksum_from_digest(struct apk_checksum *csum, const struct apk_digest *d)
|
||||
{
|
||||
csum->type = d->len;
|
||||
memcpy(csum->data, d->data, d->len);
|
||||
if (d->len > sizeof csum->data) {
|
||||
csum->type = APK_CHECKSUM_NONE;
|
||||
} else {
|
||||
csum->type = d->len;
|
||||
memcpy(csum->data, d->data, d->len);
|
||||
}
|
||||
}
|
||||
|
||||
// Asymmetric keys
|
||||
|
|
|
@ -18,6 +18,8 @@ struct adb_obj;
|
|||
struct apk_ctx;
|
||||
struct apk_extract_ctx;
|
||||
|
||||
#define APK_EXTRACT_SKIP_FILE 0x111
|
||||
|
||||
#define APK_EXTRACTF_NO_CHOWN 0x0001
|
||||
#define APK_EXTRACTF_NO_OVERWRITE 0x0002
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "apk_io.h"
|
||||
#include "apk_solver_data.h"
|
||||
|
||||
struct adb_obj;
|
||||
struct apk_database;
|
||||
struct apk_name;
|
||||
struct apk_provider;
|
||||
|
@ -119,6 +120,9 @@ void apk_blob_pull_deps(apk_blob_t *from, struct apk_database *, struct apk_depe
|
|||
int apk_deps_write(struct apk_database *db, struct apk_dependency_array *deps,
|
||||
struct apk_ostream *os, apk_blob_t separator);
|
||||
|
||||
void apk_dep_from_adb(struct apk_dependency *dep, struct apk_database *db, struct adb_obj *d);
|
||||
void apk_deps_from_adb(struct apk_dependency_array **deps, struct apk_database *db, struct adb_obj *da);
|
||||
|
||||
void apk_deps_add(struct apk_dependency_array **depends, struct apk_dependency *dep);
|
||||
void apk_deps_del(struct apk_dependency_array **deps, struct apk_name *name);
|
||||
int apk_script_type(const char *name);
|
||||
|
@ -126,13 +130,14 @@ int apk_script_type(const char *name);
|
|||
struct apk_package *apk_pkg_get_installed(struct apk_name *name);
|
||||
|
||||
struct apk_package *apk_pkg_new(void);
|
||||
int apk_pkg_read(struct apk_database *db, const char *name, struct apk_package **pkg);
|
||||
int apk_pkg_read(struct apk_database *db, const char *name, struct apk_package **pkg, int v3ok);
|
||||
void apk_pkg_free(struct apk_package *pkg);
|
||||
|
||||
int apk_pkg_parse_name(apk_blob_t apkname, apk_blob_t *name, apk_blob_t *version);
|
||||
|
||||
int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
|
||||
char field, apk_blob_t value);
|
||||
void apk_pkg_from_adb(struct apk_database *db, struct apk_package *pkg, struct adb_obj *pkgo);
|
||||
|
||||
struct apk_installed_package *apk_pkg_install(struct apk_database *db, struct apk_package *pkg);
|
||||
void apk_pkg_uninstall(struct apk_database *db, struct apk_package *pkg);
|
||||
|
|
|
@ -160,7 +160,7 @@ static int add_main(void *ctx, struct apk_ctx *ac, struct apk_string_array *args
|
|||
if (non_repository_check(db))
|
||||
return -1;
|
||||
|
||||
r = apk_pkg_read(db, *parg, &pkg);
|
||||
r = apk_pkg_read(db, *parg, &pkg, TRUE);
|
||||
if (r != 0) {
|
||||
apk_err(out, "%s: %s", *parg, apk_error_str(r));
|
||||
return -1;
|
||||
|
|
|
@ -182,7 +182,7 @@ static int index_main(void *ctx, struct apk_ctx *ac, struct apk_string_array *ar
|
|||
} while (0);
|
||||
|
||||
if (!found) {
|
||||
r = apk_pkg_read(db, *parg, &pkg);
|
||||
r = apk_pkg_read(db, *parg, &pkg, FALSE);
|
||||
if (r < 0) {
|
||||
apk_err(out, "%s: %s", *parg, apk_error_str(r));
|
||||
errors++;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "apk_print.h"
|
||||
#include "apk_openssl.h"
|
||||
#include "apk_tar.h"
|
||||
#include "apk_adb.h"
|
||||
|
||||
static const apk_spn_match_def apk_spn_repo_separators = {
|
||||
[1] = (1<<1) /* tab */,
|
||||
|
@ -2374,6 +2375,29 @@ static int apk_db_install_v2meta(struct apk_extract_ctx *ectx, struct apk_istrea
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int apk_db_install_v3meta(struct apk_extract_ctx *ectx, struct adb_obj *pkg)
|
||||
{
|
||||
struct install_ctx *ctx = container_of(ectx, struct install_ctx, ectx);
|
||||
struct apk_database *db = ctx->db;
|
||||
struct apk_installed_package *ipkg = ctx->ipkg;
|
||||
struct adb_obj triggers, pkginfo, obj;
|
||||
int i;
|
||||
|
||||
apk_pkg_from_adb(db, ctx->pkg, pkg);
|
||||
adb_ro_obj(pkg, ADBI_PKG_PKGINFO, &pkginfo);
|
||||
apk_deps_from_adb(&ipkg->replaces, db, adb_ro_obj(&pkginfo, ADBI_PI_REPLACES, &obj));
|
||||
ipkg->replaces_priority = adb_ro_int(&pkginfo, ADBI_PI_PRIORITY);
|
||||
|
||||
apk_string_array_resize(&ipkg->triggers, 0);
|
||||
adb_ro_obj(pkg, ADBI_PKG_TRIGGERS, &triggers);
|
||||
for (i = ADBI_FIRST; i <= adb_ra_num(&triggers); i++)
|
||||
*apk_string_array_add(&ipkg->triggers) = apk_blob_cstr(adb_ro_blob(&triggers, i));
|
||||
if (ctx->ipkg->triggers->num != 0 && !list_hashed(&ipkg->trigger_pkgs_list))
|
||||
list_add_tail(&ipkg->trigger_pkgs_list, &db->installed.triggers);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apk_db_install_script(struct apk_extract_ctx *ectx, unsigned int type, size_t size, struct apk_istream *is)
|
||||
{
|
||||
struct install_ctx *ctx = container_of(ectx, struct install_ctx, ectx);
|
||||
|
@ -2412,6 +2436,13 @@ static int apk_db_install_file(struct apk_extract_ctx *ectx, const struct apk_fi
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (ae->uvol_name) {
|
||||
apk_warn(out, PKG_VER_FMT": %s: uvol not supported yet",
|
||||
PKG_VER_PRINTF(pkg), ae->name);
|
||||
ipkg->broken_files = 1;
|
||||
return APK_EXTRACT_SKIP_FILE;
|
||||
}
|
||||
|
||||
/* Installable entry */
|
||||
ctx->current_file_size = apk_calc_installed_size(ae->size);
|
||||
if (!S_ISDIR(ae->mode)) {
|
||||
|
@ -2542,13 +2573,19 @@ static int apk_db_install_file(struct apk_extract_ctx *ectx, const struct apk_fi
|
|||
else
|
||||
apk_checksum_from_digest(&file->csum, &ae->digest);
|
||||
/* only warn once per package */
|
||||
if (file->csum.type == APK_CHECKSUM_NONE && !ctx->missing_checksum) {
|
||||
if (ae->digest.alg == APK_DIGEST_NONE && !ctx->missing_checksum) {
|
||||
apk_warn(out,
|
||||
PKG_VER_FMT": support for packages without embedded "
|
||||
"checksums will be dropped in apk-tools 3.",
|
||||
PKG_VER_PRINTF(pkg));
|
||||
ipkg->broken_files = 1;
|
||||
ctx->missing_checksum = 1;
|
||||
} else if (file->csum.type == APK_CHECKSUM_NONE && !ctx->missing_checksum) {
|
||||
apk_warn(out,
|
||||
PKG_VER_FMT": v3 checksums ignored",
|
||||
PKG_VER_PRINTF(pkg));
|
||||
ipkg->broken_files = 1;
|
||||
ctx->missing_checksum = 1;
|
||||
}
|
||||
break;
|
||||
case -ENOTSUP:
|
||||
|
@ -2580,6 +2617,7 @@ static int apk_db_install_file(struct apk_extract_ctx *ectx, const struct apk_fi
|
|||
|
||||
static const struct apk_extract_ops extract_installer = {
|
||||
.v2meta = apk_db_install_v2meta,
|
||||
.v3meta = apk_db_install_v3meta,
|
||||
.script = apk_db_install_script,
|
||||
.file = apk_db_install_file,
|
||||
};
|
||||
|
|
|
@ -93,6 +93,8 @@ static int apk_extract_v3_file(struct apk_extract_ctx *ectx, off_t sz, struct ap
|
|||
|
||||
fi.mode |= S_IFREG;
|
||||
r = ectx->ops->file(ectx, &fi, apk_istream_verify(&dis, is, &fi.digest));
|
||||
if (r == APK_EXTRACT_SKIP_FILE)
|
||||
return 0;
|
||||
return apk_istream_close_error(&dis.is, r);
|
||||
}
|
||||
|
||||
|
@ -255,6 +257,7 @@ int apk_extract_v3(struct apk_extract_ctx *ectx, struct apk_istream *is)
|
|||
}
|
||||
}
|
||||
if (r == -ECANCELED) r = 0;
|
||||
if (r == 0 && !ctx.db.adb.len) r = -APKE_ADB_BLOCK;
|
||||
adb_free(&ctx.db);
|
||||
apk_extract_reset(ectx);
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "apk_database.h"
|
||||
#include "apk_print.h"
|
||||
#include "apk_extract.h"
|
||||
#include "apk_adb.h"
|
||||
|
||||
const apk_spn_match_def apk_spn_dependency_comparer = {
|
||||
[7] = (1<<4) /*<*/ | (1<<5) /*=*/ | (1<<6) /*<*/,
|
||||
|
@ -448,6 +449,27 @@ int apk_deps_write(struct apk_database *db, struct apk_dependency_array *deps, s
|
|||
return n;
|
||||
}
|
||||
|
||||
void apk_dep_from_adb(struct apk_dependency *dep, struct apk_database *db, struct adb_obj *d)
|
||||
{
|
||||
*dep = (struct apk_dependency) {
|
||||
.name = apk_db_get_name(db, adb_ro_blob(d, ADBI_DEP_NAME)),
|
||||
.version = apk_atomize_dup(&db->atoms, adb_ro_blob(d, ADBI_DEP_VERSION)),
|
||||
.result_mask = adb_ro_int(d, ADBI_DEP_MATCH) ?: APK_VERSION_EQUAL,
|
||||
};
|
||||
}
|
||||
|
||||
void apk_deps_from_adb(struct apk_dependency_array **deps, struct apk_database *db, struct adb_obj *da)
|
||||
{
|
||||
struct adb_obj obj;
|
||||
int i;
|
||||
|
||||
for (i = ADBI_FIRST; i <= adb_ra_num(da); i++) {
|
||||
struct apk_dependency *d = apk_dependency_array_add(deps);
|
||||
adb_ro_obj(da, i, &obj);
|
||||
apk_dep_from_adb(d, db, &obj);
|
||||
}
|
||||
}
|
||||
|
||||
const char *apk_script_types[] = {
|
||||
[APK_SCRIPT_PRE_INSTALL] = "pre-install",
|
||||
[APK_SCRIPT_POST_INSTALL] = "post-install",
|
||||
|
@ -474,6 +496,7 @@ struct read_info_ctx {
|
|||
struct apk_database *db;
|
||||
struct apk_package *pkg;
|
||||
struct apk_extract_ctx ectx;
|
||||
int v3ok;
|
||||
};
|
||||
|
||||
int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
|
||||
|
@ -549,6 +572,47 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static char *commit_id(apk_blob_t b)
|
||||
{
|
||||
char buf[80];
|
||||
apk_blob_t to = APK_BLOB_BUF(buf);
|
||||
|
||||
apk_blob_push_hexdump(&to, b);
|
||||
to = apk_blob_pushed(APK_BLOB_BUF(buf), to);
|
||||
if (APK_BLOB_IS_NULL(to)) return NULL;
|
||||
return apk_blob_cstr(to);
|
||||
}
|
||||
|
||||
void apk_pkg_from_adb(struct apk_database *db, struct apk_package *pkg, struct adb_obj *pkgo)
|
||||
{
|
||||
struct adb_obj pkginfo, obj;
|
||||
apk_blob_t uid;
|
||||
|
||||
adb_ro_obj(pkgo, ADBI_PKG_PKGINFO, &pkginfo);
|
||||
|
||||
uid = adb_ro_blob(&pkginfo, ADBI_PI_UNIQUE_ID);
|
||||
if (uid.len == APK_CHECKSUM_SHA1) {
|
||||
pkg->csum.type = APK_CHECKSUM_SHA1;
|
||||
memcpy(pkg->csum.data, uid.ptr, uid.len);
|
||||
}
|
||||
|
||||
pkg->name = apk_db_get_name(db, adb_ro_blob(&pkginfo, ADBI_PI_NAME));
|
||||
pkg->version = apk_atomize_dup(&db->atoms, adb_ro_blob(&pkginfo, ADBI_PI_VERSION));
|
||||
pkg->description = apk_blob_cstr(adb_ro_blob(&pkginfo, ADBI_PI_DESCRIPTION));
|
||||
pkg->url = apk_blob_cstr(adb_ro_blob(&pkginfo, ADBI_PI_URL));
|
||||
pkg->license = apk_atomize_dup(&db->atoms, adb_ro_blob(&pkginfo, ADBI_PI_LICENSE));
|
||||
pkg->arch = apk_atomize_dup(&db->atoms, adb_ro_blob(&pkginfo, ADBI_PI_ARCH));
|
||||
pkg->installed_size = adb_ro_int(&pkginfo, ADBI_PI_INSTALLED_SIZE);
|
||||
pkg->origin = apk_atomize_dup(&db->atoms, adb_ro_blob(&pkginfo, ADBI_PI_ORIGIN));
|
||||
pkg->maintainer = apk_atomize_dup(&db->atoms, adb_ro_blob(&pkginfo, ADBI_PI_MAINTAINER));
|
||||
pkg->build_time = adb_ro_int(&pkginfo, ADBI_PI_BUILD_TIME);
|
||||
pkg->commit = commit_id(adb_ro_blob(&pkginfo, ADBI_PI_REPO_COMMIT));
|
||||
|
||||
apk_deps_from_adb(&pkg->depends, db, adb_ro_obj(&pkginfo, ADBI_PI_DEPENDS, &obj));
|
||||
apk_deps_from_adb(&pkg->provides, db, adb_ro_obj(&pkginfo, ADBI_PI_PROVIDES, &obj));
|
||||
apk_deps_from_adb(&pkg->install_if, db, adb_ro_obj(&pkginfo, ADBI_PI_INSTALL_IF, &obj));
|
||||
}
|
||||
|
||||
static int read_info_line(struct read_info_ctx *ri, apk_blob_t line)
|
||||
{
|
||||
static struct {
|
||||
|
@ -601,13 +665,27 @@ static int apk_pkg_v2meta(struct apk_extract_ctx *ectx, struct apk_istream *is)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int apk_pkg_v3meta(struct apk_extract_ctx *ectx, struct adb_obj *pkg)
|
||||
{
|
||||
struct read_info_ctx *ri = container_of(ectx, struct read_info_ctx, ectx);
|
||||
|
||||
if (!ri->v3ok) return -APKE_FORMAT_NOT_SUPPORTED;
|
||||
|
||||
apk_pkg_from_adb(ri->db, ri->pkg, pkg);
|
||||
return -ECANCELED;
|
||||
}
|
||||
|
||||
static const struct apk_extract_ops extract_pkgmeta_ops = {
|
||||
.v2meta = apk_pkg_v2meta,
|
||||
.v3meta = apk_pkg_v3meta,
|
||||
};
|
||||
|
||||
int apk_pkg_read(struct apk_database *db, const char *file, struct apk_package **pkg)
|
||||
int apk_pkg_read(struct apk_database *db, const char *file, struct apk_package **pkg, int v3ok)
|
||||
{
|
||||
struct read_info_ctx ctx;
|
||||
struct read_info_ctx ctx = {
|
||||
.db = db,
|
||||
.v3ok = v3ok,
|
||||
};
|
||||
struct apk_file_info fi;
|
||||
int r;
|
||||
|
||||
|
@ -615,8 +693,6 @@ int apk_pkg_read(struct apk_database *db, const char *file, struct apk_package *
|
|||
if (r != 0)
|
||||
return r;
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
ctx.db = db;
|
||||
ctx.pkg = apk_pkg_new();
|
||||
r = -ENOMEM;
|
||||
if (ctx.pkg == NULL)
|
||||
|
@ -628,8 +704,10 @@ int apk_pkg_read(struct apk_database *db, const char *file, struct apk_package *
|
|||
|
||||
r = apk_extract(&ctx.ectx, apk_istream_from_file(AT_FDCWD, file));
|
||||
if (r < 0) goto err;
|
||||
if (ctx.pkg->name == NULL || ctx.pkg->uninstallable) {
|
||||
r = -ENOTSUP;
|
||||
if (ctx.pkg->csum.type == APK_CHECKSUM_NONE ||
|
||||
ctx.pkg->name == NULL ||
|
||||
ctx.pkg->uninstallable) {
|
||||
r = -APKE_FORMAT_NOT_SUPPORTED;
|
||||
goto err;
|
||||
}
|
||||
ctx.pkg->filename = strdup(file);
|
||||
|
|
Loading…
Reference in New Issue