Panu Matilainen 93c12c
diff -up rpm-4.10.90.git11978/lib/depends.c.rpmlib-filesystem-check rpm-4.10.90.git11978/lib/depends.c
Panu Matilainen 93c12c
--- rpm-4.10.90.git11978/lib/depends.c.rpmlib-filesystem-check	2012-11-01 09:40:26.000000000 +0200
Panu Matilainen 93c12c
+++ rpm-4.10.90.git11978/lib/depends.c	2012-11-05 10:53:42.294733695 +0200
Panu Matilainen 93c12c
@@ -537,6 +537,109 @@ static int rpmdbProvides(rpmts ts, depCa
Panu Matilainen 93c12c
     return rc;
Panu Matilainen 93c12c
 }
Panu Matilainen 93c12c
 
Panu Matilainen 93c12c
+/*
Panu Matilainen 93c12c
+ * Temporary support for live-conversion of the filesystem hierarchy
Panu Matilainen 93c12c
+ *   mailto: kay@redhat.com, harald@redhat.com
Panu Matilainen 93c12c
+ *   https://fedoraproject.org/wiki/Features/UsrMove
Panu Matilainen 93c12c
+ *
Panu Matilainen 93c12c
+ *   X-CheckUnifiedSystemdir:
Panu Matilainen 93c12c
+ *     /bin, /sbin, /lib, /lib64 --> /usr
Panu Matilainen 93c12c
+ *
Panu Matilainen 93c12c
+ *   X-CheckUnifiedBindir:
Panu Matilainen 93c12c
+ *     /usr/sbin -> /usr/bin
Panu Matilainen 93c12c
+ *
Panu Matilainen 93c12c
+ *   X-CheckMultiArchLibdir:
Panu Matilainen 93c12c
+ *     /usr/lib64 /usr/lib/<platform tuple> (e.g. x86_64-linux-gnu)
Panu Matilainen 93c12c
+ *
Panu Matilainen 93c12c
+ * This code is not needed for new installations, it can be removed after
Panu Matilainen 93c12c
+ * updates from older systems are no longer supported: Fedora 19 / RHEL 8.
Panu Matilainen 93c12c
+ */
Panu Matilainen 93c12c
+
Panu Matilainen 93c12c
+static int CheckLink(const char *dir, const char *root)
Panu Matilainen 93c12c
+{
Panu Matilainen 93c12c
+    char *d = NULL;
Panu Matilainen 93c12c
+    struct stat sbuf;
Panu Matilainen 93c12c
+    int rc = 0;
Panu Matilainen 93c12c
+
Panu Matilainen 93c12c
+    if (!root)
Panu Matilainen 93c12c
+	root = "/";
Panu Matilainen 93c12c
+
Panu Matilainen 93c12c
+    rasprintf(&d, "%s%s", root, dir);
Panu Matilainen 93c12c
+    if (!d) {
Panu Matilainen 93c12c
+	rc = -1;
Panu Matilainen 93c12c
+	goto exit;
Panu Matilainen 93c12c
+    }
Panu Matilainen 93c12c
+
Panu Matilainen 93c12c
+    /* directory or symlink does not exist, all is fine */
Panu Matilainen 93c12c
+    if (lstat(d, &sbuf) < 0) {
Panu Matilainen 93c12c
+	rc = 1;
Panu Matilainen 93c12c
+	goto exit;
Panu Matilainen 93c12c
+    }
Panu Matilainen 93c12c
+
Panu Matilainen 93c12c
+    /* if it is a symlink, all is fine */
Panu Matilainen 93c12c
+    if (S_ISLNK(sbuf.st_mode))
Panu Matilainen 93c12c
+	rc = 1;
Panu Matilainen 93c12c
+
Panu Matilainen 93c12c
+exit:
Panu Matilainen 93c12c
+    free(d);
Panu Matilainen 93c12c
+    return rc;
Panu Matilainen 93c12c
+}
Panu Matilainen 93c12c
+
Panu Matilainen 93c12c
+static int CheckFilesystemHierarchy(rpmds * dsp, const char *root)
Panu Matilainen 93c12c
+{
Panu Matilainen 93c12c
+    static const char *dirs[] = { "bin", "sbin", "lib", "lib64" };
Panu Matilainen 93c12c
+    int check;
Panu Matilainen 93c12c
+    int i;
Panu Matilainen 93c12c
+    rpmds ds;
Panu Matilainen 93c12c
+    rpmstrPool pool = rpmdsPool(*dsp);
Panu Matilainen 93c12c
+    int rc = 0;
Panu Matilainen 93c12c
+
Panu Matilainen 93c12c
+    for (i = 0; i < sizeof(dirs) / sizeof(dirs[0]); i++) {
Panu Matilainen 93c12c
+	check = CheckLink(dirs[i], root);
Panu Matilainen 93c12c
+	if (check < 0) {
Panu Matilainen 93c12c
+	    rc = -1;
Panu Matilainen 93c12c
+	    goto exit;
Panu Matilainen 93c12c
+	}
Panu Matilainen 93c12c
+
Panu Matilainen 93c12c
+	if (check == 0)
Panu Matilainen 93c12c
+	    goto exit;
Panu Matilainen 93c12c
+    }
Panu Matilainen 93c12c
+    ds = rpmdsSinglePool(pool, RPMTAG_PROVIDENAME,
Panu Matilainen 93c12c
+			 "rpmlib(X-CheckUnifiedSystemdir)", "1",
Panu Matilainen 93c12c
+			 RPMSENSE_EQUAL);
Panu Matilainen 93c12c
+    rpmdsMerge(dsp, ds);
Panu Matilainen 93c12c
+    rpmdsFree(ds);
Panu Matilainen 93c12c
+
Panu Matilainen 93c12c
+    check = CheckLink("usr/lib64", root);
Panu Matilainen 93c12c
+    if (check < 0) {
Panu Matilainen 93c12c
+        rc = -1;
Panu Matilainen 93c12c
+        goto exit;
Panu Matilainen 93c12c
+    }
Panu Matilainen 93c12c
+    if (check > 0) {
Panu Matilainen 93c12c
+	ds = rpmdsSinglePool(pool, RPMTAG_PROVIDENAME,
Panu Matilainen 93c12c
+			     "rpmlib(X-CheckMultiArchLibdir)", "1",
Panu Matilainen 93c12c
+			     RPMSENSE_EQUAL);
Panu Matilainen 93c12c
+	rpmdsMerge(dsp, ds);
Panu Matilainen 93c12c
+	rpmdsFree(ds);
Panu Matilainen 93c12c
+    }
Panu Matilainen 93c12c
+
Panu Matilainen 93c12c
+    check = CheckLink("usr/sbin", root);
Panu Matilainen 93c12c
+    if (check < 0) {
Panu Matilainen 93c12c
+	rc = -1;
Panu Matilainen 93c12c
+	goto exit;
Panu Matilainen 93c12c
+    }
Panu Matilainen 93c12c
+    if (check > 0) {
Panu Matilainen 93c12c
+	ds = rpmdsSinglePool(pool, RPMTAG_PROVIDENAME,
Panu Matilainen 93c12c
+			     "rpmlib(X-CheckUnifiedBindir)", "1",
Panu Matilainen 93c12c
+			     RPMSENSE_EQUAL);
Panu Matilainen 93c12c
+	rpmdsMerge(dsp, ds);
Panu Matilainen 93c12c
+	rpmdsFree(ds);
Panu Matilainen 93c12c
+    }
Panu Matilainen 93c12c
+
Panu Matilainen 93c12c
+exit:
Panu Matilainen 93c12c
+    return rc;
Panu Matilainen 93c12c
+}
Panu Matilainen 93c12c
+
Panu Matilainen 93c12c
 /**
Panu Matilainen 93c12c
  * Check dep for an unsatisfied dependency.
Panu Matilainen 93c12c
  * @param ts		transaction set
Panu Matilainen 93c12c
@@ -560,8 +663,10 @@ retry:
Panu Matilainen 93c12c
      * Check those dependencies now.
Panu Matilainen 93c12c
      */
Panu Matilainen 93c12c
     if (dsflags & RPMSENSE_RPMLIB) {
Panu Matilainen 93c12c
-	if (tsmem->rpmlib == NULL)
Panu Matilainen 93c12c
+	if (tsmem->rpmlib == NULL) {
Panu Matilainen b1ec72
 	    rpmdsRpmlibPool(rpmtsPool(ts), &(tsmem->rpmlib), NULL);
Panu Matilainen 93c12c
+	    CheckFilesystemHierarchy(&(tsmem->rpmlib), rpmtsRootDir(ts));
Panu Matilainen 93c12c
+	}
Panu Matilainen 93c12c
 	
Panu Matilainen 93c12c
 	if (tsmem->rpmlib != NULL && rpmdsSearch(tsmem->rpmlib, dep) >= 0) {
Panu Matilainen 93c12c
 	    rpmdsNotify(dep, "(rpmlib provides)", rc);