]> git.ipfire.org Git - pakfire.git/commitdiff
packager: Add a function that adds a file to the payload
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 6 Mar 2021 15:15:07 +0000 (15:15 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 6 Mar 2021 15:15:07 +0000 (15:15 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/include/pakfire/packager.h
src/libpakfire/libpakfire.sym
src/libpakfire/packager.c
tests/libpakfire/packager.c

index 139b87b4bc8494743f8cade162d29b5e83b78610..9abccac7039777bb642a6ece5236639f80ab7ec5 100644 (file)
@@ -30,4 +30,6 @@ int pakfire_packager_create(struct pakfire_packager** packager, PakfirePackage p
 struct pakfire_packager* pakfire_packager_ref(struct pakfire_packager* packager);
 struct pakfire_packager* pakfire_packager_unref(struct pakfire_packager* packager);
 
+int pakfire_packager_add(struct pakfire_packager* packager, const char* path);
+
 #endif /* PAKFIRE_PACKAGER_H */
index 9e9c73041f0cd41180e9b558fd0d3f557d03c8b9..215ff18e3149cb1efb6bf7a33a3a4d2ff273c934 100644 (file)
@@ -249,6 +249,7 @@ global:
 
        # packager
 
+       pakfire_packager_add;
        pakfire_packager_create;
        pakfire_packager_ref;
        pakfire_packager_unref;
index 9895833093d2cafdf10435abd380f3e10f1b5da0..211470b2efa7eae13ee1a90c5a69eaface669825 100644 (file)
 #include <fcntl.h>
 #include <linux/limits.h>
 #include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 #include <archive.h>
+#include <archive_entry.h>
 
 #include <pakfire/logging.h>
 #include <pakfire/package.h>
@@ -32,6 +36,8 @@
 #include <pakfire/private.h>
 #include <pakfire/types.h>
 
+#define BUFFER_SIZE 64 * 1024
+
 struct pakfire_packager {
        Pakfire pakfire;
        int nrefs;
@@ -143,3 +149,83 @@ PAKFIRE_EXPORT struct pakfire_packager* pakfire_packager_unref(
 
        return NULL;
 }
+
+PAKFIRE_EXPORT int pakfire_packager_add(struct pakfire_packager* packager,
+               const char* path) {
+       FILE* f = NULL;
+       struct stat st;
+       char buffer[BUFFER_SIZE];
+
+       // Check if path is set
+       if (!path)
+               return EINVAL;
+
+       // Stat the input file
+       int r = stat(path, &st);
+       if (r) {
+               ERROR(packager->pakfire, "stat() on %s failed: %s\n", path, strerror(errno));
+               return r;
+       }
+
+       // Create a new file entry
+       struct archive_entry* entry = archive_entry_new();
+       if (!entry)
+               return ENOMEM;
+
+       // Set path in archive
+       archive_entry_set_pathname(entry, path);
+
+       // Copy all attributes from stat()
+       archive_entry_copy_stat(entry, &st);
+
+       // Write the header
+       r = archive_write_header(packager->payload, entry);
+       if (r) {
+               ERROR(packager->pakfire, "Error writing file header: %s\n",
+                       archive_error_string(packager->payload));
+               goto ERROR;
+       }
+
+       // Copy the data of regular files
+       if (archive_entry_filetype(entry) == AE_IFREG) {
+               f = fopen(path, "r");
+               if (!f) {
+                       ERROR(packager->pakfire, "Could not open %s: %s\n", path, strerror(errno));
+                       r = errno;
+                       goto ERROR;
+               }
+
+               while (!feof(f)) {
+                       // Read a block from file
+                       size_t bytes_read = fread(buffer, 1, sizeof(buffer), f);
+
+                       if (ferror(f)) {
+                               ERROR(packager->pakfire, "Error reading from file %s: %s\n",
+                                       path, strerror(errno));
+                               r = errno;
+                               goto ERROR;
+                       }
+
+                       // Write the block to the archive
+                       ssize_t bytes_written = archive_write_data(packager->payload, buffer, bytes_read);
+                       if (bytes_written < 0) {
+                               ERROR(packager->pakfire, "Error writing data to archive: %s\n",
+                                       archive_error_string(packager->payload));
+                               r = 1;
+                               goto ERROR;
+                       }
+               }
+       }
+
+       // Successful
+       r = 0;
+
+ERROR:
+       if (entry)
+               archive_entry_free(entry);
+
+       if (f)
+               fclose(f);
+
+       return r;
+}
index 862102ab3f63831dea5ee3b99463acfcd9f64ede..7838cf0e80431c5f6b55feeb18c7171e7bd76959 100644 (file)
@@ -21,6 +21,7 @@
 #include <pakfire/package.h>
 #include <pakfire/packager.h>
 #include <pakfire/repo.h>
+#include <pakfire/util.h>
 
 #include "../testsuite.h"
 
@@ -37,11 +38,19 @@ static int test_create(const struct test* t) {
        // Create packager
        int r = pakfire_packager_create(&packager, pkg);
        ASSERT(r == 0);
-       
+
+       // Add a file to the package
+       char* path = pakfire_path_join(TEST_SRC_PATH, "data/beep-1.3-2.ip3.x86_64.pfm");
+       ASSERT(path);
+
+       r = pakfire_packager_add(packager, path);
+       ASSERT(r == 0);
+
        // Cleanup
        pakfire_packager_unref(packager);
        pakfire_package_unref(pkg);
        pakfire_repo_unref(repo);
+       free(path);
 
        return EXIT_SUCCESS;
 }