#include <json.h>
#include <pakfire/archive.h>
-#include <pakfire/compress.h>
+#include <pakfire/archive_writer.h>
#include <pakfire/constants.h>
#include <pakfire/logging.h>
#include <pakfire/package.h>
return strdup(filename);
}
-static struct archive_entry* pakfire_packager_create_file(
- struct pakfire_packager* packager, const char* filename, size_t size, mode_t mode) {
- // Create a new file entry
- struct archive_entry* entry = archive_entry_new();
- if (!entry)
- return NULL;
-
- // 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 size
- archive_entry_set_size(entry, size);
-
- // 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, packager->time_created, 0);
- archive_entry_set_ctime(entry, packager->time_created, 0);
- archive_entry_set_mtime(entry, packager->time_created, 0);
- archive_entry_set_atime(entry, packager->time_created, 0);
-
- return entry;
-}
-
-static int pakfire_packager_write_file_from_buffer(struct pakfire_packager* packager,
- struct archive* a, const char* filename, mode_t mode, const char* buffer) {
- size_t size = strlen(buffer);
-
- // Create a new file
- struct archive_entry* entry = pakfire_packager_create_file(packager, filename, size, mode);
- if (!entry) {
- ERROR(packager->ctx, "Could not create file '%s'\n", filename);
- return -errno;
- }
-
- // This is the end of the header
- int r = archive_write_header(a, entry);
- if (r) {
- ERROR(packager->ctx, "Error writing header: %s\n", archive_error_string(a));
- goto ERROR;
- }
-
- // Write content
- r = archive_write_data(a, buffer, strlen(buffer));
- if (r < 0) {
- ERROR(packager->ctx, "Error writing data: %s\n", archive_error_string(a));
- goto ERROR;
- }
-
- // Success
- r = 0;
-
-ERROR:
- archive_entry_free(entry);
-
- return r;
-}
-
static int pakfire_packager_write_format(struct pakfire_packager* packager,
- struct archive* a) {
- const char buffer[] = TO_STRING(PACKAGE_FORMAT) "\n";
+ struct pakfire_archive_writer* writer) {
+ const char format[] = TO_STRING(PACKAGE_FORMAT) "\n";
+ int r;
DEBUG(packager->ctx, "Writing package format\n");
- int r = pakfire_packager_write_file_from_buffer(packager, a,
- "pakfire-format", 0444, buffer);
- if (r)
+ // Write the file
+ r = pakfire_archive_writer_create_file(writer,
+ "pakfire-format", 0444, format, strlen(format));
+ if (r < 0) {
+ ERROR(packager->ctx, "Failed to write pakfire-format: %s\n", strerror(-r));
return r;
+ }
// Add package format marker
r = pakfire_package_add_dep(packager->pkg, PAKFIRE_PKG_REQUIRES,
- "pakfire(PackageFormat-" TO_STRING(PACKAGE_FORMAT) ")");
- if (r)
+ "pakfire(PackageFormat-%d)", PACKAGE_FORMAT);
+ if (r < 0)
return r;
return 0;
}
-static char* pakfire_packager_make_metadata(struct pakfire_packager* packager) {
- char* result = NULL;
+static int pakfire_packager_write_metadata(struct pakfire_packager* packager,
+ struct pakfire_archive_writer* writer) {
+ struct json_object* md = NULL;
+ const char* s = NULL;
+ int r;
// Convert all package metadata to JSON
- struct json_object* md = pakfire_package_to_json(packager->pkg);
- if (!md)
+ md = pakfire_package_to_json(packager->pkg);
+ if (!md) {
+ r = -errno;
goto ERROR;
+ }
- // Serialize JSON to file
- const char* s = json_object_to_json_string_ext(md, 0);
- if (!s)
+ // Serialize JSON to string
+ s = json_object_to_json_string_ext(md, 0);
+ if (!s) {
+ r = -errno;
goto ERROR;
+ }
+
+ DEBUG(packager->ctx, "Generated package metadata:\n%s\n", s);
- // Copy result onto heap
- result = strdup(s);
- if (!result)
+ // Write metadata
+ r = pakfire_archive_writer_create_file(writer, ".PKGINFO", 0444, s, strlen(s));
+ if (r < 0) {
+ ERROR(packager->ctx, "Failed to write package metadata: %s\n", strerror(-r));
goto ERROR;
+ }
ERROR:
- // Free metadata
if (md)
json_object_put(md);
- return result;
-}
-
-static int pakfire_packager_write_metadata(struct pakfire_packager* packager,
- struct archive* a) {
- int r;
-
- // Make metadata
- char* buffer = pakfire_packager_make_metadata(packager);
- if (!buffer)
- return -errno;
-
- DEBUG(packager->ctx, "Generated package metadata:\n%s\n", buffer);
-
- // Write buffer
- r = pakfire_packager_write_file_from_buffer(packager, a, ".PKGINFO", 0444, buffer);
- free(buffer);
-
return r;
}
static int pakfire_packager_write_scriptlet(struct pakfire_packager* packager,
- struct archive* a, struct pakfire_scriptlet* scriptlet) {
+ struct pakfire_archive_writer* writer, struct pakfire_scriptlet* scriptlet) {
char filename[PATH_MAX];
size_t size;
int r;
// Make filename
r = pakfire_string_format(filename, ".scriptlets/%s", type);
- if (r)
+ if (r < 0)
return r;
// Fetch scriptlet
const char* data = pakfire_scriptlet_get_data(scriptlet, &size);
// Write file
- return pakfire_packager_write_file_from_buffer(packager, a, filename, 0544, data);
+ return pakfire_archive_writer_create_file(writer, filename, 0544, data, size);
}
/*
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;
- unsigned int level;
- int r = 1;
+ struct pakfire_archive_writer* writer = NULL;
+ int r;
+ // Fetch nevra
const char* nevra = pakfire_package_get_string(packager->pkg, PAKFIRE_PKG_NEVRA);
// Add requires feature markers
goto ERROR;
}
+ // Add feature marker
+ pakfire_package_add_dep(packager->pkg,
+ PAKFIRE_PKG_REQUIRES, "pakfire(Compress-Zstandard)");
+
// Add filelist
r = pakfire_package_set_filelist(packager->pkg, packager->filelist);
if (r)
if (r)
goto ERROR;
- // Select compression level
- if (pakfire_package_is_source(packager->pkg))
- level = 1;
- else
- level = 20;
-
- // Create a new archive that is being compressed as fast as possible
- r = pakfire_compress_create_archive(packager->pakfire, &a, f,
- PAKFIRE_COMPRESS_ZSTD, level);
- if (r)
+ // Create a new archive writer
+ r = pakfire_archive_writer_create(&writer, packager->pakfire,
+ PAKFIRE_FORMAT_ARCHIVE, f);
+ if (r < 0)
goto ERROR;
- // Add feature marker
- pakfire_package_add_dep(packager->pkg,
- PAKFIRE_PKG_REQUIRES, "pakfire(Compress-Zstandard)");
+ // Set the title
+ r = pakfire_archive_writer_set_title(writer, "%s", nevra);
+ if (r < 0)
+ goto ERROR;
// Start with the format file
- r = pakfire_packager_write_format(packager, a);
- if (r) {
- ERROR(packager->ctx, "Could not add format file to archive: %s\n",
- archive_error_string(a));
+ r = pakfire_packager_write_format(packager, writer);
+ if (r < 0) {
+ ERROR(packager->ctx, "Could not add format file to archive: %s\n", strerror(-r));
goto ERROR;
}
// Write the metadata
- r = pakfire_packager_write_metadata(packager, a);
- if (r) {
- ERROR(packager->ctx, "Could not add metadata file to archive: %s\n",
- archive_error_string(a));
+ r = pakfire_packager_write_metadata(packager, writer);
+ if (r < 0) {
+ ERROR(packager->ctx, "Could not add metadata file to archive: %s\n", strerror(-r));
goto ERROR;
}
// Write scriptlets
for (unsigned int i = 0; i < packager->num_scriptlets; i++) {
- r = pakfire_packager_write_scriptlet(packager, a, packager->scriptlets[i]);
- if (r) {
- ERROR(packager->ctx, "Could not add scriptlet to the archive: %m\n");
+ r = pakfire_packager_write_scriptlet(packager, writer, packager->scriptlets[i]);
+ if (r < 0) {
+ ERROR(packager->ctx, "Could not add scriptlet to the archive: %s\n", strerror(-r));
goto ERROR;
}
}
// Write the payload
- r = pakfire_compress(packager->pakfire, a, packager->filelist, nevra,
- PAKFIRE_COMPRESS_SHOW_THROUGHPUT, PAKFIRE_PACKAGER_HASHES);
- if (r)
+ r = pakfire_archive_writer_write_files(writer, packager->filelist);
+ if (r < 0)
goto ERROR;
- // Flush all buffers to disk
- fflush(f);
-
- // Success
- r = 0;
-
ERROR:
- if (a)
- archive_write_free(a);
+ if (writer)
+ pakfire_archive_writer_unref(writer);
return r;
}