diff options
Diffstat (limited to 'src/app_mkndx.c')
-rw-r--r-- | src/app_mkndx.c | 113 |
1 files changed, 56 insertions, 57 deletions
diff --git a/src/app_mkndx.c b/src/app_mkndx.c index 3316de5..b1e809b 100644 --- a/src/app_mkndx.c +++ b/src/app_mkndx.c @@ -18,6 +18,7 @@ #include "apk_adb.h" #include "apk_applet.h" #include "apk_database.h" +#include "apk_extract.h" #include "apk_print.h" struct mkndx_ctx { @@ -29,9 +30,10 @@ struct mkndx_ctx { apk_blob_t r; struct adb db; struct adb_obj pkgs; + struct adb_obj pkginfo; time_t index_mtime; - struct apk_sign_ctx sctx; + struct apk_extract_ctx ectx; size_t file_size; }; @@ -83,7 +85,7 @@ static int cmpfield(const void *pa, const void *pb) return apk_blob_sort(a->str, b->str); } -static adb_val_t mkndx_read_v2_pkginfo(struct adb *db, struct apk_istream *is, size_t file_size, struct apk_sign_ctx *sctx, apk_blob_t rewrite_arch) +static int mkndx_parse_v2meta(struct apk_extract_ctx *ectx, struct apk_istream *is) { static struct field fields[] = { FIELD("arch", ADBI_PI_ARCH), @@ -99,34 +101,35 @@ static adb_val_t mkndx_read_v2_pkginfo(struct adb *db, struct apk_istream *is, s FIELD("pkgdesc", ADBI_PI_DESCRIPTION), FIELD("pkgname", ADBI_PI_NAME), FIELD("pkgver", ADBI_PI_VERSION), - FIELD("provider_priority", 0), + FIELD("provider_priority", ADBI_PI_PROVIDER_PRIORITY), FIELD("provides", ADBI_PI_PROVIDES), FIELD("replaces", ADBI_PI_REPLACES), - FIELD("replaces_priority", ADBI_PI_PRIORITY), + FIELD("replaces_priority", 0), FIELD("size", ADBI_PI_INSTALLED_SIZE), FIELD("triggers", 0), FIELD("url", ADBI_PI_URL), }; + struct mkndx_ctx *ctx = container_of(ectx, struct mkndx_ctx, ectx); struct field *f, key; - struct adb_obj pkginfo, deps[3]; + struct adb *db = &ctx->db; + struct adb_obj deps[3]; apk_blob_t line, k, v, token = APK_BLOB_STR("\n"), bdep; int r, e = 0, i = 0; - adb_wo_alloca(&pkginfo, &schema_pkginfo, db); adb_wo_alloca(&deps[0], &schema_dependency_array, db); adb_wo_alloca(&deps[1], &schema_dependency_array, db); adb_wo_alloca(&deps[2], &schema_dependency_array, db); while ((r = apk_istream_get_delim(is, token, &line)) == 0) { - if (sctx) apk_sign_ctx_parse_pkginfo_line(sctx, line); if (line.len < 1 || line.ptr[0] == '#') continue; if (!apk_blob_split(line, APK_BLOB_STR(" = "), &k, &v)) continue; + apk_extract_v2_control(ectx, k, v); key.str = k; f = bsearch(&key, fields, ARRAY_SIZE(fields), sizeof(fields[0]), cmpfield); if (!f || f->ndx == 0) continue; - if (adb_ro_val(&pkginfo, f->ndx) != ADB_NULL) { + if (adb_ro_val(&ctx->pkginfo, f->ndx) != ADB_NULL) { /* Workaround abuild bug that emitted multiple license lines */ if (f->ndx == ADBI_PI_LICENSE) continue; return ADB_ERROR(APKE_ADB_PACKAGE_FORMAT); @@ -134,7 +137,7 @@ static adb_val_t mkndx_read_v2_pkginfo(struct adb *db, struct apk_istream *is, s switch (f->ndx) { case ADBI_PI_ARCH: - if (!APK_BLOB_IS_NULL(rewrite_arch)) v = rewrite_arch; + if (!APK_BLOB_IS_NULL(ctx->rewrite_arch)) v = ctx->rewrite_arch; break; case ADBI_PI_DEPENDS: i = 0; @@ -151,50 +154,42 @@ static adb_val_t mkndx_read_v2_pkginfo(struct adb *db, struct apk_istream *is, s } continue; } - adb_wo_pkginfo(&pkginfo, f->ndx, v); + adb_wo_pkginfo(&ctx->pkginfo, f->ndx, v); } if (r != -APKE_EOF) return ADB_ERROR(-r); - adb_wo_arr(&pkginfo, ADBI_PI_DEPENDS, &deps[0]); - adb_wo_arr(&pkginfo, ADBI_PI_PROVIDES, &deps[1]); - adb_wo_arr(&pkginfo, ADBI_PI_REPLACES, &deps[2]); - adb_wo_int(&pkginfo, ADBI_PI_FILE_SIZE, file_size); + adb_wo_arr(&ctx->pkginfo, ADBI_PI_DEPENDS, &deps[0]); + adb_wo_arr(&ctx->pkginfo, ADBI_PI_PROVIDES, &deps[1]); + adb_wo_arr(&ctx->pkginfo, ADBI_PI_REPLACES, &deps[2]); - return adb_w_obj(&pkginfo); + return 0; } -static int mkndx_parse_v2_tar(void *pctx, const struct apk_file_info *ae, struct apk_istream *is) +static int mkndx_parse_v3meta(struct apk_extract_ctx *ectx, struct adb_obj *pkg) { - struct mkndx_ctx *ctx = pctx; - adb_val_t o; - int r; - - r = apk_sign_ctx_process_file(&ctx->sctx, ae, is); - if (r <= 0) return r; - if (ctx->sctx.control_verified) return -ECANCELED; - if (!ctx->sctx.control_started || ctx->sctx.data_started) return 0; - - if (strcmp(ae->name, ".PKGINFO") == 0) { - o = adb_wa_append( - &ctx->pkgs, - mkndx_read_v2_pkginfo( - &ctx->db, is, ctx->file_size, &ctx->sctx, - ctx->rewrite_arch)); - if (ADB_IS_ERROR(o)) return -ADB_VAL_VALUE(o); - } + struct mkndx_ctx *ctx = container_of(ectx, struct mkndx_ctx, ectx); + struct adb_obj pkginfo; + + adb_ro_obj(pkg, ADBI_PKG_PKGINFO, &pkginfo); + adb_wo_copyobj(&ctx->pkginfo, &pkginfo); return 0; } +static const struct apk_extract_ops extract_ndxinfo_ops = { + .v2meta = mkndx_parse_v2meta, + .v3meta = mkndx_parse_v3meta, +}; + static int mkndx_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *args) { struct apk_out *out = &ac->out; - struct apk_id_cache *idc = apk_ctx_get_id_cache(ac); struct apk_trust *trust = apk_ctx_get_trust(ac); struct adb odb, tmpdb; struct adb_obj oroot, opkgs, ndx, tmpl; struct apk_file_info fi; - adb_val_t match; + struct apk_checksum csum; + adb_val_t val; int r, found, errors = 0, newpkgs = 0, numpkgs; struct mkndx_ctx *ctx = pctx; char **parg; @@ -205,13 +200,16 @@ static int mkndx_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *a return -1; } + apk_extract_init(&ctx->ectx, ac, &extract_ndxinfo_ops); + adb_init(&odb); adb_w_init_tmp(&tmpdb, 200); adb_wo_alloca(&tmpl, &schema_pkginfo, &tmpdb); - adb_w_init_alloca(&ctx->db, ADB_SCHEMA_INDEX, 1000); + adb_w_init_alloca(&ctx->db, ADB_SCHEMA_INDEX, 8000); adb_wo_alloca(&ndx, &schema_index, &ctx->db); adb_wo_alloca(&ctx->pkgs, &schema_pkginfo_array, &ctx->db); + adb_wo_alloca(&ctx->pkginfo, &schema_pkginfo, &ctx->db); if (ctx->index) { apk_fileinfo_get(AT_FDCWD, ctx->index, 0, &fi, 0); @@ -221,7 +219,7 @@ static int mkndx_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *a ADB_SCHEMA_INDEX, trust); if (r) { apk_err(out, "%s: %s", ctx->index, apk_error_str(r)); - return r; + goto done; } adb_ro_obj(adb_r_rootobj(&odb, &oroot, &schema_index), ADBI_NDX_PACKAGES, &opkgs); } @@ -240,6 +238,7 @@ static int mkndx_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *a if (index_mtime >= fi.mtime) { char *fname, *fend; apk_blob_t bname, bver; + int i; /* Check that it looks like a package name */ fname = strrchr(*parg, '/'); @@ -257,39 +256,38 @@ static int mkndx_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *a adb_wo_resetdb(&tmpl); adb_wo_blob(&tmpl, ADBI_PI_NAME, bname); adb_wo_blob(&tmpl, ADBI_PI_VERSION, bver); - match = adb_w_obj(&tmpl); + adb_wo_int(&tmpl, ADBI_PI_FILE_SIZE, fi.size); - for (int i = 0; (i = adb_ra_find(&opkgs, i, &tmpdb, match)) > 0; ) { + if ((i = adb_ra_find(&opkgs, 0, &tmpl)) > 0) { struct adb_obj pkg; - adb_val_t val; - adb_ro_obj(&opkgs, i, &pkg); - if (apk_blob_compare(bname, adb_ro_blob(&pkg, ADBI_PI_NAME))) continue; - if (apk_blob_compare(bver, adb_ro_blob(&pkg, ADBI_PI_VERSION))) continue; - if (fi.size != adb_ro_int(&pkg, ADBI_PI_FILE_SIZE)) continue; val = adb_wa_append(&ctx->pkgs, adb_w_copy(&ctx->db, &odb, adb_ro_val(&opkgs, i))); - if (ADB_IS_ERROR(val)) - errors++; - found = TRUE; - break; } } if (!found) { do_file: - apk_sign_ctx_init(&ctx->sctx, APK_SIGN_VERIFY, NULL, trust); - r = apk_tar_parse( - apk_istream_gunzip_mpart(apk_istream_from_file(AT_FDCWD, *parg), apk_sign_ctx_mpart_cb, &ctx->sctx), - mkndx_parse_v2_tar, ctx, idc); - apk_sign_ctx_free(&ctx->sctx); + apk_extract_reset(&ctx->ectx); + apk_extract_generate_identity(&ctx->ectx, &csum); + csum.type = APK_CHECKSUM_NONE; + r = apk_extract(&ctx->ectx, apk_istream_from_file(AT_FDCWD, *parg)); if (r < 0 && r != -ECANCELED) goto err_pkg; + + adb_wo_int(&ctx->pkginfo, ADBI_PI_FILE_SIZE, ctx->file_size); + if (csum.type != APK_CHECKSUM_NONE) + adb_wo_blob(&ctx->pkginfo, ADBI_PI_UNIQUE_ID, + APK_BLOB_CSUM(csum)); + + val = adb_wa_append_obj(&ctx->pkgs, &ctx->pkginfo); newpkgs++; } + if (ADB_IS_ERROR(val)) errors++; } if (errors) { apk_err(out, "%d errors, not creating index", errors); - return -1; + r = -1; + goto done; } numpkgs = adb_ra_num(&ctx->pkgs); @@ -301,14 +299,15 @@ static int mkndx_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *a apk_ostream_to_file(AT_FDCWD, ctx->output, 0644), &ctx->db, trust); - adb_free(&ctx->db); - adb_free(&odb); - if (r == 0) apk_msg(out, "Index has %d packages (of which %d are new)", numpkgs, newpkgs); else apk_err(out, "Index creation failed: %s", apk_error_str(r)); +done: + adb_wo_free(&ctx->pkgs); + adb_free(&ctx->db); + adb_free(&odb); #if 0 apk_hash_foreach(&db->available.names, warn_if_no_providers, &counts); |