diff --git a/src/manifest.c b/src/manifest.c index ac86936..fe91b63 100644 --- a/src/manifest.c +++ b/src/manifest.c @@ -11,6 +11,8 @@ */ #include +#include + #include "apk_defines.h" #include "apk_applet.h" #include "apk_database.h" @@ -23,6 +25,11 @@ static char *csum_types[APK_CHECKSUM_SHA1 + 1] = { [APK_CHECKSUM_SHA1] = "sha1", }; +struct manifest_file_ctx { + const char *file; + struct apk_sign_ctx *sctx; +}; + static void process_package(struct apk_database *db, struct apk_package *pkg) { struct apk_installed_package *ipkg = pkg->ipkg; @@ -51,12 +58,60 @@ static void process_package(struct apk_database *db, struct apk_package *pkg) } } +static int read_file_entry(void *ctx, const struct apk_file_info *ae, + struct apk_istream *is) +{ + struct manifest_file_ctx *mctx = ctx; + char csum_buf[(APK_CHECKSUM_SHA1 * 2) + 1]; + apk_blob_t csum_blob = APK_BLOB_BUF(csum_buf); + + if (ae->name[0] == '.') { + if (!strncmp(ae->name, ".PKGINFO", 8) || !strncmp(ae->name, ".SIGN.", 6)) + return 0; + } + + if ((ae->mode & S_IFMT) != S_IFREG) + return 0; + + memset(csum_buf, '\0', sizeof(csum_buf)); + apk_blob_push_hexdump(&csum_blob, APK_BLOB_CSUM(ae->csum)); + + if (apk_verbosity > 1) + printf("%s: ", mctx->file); + + printf("%s:%s %s\n", csum_types[ae->csum.type], csum_buf, ae->name); + + return 0; +} + +static void process_file(struct apk_database *db, const char *match) +{ + struct apk_sign_ctx sctx; + struct apk_istream *is; + struct manifest_file_ctx ctx = {match, &sctx}; + + apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd); + is = apk_bstream_gunzip_mpart(apk_bstream_from_file(AT_FDCWD, match), + apk_sign_ctx_mpart_cb, &sctx); + + if (IS_ERR_OR_NULL(is)) { + apk_error("%s: %s", match, strerror(errno)); + return; + } + + (void) apk_tar_parse(is, read_file_entry, &ctx, FALSE, &db->id_cache); + is->close(is); +} + static void process_match(struct apk_database *db, const char *match, struct apk_name *name, void *ctx) { struct apk_provider *p; if (name == NULL) + { + process_file(db, match); return; + } foreach_array_item(p, name->providers) process_package(db, p->pkg);