fixed bugs, added dependency checks for removed packages

CVS patchset: 635
CVS date: 1996/06/10 17:42:57
This commit is contained in:
ewt 1996-06-10 17:42:57 +00:00
parent 20c3b8d652
commit fa630a02d5
1 changed files with 158 additions and 44 deletions

View File

@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
#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;
}