teknoraver / rpms / rpm

Forked from rpms/rpm 4 months ago
Clone
Blob Blame History Raw
commit 566a15c9c08aa593d05e2f55f1c171a48bc1b1bc
Author: Panu Matilainen <pmatilai@redhat.com>
Date:   Wed Mar 9 09:39:32 2011 +0200

    Take file state into account for file dependencies
    - Files which are not installed, have been replaced or are of wrong
      color can not actually satisfy a dependency despite what the package's
      file list says.
    - This prevents breaking the system despite seemingly correct dependencies
      in some situations, such as on multilib systems where a colored
      files can appear to be shared between primary and secondary architecture
      packages, but only the file from primary arch package is physically
      present, and removing the primary arch package would remove the
      file and silently break any dependencies on such files in practise.
      Similarly replaced files become owned by the replacing package in
      practise, so the original package whose files were replaced can no
      longer satisfy dependency on those files.

diff --git a/lib/depends.c b/lib/depends.c
index 4daa512..69aecbb 100644
--- a/lib/depends.c
+++ b/lib/depends.c
@@ -345,12 +345,25 @@ static int rpmdbProvides(rpmts ts, depCache dcache, rpmds dep)
 	return rc;
     }
 
-    /* See if a filename dependency is a real file in some package */
+    /*
+     * See if a filename dependency is a real file in some package,
+     * taking file state into account: replaced, wrong colored and
+     * not installed files can not satisfy a dependency.
+     */
     if (Name[0] == '/') {
 	mi = rpmtsPrunedIterator(ts, RPMDBI_BASENAMES, Name);
 	while ((h = rpmdbNextIterator(mi)) != NULL) {
-	    rpmdsNotify(dep, "(db files)", rc);
-	    break;
+	    int fs = RPMFILE_STATE_MISSING;
+	    struct rpmtd_s states;
+	    if (headerGet(h, RPMTAG_FILESTATES, &states, HEADERGET_MINMEM)) {
+		rpmtdSetIndex(&states, rpmdbGetIteratorFileNum(mi));
+		fs = rpmtdGetNumber(&states);
+		rpmtdFreeData(&states);
+	    }
+	    if (fs == RPMFILE_STATE_NORMAL || fs == RPMFILE_STATE_NETSHARED) {
+		rpmdsNotify(dep, "(db files)", rc);
+		break;
+	    }
 	}
 	rpmdbFreeIterator(mi);
     }