From: Michael Tremer Date: Sat, 6 Mar 2021 15:15:07 +0000 (+0000) Subject: packager: Add a function that adds a file to the payload X-Git-Tag: 0.9.28~1285^2~619 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=da08f9891f9b65ca3d8049be6ef1abaf2e5acfef;p=pakfire.git packager: Add a function that adds a file to the payload Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/include/pakfire/packager.h b/src/libpakfire/include/pakfire/packager.h index 139b87b4b..9abccac70 100644 --- a/src/libpakfire/include/pakfire/packager.h +++ b/src/libpakfire/include/pakfire/packager.h @@ -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 */ diff --git a/src/libpakfire/libpakfire.sym b/src/libpakfire/libpakfire.sym index 9e9c73041..215ff18e3 100644 --- a/src/libpakfire/libpakfire.sym +++ b/src/libpakfire/libpakfire.sym @@ -249,6 +249,7 @@ global: # packager + pakfire_packager_add; pakfire_packager_create; pakfire_packager_ref; pakfire_packager_unref; diff --git a/src/libpakfire/packager.c b/src/libpakfire/packager.c index 989583309..211470b2e 100644 --- a/src/libpakfire/packager.c +++ b/src/libpakfire/packager.c @@ -22,8 +22,12 @@ #include #include #include +#include +#include +#include #include +#include #include #include @@ -32,6 +36,8 @@ #include #include +#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; +} diff --git a/tests/libpakfire/packager.c b/tests/libpakfire/packager.c index 862102ab3..7838cf0e8 100644 --- a/tests/libpakfire/packager.c +++ b/tests/libpakfire/packager.c @@ -21,6 +21,7 @@ #include #include #include +#include #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; }