From: Michael Tremer Date: Fri, 10 Mar 2023 16:25:54 +0000 (+0000) Subject: archive: Fix reading files from archives X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2b2a3e0f9d299de0ef24c69c7f16585d2efb8001;p=people%2Fstevee%2Fpakfire.git archive: Fix reading files from archives Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/archive.c b/src/libpakfire/archive.c index a7df2fef..f840e1af 100644 --- a/src/libpakfire/archive.c +++ b/src/libpakfire/archive.c @@ -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) { diff --git a/tests/libpakfire/archive.c b/tests/libpakfire/archive.c index 29926c24..4b691fa2 100644 --- a/tests/libpakfire/archive.c +++ b/tests/libpakfire/archive.c @@ -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);