From fa630a02d556c9f3f05c29ef3b7a4d82fce7601a Mon Sep 17 00:00:00 2001 From: ewt Date: Mon, 10 Jun 1996 17:42:57 +0000 Subject: [PATCH] fixed bugs, added dependency checks for removed packages CVS patchset: 635 CVS date: 1996/06/10 17:42:57 --- lib/depends.c | 202 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 158 insertions(+), 44 deletions(-) diff --git a/lib/depends.c b/lib/depends.c index bb331dcd8..6b0641ad3 100644 --- a/lib/depends.c +++ b/lib/depends.c @@ -2,6 +2,7 @@ #include #include +#include "rpmerr.h" #include "rpmlib.h" struct addedPackage { @@ -21,9 +22,27 @@ struct rpmDependencyCheck { int numProvides; }; +struct problemsSet { + struct rpmDependencyConflict * problems; + int num; + int alloced; +}; + static int intcmp(const void * a, const void *b); +static int stringcmp(void * a, void *b); static int badDependency(rpmDependencies rpmdep, char * reqName, char * reqVersion, int reqFlags); +static int checkDependentPackages(rpmDependencies rpmdep, + struct problemsSet * psp, char * requires); +static int checkPackage(rpmDependencies rpmdep, struct problemsSet * psp, + Header h, const char * requirement); + +int stringcmp(void * a, void *b) { + const char ** aptr = a; + const char ** bptr = b; + + return strcmp(*aptr, *bptr); +} int intcmp(const void * a, const void *b) { const int * aptr = a; @@ -74,7 +93,7 @@ void rpmdepAddPackage(rpmDependencies rpmdep, Header h) { getEntry(p->h, RPMTAG_RELEASE, &type, (void **) &p->release, &i); p->hasSerial = getEntry(h, RPMTAG_SERIAL, &type, (void **) &p->serial, &i); - if (!getEntry(h, RPMTAG_RELEASE, &type, (void **) &p->provides, + if (!getEntry(h, RPMTAG_PROVIDES, &type, (void **) &p->provides, &p->providesCount)) { p->providesCount = 0; p->provides = NULL; @@ -115,17 +134,19 @@ int rpmdepCheck(rpmDependencies rpmdep, struct rpmDependencyConflict ** conflicts, int * numConflicts) { struct addedPackage * p; int i, j, k; - struct rpmDependencyConflict * problems; - int numProblems = 0; - int allocedProblems = 5; - char ** requires; - int requiresCount; - int type, rc; + char ** provides; + int providesCount; + int type; + char * name; + Header h; + struct problemsSet ps; + + ps.alloced = 5; + ps.num = 0; + ps.problems = malloc(sizeof(struct rpmDependencyConflict) * ps.alloced); *conflicts = NULL; *numConflicts = 0; - problems = malloc(sizeof(struct rpmDependencyConflict) * - allocedProblems); qsort(rpmdep->removedPackages, rpmdep->numRemovedPackages, sizeof(int), intcmp); @@ -150,50 +171,51 @@ int rpmdepCheck(rpmDependencies rpmdep, } qsort(rpmdep->providesTable, rpmdep->numProvides, sizeof(char *), - (void *) strcmp); + (void *) stringcmp); /* look at all of the added packages and make sure their dependencies are satisfied */ p = rpmdep->addedPackages; for (i = 0; i < rpmdep->numAddedPackages; i++, p++) { - if (!getEntry(p->h, RPMTAG_REQUIRENAME, &type, (void **) &requires, - &requiresCount)) continue; - if (!requiresCount) continue; + if (checkPackage(rpmdep, &ps, p->h, NULL)) { + free(ps.problems); + return 1; + } + } - for (j = 0; j < requiresCount; j++) { - rc = badDependency(rpmdep, requires[j], "", 0); - if (rc == 1) { - message(MESS_DEBUG, "package %s require not satisfied: %s\n", - p->name, requires[j]); - - if (numProblems == allocedProblems) { - allocedProblems += 5; - problems = realloc(problems, sizeof(*problems) * - allocedProblems); - } - problems[numProblems].byName = p->name; - problems[numProblems].byVersion = p->version; - problems[numProblems].byRelease = p->release; - problems[numProblems].needsName = requires[j]; - problems[numProblems].needsVersion = NULL; - problems[numProblems].needsFlags = 0; - numProblems++; - } else if (rc) { - /* something went wrong! */ - free(requires); - free(problems); + /* now look at the removed packages and make sure they aren't critical */ + for (i = 0; i < rpmdep->numRemovedPackages; i++) { + h = rpmdbGetRecord(rpmdep->db, rpmdep->removedPackages[i]); + if (!h) { + error(RPMERR_DBCORRUPT, "cannot read header at %d for dependency " + "check", rpmdep->removedPackages[i]); + free(ps.problems); + return 1; + } + + getEntry(h, RPMTAG_NAME, &type, (void **) &name, &providesCount); + + if (checkDependentPackages(rpmdep, &ps, name)) { + free(ps.problems); + return 1; + } + + if (!getEntry(h, RPMTAG_PROVIDES, &type, (void **) &provides, + &providesCount)) continue; + + for (j = 0; j < providesCount; j++) { + if (checkDependentPackages(rpmdep, &ps, provides[j])) { + free(ps.problems); return 1; } } - - free(requires); } - if (!numProblems) - free(problems); + if (!ps.num) + free(ps.problems); else { - *conflicts = problems; - *numConflicts = numProblems; + *conflicts = ps.problems; + *numConflicts = ps.num; } return 0; @@ -208,15 +230,29 @@ static int badDependency(rpmDependencies rpmdep, char * reqName, message(MESS_DEBUG, "dependencies: looking for %s\n", reqName); - if (bsearch(reqName, rpmdep->providesTable, rpmdep->numProvides, - sizeof(char *), (void *) strcmp)) { + if (bsearch(&reqName, rpmdep->providesTable, rpmdep->numProvides, + sizeof(char *), (void *) stringcmp)) { /* this needs to check the reqFlags! ***/ return 0; } if (!rpmdbFindByProvides(rpmdep->db, reqName, &matches)) { for (i = 0; i < matches.count; i++) { - if (bsearch(&i, rpmdep->removedPackages, + if (bsearch(&matches.recs[i].recOffset, rpmdep->removedPackages, + rpmdep->numRemovedPackages, sizeof(int *), intcmp)) + continue; + + /* this needs to check the reqFlags ! ***/ + break; + } + + freeDBIndexRecord(matches); + if (i < matches.count) return 0; + } + + if (!rpmdbFindPackage(rpmdep->db, reqName, &matches)) { + for (i = 0; i < matches.count; i++) { + if (bsearch(&matches.recs[i].recOffset, rpmdep->removedPackages, rpmdep->numRemovedPackages, sizeof(int *), intcmp)) continue; @@ -230,3 +266,81 @@ static int badDependency(rpmDependencies rpmdep, char * reqName, return 1; } + +static int checkDependentPackages(rpmDependencies rpmdep, + struct problemsSet * psp, char * requires) { + dbIndexSet matches; + Header h; + int i; + + if (rpmdbFindByRequiredBy(rpmdep->db, requires, &matches)) { + return 0; + } + + for (i = 0; i < matches.count; i++) { + if (bsearch(&matches.recs[i].recOffset, rpmdep->removedPackages, + rpmdep->numRemovedPackages, sizeof(int *), intcmp)) + continue; + + h = rpmdbGetRecord(rpmdep->db, matches.recs[i].recOffset); + if (!h) { + error(RPMERR_DBCORRUPT, "cannot read header at %d for dependency " + "check", rpmdep->removedPackages[i]); + return 1; + } + + if (checkPackage(rpmdep, psp, h, requires)) + return 1; + } + + return 0; +} + +static int checkPackage(rpmDependencies rpmdep, struct problemsSet * psp, + Header h, const char * requirement) { + char ** requires; + char * name, * version, * release; + int requiresCount; + int type, count; + int i, rc; + + if (!getEntry(h, RPMTAG_REQUIRENAME, &type, (void **) &requires, + &requiresCount)) return 0; + if (!requiresCount) return 0; + + for (i = 0; i < requiresCount; i++) { + if (requirement && strcmp(requirement, requires[i])) continue; + + rc = badDependency(rpmdep, requires[i], "", 0); + if (rc == 1) { + getEntry(h, RPMTAG_NAME, &type, (void **) &name, &count); + getEntry(h, RPMTAG_VERSION, &type, (void **) &version, &count); + getEntry(h, RPMTAG_RELEASE, &type, (void **) &release, &count); + + message(MESS_DEBUG, "package %s require not satisfied: %s\n", + name, requires[i]); + + if (psp->num == psp->alloced) { + psp->alloced += 5; + psp->problems = realloc(psp->problems, sizeof(*psp->problems) * + psp->alloced); + } + psp->problems[psp->num].byName = name; + psp->problems[psp->num].byVersion = version; + psp->problems[psp->num].byRelease = release; + psp->problems[psp->num].needsName = requires[i]; + psp->problems[psp->num].needsVersion = NULL; + psp->problems[psp->num].needsFlags = 0; + psp->num++; + } else if (rc) { + /* something went wrong! */ + free(requires); + return 1; + } + } + + free(requires); + + return 0; +} +