fixed bugs, added dependency checks for removed packages
CVS patchset: 635 CVS date: 1996/06/10 17:42:57
This commit is contained in:
parent
20c3b8d652
commit
fa630a02d5
202
lib/depends.c
202
lib/depends.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue