Detect a conflict between a file/symlink in one package and a directory
in another when both are being installed at once.

A side effect is the creation on conflicts between a direcotry symlink
and a real directory (e.g lib -> usr/lib in pkg1 and /lib in pkg2).
Given we can not guarantee pkg1 is installed before pkg2, this is a
genuine conflict.

Signed-off-by: Allan McRae <[email protected]>
---
 lib/libalpm/conflict.c               | 48 +++++++++++++++++++++++++-----------
 test/pacman/tests/fileconflict002.py |  2 --
 test/pacman/tests/fileconflict015.py |  2 --
 3 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c
index f3b269f..041ba6f 100644
--- a/lib/libalpm/conflict.c
+++ b/lib/libalpm/conflict.c
@@ -274,28 +274,48 @@ static alpm_list_t *filelist_intersection(alpm_filelist_t 
*filesA,
        size_t ctrA = 0, ctrB = 0;
 
        while(ctrA < filesA->count && ctrB < filesB->count) {
+               int cmp, isdirA, isdirB;
+
                alpm_file_t *fileA = filesA->files + ctrA;
                alpm_file_t *fileB = filesB->files + ctrB;
-               const char *strA = fileA->name;
-               const char *strB = fileB->name;
-               /* skip directories, we don't care about them */
+               char *strA = strdup(fileA->name);
+               char *strB = strdup(fileB->name);
+
+               isdirA = 0;
                if(strA[strlen(strA)-1] == '/') {
+                       isdirA = 1;
+                       strA[strlen(strA)-1] = '\0';
+               }
+
+               isdirB = 0;
+               if(strB[strlen(strB)-1] == '/') {
+                       isdirB = 1;
+                       strB[strlen(strB)-1] = '\0';
+               }
+
+               cmp = strcmp(strA, strB);
+               if(cmp < 0) {
                        ctrA++;
-               } else if(strB[strlen(strB)-1] == '/') {
+               } else if(cmp > 0) {
                        ctrB++;
                } else {
-                       int cmp = strcmp(strA, strB);
-                       if(cmp < 0) {
-                               ctrA++;
-                       } else if(cmp > 0) {
-                               ctrB++;
-                       } else {
-                               /* item in both, qualifies as an intersect */
+                       /* TODO: this creates conflicts between a symlink to a 
directory in
+                        * one package and a real directory in the other. For 
example,
+                        * lib -> /usr/lib in pkg1 and /lib in pkg2.  This 
would be allowed
+                        * when installing one package at a time _provided_ 
pkg1 is installed
+                        * first. This will need adjusted if the order of 
package install can
+                        * be guaranteed to install the symlink first */
+
+                       /* when not directories, item in both qualifies as an 
intersect */
+                       if(! (isdirA && isdirB)) {
                                ret = alpm_list_add(ret, fileA);
-                               ctrA++;
-                               ctrB++;
                        }
-         }
+                       ctrA++;
+                       ctrB++;
+               }
+
+               free(strA);
+               free(strB);
        }
 
        return ret;
diff --git a/test/pacman/tests/fileconflict002.py 
b/test/pacman/tests/fileconflict002.py
index e107cd2..1e6113c 100644
--- a/test/pacman/tests/fileconflict002.py
+++ b/test/pacman/tests/fileconflict002.py
@@ -19,5 +19,3 @@
 self.addrule("!PKG_EXIST=pkg1")
 self.addrule("!PKG_EXIST=pkg2")
 self.addrule("!FILE_EXIST=dir/realdir/file")
-
-self.expectfailure = True
diff --git a/test/pacman/tests/fileconflict015.py 
b/test/pacman/tests/fileconflict015.py
index 78634d7..3c80bbc 100644
--- a/test/pacman/tests/fileconflict015.py
+++ b/test/pacman/tests/fileconflict015.py
@@ -13,5 +13,3 @@
 self.addrule("PACMAN_RETCODE=1")
 self.addrule("!PKG_EXIST=pkg1")
 self.addrule("!PKG_EXIST=pkg2")
-
-self.expectfailure = True
-- 
1.7.11.2


Reply via email to