Signed-off-by: Andrew Gregory <[email protected]>
---

lrealpath definition moved to query_fileowner patch.

 lib/libalpm/conflict.c               | 39 ++++++++++++++++++------------------
 test/pacman/tests/fileconflict007.py |  2 --
 test/pacman/tests/symlink020.py      | 20 ++++++++++++++++++
 3 files changed, 40 insertions(+), 21 deletions(-)
 create mode 100644 test/pacman/tests/symlink020.py

diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c
index d44a459..ab9546c 100644
--- a/lib/libalpm/conflict.c
+++ b/lib/libalpm/conflict.c
@@ -505,6 +505,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t 
*handle,
                        size_t pathlen;
 
                        pathlen = snprintf(path, PATH_MAX, "%s%s", 
handle->root, filestr);
+                       relative_path = path + rootlen;
 
                        /* stat the file - if it exists, do some checks */
                        if(_alpm_lstat(path, &lsbuf) != 0) {
@@ -513,7 +514,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t 
*handle,
 
                        _alpm_log(handle, ALPM_LOG_DEBUG, "checking possible 
conflict: %s\n", path);
 
-                       if(filestr[strlen(filestr) - 1] == '/') {
+                       if(path[pathlen - 1] == '/') {
                                if(S_ISDIR(lsbuf.st_mode)) {
                                        _alpm_log(handle, ALPM_LOG_DEBUG, "file 
is a directory, not a conflict\n");
                                        continue;
@@ -522,9 +523,25 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t 
*handle,
                                 * not include the trailing slash. This allows 
things like file ->
                                 * directory replacements. */
                                path[pathlen - 1] = '\0';
-                       }
 
-                       relative_path = path + rootlen;
+                               /* Check if the directory was a file in dbpkg */
+                               
if(alpm_filelist_contains(alpm_pkg_get_files(dbpkg), relative_path)) {
+                                       size_t fslen = strlen(filestr);
+                                       _alpm_log(handle, ALPM_LOG_DEBUG,
+                                                       "replacing package file 
with a directory, not a conflict\n");
+                                       resolved_conflict = 1;
+
+                                       /* go ahead and skip any files inside 
filestr as they will
+                                        * necessarily be resolved by replacing 
the file with a dir
+                                        * NOTE: afterward, j will point to the 
last file inside filestr */
+                                       for( ; j->next; j = j->next) {
+                                               const char *filestr2 = 
j->next->data;
+                                               if(strncmp(filestr, filestr2, 
fslen) != 0) {
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
 
                        /* Check remove list (will we remove the conflicting 
local file?) */
                        for(k = rem; k && !resolved_conflict; k = k->next) {
@@ -573,22 +590,6 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t 
*handle,
                                free(dir);
                        }
 
-                       /* check if a component of the filepath was a link. 
canonicalize the path
-                        * and look for it in the old package. note that the 
actual file under
-                        * consideration cannot itself be a link, as it might 
be unowned- path
-                        * components can be safely checked as all directories 
are "unowned". */
-                       if(!resolved_conflict && dbpkg && 
!S_ISLNK(lsbuf.st_mode)) {
-                               char rpath[PATH_MAX];
-                               if(realpath(path, rpath)) {
-                                       const char *relative_rpath = rpath + 
rootlen;
-                                       
if(alpm_filelist_contains(alpm_pkg_get_files(dbpkg), relative_rpath)) {
-                                               _alpm_log(handle, 
ALPM_LOG_DEBUG,
-                                                               "package 
contained the resolved realpath\n");
-                                               resolved_conflict = 1;
-                                       }
-                               }
-                       }
-
                        /* is the file unowned and in the backup list of the 
new package? */
                        if(!resolved_conflict && 
_alpm_needbackup(relative_path, p1)) {
                                alpm_list_t *local_pkgs = 
_alpm_db_get_pkgcache(handle->db_local);
diff --git a/test/pacman/tests/fileconflict007.py 
b/test/pacman/tests/fileconflict007.py
index b61ddb4..7fe65ed 100644
--- a/test/pacman/tests/fileconflict007.py
+++ b/test/pacman/tests/fileconflict007.py
@@ -16,5 +16,3 @@
 self.addrule("PKG_EXIST=pkg")
 self.addrule("PKG_VERSION=pkg|1.0-2")
 self.addrule("FILE_TYPE=dir/symdir/|dir")
-
-self.expectfailure = True
diff --git a/test/pacman/tests/symlink020.py b/test/pacman/tests/symlink020.py
new file mode 100644
index 0000000..343add2
--- /dev/null
+++ b/test/pacman/tests/symlink020.py
@@ -0,0 +1,20 @@
+self.description = "symlink -> dir replacment"
+
+lp1 = pmpkg("pkg1")
+lp1.files = ["usr/lib/foo",
+             "lib -> usr/lib/"]
+self.addpkg2db("local", lp1)
+
+lp1 = pmpkg("pkg2")
+lp1.files = ["usr/lib/bar"]
+self.addpkg2db("local", lp1)
+
+sp = pmpkg("pkg1", "1.0-2")
+sp.files = ["lib/bar"]
+self.addpkg2db("sync", sp)
+
+self.args = "-S %s" % sp.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("FILE_TYPE=lib|dir")
+self.addrule("FILE_TYPE=lib/bar|file")
-- 
1.8.2.2


Reply via email to