From: Michael Tremer Date: Thu, 20 May 2021 17:23:37 +0000 (+0000) Subject: archive: Make files sticky X-Git-Tag: 0.9.28~1285^2~119 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f99c69bb7f9b6ecfb0af44ed4a5511257e2708df;p=pakfire.git archive: Make files sticky 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 --- diff --git a/src/libpakfire/archive.c b/src/libpakfire/archive.c index 783020e17..7bc5173d5 100644 --- a/src/libpakfire/archive.c +++ b/src/libpakfire/archive.c @@ -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;