char ** provides;
char * name, * version, * release;
int serial, hasSerial, providesCount;
+ void * key;
} ;
struct availableIndexEntry {
static void alCreate(struct availableList * al);
static void alFreeIndex(struct availableList * al);
static void alFree(struct availableList * al);
-static void alAddPackage(struct availableList * al, Header h);
+static void alAddPackage(struct availableList * al, Header h, void * key);
static int intcmp(const void * a, const void *b);
static int indexcmp(const void * a, const void *b);
static int unsatisfiedDepend(rpmDependencies rpmdep, char * reqName,
- char * reqVersion, int reqFlags);
+ char * reqVersion, int reqFlags,
+ struct availablePackage ** suggestion);
static int checkDependentPackages(rpmDependencies rpmdep,
struct problemsSet * psp, char * requires);
static int checkPackageDeps(rpmDependencies rpmdep, struct problemsSet * psp,
static int dbrecMatchesDepFlags(rpmDependencies rpmdep, int recOffset,
char * reqVersion, int reqFlags);
static int headerMatchesDepFlags(Header h, char * reqVersion, int reqFlags);
-int alSatisfiesDepend(struct availableList * al, char * reqName,
- char * reqVersion, int reqFlags);
+struct availablePackage * alSatisfiesDepend(struct availableList * al,
+ char * reqName, char * reqVersion,
+ int reqFlags);
static void alCreate(struct availableList * al) {
al->list = malloc(sizeof(*al->list) * 5);
alFreeIndex(al);
}
-static void alAddPackage(struct availableList * al, Header h) {
+static void alAddPackage(struct availableList * al, Header h, void * key) {
struct availablePackage * p;
int i, type;
p->provides = NULL;
}
+ p->key = key;
+
alFreeIndex(al);
}
}
}
-int alSatisfiesDepend(struct availableList * al, char * reqName,
- char * reqVersion, int reqFlags) {
+struct availablePackage * alSatisfiesDepend(struct availableList * al,
+ char * reqName, char * reqVersion,
+ int reqFlags) {
struct availableIndexEntry needle, * match;
- if (!al->index.size) return 0;
+ if (!al->index.size) return NULL;
needle.entry = reqName;
match = bsearch(&needle, al->index.index, al->index.size,
sizeof(*al->index.index), (void *) indexcmp);
- if (!match) return 0;
- if (match->isProvides) return 1;
+ if (!match) return NULL;
+ if (match->isProvides) return match->package;
if (headerMatchesDepFlags(match->package->h, reqVersion, reqFlags))
- return 1;
+ return match->package;
- return 0;
+ return NULL;
}
int indexcmp(const void * a, const void *b) {
char * name;
int count, type, i;
- alAddPackage(&rpmdep->addedPackages, h);
+ alAddPackage(&rpmdep->addedPackages, h, NULL);
if (!rpmdep->db) return;
}
void rpmdepAddPackage(rpmDependencies rpmdep, Header h) {
- alAddPackage(&rpmdep->addedPackages, h);
+ alAddPackage(&rpmdep->addedPackages, h, NULL);
+}
+
+void rpmdepAvailablePackage(rpmDependencies rpmdep, Header h, void * key) {
+ alAddPackage(&rpmdep->availablePackages, h, key);
}
void rpmdepRemovePackage(rpmDependencies rpmdep, int dboffset) {
/* 2 == error */
/* 1 == dependency not satisfied */
static int unsatisfiedDepend(rpmDependencies rpmdep, char * reqName,
- char * reqVersion, int reqFlags) {
+ char * reqVersion, int reqFlags,
+ struct availablePackage ** suggestion) {
dbIndexSet matches;
int i;
message(MESS_DEBUG, "dependencies: looking for %s\n", reqName);
+ if (suggestion) *suggestion = NULL;
+
if (alSatisfiesDepend(&rpmdep->addedPackages, reqName, reqVersion,
reqFlags))
return 0;
- if (!rpmdep->db) return 1;
+ if (rpmdep->db) {
+ if (!reqFlags && !rpmdbFindByProvides(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;
+ break;
+ }
- if (!reqFlags && !rpmdbFindByProvides(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;
- break;
+ freeDBIndexRecord(matches);
+ if (i < matches.count) return 0;
}
- 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;
-
- if (dbrecMatchesDepFlags(rpmdep, matches.recs[i].recOffset,
- reqVersion, reqFlags)) {
- break;
+ 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;
+
+ if (dbrecMatchesDepFlags(rpmdep, matches.recs[i].recOffset,
+ reqVersion, reqFlags)) {
+ break;
+ }
}
- }
- freeDBIndexRecord(matches);
- if (i < matches.count) return 0;
+ freeDBIndexRecord(matches);
+ if (i < matches.count) return 0;
+ }
}
+ *suggestion = alSatisfiesDepend(&rpmdep->availablePackages, reqName,
+ reqVersion, reqFlags);
+
return 1;
}
int type, count;
int i, rc;
int * requireFlags;
+ struct availablePackage * suggestion;
if (!getEntry(h, RPMTAG_REQUIRENAME, &type, (void **) &requires,
&requiresCount)) return 0;
if (requirement && strcmp(requirement, requires[i])) continue;
rc = unsatisfiedDepend(rpmdep, requires[i], requiresVersion[i],
- requireFlags[i]);
+ requireFlags[i], &suggestion);
if (rc == 1) {
getEntry(h, RPMTAG_NAME, &type, (void **) &name, &count);
getEntry(h, RPMTAG_VERSION, &type, (void **) &version, &count);
psp->problems[psp->num].needsVersion = requiresVersion[i];
psp->problems[psp->num].needsFlags = requireFlags[i];
psp->problems[psp->num].sense = RPMDEP_SENSE_REQUIRES;
+ psp->problems[psp->num].suggestedPackage = suggestion->key;
psp->num++;
} else if (rc) {