]> git.ipfire.org Git - pakfire.git/commitdiff
archive: Fix reading files from archives
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 10 Mar 2023 16:25:54 +0000 (16:25 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 10 Mar 2023 16:35:35 +0000 (16:35 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/archive.c
tests/libpakfire/archive.c

index a7df2fef23a77be43afd16a167577eacfa445059..f840e1afdf52e96a13c75009b813051321c63dfb 100644 (file)
@@ -554,49 +554,55 @@ static int __pakfire_archive_filter_payload(struct pakfire* pakfire,
        }
 }
 
-static int __pakfire_archive_read_payload(struct pakfire* pakfire,
-               struct archive* a, struct archive_entry* entry, void* p) {
-       struct pakfire_archive_read* _read = (struct pakfire_archive_read*)p;
+PAKFIRE_EXPORT int pakfire_archive_read(struct pakfire_archive* archive,
+               const char* path, char** data, size_t* length) {
        int r;
 
-       const char* path = archive_entry_pathname(entry);
+       // Strip leading / from filenames, because tarballs don't use any leading slashes
+       path = pakfire_path_relpath("/", path);
 
-       if (strcmp(_read->path, path) == 0) {
-               r = pakfire_archive_copy_data_to_buffer(pakfire, a, entry,
-                       _read->data, _read->length);
-               if (r)
-                       return r;
+       // Check inputs
+       if (!path || !data || !length) {
+               errno = EINVAL;
+               return 1;
        }
 
-       return 0;
-}
+       // Reset data
+       *data = NULL;
 
-static int __pakfire_archive_read(struct pakfire_archive* archive,
-               const char* path, char** data, size_t* length) {
-       struct pakfire_archive_read _read = {
-               .archive = archive,
-               .path    = path,
-               .data    = data,
-               .length  = length,
-       };
+       int __pakfire_archive_read(struct pakfire* pakfire, struct archive* a,
+                       struct archive_entry* e, void* __data) {
+               // Fetch the path of this entry
+               const char* p = archive_entry_pathname(e);
+               if (!p)
+                       return 1;
+
+               if (strcmp(path, p) == 0) {
+                       r = pakfire_archive_copy_data_to_buffer(pakfire, a, e, data, length);
+                       if (r)
+                               return r;
+               }
+
+               return 0;
+       }
 
        // Walk through the archive
-       return pakfire_archive_walk(archive, __pakfire_archive_read_payload,
-               __pakfire_archive_filter_payload, &_read);
-}
+       r = pakfire_archive_walk(archive,
+               __pakfire_archive_read, __pakfire_archive_filter_payload, NULL);
+       if (r)
+               return r;
 
-PAKFIRE_EXPORT int pakfire_archive_read(struct pakfire_archive* archive,
-               const char* path, char** data, size_t* length) {
-       // Strip leading / from filenames, because tarballs don't use any leading slashes
-       path = pakfire_path_relpath("/", path);
+       // Nothing found
+       if (!*data) {
+               // No such file or directory
+               errno = ENOENT;
+
+               ERROR(archive->pakfire, "Could not find /%s: %m\n", path);
 
-       // Check inputs
-       if (!path || !data || !length) {
-               errno = EINVAL;
                return 1;
        }
 
-       return __pakfire_archive_read(archive, path, data, length);
+       return 0;
 }
 
 int pakfire_archive_copy(struct pakfire_archive* archive, const char* path) {
index 29926c24dc69313f81df2c6b70ada18f53072b5c..4b691fa203fa19ef78e90e4d5f46f03b43133091 100644 (file)
@@ -249,10 +249,7 @@ FAIL:
 int main(int argc, const char* argv[]) {
        testsuite_add_test(test_open);
        testsuite_add_test(test_open_directory);
-#warning Reading files from an archive seems to be broken
-#if 0
        testsuite_add_test(test_read);
-#endif
        testsuite_add_test(test_copy);
        testsuite_add_test(test_filelist);
        testsuite_add_test(test_extract);