// A reference to the archive
struct pakfire_archive* archive;
+ // The path we are reading
+ char path[PATH_MAX];
+
// A copy of the underlying file descriptor
FILE* f;
// The opened archive
struct archive* a;
+
+ // File handle opened by the cookie
+ FILE* __f;
};
static ssize_t __pakfire_archive_cookie_read(void* c, char* buffer, size_t size) {
.close = __pakfire_archive_cookie_close,
};
+// Tries to find a matching file in the archive
+static int __pakfire_archive_read_filter(struct pakfire* pakfire, struct archive* a,
+ struct archive_entry* e, void* data) {
+ struct pakfire_archive_read_cookie* cookie = (struct pakfire_archive_read_cookie*)data;
+
+ // Fetch path
+ const char* p = archive_entry_pathname(e);
+ if (!p)
+ return PAKFIRE_WALK_ERROR;
+
+ // We found a match
+ if (strcmp(cookie->path, p) == 0)
+ return PAKFIRE_WALK_DONE;
+
+ // Otherwise we skip the file
+ return PAKFIRE_WALK_SKIP;
+}
+
+// Reads a matching file into memory
+static int __pakfire_archive_read(struct pakfire* pakfire, struct archive* a,
+ struct archive_entry* e, void* data) {
+ struct pakfire_archive_read_cookie* cookie = (struct pakfire_archive_read_cookie*)data;
+
+ // Create a file descriptor
+ cookie->__f = fopencookie(cookie, "r", pakfire_archive_read_functions);
+ if (!cookie->__f) {
+ ERROR(pakfire, "Could not open /%s: %m\n", cookie->path);
+ return PAKFIRE_WALK_ERROR;
+ }
+
+ return PAKFIRE_WALK_DONE;
+}
+
PAKFIRE_EXPORT FILE* pakfire_archive_read(struct pakfire_archive* archive, const char* path) {
struct pakfire_archive_read_cookie* cookie = NULL;
- FILE* f = NULL;
int r;
// Check if path is absolute
// Store a reference to the archive
cookie->archive = pakfire_archive_ref(archive);
+ // Store the path
+ r = pakfire_string_set(cookie->path, path);
+ if (r) {
+ ERROR(archive->pakfire, "Could not set path: %m\n");
+ goto ERROR;
+ }
+
// Clone the archive file descriptor to read the file independently
cookie->f = pakfire_archive_clone_file(archive);
if (!cookie->f) {
if (!cookie->a)
goto ERROR;
- // 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) {
- // Stop reading the archive after we have found our file
- if (f)
- return PAKFIRE_WALK_END;
-
- // Fetch path
- const char* p = archive_entry_pathname(e);
- if (!p)
- return PAKFIRE_WALK_ERROR;
-
- // We found a match
- if (strcmp(path, p) == 0)
- return PAKFIRE_WALK_OK;
-
- // 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) {
- // Create a file descriptor
- f = fopencookie(cookie, "r", pakfire_archive_read_functions);
- if (!f) {
- ERROR(pakfire, "Could not open /%s: %m\n", path);
- return PAKFIRE_WALK_ERROR;
- }
-
- return PAKFIRE_WALK_DONE;
- }
-
// Walk through the archive
r = pakfire_walk(archive->pakfire, cookie->a,
- __pakfire_archive_read, __pakfire_archive_read_filter, NULL);
+ __pakfire_archive_read, __pakfire_archive_read_filter, cookie);
if (r)
goto ERROR;
// Nothing found
- if (!f) {
+ if (!cookie->__f) {
ERROR(archive->pakfire, "Could not find /%s\n", path);
// No such file or directory
goto ERROR;
}
- return f;
+ return cookie->__f;
ERROR:
if (cookie)