db: support "replaces" directive (fixes #113)
it will allow to overwrite files owned by some other packages to get upgrades right (e.g. when splitting or renaming packages)cute-signatures
parent
1fea5639b4
commit
a602c49b31
|
@ -103,6 +103,7 @@ void apk_sign_ctx_free(struct apk_sign_ctx *ctx);
|
||||||
int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx,
|
int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx,
|
||||||
const struct apk_file_info *fi,
|
const struct apk_file_info *fi,
|
||||||
struct apk_istream *is);
|
struct apk_istream *is);
|
||||||
|
int apk_sign_ctx_parse_pkginfo_line(void *ctx, apk_blob_t line);
|
||||||
int apk_sign_ctx_verify_tar(void *ctx, const struct apk_file_info *fi,
|
int apk_sign_ctx_verify_tar(void *ctx, const struct apk_file_info *fi,
|
||||||
struct apk_istream *is);
|
struct apk_istream *is);
|
||||||
int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t blob);
|
int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t blob);
|
||||||
|
|
|
@ -41,6 +41,7 @@ struct install_ctx {
|
||||||
struct apk_db_dir_instance *diri;
|
struct apk_db_dir_instance *diri;
|
||||||
struct apk_checksum data_csum;
|
struct apk_checksum data_csum;
|
||||||
struct apk_sign_ctx sctx;
|
struct apk_sign_ctx sctx;
|
||||||
|
struct apk_name_array *replaces;
|
||||||
|
|
||||||
apk_progress_cb cb;
|
apk_progress_cb cb;
|
||||||
void *cb_ctx;
|
void *cb_ctx;
|
||||||
|
@ -1353,6 +1354,37 @@ static struct apk_db_dir_instance *find_diri(struct apk_package *pkg,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int parse_replaces(void *_ctx, apk_blob_t blob)
|
||||||
|
{
|
||||||
|
struct install_ctx *ctx = (struct install_ctx *) _ctx;
|
||||||
|
|
||||||
|
if (blob.len == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*apk_name_array_add(&ctx->replaces) = apk_db_get_name(ctx->db, blob);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_info_line(void *_ctx, apk_blob_t line)
|
||||||
|
{
|
||||||
|
struct install_ctx *ctx = (struct install_ctx *) _ctx;
|
||||||
|
apk_blob_t l, r;
|
||||||
|
|
||||||
|
if (line.ptr == NULL || line.len < 1 || line.ptr[0] == '#')
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!apk_blob_split(line, APK_BLOB_STR(" = "), &l, &r))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (apk_blob_compare(APK_BLOB_STR("replaces"), l) == 0) {
|
||||||
|
apk_blob_for_each_segment(r, " ", parse_replaces, ctx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
apk_sign_ctx_parse_pkginfo_line(&ctx->sctx, line);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int apk_db_install_archive_entry(void *_ctx,
|
static int apk_db_install_archive_entry(void *_ctx,
|
||||||
const struct apk_file_info *ae,
|
const struct apk_file_info *ae,
|
||||||
struct apk_istream *is)
|
struct apk_istream *is)
|
||||||
|
@ -1366,11 +1398,15 @@ static int apk_db_install_archive_entry(void *_ctx,
|
||||||
const char *p;
|
const char *p;
|
||||||
int r = 0, type = APK_SCRIPT_INVALID;
|
int r = 0, type = APK_SCRIPT_INVALID;
|
||||||
|
|
||||||
apk_sign_ctx_verify_tar(&ctx->sctx, ae, is);
|
|
||||||
|
|
||||||
/* Package metainfo and script processing */
|
/* Package metainfo and script processing */
|
||||||
if (ae->name[0] == '.') {
|
if (ae->name[0] == '.') {
|
||||||
/* APK 2.0 format */
|
/* APK 2.0 format */
|
||||||
|
if (strcmp(ae->name, ".PKGINFO") == 0) {
|
||||||
|
apk_blob_t blob = apk_blob_from_istream(is, ae->size);
|
||||||
|
apk_blob_for_each_segment(blob, "\n", read_info_line, ctx);
|
||||||
|
free(blob.ptr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
type = apk_script_type(&ae->name[1]);
|
type = apk_script_type(&ae->name[1]);
|
||||||
if (type == APK_SCRIPT_INVALID)
|
if (type == APK_SCRIPT_INVALID)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1428,8 +1464,18 @@ static int apk_db_install_archive_entry(void *_ctx,
|
||||||
opkg = NULL;
|
opkg = NULL;
|
||||||
file = apk_db_file_query(db, bdir, bfile);
|
file = apk_db_file_query(db, bdir, bfile);
|
||||||
if (file != NULL) {
|
if (file != NULL) {
|
||||||
|
int i;
|
||||||
|
|
||||||
opkg = file->diri->pkg;
|
opkg = file->diri->pkg;
|
||||||
if (opkg->name != pkg->name) {
|
do {
|
||||||
|
if (opkg->name == pkg->name)
|
||||||
|
break;
|
||||||
|
for (i = 0; ctx->replaces && i < ctx->replaces->num; i++)
|
||||||
|
if (opkg->name == ctx->replaces->item[i])
|
||||||
|
break;
|
||||||
|
if (ctx->replaces && i < ctx->replaces->num)
|
||||||
|
break;
|
||||||
|
|
||||||
if (!(apk_flags & APK_FORCE)) {
|
if (!(apk_flags & APK_FORCE)) {
|
||||||
apk_error("%s: Trying to overwrite %s "
|
apk_error("%s: Trying to overwrite %s "
|
||||||
"owned by %s.",
|
"owned by %s.",
|
||||||
|
@ -1440,7 +1486,7 @@ static int apk_db_install_archive_entry(void *_ctx,
|
||||||
apk_warning("%s: Overwriting %s owned by %s.",
|
apk_warning("%s: Overwriting %s owned by %s.",
|
||||||
pkg->name->name, ae->name,
|
pkg->name->name, ae->name,
|
||||||
opkg->name->name);
|
opkg->name->name);
|
||||||
}
|
} while (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opkg != pkg) {
|
if (opkg != pkg) {
|
||||||
|
@ -1694,6 +1740,8 @@ static int apk_db_unpack_pkg(struct apk_database *db,
|
||||||
r = apk_tar_parse(tar, apk_db_install_archive_entry, &ctx, TRUE);
|
r = apk_tar_parse(tar, apk_db_install_archive_entry, &ctx, TRUE);
|
||||||
apk_sign_ctx_free(&ctx.sctx);
|
apk_sign_ctx_free(&ctx.sctx);
|
||||||
tar->close(tar);
|
tar->close(tar);
|
||||||
|
if (ctx.replaces)
|
||||||
|
free(ctx.replaces);
|
||||||
|
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
apk_error("%s-%s: %s",
|
apk_error("%s-%s: %s",
|
||||||
|
|
|
@ -415,7 +415,7 @@ int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_datahash(void *ctx, apk_blob_t line)
|
int apk_sign_ctx_parse_pkginfo_line(void *ctx, apk_blob_t line)
|
||||||
{
|
{
|
||||||
struct apk_sign_ctx *sctx = (struct apk_sign_ctx *) ctx;
|
struct apk_sign_ctx *sctx = (struct apk_sign_ctx *) ctx;
|
||||||
apk_blob_t l, r;
|
apk_blob_t l, r;
|
||||||
|
@ -448,7 +448,9 @@ int apk_sign_ctx_verify_tar(void *sctx, const struct apk_file_info *fi,
|
||||||
|
|
||||||
if (strcmp(fi->name, ".PKGINFO") == 0) {
|
if (strcmp(fi->name, ".PKGINFO") == 0) {
|
||||||
apk_blob_t blob = apk_blob_from_istream(is, fi->size);
|
apk_blob_t blob = apk_blob_from_istream(is, fi->size);
|
||||||
apk_blob_for_each_segment(blob, "\n", read_datahash, ctx);
|
apk_blob_for_each_segment(
|
||||||
|
blob, "\n",
|
||||||
|
apk_sign_ctx_parse_pkginfo_line, ctx);
|
||||||
free(blob.ptr);
|
free(blob.ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -628,15 +630,7 @@ static int read_info_line(void *ctx, apk_blob_t line)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
apk_sign_ctx_parse_pkginfo_line(ri->sctx, line);
|
||||||
if (ri->sctx->data_started == 0 &&
|
|
||||||
apk_blob_compare(APK_BLOB_STR("datahash"), l) == 0) {
|
|
||||||
ri->sctx->has_data_checksum = 1;
|
|
||||||
ri->sctx->md = EVP_sha256();
|
|
||||||
apk_blob_pull_hexdump(
|
|
||||||
&r, APK_BLOB_PTR_LEN(ri->sctx->data_checksum,
|
|
||||||
EVP_MD_size(ri->sctx->md)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue