]> git.ipfire.org Git - pakfire.git/commitdiff
archive: Make files sticky
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 20 May 2021 17:23:37 +0000 (17:23 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 20 May 2021 17:35:25 +0000 (17:35 +0000)
We can now return to open the archive file once and keep it opened. This
makes files sticky and nobody can replace or delete a file
mid-transaction.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/archive.c

index 783020e17020d555e741bf34f60ba0aad37b9529..7bc5173d52fd3cafdaed51cfcef136b36b3175cb 100644 (file)
@@ -65,8 +65,9 @@ struct _PakfireArchive {
        Pakfire pakfire;
        int nrefs;
 
-       PakfirePackage package;
        char path[PATH_MAX];
+       FILE* f;
+       PakfirePackage package;
 
        // metadata
        unsigned int format;
@@ -94,7 +95,20 @@ struct _PakfireArchiveSignature {
        int nrefs;
 };
 
-static int archive_open(PakfireArchive archive, struct archive** a) {
+/*
+       A helper function to close the archive and reset our data structures
+*/
+static void close_archive(PakfireArchive archive, struct archive* a) {
+       archive_read_free(a);
+
+       // Rewind the file descriptor
+       rewind(archive->f);
+}
+
+/*
+       A helper function that opens the archive for reading
+*/
+static int open_archive(PakfireArchive archive, struct archive** a) {
        *a = archive_read_new();
        if (!*a)
                return ENOMEM;
@@ -103,16 +117,21 @@ static int archive_open(PakfireArchive archive, struct archive** a) {
        archive_read_support_format_tar(*a);
 
        // Try opening the archive file
-       int r = archive_read_open_filename(*a, archive->path, 8192);
+       int r = archive_read_open_FILE(*a, archive->f);
        if (r) {
                ERROR(archive->pakfire, "Could not open archive %s: %s\n",
                        archive->path, archive_error_string(*a));
-               archive_read_free(*a);
-               *a = NULL;
-               return r;
+               goto ERROR;
        }
 
+       // Success
        return 0;
+
+ERROR:
+       close_archive(archive, *a);
+       *a = NULL;
+
+       return r;
 }
 
 static int find_archive_entry(struct archive_entry** entry, struct archive* a, const char* filename) {
@@ -336,6 +355,10 @@ static void pakfire_archive_free_chksums(PakfireArchive archive) {
 static void pakfire_archive_free(PakfireArchive archive) {
        DEBUG(archive->pakfire, "Releasing archive at %p\n", archive);
 
+       // Close the file
+       if (archive->f)
+               fclose(archive->f);
+
        // Free all checksums
        pakfire_archive_free_chksums(archive);
 
@@ -428,7 +451,7 @@ static int pakfire_archive_parse_metadata(PakfireArchive archive) {
                return 0;
 
        // Open the archive
-       int r = archive_open(archive, &a);
+       int r = open_archive(archive, &a);
        if (r)
                goto ERROR;
 
@@ -602,7 +625,7 @@ static int pakfire_archive_walk(PakfireArchive archive,
        struct archive* a;
 
        // Open the archive file
-       int r = archive_open(archive, &a);
+       int r = open_archive(archive, &a);
        if (r)
                return r;
 
@@ -689,9 +712,14 @@ static int pakfire_archive_try_open(PakfireArchive archive, const char* path) {
        // Store path
        pakfire_string_set(archive->path, path);
 
+       // Open the file (and keep the file descriptor open)
+       archive->f = fopen(archive->path, "r");
+       if (!archive->f)
+               return 1;
+
        // Open the archive file for reading.
        struct archive* a = NULL;
-       int r = archive_open(archive, &a);
+       int r = open_archive(archive, &a);
        if (r)
                goto ERROR;
 
@@ -749,7 +777,7 @@ PAKFIRE_EXPORT int pakfire_archive_read(PakfireArchive archive, const char* file
        while (*filename == '/')
                filename++;
 
-       int r = archive_open(archive, &a);
+       int r = open_archive(archive, &a);
        if (r)
                goto ERROR;
 
@@ -952,7 +980,7 @@ PAKFIRE_EXPORT int pakfire_archive_extract(PakfireArchive archive, const char* p
                goto ERROR;
 
        // Open the archive
-       r = archive_open(archive, &a);
+       r = open_archive(archive, &a);
        if (r)
                goto ERROR;
 
@@ -1044,7 +1072,7 @@ static int pakfire_archive_load_filelist(PakfireArchive archive) {
        int r;
 
        // Open the archive
-       r = archive_open(archive, &a);
+       r = open_archive(archive, &a);
        if (r)
                goto ERROR;
 
@@ -1347,7 +1375,7 @@ PAKFIRE_EXPORT pakfire_archive_verify_status_t pakfire_archive_verify(PakfireArc
 
        // Open the archive file
        struct archive* a;
-       int r = archive_open(archive, &a);
+       int r = open_archive(archive, &a);
        if (r)
                return PAKFIRE_ARCHIVE_VERIFY_ERROR;