]> git.ipfire.org Git - pakfire.git/commitdiff
transaction: Perform file conflict check
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 10 Nov 2021 11:48:25 +0000 (11:48 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 10 Nov 2021 11:48:25 +0000 (11:48 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/transaction.c

index 7aac7868775724df0587502f47644eb5dcb84666..aa3faa52218480ee54003dfaaaf42b70294d9bcc 100644 (file)
@@ -23,6 +23,8 @@
 
 #include <openssl/crypto.h>
 #include <openssl/evp.h>
+
+#include <solv/pool_fileconflicts.h>
 #include <solv/transaction.h>
 
 #include <pakfire/archive.h>
@@ -579,6 +581,53 @@ PAKFIRE_EXPORT char* pakfire_transaction_dump(struct pakfire_transaction* transa
        return string;
 }
 
+static void* pakfire_transaction_fileconflict_callback(
+               Pool* pool, Id p, void* data) {
+       return NULL;
+}
+
+static int pakfire_transaction_check_fileconflicts(
+               struct pakfire_transaction* transaction) {
+       Pool* pool = pakfire_get_solv_pool(transaction->pakfire);
+
+       const int flags =
+               FINDFILECONFLICTS_USE_SOLVABLEFILELIST |
+               FINDFILECONFLICTS_CHECK_DIRALIASING |
+               FINDFILECONFLICTS_USE_ROOTDIR;
+
+       Queue pkgs;
+       queue_init(&pkgs);
+
+       Queue conflicts;
+       queue_init(&conflicts);
+
+       // Fetch all installed packages
+       int newpkgs = transaction_installedresult(transaction->transaction, &pkgs);
+
+       // Perform check
+       int count = pool_findfileconflicts(pool, &pkgs, newpkgs, &conflicts, flags,
+               pakfire_transaction_fileconflict_callback, NULL);
+
+       DEBUG(transaction->pakfire, "Found %d file conflict(s)\n", count);
+
+       // Free everything
+       queue_free(&pkgs);
+       queue_free(&conflicts);
+
+       return (count > 0);
+}
+
+static int pakfire_transaction_check(struct pakfire_transaction* transaction) {
+       int r;
+
+       // Check for any file conflicts
+       r = pakfire_transaction_check_fileconflicts(transaction);
+       if (r)
+               return r;
+
+       return 0;
+}
+
 static int pakfire_transaction_verify(struct pakfire_transaction* transaction,
                struct pakfire_package* pkg, struct pakfire_archive* archive) {
        int r;
@@ -1148,6 +1197,11 @@ PAKFIRE_EXPORT int pakfire_transaction_run(struct pakfire_transaction* transacti
        // Write transaction dump to log
        INFO(transaction->pakfire, "%s\n", dump);
 
+       // Perform a check if this can actually be run
+       r = pakfire_transaction_check(transaction);
+       if (r)
+               goto ERROR;
+
        // Download what we need
        r = pakfire_transaction_download(transaction);
        if (r)