#############################################################################*/
#include <errno.h>
+#include <fcntl.h>
+#include <linux/limits.h>
#include <stdlib.h>
+#include <archive.h>
+
+#include <pakfire/logging.h>
#include <pakfire/package.h>
#include <pakfire/packager.h>
#include <pakfire/pakfire.h>
int nrefs;
PakfirePackage pkg;
+
+ struct archive* payload;
+ char payload_path[PATH_MAX + 1];
};
+static int pakfire_packager_create_payload(struct pakfire_packager* p, int compress) {
+ p->payload = archive_write_new();
+
+ // Use the PAX format
+ int r = archive_write_set_format_pax(p->payload);
+ if (r) {
+ ERROR(p->pakfire, "Could not set format to PAX: %s\n",
+ archive_error_string(p->payload));
+ return r;
+ }
+
+ // Add filters to compress the payload
+ if (compress) {
+ // Enable Zstd
+ r = archive_write_add_filter_zstd(p->payload);
+ if (r) {
+ ERROR(p->pakfire, "Could not enable Zstandard compression: %s\n",
+ archive_error_string(p->payload));
+ return r;
+ }
+
+ // Set compression level to highest
+ r = archive_write_set_filter_option(p->payload, NULL, "compression-level", "19");
+ if (r) {
+ ERROR(p->pakfire, "Could not set Zstandard compression level: %s\n",
+ archive_error_string(p->payload));
+ return r;
+ }
+ }
+
+ // Allocate a temporary file to write the payload to
+ snprintf(p->payload_path, PATH_MAX, "/tmp/.pakfire-payload.XXXXXX");
+
+ int fd = mkostemp(p->payload_path, O_CLOEXEC);
+ if (fd < 0) {
+ ERROR(p->pakfire, "mkostemp() failed: %s\n", strerror(errno));
+ return 1;
+ }
+
+ r = archive_write_open_fd(p->payload, fd);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+static void pakfire_packager_free(struct pakfire_packager* packager) {
+ if (packager->payload)
+ archive_write_free(packager->payload);
+
+ pakfire_package_unref(packager->pkg);
+ pakfire_unref(packager->pakfire);
+}
+
PAKFIRE_EXPORT int pakfire_packager_create(struct pakfire_packager** packager,
PakfirePackage pkg) {
struct pakfire_packager* p = calloc(1, sizeof(*p));
// Store a reference to the package
p->pkg = pakfire_package_ref(pkg);
+ // Start payload
+ int r = pakfire_packager_create_payload(p, 1);
+ if (r) {
+ pakfire_packager_free(p);
+ return r;
+ }
+
*packager = p;
return 0;
}
-static void pakfire_packager_free(struct pakfire_packager* packager) {
- pakfire_package_unref(packager->pkg);
- pakfire_unref(packager->pakfire);
-}
-
PAKFIRE_EXPORT struct pakfire_packager* pakfire_packager_ref(
struct pakfire_packager* packager) {
++packager->nrefs;