return pakfire_parser_get(archive->parser, namespace, key);
}
-PAKFIRE_EXPORT int pakfire_archive_read(struct pakfire_archive* archive, const char* filename,
- char** data, size_t* size) {
+static int __pakfire_archive_read_legacy(struct pakfire_archive* archive,
+ const char* path, char** data, size_t* length) {
+ int r = 1;
+
struct archive* a = NULL;
struct archive_entry* entry = NULL;
- int r = 0;
-
- if (!filename || !data || !size) {
- errno = EINVAL;
- return 1;
- }
-
- // Strip leading / from filenames, because the payload does
- // not have leading slashes.
- while (*filename == '/')
- filename++;
struct archive* payload = pakfire_archive_open_payload(archive, &a, NULL);
if (!payload)
goto ERROR;
- r = find_archive_entry(archive, &entry, payload, filename);
+ r = find_archive_entry(archive, &entry, payload, path);
if (r)
goto ERROR;
r = pakfire_archive_copy_data_to_buffer(archive->pakfire, payload, entry,
- data, size);
+ data, length);
ERROR:
if (payload)
return r;
}
+struct pakfire_archive_read {
+ 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) {
+ const char* path = NULL;
+
+ // Format >= 6
+ if (archive->format >= 6) {
+ path = archive_entry_pathname(entry);
+
+ // Skip any hidden files
+ if (path && *path == '.')
+ return ARCHIVE_RETRY;
+ }
+
+ // Otherwise permit reading any files
+ 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;
+ 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,
+ _read->data, _read->length);
+ if (r)
+ return r;
+ }
+
+ return 0;
+}
+
+static int __pakfire_archive_read(struct pakfire_archive* archive,
+ const char* path, char** data, size_t* length) {
+ struct pakfire_archive_read _read = {
+ .path = path,
+ .data = data,
+ .length = length,
+ };
+
+ // Walk through the archive
+ return pakfire_archive_walk(archive, __pakfire_archive_read_payload,
+ __pakfire_archive_filter_payload, &_read);
+}
+
+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);
+
+ // Check inputs
+ if (!path || !data || !length) {
+ errno = EINVAL;
+ return 1;
+ }
+
+ if (archive->format >= 6)
+ return __pakfire_archive_read(archive, path, data, length);
+ else
+ return __pakfire_archive_read_legacy(archive, path, data, length);
+}
+
int pakfire_archive_copy(struct pakfire_archive* archive, const char* path) {
if (!path) {
errno = EINVAL;