]> git.ipfire.org Git - pakfire.git/commitdiff
archive: Add a function to copy an archive to somewhere else
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 20 Aug 2021 10:50:24 +0000 (10:50 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 20 Aug 2021 10:50:24 +0000 (10:50 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
configure.ac
src/libpakfire/archive.c
src/libpakfire/include/pakfire/archive.h

index 1f2ca732afded9c2e15f374864fd829b41785938..3143d6873130d874aa1ed212c2e749241c5e28dd 100644 (file)
@@ -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 \
index 0b60b29802180c2164c36b54bc89f22415521420..38873a436b67f3a4add6aba34f74dcec2e102401 100644 (file)
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <sys/queue.h>
 #include <sys/types.h>
+#include <sys/sendfile.h>
 #include <sys/stat.h>
 
 // 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];
index 7efe1ccb75eb746d044c1ed6ea67ecd77a0eef03..957265ba2153f9a8eded47252f4ec5dcbdc95c54 100644 (file)
@@ -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);