From: Michael Tremer Date: Fri, 20 Aug 2021 10:50:24 +0000 (+0000) Subject: archive: Add a function to copy an archive to somewhere else X-Git-Tag: 0.9.28~980 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=285b27587d038a2b7537fb9701d199e98ae1a83a;p=pakfire.git archive: Add a function to copy an archive to somewhere else Signed-off-by: Michael Tremer --- diff --git a/configure.ac b/configure.ac index 1f2ca732a..3143d6873 100644 --- a/configure.ac +++ b/configure.ac @@ -169,6 +169,7 @@ AC_CHECK_HEADERS([ \ sys/personality.h \ sys/random.h \ sys/resource.h \ + sys/sendfile.h \ sys/stat.h \ sys/sysmacros.h \ sys/types.h \ @@ -197,6 +198,7 @@ AC_CHECK_FUNCS([ \ personality \ remove \ secure_getenv \ + sendfile \ snprintf \ strcmp \ strdup \ diff --git a/src/libpakfire/archive.c b/src/libpakfire/archive.c index 0b60b2980..38873a436 100644 --- a/src/libpakfire/archive.c +++ b/src/libpakfire/archive.c @@ -25,6 +25,7 @@ #include #include #include +#include #include // libarchive @@ -676,6 +677,46 @@ ERROR: return r; } +int pakfire_archive_copy(struct pakfire_archive* archive, const char* path) { + if (!path) { + errno = EINVAL; + return 1; + } + + // Determine the file size + ssize_t size = pakfire_archive_get_size(archive); + if (size < 0) + return 1; + + DEBUG(archive->pakfire, "Copying %s to %s...\n", archive->path, path); + + // Open destination file + FILE* f = fopen(path, "w"); + if (!f) + return 1; + + int r = 1; + + // Copy everything + ssize_t bytes_written = sendfile(fileno(f), fileno(archive->f), NULL, size); + if (bytes_written != size) + goto ERROR; + + // Success + r = 0; + +ERROR: + fclose(f); + + // Delete the file on error + if (r) + unlink(path); + + rewind(archive->f); + + return r; +} + static int pakfire_archive_extraction_path(struct pakfire_archive* archive, char* path, size_t length, const char* prefix) { char buffer[PATH_MAX]; diff --git a/src/libpakfire/include/pakfire/archive.h b/src/libpakfire/include/pakfire/archive.h index 7efe1ccb7..957265ba2 100644 --- a/src/libpakfire/include/pakfire/archive.h +++ b/src/libpakfire/include/pakfire/archive.h @@ -70,6 +70,8 @@ int pakfire_archive_make_package(struct pakfire_archive* archive, #ifdef PAKFIRE_PRIVATE +int pakfire_archive_copy(struct pakfire_archive* archive, const char* path); + struct pakfire_scriptlet* pakfire_archive_get_scriptlet( struct pakfire_archive* archive, const char* type);