]> git.ipfire.org Git - pakfire.git/commitdiff
archive: Read filelist in mtree format
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 21 May 2021 19:39:49 +0000 (19:39 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 21 May 2021 19:39:49 +0000 (19:39 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/archive.c
src/libpakfire/file.c
src/libpakfire/include/pakfire/file.h

index 89d99dfc2a933bd62b3a08c48f0587c2473d5952..335ef1f447fb96c9bd3161a87f2956726bd12385 100644 (file)
@@ -1022,7 +1022,87 @@ PAKFIRE_EXPORT unsigned int pakfire_archive_get_format(PakfireArchive archive) {
        return archive->format;
 }
 
-static int pakfire_archive_load_filelist(PakfireArchive archive) {
+static int pakfire_archive_load_filelist_mtree(PakfireArchive archive) {
+       struct archive* a;
+       struct archive_entry* entry;
+       int r;
+
+       // Find filelist
+       r = open_archive_and_find(archive, &a, &entry, "filelist");
+       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;
+       }
+
+       // Read filelist
+       r = pakfire_filelist_create(&archive->filelist, archive->pakfire);
+       if (r)
+               goto ERROR;
+
+       for (;;) {
+               PakfireFile file;
+
+               r = archive_read_next_header(mtree, &entry);
+               if (r == ARCHIVE_EOF)
+                       break;
+               else if (r)
+                       goto ERROR;
+
+               // Create a new file object
+               r = pakfire_file_create_from_archive_entry(&file, archive->pakfire, entry);
+               if (r)
+                       goto ERROR;
+
+               printf("--> %s\n", pakfire_file_get_path(file));
+
+               // Append to filelist
+               r = pakfire_filelist_append(archive->filelist, file);
+               pakfire_file_unref(file);
+               if (r)
+                       goto ERROR;
+       }
+
+ERROR:
+       // Destroy the filelist on error
+       if (r && archive->filelist) {
+               pakfire_filelist_unref(archive->filelist);
+               archive->filelist = NULL;
+       }
+
+       if (mtree)
+               archive_read_free(mtree);
+       close_archive(archive, a);
+
+       return r;
+}
+
+static int pakfire_archive_load_filelist_legacy(PakfireArchive archive) {
        char* data = NULL;
        size_t size;
 
@@ -1050,6 +1130,13 @@ static int pakfire_archive_load_filelist(PakfireArchive archive) {
        return r;
 }
 
+static int pakfire_archive_load_filelist(PakfireArchive archive) {
+       if (archive->format >= 6)
+               return pakfire_archive_load_filelist_mtree(archive);
+       else
+               return pakfire_archive_load_filelist_legacy(archive);
+}
+
 PAKFIRE_EXPORT PakfireFilelist pakfire_archive_get_filelist(PakfireArchive archive) {
        if (!archive->filelist) {
                int r = pakfire_archive_load_filelist(archive);
index 11be050daa0f798596fc4487bdbdb2e2b2084787..5670de1d7c616ad04f119bcbe68f0b9af1187a75 100644 (file)
@@ -69,6 +69,26 @@ PAKFIRE_EXPORT int pakfire_file_create(PakfireFile* file, Pakfire pakfire) {
        return 0;
 }
 
+int pakfire_file_create_from_archive_entry(PakfireFile* file, Pakfire pakfire,
+               struct archive_entry* entry) {
+       int r = pakfire_file_create(file, pakfire);
+       if (r)
+               return r;
+
+       // Copy archive entry
+       r = pakfire_file_copy_archive_entry(*file, entry);
+       if (r)
+               goto ERROR;
+
+       return 0;
+
+ERROR:
+       pakfire_file_unref(*file);
+       *file = NULL;
+
+       return r;
+}
+
 struct archive_entry* pakfire_file_archive_entry(PakfireFile file) {
        struct archive_entry* entry = archive_entry_new();
        if (!entry)
index 9758f0181b58777aea96a6075679c82507473e3c..200b8b3bdef5b6758bfcaec9fc8f1f4a143584a8 100644 (file)
@@ -65,6 +65,8 @@ PakfireFile pakfire_file_parse_from_file(const char* list, unsigned int format);
 
 #include <archive_entry.h>
 
+int pakfire_file_create_from_archive_entry(PakfireFile* file, Pakfire pakfire,
+               struct archive_entry* entry);
 struct archive_entry* pakfire_file_archive_entry(PakfireFile file);
 int pakfire_file_copy_archive_entry(PakfireFile file, struct archive_entry* entry);