diff --git a/CHANGES b/CHANGES index 92aadc426..9dd00bcfe 100644 --- a/CHANGES +++ b/CHANGES @@ -30,6 +30,7 @@ - fix: n>1 occurrences of %config(noreplace) should not FA_CREATE (#4355). - fix: use pgp5 rather than pgp-2.6.3 if both are in %_pgpbin (#4564). - match "de" when locale is specified as "de_DE.ISO-8859-1@Munich". + - add versions to obsoletes. 3.0.1 -> 3.0.2 - eliminate armv4 entries from rpmrc (Andrew E. Mileski). diff --git a/build/parseReqs.c b/build/parseReqs.c index deb8ba37a..0fc702224 100644 --- a/build/parseReqs.c +++ b/build/parseReqs.c @@ -137,7 +137,6 @@ int parseRCPOT(Spec spec, Package pkg, const char *field, int tag, int index) } switch(tag) { - case RPMTAG_OBSOLETES: case RPMTAG_BUILDPREREQ: case RPMTAG_PREREQ: rpmError(RPMERR_BADSPEC, diff --git a/build/reqprov.c b/build/reqprov.c index 1a79b5b98..00ce825a4 100644 --- a/build/reqprov.c +++ b/build/reqprov.c @@ -24,6 +24,8 @@ int addReqProv(Spec spec, Header h, flagtag = RPMTAG_PROVIDEFLAGS; } else if (flag & RPMSENSE_OBSOLETES) { nametag = RPMTAG_OBSOLETES; + versiontag = RPMTAG_OBSOLETEVERSION; + flagtag = RPMTAG_OBSOLETEFLAGS; } else if (flag & RPMSENSE_CONFLICTS) { nametag = RPMTAG_CONFLICTNAME; versiontag = RPMTAG_CONFLICTVERSION; diff --git a/lib/depends.c b/lib/depends.c index 54a9965e0..7047c09cd 100644 --- a/lib/depends.c +++ b/lib/depends.c @@ -194,180 +194,6 @@ static int intcmp(const void * a, const void *b) return 1; } -rpmTransactionSet rpmtransCreateSet(rpmdb db, const char * root) -{ - rpmTransactionSet rpmdep; - int rootLength; - - if (!root) root = ""; - - rpmdep = malloc(sizeof(*rpmdep)); - rpmdep->db = db; - rpmdep->scriptFd = NULL; - rpmdep->numRemovedPackages = 0; - rpmdep->allocedRemovedPackages = 5; - rpmdep->removedPackages = malloc(sizeof(int) * - rpmdep->allocedRemovedPackages); - - /* This canonicalizes the root */ - rootLength = strlen(root); - if (root && root[rootLength] == '/') { - char * newRootdir; - - newRootdir = alloca(rootLength + 2); - strcpy(newRootdir, root); - newRootdir[rootLength++] = '/'; - newRootdir[rootLength] = '\0'; - root = newRootdir; - } - - rpmdep->root = strdup(root); - - alCreate(&rpmdep->addedPackages); - alCreate(&rpmdep->availablePackages); - - rpmdep->orderAlloced = 5; - rpmdep->orderCount = 0; - rpmdep->order = malloc(sizeof(*rpmdep->order) * rpmdep->orderAlloced); - - return rpmdep; -} - -static void removePackage(rpmTransactionSet rpmdep, int dboffset, int depends) -{ - if (rpmdep->numRemovedPackages == rpmdep->allocedRemovedPackages) { - rpmdep->allocedRemovedPackages += 5; - rpmdep->removedPackages = realloc(rpmdep->removedPackages, - sizeof(int *) * rpmdep->allocedRemovedPackages); - } - - rpmdep->removedPackages[rpmdep->numRemovedPackages++] = dboffset; - - if (rpmdep->orderCount == rpmdep->orderAlloced) { - rpmdep->orderAlloced += 5; - rpmdep->order = realloc(rpmdep->order, - sizeof(*rpmdep->order) * rpmdep->orderAlloced); - } - - rpmdep->order[rpmdep->orderCount].type = TR_REMOVED; - rpmdep->order[rpmdep->orderCount].u.removed.dboffset = dboffset; - rpmdep->order[rpmdep->orderCount++].u.removed.dependsOnIndex = depends; -} - -int rpmtransAddPackage(rpmTransactionSet rpmdep, Header h, FD_t fd, - const void * key, int upgrade, rpmRelocation * relocs) -{ - /* this is an install followed by uninstalls */ - dbiIndexSet matches; - char * name; - int count, i, j; - char ** obsoletes; - int alNum; - int * caps; - - /* XXX binary rpms always have RPMTAG_SOURCERPM, source rpms do not */ - if (headerIsEntry(h, RPMTAG_SOURCEPACKAGE)) - return 1; - - /* Make sure we've implemented all of the capabilities we need */ - if (headerGetEntry(h, RPMTAG_CAPABILITY, NULL, (void **)&caps, &count)) { - if (count != 1 || *caps) { - return 2; - } - } - - /* FIXME: handling upgrades like this is *almost* okay. It doesn't - check to make sure we're upgrading to a newer version, and it - makes it difficult to generate a return code based on the number of - packages which failed. */ - - if (rpmdep->orderCount == rpmdep->orderAlloced) { - rpmdep->orderAlloced += 5; - rpmdep->order = realloc(rpmdep->order, - sizeof(*rpmdep->order) * rpmdep->orderAlloced); - } - rpmdep->order[rpmdep->orderCount].type = TR_ADDED; - alNum = alAddPackage(&rpmdep->addedPackages, h, key, fd, relocs) - - rpmdep->addedPackages.list; - rpmdep->order[rpmdep->orderCount++].u.addedIndex = alNum; - - if (!upgrade || rpmdep->db == NULL) return 0; - - headerGetEntry(h, RPMTAG_NAME, NULL, (void **) &name, &count); - - if (!rpmdbFindPackage(rpmdep->db, name, &matches)) { - Header h2; - - for (i = 0; i < dbiIndexSetCount(matches); i++) { - h2 = rpmdbGetRecord(rpmdep->db, dbiIndexRecordOffset(matches, i)); - if (h2) { - if (rpmVersionCompare(h, h2)) { - removePackage(rpmdep, dbiIndexRecordOffset(matches, i), - alNum); - } - headerFree(h2); - } - } - - dbiFreeIndexRecord(matches); - } - - if (headerGetEntry(h, RPMTAG_OBSOLETES, NULL, (void **) &obsoletes, - &count)) { - for (j = 0; j < count; j++) { - if (!rpmdbFindPackage(rpmdep->db, obsoletes[j], &matches)) { - for (i = 0; i < dbiIndexSetCount(matches); i++) { - removePackage(rpmdep, dbiIndexRecordOffset(matches, i), - alNum); - } - - dbiFreeIndexRecord(matches); - } - } - - free(obsoletes); - } - - return 0; -} - -void rpmtransAvailablePackage(rpmTransactionSet rpmdep, Header h, void * key) -{ - alAddPackage(&rpmdep->availablePackages, h, key, NULL, NULL); -} - -void rpmtransRemovePackage(rpmTransactionSet rpmdep, int dboffset) -{ - removePackage(rpmdep, dboffset, -1); -} - -void rpmtransFree(rpmTransactionSet rpmdep) -{ - alFree(&rpmdep->addedPackages); - alFree(&rpmdep->availablePackages); - free(rpmdep->removedPackages); - free(rpmdep->root); - - free(rpmdep); -} - -void rpmdepFreeConflicts(struct rpmDependencyConflict * conflicts, int - numConflicts) -{ - int i; - - for (i = 0; i < numConflicts; i++) { - headerFree(conflicts[i].byHeader); - free(conflicts[i].byName); - free(conflicts[i].byVersion); - free(conflicts[i].byRelease); - free(conflicts[i].needsName); - free(conflicts[i].needsVersion); - } - - free(conflicts); -} - static void parseEVR(char *evr, const char **ep, const char **vp, const char **rp) { const char *epoch = NULL; @@ -559,6 +385,194 @@ static inline int dbrecMatchesDepFlags(rpmTransactionSet rpmdep, int recOffset, return rc; } +rpmTransactionSet rpmtransCreateSet(rpmdb db, const char * root) +{ + rpmTransactionSet rpmdep; + int rootLength; + + if (!root) root = ""; + + rpmdep = malloc(sizeof(*rpmdep)); + rpmdep->db = db; + rpmdep->scriptFd = NULL; + rpmdep->numRemovedPackages = 0; + rpmdep->allocedRemovedPackages = 5; + rpmdep->removedPackages = malloc(sizeof(int) * + rpmdep->allocedRemovedPackages); + + /* This canonicalizes the root */ + rootLength = strlen(root); + if (root && root[rootLength] == '/') { + char * newRootdir; + + newRootdir = alloca(rootLength + 2); + strcpy(newRootdir, root); + newRootdir[rootLength++] = '/'; + newRootdir[rootLength] = '\0'; + root = newRootdir; + } + + rpmdep->root = strdup(root); + + alCreate(&rpmdep->addedPackages); + alCreate(&rpmdep->availablePackages); + + rpmdep->orderAlloced = 5; + rpmdep->orderCount = 0; + rpmdep->order = malloc(sizeof(*rpmdep->order) * rpmdep->orderAlloced); + + return rpmdep; +} + +static void removePackage(rpmTransactionSet rpmdep, int dboffset, int depends) +{ + if (rpmdep->numRemovedPackages == rpmdep->allocedRemovedPackages) { + rpmdep->allocedRemovedPackages += 5; + rpmdep->removedPackages = realloc(rpmdep->removedPackages, + sizeof(int *) * rpmdep->allocedRemovedPackages); + } + + rpmdep->removedPackages[rpmdep->numRemovedPackages++] = dboffset; + + if (rpmdep->orderCount == rpmdep->orderAlloced) { + rpmdep->orderAlloced += 5; + rpmdep->order = realloc(rpmdep->order, + sizeof(*rpmdep->order) * rpmdep->orderAlloced); + } + + rpmdep->order[rpmdep->orderCount].type = TR_REMOVED; + rpmdep->order[rpmdep->orderCount].u.removed.dboffset = dboffset; + rpmdep->order[rpmdep->orderCount++].u.removed.dependsOnIndex = depends; +} + +int rpmtransAddPackage(rpmTransactionSet rpmdep, Header h, FD_t fd, + const void * key, int upgrade, rpmRelocation * relocs) +{ + /* this is an install followed by uninstalls */ + dbiIndexSet matches; + char * name; + int count, i, j; + const char ** obsoletes; + int alNum; + int * caps; + + /* XXX binary rpms always have RPMTAG_SOURCERPM, source rpms do not */ + if (headerIsEntry(h, RPMTAG_SOURCEPACKAGE)) + return 1; + + /* Make sure we've implemented all of the capabilities we need */ + if (headerGetEntry(h, RPMTAG_CAPABILITY, NULL, (void **)&caps, &count)) { + if (count != 1 || *caps) { + return 2; + } + } + + /* FIXME: handling upgrades like this is *almost* okay. It doesn't + check to make sure we're upgrading to a newer version, and it + makes it difficult to generate a return code based on the number of + packages which failed. */ + + if (rpmdep->orderCount == rpmdep->orderAlloced) { + rpmdep->orderAlloced += 5; + rpmdep->order = realloc(rpmdep->order, + sizeof(*rpmdep->order) * rpmdep->orderAlloced); + } + rpmdep->order[rpmdep->orderCount].type = TR_ADDED; + alNum = alAddPackage(&rpmdep->addedPackages, h, key, fd, relocs) - + rpmdep->addedPackages.list; + rpmdep->order[rpmdep->orderCount++].u.addedIndex = alNum; + + if (!upgrade || rpmdep->db == NULL) return 0; + + headerGetEntry(h, RPMTAG_NAME, NULL, (void **) &name, &count); + + if (!rpmdbFindPackage(rpmdep->db, name, &matches)) { + Header h2; + + for (i = 0; i < dbiIndexSetCount(matches); i++) { + h2 = rpmdbGetRecord(rpmdep->db, dbiIndexRecordOffset(matches, i)); + if (h2 == NULL) + continue; + if (rpmVersionCompare(h, h2)) + removePackage(rpmdep, dbiIndexRecordOffset(matches, i), alNum); + headerFree(h2); + } + + dbiFreeIndexRecord(matches); + } + + if (headerGetEntry(h, RPMTAG_OBSOLETENAME, NULL, (void **) &obsoletes, &count)) { + const char **obsoletesVersion, *obsV; + int *obsoletesFlags, obsF; + + headerGetEntry(h, RPMTAG_OBSOLETEFLAGS, NULL, (void **) &obsoletesFlags, NULL); + headerGetEntry(h, RPMTAG_OBSOLETEVERSION, NULL, (void **) &obsoletesVersion, NULL); + + for (j = 0; j < count; j++) { + if (rpmdbFindPackage(rpmdep->db, obsoletes[j], &matches)) + continue; + for (i = 0; i < dbiIndexSetCount(matches); i++) { + unsigned int recOffset = dbiIndexRecordOffset(matches, i); + if (bsearch(&recOffset, + rpmdep->removedPackages, rpmdep->numRemovedPackages, + sizeof(int), intcmp)) + continue; + + obsV = obsoletesVersion ? obsoletesVersion[j] : ""; + obsF = obsoletesFlags ? obsoletesFlags[j] : 0; + if (dbrecMatchesDepFlags(rpmdep, recOffset, + obsoletes[j], obsV, obsF, headerMatchesDepFlags)) { + removePackage(rpmdep, recOffset, alNum); + } + } + + dbiFreeIndexRecord(matches); + } + + if (obsoletesVersion) free(obsoletesVersion); + free(obsoletes); + } + + return 0; +} + +void rpmtransAvailablePackage(rpmTransactionSet rpmdep, Header h, void * key) +{ + alAddPackage(&rpmdep->availablePackages, h, key, NULL, NULL); +} + +void rpmtransRemovePackage(rpmTransactionSet rpmdep, int dboffset) +{ + removePackage(rpmdep, dboffset, -1); +} + +void rpmtransFree(rpmTransactionSet rpmdep) +{ + alFree(&rpmdep->addedPackages); + alFree(&rpmdep->availablePackages); + free(rpmdep->removedPackages); + free(rpmdep->root); + + free(rpmdep); +} + +void rpmdepFreeConflicts(struct rpmDependencyConflict * conflicts, int + numConflicts) +{ + int i; + + for (i = 0; i < numConflicts; i++) { + headerFree(conflicts[i].byHeader); + free(conflicts[i].byName); + free(conflicts[i].byVersion); + free(conflicts[i].byRelease); + free(conflicts[i].needsName); + free(conflicts[i].needsVersion); + } + + free(conflicts); +} + static struct availablePackage * alSatisfiesDepend(struct availableList * al, const char * reqName, const char * reqVersion, int reqFlags) { diff --git a/po/rpm.pot b/po/rpm.pot index e6127c8af..12c29f564 100644 --- a/po/rpm.pot +++ b/po/rpm.pot @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 1999-08-20 13:48-0400\n" +"POT-Creation-Date: 1999-08-20 17:02-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1812,12 +1812,12 @@ msgstr "" msgid "line %d: Versioned file name not permitted: %s" msgstr "" -#: ../build/parseReqs.c:144 +#: ../build/parseReqs.c:143 #, c-format msgid "line %d: Version not permitted: %s" msgstr "" -#: ../build/parseReqs.c:164 +#: ../build/parseReqs.c:163 #, c-format msgid "line %d: Version required: %s" msgstr "" @@ -1976,31 +1976,31 @@ msgstr "" msgid "error removing record %s into %s" msgstr "" -#: ../lib/depends.c:551 +#: ../lib/depends.c:377 msgid "dbrecMatchesDepFlags() failed to read header" msgstr "" -#: ../lib/depends.c:593 +#: ../lib/depends.c:607 #, c-format msgid "dependencies: looking for %s\n" msgstr "" -#: ../lib/depends.c:718 +#: ../lib/depends.c:732 #, c-format msgid "package %s require not satisfied: %s\n" msgstr "" -#: ../lib/depends.c:757 +#: ../lib/depends.c:771 #, c-format msgid "package %s conflicts: %s\n" msgstr "" -#: ../lib/depends.c:810 ../lib/depends.c:1113 +#: ../lib/depends.c:824 ../lib/depends.c:1127 #, c-format msgid "cannot read header at %d for dependency check" msgstr "" -#: ../lib/depends.c:902 +#: ../lib/depends.c:916 #, c-format msgid "loop in prerequisite chain: %s" msgstr ""