return json_object_get_int64(object);
}
-struct pakfire_archive_read {
- struct pakfire_archive* archive;
- const char* path;
- char** data;
- size_t* length;
-};
-
static int __pakfire_archive_filter_payload(struct pakfire* pakfire,
struct archive* a, struct archive_entry* entry, void* p) {
const char* path = archive_entry_pathname(entry);
PAKFIRE_EXPORT int pakfire_archive_read(struct pakfire_archive* archive,
const char* path, char** data, size_t* length) {
+ int found = 0;
int r;
- // Strip leading / from filenames, because tarballs don't use any leading slashes
- path = pakfire_path_relpath("/", path);
+ // Check if path is absolute
+ if (!path || *path != '/') {
+ errno = EINVAL;
+ return 1;
- // Check inputs
- if (!path || !data || !length) {
+ // Check other inputs
+ } else if (!data || !length) {
errno = EINVAL;
return 1;
}
- // Reset data
- *data = NULL;
+ // Strip leading / from filenames, because tarballs don't use any leading slashes
+ path = pakfire_path_relpath("/", path);
+ if (!path)
+ return 1;
- int __pakfire_archive_read(struct pakfire* pakfire, struct archive* a,
+ // Tries to find a matching file in the archive
+ int __pakfire_archive_read_filter(struct pakfire* pakfire, struct archive* a,
struct archive_entry* e, void* __data) {
- // Fetch the path of this entry
+ // Stop reading the archive after we have found our file
+ if (found)
+ return PAKFIRE_WALK_END;
+
+ // Fetch path
const char* p = archive_entry_pathname(e);
if (!p)
- return 1;
+ return PAKFIRE_WALK_ERROR;
- if (strcmp(path, p) == 0) {
- r = pakfire_archive_copy_data_to_buffer(pakfire, a, e, data, length);
- if (r)
- return r;
- }
+ // We found a match
+ if (strcmp(path, p) == 0)
+ return PAKFIRE_WALK_OK;
- return 0;
+ // Otherwise we skip the file
+ return PAKFIRE_WALK_SKIP;
+ }
+
+ // Reads a matching file into memory
+ int __pakfire_archive_read(struct pakfire* pakfire, struct archive* a,
+ struct archive_entry* e, void* __data) {
+ // We have found our file
+ found = 1;
+
+ return pakfire_archive_copy_data_to_buffer(pakfire, a, e, data, length);
}
// Walk through the archive
r = pakfire_archive_walk(archive,
- __pakfire_archive_read, __pakfire_archive_filter_payload, NULL);
+ __pakfire_archive_read, __pakfire_archive_read_filter, NULL);
if (r)
return r;
// Nothing found
- if (!*data) {
+ if (!found) {
// No such file or directory
errno = ENOENT;