diff options
Diffstat (limited to 'lib/depends.c')
-rw-r--r-- | lib/depends.c | 68 |
1 files changed, 65 insertions, 3 deletions
diff --git a/lib/depends.c b/lib/depends.c index ba9ab8ede..d0792842f 100644 --- a/lib/depends.c +++ b/lib/depends.c @@ -175,6 +175,9 @@ static /*@exposed@*/ struct availablePackage * alAddPackage(struct availableList int first, last, fileNum; int origNumDirs; int pkgNum; + uint_32 multiLibMask = 0; + uint_32 * fileFlags = NULL; + uint_32 * pp = NULL; if (al->size == al->alloced) { al->alloced += 5; @@ -184,9 +187,28 @@ static /*@exposed@*/ struct availablePackage * alAddPackage(struct availableList pkgNum = al->size++; p = al->list + pkgNum; p->h = headerLink(h); /* XXX reference held by transaction set */ + p->multiLib = 0; /* MULTILIB */ headerNVR(p->h, &p->name, &p->version, &p->release); + /* XXX This should be added always so that packages look alike. + * XXX However, there is logic in files.c/depends.c that checks for + * XXX existence (rather than value) that will need to change as well. + */ + if (headerGetEntry(p->h, RPMTAG_MULTILIBS, NULL, (void **) &pp, NULL)) + multiLibMask = *pp; + + if (multiLibMask) { + for (i = 0; i < pkgNum - 1; i++) { + if (!strcmp (p->name, al->list[i].name) + && headerGetEntry(al->list[i].h, RPMTAG_MULTILIBS, NULL, + (void **) &pp, NULL) + && !rpmVersionCompare(p->h, al->list[i].h) + && *pp && !(*pp & multiLibMask)) + p->multiLib = multiLibMask; + } + } + if (!headerGetEntry(h, RPMTAG_EPOCH, NULL, (void **) &p->epoch, NULL)) p->epoch = NULL; @@ -214,6 +236,7 @@ static /*@exposed@*/ struct availablePackage * alAddPackage(struct availableList &dirNames, &numDirs); headerGetEntryMinMemory(h, RPMTAG_DIRINDEXES, NULL, (void **) &dirIndexes, NULL); + headerGetEntry(h, RPMTAG_FILEFLAGS, NULL, (void **) &fileFlags, NULL); /* XXX FIXME: We ought to relocate the directory list here */ @@ -260,6 +283,8 @@ static /*@exposed@*/ struct availablePackage * alAddPackage(struct availableList dirMatch->files[dirMatch->numFiles].baseName = p->baseNames[fileNum]; dirMatch->files[dirMatch->numFiles].pkgNum = pkgNum; + dirMatch->files[dirMatch->numFiles].fileFlags = + fileFlags[fileNum]; dirMatch->numFiles++; } @@ -332,6 +357,14 @@ static void alMakeIndex(struct availableList * al) #endif for (j = 0; j < al->list[i].providesCount; j++) { + + /* If multilib install, skip non-multilib provides. */ + if (al->list[i].multiLib && + !isDependsMULTILIB(al->list[i].provideFlags[j])) { + ai->size--; + continue; + } + ai->index[k].package = al->list + i; ai->index[k].entry = al->list[i].provides[j]; ai->index[k].entryLen = strlen(al->list[i].provides[j]); @@ -656,6 +689,18 @@ int rpmtransAddPackage(rpmTransactionSet rpmdep, Header h, FD_t fd, while((h2 = rpmdbNextIterator(mi)) != NULL) { if (rpmVersionCompare(h, h2)) removePackage(rpmdep, rpmdbGetIteratorOffset(mi), alNum); + else { + uint_32 *p, multiLibMask = 0, oldmultiLibMask = 0; + + if (headerGetEntry(h2, RPMTAG_MULTILIBS, NULL, (void **) &p, NULL)) + oldmultiLibMask = *p; + if (headerGetEntry(h, RPMTAG_MULTILIBS, NULL, (void **) &p, NULL)) + multiLibMask = *p; + if (oldmultiLibMask && multiLibMask + && !(oldmultiLibMask & multiLibMask)) { + rpmdep->addedPackages.list[alNum].multiLib = multiLibMask; + } + } } rpmdbFreeIterator(mi); } @@ -782,6 +827,13 @@ alFileSatisfiesDepend(struct availableList * al, /* XXX FIXME: these file lists should be sorted and bsearched */ for (i = 0; i < dirMatch->numFiles; i++) { if (!strcmp(dirMatch->files[i].baseName, baseName)) { + + /* If a file dependency would be satisfied by a file + we are not going to install, skip it. */ + if (al->list[dirMatch->files[i].pkgNum].multiLib && + !isFileMULTILIB(dirMatch->files[i].fileFlags)) + continue; + if (keyType) rpmMessage(RPMMESS_DEBUG, _("%s: %-45s YES (added files)\n"), keyType, fileName); @@ -1024,7 +1076,7 @@ exit: } static int checkPackageDeps(rpmTransactionSet rpmdep, struct problemsSet * psp, - Header h, const char * keyName) + Header h, const char * keyName, uint_32 multiLib) { const char * name, * version, * release; const char ** requires, ** requiresEVR = NULL; @@ -1055,6 +1107,11 @@ static int checkPackageDeps(rpmTransactionSet rpmdep, struct problemsSet * psp, if (keyName && strcmp(keyName, requires[i])) continue; + /* If this requirement comes from the core package only, not libraries, + then if we're installing the libraries only, don't count it in. */ + if (multiLib && !isDependsMULTILIB(requireFlags[i])) + continue; + keyDepend = printDepend("R", requires[i], requiresEVR[i], requireFlags[i]); rc = unsatisfiedDepend(rpmdep, " Requires", keyDepend, @@ -1118,6 +1175,11 @@ static int checkPackageDeps(rpmTransactionSet rpmdep, struct problemsSet * psp, if (keyName && strcmp(keyName, conflicts[i])) continue; + /* If this requirement comes from the core package only, not libraries, + then if we're installing the libraries only, don't count it in. */ + if (multiLib && !isDependsMULTILIB(conflictFlags[i])) + continue; + keyDepend = printDepend("C", conflicts[i], conflictsEVR[i], conflictFlags[i]); rc = unsatisfiedDepend(rpmdep, "Conflicts", keyDepend, @@ -1175,7 +1237,7 @@ static int checkPackageSet(rpmTransactionSet rpmdep, struct problemsSet * psp, rpmdbPruneIterator(mi, rpmdep->removedPackages, rpmdep->numRemovedPackages, 1); while ((h = rpmdbNextIterator(mi)) != NULL) { - if (checkPackageDeps(rpmdep, psp, h, key)) { + if (checkPackageDeps(rpmdep, psp, h, key, 0)) { rc = 1; break; } @@ -1431,7 +1493,7 @@ int rpmdepCheck(rpmTransactionSet rpmdep, p = rpmdep->addedPackages.list; for (i = 0; i < rpmdep->addedPackages.size; i++, p++) { - if (checkPackageDeps(rpmdep, &ps, p->h, NULL)) + if (checkPackageDeps(rpmdep, &ps, p->h, NULL, p->multiLib)) goto exit; /* Adding: check name against conflicts matches. */ |