return r;
}
-static int pakfire_archive_walk_entries(struct pakfire_archive* archive, struct archive* a,
- int (*callback)(struct pakfire_archive* archive, struct archive* a,
- struct archive_entry* e, void* data),
- int (*filter_callback)(struct pakfire_archive* archive, struct archive* a,
- struct archive_entry* e, void* data),
- void* data) {
- struct archive_entry* e = NULL;
-
- // Walk through the archive
- while (1) {
- int r = archive_read_next_header(a, &e);
-
- // Return OK when we reached the end of the archive
- if (r == ARCHIVE_EOF)
- return ARCHIVE_OK;
-
- // Raise any other errors
- else if (r)
- return r;
-
- // Call the filter callback before we call the actual callback
- if (filter_callback) {
- r = filter_callback(archive, a, e, data);
-
- // End processing the archive if the filter callback asked us to
- if (r == ARCHIVE_EOF)
- break;
-
- // Skip this file
- else if (r == ARCHIVE_RETRY)
- continue;
-
- // Raise any errors
- else if (r)
- return r;
- }
-
- // Run callback
- if (callback) {
- r = callback(archive, a, e, data);
- if (r)
- return r;
- }
- }
-
- return 0;
-}
-
static int pakfire_archive_walk(struct pakfire_archive* archive,
- int (*callback)(struct pakfire_archive* archive, struct archive* a,
- struct archive_entry* e, void* data),
- int (*filter_callback)(struct pakfire_archive* archive, struct archive* a,
- struct archive_entry* e, void* data),
- void* data) {
- struct archive* a;
+ pakfire_walk_callback callback, pakfire_walk_filter_callback filter_callback, void* data) {
+ struct archive* a = NULL;
// Open the archive file
int r = open_archive(archive, &a);
return r;
// Walk through the archive
- r = pakfire_archive_walk_entries(archive, a, callback, filter_callback, data);
+ r = pakfire_walk(archive->pakfire, a, callback, filter_callback, data);
// Close the archive
- close_archive(archive, a);
+ if (a)
+ close_archive(archive, a);
return r;
}
return 0;
}
-static int __pakfire_archive_read_metadata(struct pakfire_archive* archive,
- struct archive* a, struct archive_entry* entry, void* p) {
+static int __pakfire_archive_read_metadata(struct pakfire* pakfire, struct archive* a,
+ struct archive_entry* entry, void* p) {
+ struct pakfire_archive* archive = (struct pakfire_archive*)p;
+
char* data = NULL;
size_t length = 0;
int r;
return r;
}
-static int __pakfire_archive_filter_metadata(struct pakfire_archive* archive,
- struct archive* a, struct archive_entry* entry, void* data) {
+static int __pakfire_archive_filter_metadata(struct pakfire* pakfire,
+ struct archive* a, struct archive_entry* entry, void* p) {
+ struct pakfire_archive* archive = (struct pakfire_archive*)p;
+
const char* path = archive_entry_pathname(entry);
// Format >= 6
}
struct pakfire_archive_read {
+ struct pakfire_archive* archive;
const char* path;
char** data;
size_t* length;
};
-static int __pakfire_archive_filter_payload(struct pakfire_archive* archive,
- struct archive* a, struct archive_entry* entry, void* data) {
+static int __pakfire_archive_filter_payload(struct pakfire* pakfire,
+ struct archive* a, struct archive_entry* entry, void* p) {
+ struct pakfire_archive_read* _read = (struct pakfire_archive_read*)p;
+ struct pakfire_archive* archive = _read->archive;
+
const char* path = NULL;
// Format >= 6
return ARCHIVE_OK;
}
-static int __pakfire_archive_read_payload(struct pakfire_archive* archive,
- struct archive* a, struct archive_entry* entry, void* data) {
- struct pakfire_archive_read* _read = (struct pakfire_archive_read*)data;
+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;
int r;
const char* path = archive_entry_pathname(entry);
if (strcmp(_read->path, path) == 0) {
- r = pakfire_archive_copy_data_to_buffer(archive->pakfire, a, entry,
+ r = pakfire_archive_copy_data_to_buffer(pakfire, a, entry,
_read->data, _read->length);
if (r)
return r;
return NULL;
}
+/*
+ Helper function to conditionally walk through an archive
+ and perform actions based on the callback.
+*/
+int pakfire_walk(struct pakfire* pakfire, struct archive* archive,
+ pakfire_walk_callback callback, pakfire_walk_filter_callback filter_callback,
+ void* p) {
+ struct archive_entry* entry = NULL;
+ int r;
+
+ // Walk through the archive
+ for (;;) {
+ r = archive_read_next_header(archive, &entry);
+
+ // Handle the return code
+ switch (r) {
+ // Return OK when we reached the end of the archive
+ case ARCHIVE_EOF:
+ return 0;
+
+ // Raise any other errors
+ default:
+ return r;
+ }
+
+ // Call the filter callback before we call the actual callback
+ if (filter_callback) {
+ r = filter_callback(pakfire, archive, entry, p);
+
+ // Handle the return code
+ switch (r) {
+ case PAKFIRE_WALK_OK:
+ break;
+
+ case PAKFIRE_WALK_DONE:
+ DEBUG(pakfire, "Filter callback sent DONE\n");
+ return 0;
+
+ case PAKFIRE_WALK_SKIP:
+ DEBUG(pakfire, "Filter callback sent SKIP\n");
+ continue;
+
+ // Raise any other errors
+ default:
+ DEBUG(pakfire, "Filter callback received an error: %d\n", r);
+ return r;
+ }
+ }
+
+ // Run callback
+ if (callback) {
+ r = callback(pakfire, archive, entry, p);
+
+ // Handle the return code
+ switch (r) {
+ case PAKFIRE_WALK_OK:
+ break;
+
+ case PAKFIRE_WALK_DONE:
+ DEBUG(pakfire, "Callback sent DONE\n");
+ return 0;
+
+ // Raise any other errors
+ default:
+ return r;
+ }
+ }
+ }
+
+ return 0;
+}
+
// Common extraction
struct pakfire_extract {
// ZSTD
FILE* pakfire_zstdfopen(FILE* f, const char* mode);
+// Walk
+
+typedef int (*pakfire_walk_callback)
+ (struct pakfire* pakfire, struct archive* a, struct archive_entry* e, void* p);
+typedef int (*pakfire_walk_filter_callback)
+ (struct pakfire* pakfire, struct archive* a, struct archive_entry* e, void* p);
+
+enum pakfire_walk_codes {
+ PAKFIRE_WALK_OK = 0,
+
+ // After this code has been sent, we will not process any further entries
+ PAKFIRE_WALK_DONE = -10,
+
+ // Request the next entry (only in filter callback)
+ PAKFIRE_WALK_SKIP = -20,
+};
+
+int pakfire_walk(struct pakfire* pakfire, struct archive* archive,
+ pakfire_walk_callback callback, pakfire_walk_filter_callback filter_callback, void* p);
+
// Extract
enum pakfire_extract_flags {
PAKFIRE_EXTRACT_DRY_RUN = (1 << 0),