}
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) {
}
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)