]> git.ipfire.org Git - pakfire.git/commitdiff
archive: Read checksums from mtree
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 12 Jul 2021 17:50:52 +0000 (17:50 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 12 Jul 2021 17:50:52 +0000 (17:50 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/archive.c

index be73cb8dfa9ae5f13b49dcba0a3f281127f96d90..9e1a37de2990de63c68e05e1bb920764499aef67 100644 (file)
@@ -1193,7 +1193,83 @@ ERROR:
 }
 
 static int pakfire_archive_load_checksums_mtree(struct pakfire_archive* archive) {
-       return 0;
+       struct archive* a = NULL;
+       struct archive_entry* entry = NULL;
+       int r;
+
+       // Find chksums
+       r = open_archive_and_find(archive, &a, &entry, "chksums");
+       if (r)
+               return r;
+
+       // Allocate a new archive reader
+       struct archive* mtree = archive_read_new();
+       if (!mtree) {
+               ERROR(archive->pakfire, "Could not allocate mtree reader\n");
+               goto ERROR;
+       }
+
+       // Enable reading the mtree format
+       r = archive_read_support_format_mtree(mtree);
+       if (r) {
+               ERROR(archive->pakfire, "Could not enable mtree format: %s\n",
+                       archive_error_string(mtree));
+               goto ERROR;
+       }
+
+       // Filelists can be Zstandard-compressed
+       r = archive_read_support_filter_zstd(mtree);
+       if (r)
+               goto ERROR;
+
+       // Try opening the mtree
+       r = archive_read_open2(mtree, a, NULL, pakfire_archive_read_callback, NULL, NULL);
+       if (r) {
+               ERROR(archive->pakfire, "Could not open mtree: %s\n",
+                       archive_error_string(mtree));
+               goto ERROR;
+       }
+
+       for (;;) {
+               // Read next entry
+               r = archive_read_next_header(mtree, &entry);
+
+               // We have reached the end of the list
+               if (r == ARCHIVE_EOF)
+                       break;
+
+               // An unexpected error has occurred
+               else if (r) {
+                       ERROR(archive->pakfire, "Could not read mtree entry: %s\n",
+                               archive_error_string(mtree));
+                       goto ERROR;
+               }
+
+               // Fetch pathname
+               const char* path = archive_entry_pathname(entry);
+
+               // Fetch all supported digests
+               const unsigned char* digest_sha512 = archive_entry_digest(
+                       entry, ARCHIVE_ENTRY_DIGEST_SHA512);
+               const unsigned char* digest_sha256 = archive_entry_digest(
+                       entry, ARCHIVE_ENTRY_DIGEST_SHA256);
+
+               // Add the checksum to the internal list
+               r =  pakfire_archive_add_chksum(archive, path,
+                       (const char*)digest_sha512, (const char*)digest_sha256);
+               if (r)
+                       goto ERROR;
+       }
+
+       // Success
+       r = 0;
+
+ERROR:
+       if (mtree)
+               archive_read_free(mtree);
+       close_archive(archive, a);
+
+       return r;
 }
 
 static int pakfire_archive_load_checksums_legacy(struct pakfire_archive* archive) {
@@ -1201,6 +1277,10 @@ static int pakfire_archive_load_checksums_legacy(struct pakfire_archive* archive
 }
 
 static int pakfire_archive_load_checksums(struct pakfire_archive* archive) {
+       // Do nothing if the list has already been loaded
+       if (!STAILQ_EMPTY(&archive->chksums))
+               return 0;
+
        DEBUG(archive->pakfire, "Loading checksums from archive %p\n", archive);
 
        if (archive->format >= 6)