return r;
}
-static int pakfire_packager_write_archive(struct pakfire_packager* packager,
- struct archive* a, const char* filename,
- struct archive** payload, FILE* f) {
- struct stat st;
+static int pakfire_packager_copy_archive(struct pakfire_packager* packager,
+ struct archive* a, FILE* f) {
+ struct archive* payload = NULL;
+ struct archive_entry* entry = NULL;
+ int r;
- DEBUG(packager->pakfire, "Writing '%s' to package\n", filename);
-
- // Close the payload
- if (*payload) {
- archive_write_free(*payload);
- *payload = NULL;
- }
+ DEBUG(packager->pakfire, "Copying payload\n");
// Reset fd to beginning of the file
rewind(f);
- int fd = fileno(f);
+ // Re-open the payload archive for reading
+ payload = archive_read_new();
+ if (!payload) {
+ ERROR(packager->pakfire, "Could not create archive reader: %m\n");
+ r = 1;
+ goto ERROR;
+ }
- // Stat the payload file
- int r = fstat(fd, &st);
+ // We expect a tar archive
+ r = archive_read_support_format_tar(payload);
if (r) {
- ERROR(packager->pakfire, "stat() on fd %d failed: %m\n", fd);
- return 1;
+ ERROR(packager->pakfire, "Could not add support for tar: %s\n",
+ archive_error_string(payload));
+ goto ERROR;
}
- // Create a new file
- struct archive_entry* entry = pakfire_packager_create_file(packager,
- filename, st.st_size, 0444);
- if (!entry)
- return 1;
-
- // This is the end of the header
- r = archive_write_header(a, entry);
+ // Open the file handle
+ r = archive_read_open_FILE(payload, f);
if (r) {
- ERROR(packager->pakfire, "Error writing header: %s\n", archive_error_string(a));
+ ERROR(packager->pakfire, "Could not open payload: %s\n",
+ archive_error_string(payload));
goto ERROR;
}
- // Copy data
- r = pakfire_archive_copy_data_from_file(packager->pakfire, a, f);
- if (r) {
- const char* error = archive_error_string(a);
- if (!error)
- error = strerror(errno);
+ // Copy all files into our archive
+ for (;;) {
+ r = archive_read_next_header(payload, &entry);
- ERROR(packager->pakfire, "Could not copy payload: %s\n", error);
- goto ERROR;
+ // End when we have reached the end of the archive
+ if (r == ARCHIVE_EOF) {
+ r = 0;
+ break;
+ }
+
+ // Raise any other errors
+ else if (r) {
+ ERROR(packager->pakfire, "Could not read next header: %s\n",
+ archive_error_string(payload));
+ goto ERROR;
+ }
+
+ // Write the entry
+ r = archive_write_header(a, entry);
+ if (r) {
+ ERROR(packager->pakfire, "Could not write entry: %s\n",
+ archive_error_string(a));
+ goto ERROR;
+ }
+
+ // Copy the data
+ r = pakfire_archive_copy_data(packager->pakfire, payload, a);
+ if (r)
+ goto ERROR;
}
// Success
r = 0;
ERROR:
- archive_entry_free(entry);
+ if (payload)
+ archive_read_free(payload);
return r;
}
It will create a new archive and write the package to the given file descriptor.
*/
int pakfire_packager_finish(struct pakfire_packager* packager, FILE* f) {
+ struct archive* a = NULL;
int r = 1;
+ // Close the payload
+ if (packager->payload) {
+ r = archive_write_free(packager->payload);
+ if (r) {
+ ERROR(packager->pakfire, "Could not close payload: %s\n",
+ archive_error_string(packager->payload));
+ goto ERROR;
+ }
+ packager->payload = NULL;
+ }
+
// Add requires feature markers
if (pakfire_package_has_rich_deps(packager->pkg))
pakfire_package_add_requires(packager->pkg, "pakfire(RichDependencies)");
}
// Open a new archive
- struct archive* a = archive_write_new();
+ a = archive_write_new();
if (!a) {
ERROR(packager->pakfire, "archive_write_new() failed\n");
goto ERROR;
// Write the payload
if (packager->files) {
- r = pakfire_packager_write_archive(packager, a, "DATA",
- &packager->payload, packager->fpayload);
+ r = pakfire_packager_copy_archive(packager, a, packager->fpayload);
if (r) {
ERROR(packager->pakfire, "Could not add payload to archive: %s\n",
archive_error_string(a));