From 018226ef08a685f1220e531eca63ee9d57e2546c Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sat, 8 Feb 2025 12:34:26 +0000 Subject: [PATCH] archive writer: Add function to add a file from memory Signed-off-by: Michael Tremer --- src/pakfire/archive_writer.c | 74 ++++++++++++++++++++++++++++++++++++ src/pakfire/archive_writer.h | 3 ++ 2 files changed, 77 insertions(+) diff --git a/src/pakfire/archive_writer.c b/src/pakfire/archive_writer.c index 18297767..1ac2e3ae 100644 --- a/src/pakfire/archive_writer.c +++ b/src/pakfire/archive_writer.c @@ -514,8 +514,82 @@ int pakfire_archive_writer_write_files( if (r < 0) goto ERROR; + // Flush all buffers to disk + fflush(self->f); + ERROR: pakfire_progress_finish(self->progress); return r; } + +/* + * Creates a new file and writes it to the archive. + */ +int pakfire_archive_writer_create_file(struct pakfire_archive_writer* self, + const char* filename, mode_t mode, const char* payload, const size_t length) { + struct archive_entry* entry = NULL; + int r; + + // Create a new file entry + entry = archive_entry_new(); + if (!entry) { + r = -errno; + goto ERROR; + } + + // Set filename + archive_entry_set_pathname(entry, filename); + + // This is a regular file + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_perm(entry, mode); + + // Set length + archive_entry_set_size(entry, length); + + // Set ownership + archive_entry_set_uname(entry, "root"); + archive_entry_set_uid(entry, 0); + archive_entry_set_gname(entry, "root"); + archive_entry_set_gid(entry, 0); + + // Set times + archive_entry_set_birthtime(entry, self->time_created, 0); + archive_entry_set_ctime(entry, self->time_created, 0); + archive_entry_set_mtime(entry, self->time_created, 0); + archive_entry_set_atime(entry, self->time_created, 0); + + // Write the header + r = archive_write_header(self->archive, entry); + if (r) { + ERROR(self->ctx, "Error writing header: %s\n", + archive_error_string(self->archive)); + r = -EINVAL; + goto ERROR; + } + + // Write content + r = archive_write_data(self->archive, payload, length); + if (r < 0) { + ERROR(self->ctx, "Error writing data: %s\n", + archive_error_string(self->archive)); + r = -EINVAL; + goto ERROR; + } + + // Write trailer + r = archive_write_finish_entry(self->archive); + if (r) { + ERROR(self->ctx, "Failed to write the trailer: %s\n", + archive_error_string(self->archive)); + r = -EINVAL; + goto ERROR; + } + +ERROR: + if (entry) + archive_entry_free(entry); + + return r; +} diff --git a/src/pakfire/archive_writer.h b/src/pakfire/archive_writer.h index 6a6aaad1..92289684 100644 --- a/src/pakfire/archive_writer.h +++ b/src/pakfire/archive_writer.h @@ -44,4 +44,7 @@ int pakfire_archive_writer_set_title(struct pakfire_archive_writer* self, int pakfire_archive_writer_write_files( struct pakfire_archive_writer* self, struct pakfire_filelist* files); +int pakfire_archive_writer_create_file(struct pakfire_archive_writer* self, + const char* filename, mode_t mode, const char* payload, const size_t length); + #endif /* PAKFIRE_ARCHIVE_WRITER_H */ -- 2.39.5