]> git.ipfire.org Git - pakfire.git/commitdiff
packager: Setup an area for writing the payload
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 5 Mar 2021 18:07:47 +0000 (18:07 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 5 Mar 2021 18:07:47 +0000 (18:07 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/packager.c

index fd91f061b1b49dc88c6bd1605c878252b43f6df4..5625523cc8067f7e35e6b87799e20010f6b4a4ff 100644 (file)
 #############################################################################*/
 
 #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>
@@ -32,8 +37,65 @@ struct pakfire_packager {
        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));
@@ -49,16 +111,18 @@ PAKFIRE_EXPORT int pakfire_packager_create(struct pakfire_packager** packager,
        // 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;