Added install time prerequisite checking
authorewt <devnull@localhost>
Tue, 1 Jul 1997 16:24:08 +0000 (16:24 +0000)
committerewt <devnull@localhost>
Tue, 1 Jul 1997 16:24:08 +0000 (16:24 +0000)
CVS patchset: 1724
CVS date: 1997/07/01 16:24:08

CHANGES
install.c
install.h
lib/depends.c
lib/rpmlib.h
verify.c

diff --git a/CHANGES b/CHANGES
index f9f7f68..2afee5b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+2.4.2 -> 2.4.3:
+       - implemented install time prerequisites
+
 2.4.1 -> 2.4.2:
        - completely rewrote queryformat code
        - added fsnames, fssizes virtual query tags
index 77ed0f7..1266ef1 100644 (file)
--- a/install.c
+++ b/install.c
@@ -170,7 +170,8 @@ int doInstall(char * rootdir, char ** argv, char * location, int installFlags,
            packages[i] = alloca(strlen(*filename) + 30 + strlen(rootdir));
            sprintf(packages[i], "%s/var/tmp/rpm-ftp-%d-%d.tmp", rootdir, 
                    tmpnum++, (int) getpid());
-           rpmMessage(RPMMESS_DEBUG, "getting %s as %s\n", *filename, packages[i]);
+           rpmMessage(RPMMESS_DEBUG, 
+                       "getting %s as %s\n", *filename, packages[i]);
            fd = urlGetFile(*filename, packages[i]);
            if (fd < 0) {
                fprintf(stderr, 
@@ -198,8 +199,8 @@ int doInstall(char * rootdir, char ** argv, char * location, int installFlags,
            continue;
        }
 
-       rc = rpmReadPackageHeader(fd, &binaryHeaders[numBinaryPackages], &isSource,
-                          NULL, NULL);
+       rc = rpmReadPackageHeader(fd, &binaryHeaders[numBinaryPackages], 
+                                       &isSource, NULL, NULL);
 
        close(fd);
        
@@ -235,21 +236,21 @@ int doInstall(char * rootdir, char ** argv, char * location, int installFlags,
            exit(1);
        }
 
-       if (!(interfaceFlags & INSTALL_NODEPS)) {
-           rpmdep = rpmdepDependencies(db);
-           for (i = 0; i < numBinaryPackages; i++)
-               if (installFlags & RPMINSTALL_UPGRADE)
-                   rpmdepUpgradePackage(rpmdep, binaryHeaders[i]);
-               else
-                   rpmdepAddPackage(rpmdep, binaryHeaders[i]);
+       rpmdep = rpmdepDependencies(db);
+       for (i = 0; i < numBinaryPackages; i++)
+           if (installFlags & RPMINSTALL_UPGRADE)
+               rpmdepUpgradePackage(rpmdep, binaryHeaders[i],
+                                    packages[i]);
+           else
+               rpmdepAddPackage(rpmdep, binaryHeaders[i], 
+                                   packages[i]);
 
+       if (!(interfaceFlags & INSTALL_NODEPS)) {
            if (rpmdepCheck(rpmdep, &conflicts, &numConflicts)) {
                numFailed = numPackages;
                stopInstall = 1;
            }
 
-           rpmdepDone(rpmdep);
-
            if (!stopInstall && conflicts) {
                fprintf(stderr, _("failed dependencies:\n"));
                printDepProblems(stderr, conflicts, numConflicts);
@@ -258,6 +259,15 @@ int doInstall(char * rootdir, char ** argv, char * location, int installFlags,
                stopInstall = 1;
            }
        }
+
+       if (!(interfaceFlags & INSTALL_NOORDER)) {
+           if (rpmdepOrder(rpmdep, (void ***) &packages)) {
+               numFailed = numPackages;
+               stopInstall = 1;
+           }
+       }
+
+       rpmdepDone(rpmdep);
     }
     else
        db = NULL;
index effffbe..a845d91 100644 (file)
--- a/install.h
+++ b/install.h
@@ -6,6 +6,7 @@
 #define INSTALL_PERCENT         (1 << 0)
 #define INSTALL_HASH            (1 << 1)
 #define INSTALL_NODEPS          (1 << 2)
+#define INSTALL_NOORDER         (1 << 3)
 
 #define UNINSTALL_NODEPS        (1 << 0)
 #define UNINSTALL_ALLMATCHES    (1 << 1)
index 9e3f5a5..0cc3c4a 100644 (file)
@@ -23,6 +23,8 @@ struct availablePackage {
 
 enum indexEntryType { IET_NAME, IET_PROVIDES, IET_FILE };
 
+enum selectionStatus { UNSELECTED = 0, SELECTED, INPROCESS };
+
 struct availableIndexEntry {
     struct availablePackage * package;
     char * entry;
@@ -78,6 +80,11 @@ static int checkDependentConflicts(rpmDependencies rpmdep,
                            struct problemsSet * psp, char * package);
 static int checkPackageSet(rpmDependencies rpmdep, struct problemsSet * psp, 
                            char * package, dbiIndexSet * matches);
+static int addOrderedPack(rpmDependencies rpmdep, 
+                       struct availablePackage * package,
+                       void ** ordering, int * orderNumPtr, 
+                       enum selectionStatus * selected, 
+                       int satisfyDepends);
 
 static void alCreate(struct availableList * al) {
     al->list = malloc(sizeof(*al->list) * 5);
@@ -241,13 +248,13 @@ rpmDependencies rpmdepDependencies(rpmdb db) {
     return rpmdep;
 }
 
-void rpmdepUpgradePackage(rpmDependencies rpmdep, Header h) {
+void rpmdepUpgradePackage(rpmDependencies rpmdep, Header h, void * key) {
     /* this is an install followed by uninstalls */
     dbiIndexSet matches;
     char * name;
     int count, type, i;
 
-    alAddPackage(&rpmdep->addedPackages, h, NULL);
+    alAddPackage(&rpmdep->addedPackages, h, key);
 
     if (!rpmdep->db) return;
 
@@ -262,8 +269,8 @@ void rpmdepUpgradePackage(rpmDependencies rpmdep, Header h) {
     }
 }
 
-void rpmdepAddPackage(rpmDependencies rpmdep, Header h) {
-    alAddPackage(&rpmdep->addedPackages, h, NULL);
+void rpmdepAddPackage(rpmDependencies rpmdep, Header h, void * key) {
+    alAddPackage(&rpmdep->addedPackages, h, key);
 }
 
 void rpmdepAvailablePackage(rpmDependencies rpmdep, Header h, void * key) {
@@ -682,7 +689,7 @@ static int headerMatchesDepFlags(Header h, char * reqInfo, int reqFlags) {
 
     headerGetEntry(h, RPMTAG_NAME, &type, (void *) &name, &count);
 
-    if (!reqFlags) {
+    if (!(reqFlags & RPMSENSE_SENSEMASK)) {
        return 1;
     }
 
@@ -742,3 +749,77 @@ static int dbrecMatchesDepFlags(rpmDependencies rpmdep, int recOffset,
 
     return rc;
 }
+
+static int addOrderedPack(rpmDependencies rpmdep, 
+                       struct availablePackage * package,
+                       void ** ordering, int * orderNumPtr, 
+                       enum selectionStatus * selected, 
+                       int satisfyDepends) {
+    char ** requires, ** requiresVersion;
+    int_32 * requireFlags;
+    int requiresCount;
+    int packageNum = package - rpmdep->addedPackages.list;
+    int i;
+    struct availablePackage * match;
+
+    if (selected[packageNum] == INPROCESS) {
+       rpmError(RPMMESS_PREREQLOOP, "loop in prerequisite chain");
+       return 1;
+    }
+
+    selected[packageNum] = INPROCESS;
+
+    if (headerGetEntry(package->h, RPMTAG_REQUIRENAME, NULL, 
+                       (void **) &requires, &requiresCount)) {
+       headerGetEntry(package->h, RPMTAG_REQUIREFLAGS, NULL, 
+                       (void **) &requireFlags, NULL);
+       headerGetEntry(package->h, RPMTAG_REQUIREVERSION, NULL, 
+                       (void **) &requiresVersion, NULL);
+
+       for (i = 0; i < requiresCount; i++) {
+           if (satisfyDepends || (requireFlags[i] & RPMSENSE_PREREQ)) {
+               match = alSatisfiesDepend(&rpmdep->addedPackages,
+                                         requires[i], requiresVersion[i],
+                                         requireFlags[i]);
+               /* broken dependencies don't concern us */
+               if (!match) continue;
+               if (addOrderedPack(rpmdep, match, ordering, orderNumPtr,
+                                  selected, 1)) return 1;
+           }
+       }
+    }
+
+    /* whew -- add this package */
+    ordering[(*orderNumPtr)++] = package->key;
+    selected[packageNum] = SELECTED;
+
+    return 0;
+}
+
+int rpmdepOrder(rpmDependencies rpmdep, void *** keysListPtr) {
+    int i;
+    enum selectionStatus * selected;
+    void ** order;
+    int orderNum;
+
+    selected = alloca(sizeof(*selected) * rpmdep->addedPackages.size);
+    memset(selected, 0, sizeof(*selected) * rpmdep->addedPackages.size);
+
+    order = malloc(sizeof(*order) * (rpmdep->addedPackages.size + 1));
+    orderNum = 0;
+
+    for (i = 0; i < rpmdep->addedPackages.size; i++) {
+       if (selected[i] == UNSELECTED) {
+           if (addOrderedPack(rpmdep, rpmdep->addedPackages.list + i,
+                              order, &orderNum, selected, 0)) {
+               free(order);
+               return 1;
+           }
+       }
+    }
+
+    order[orderNum] = NULL;
+    *keysListPtr = order;
+
+    return 0;
+}
index a6ca8c6..6468b77 100644 (file)
@@ -268,12 +268,19 @@ struct rpmDependencyConflict {
 } ;
 
 rpmDependencies rpmdepDependencies(rpmdb db);         /* db may be NULL */
-void rpmdepAddPackage(rpmDependencies rpmdep, Header h);
+void rpmdepAddPackage(rpmDependencies rpmdep, Header h, void * key);
 void rpmdepAvailablePackage(rpmDependencies rpmdep, Header h, void * key);
-void rpmdepUpgradePackage(rpmDependencies rpmdep, Header h);
+void rpmdepUpgradePackage(rpmDependencies rpmdep, Header h, void * key);
 void rpmdepRemovePackage(rpmDependencies rpmdep, int dboffset);
+
+/* this checks for dependency satisfaction, but *not* ordering */
 int rpmdepCheck(rpmDependencies rpmdep, 
                struct rpmDependencyConflict ** conflicts, int * numConflicts);
+/* Orders items, returns error on circle, finals keys[] is NULL. No dependency
+   check is done, use rpmdepCheck() for that. If dependencies are not 
+   satisfied a "best-try" ordering is returned. */
+int rpmdepOrder(rpmDependencies order, void *** keysListPtr);
+
 void rpmdepDone(rpmDependencies rpmdep);
 void rpmdepFreeConflicts(struct rpmDependencyConflict * conflicts, int
                         numConflicts);
@@ -377,6 +384,7 @@ rpmErrorCallBackType rpmErrorSetCallback(rpmErrorCallBackType);
 #define RPMERR_STAT            -36     /* failed to stat something */
 #define RPMERR_BADDEV          -37     /* file on device not listed in mtab */
 #define RPMMESS_ALTNAME         -38     /* file written as .rpmnew */
+#define RPMMESS_PREREQLOOP      -39     /* loop in prerequisites */
 
 /* spec.c build.c pack.c */
 #define RPMERR_UNMATCHEDIF      -107    /* unclosed %ifarch or %ifos */
index b47a0fb..2c562cd 100644 (file)
--- a/verify.c
+++ b/verify.c
@@ -78,7 +78,7 @@ static void verifyDependencies(rpmdb db, Header h) {
     int type, count, i;
 
     rpmdep = rpmdepDependencies(db);
-    rpmdepAddPackage(rpmdep, h);
+    rpmdepAddPackage(rpmdep, h, NULL);
 
     rpmdepCheck(rpmdep, &conflicts, &numConflicts);
     rpmdepDone(rpmdep);