--- rpm/./lib/rpmlib.h 2004-06-14 00:39:06.000000000 +0000 +++ rpm.new/./lib/rpmlib.h 2004-08-12 18:15:12.000000000 +0000 @@ -429,6 +429,7 @@ RPMTAG_POSTTRANS = 1152, RPMTAG_PRETRANSPROG = 1153, RPMTAG_POSTTRANSPROG = 1154, + RPMTAG_DISTVERSION = 1155, /*@-enummemuse@*/ RPMTAG_FIRSTFREE_TAG /*!< internal */ /*@=enummemuse@*/ --- rpm/./lib/rpmps.h 2003-12-30 13:14:50.000000000 +0000 +++ rpm.new/./lib/rpmps.h 2004-08-25 19:57:22.000000000 +0000 @@ -36,7 +36,8 @@ RPMPROB_OLDPACKAGE, /*!< package ... (which is newer than ...) is already installed */ RPMPROB_DISKSPACE, /*!< installing package ... needs ... on the ... filesystem */ RPMPROB_DISKNODES, /*!< installing package ... needs ... on the ... filesystem */ - RPMPROB_BADPRETRANS /*!< (unimplemented) */ + RPMPROB_BADPRETRANS, /*!< (unimplemented) */ + RPMPROB_OLDDISTRO /*!< */ } rpmProblemType; /** --- rpm/./lib/rpmte.h 2004-04-03 12:30:57.000000000 +0000 +++ rpm.new/./lib/rpmte.h 2004-08-25 19:49:25.000000000 +0000 @@ -77,6 +77,8 @@ const char * arch; /*!< Architecture hint. */ /*@only@*/ /*@null@*/ const char * os; /*!< Operating system hint. */ + const char * dist; /*!< Distribution. */ + const char * distversion; /*!< Distribution version. */ int archScore; /*!< (TR_ADDED) Arch score. */ int osScore; /*!< (TR_ADDED) Os score. */ @@ -238,6 +240,24 @@ /*@*/; /** + * Retrieve distribution string of transaction element. + * @param te transaction element + * @return distribution string + */ +/*@observer@*/ /*@null@*/ +extern const char * rpmteDist(rpmte te) + /*@*/; + +/** + * Retrieve distribution version string of transaction element. + * @param te transaction element + * @return distribuion version string + */ +/*@observer@*/ /*@null@*/ +extern const char * rpmteDistVersion(rpmte te) + /*@*/; + +/** * Retrieve color bits of transaction element. * @param te transaction element * @return color bits --- rpm/./build/parsePreamble.c 2004-08-26 18:31:19.000000000 +0000 +++ rpm.new/./build/parsePreamble.c 2004-08-12 18:16:58.000000000 +0000 @@ -21,6 +21,7 @@ RPMTAG_LICENSE, RPMTAG_PACKAGER, RPMTAG_DISTRIBUTION, + RPMTAG_DISTVERSION, RPMTAG_DISTURL, RPMTAG_VENDOR, RPMTAG_ICON, @@ -328,6 +329,7 @@ { RPMTAG_PACKAGER, "%{packager}" }, { RPMTAG_DISTRIBUTION, "%{distribution}" }, { RPMTAG_DISTURL, "%{disturl}" }, + { RPMTAG_DISTVERSION, "%{distversion}" }, { -1, NULL } }; @@ -537,6 +539,7 @@ (void) stashSt(spec, pkg->header, tag, lang); /*@fallthrough@*/ case RPMTAG_DISTRIBUTION: + case RPMTAG_DISTVERSION: case RPMTAG_VENDOR: case RPMTAG_LICENSE: case RPMTAG_PACKAGER: @@ -743,6 +746,7 @@ {RPMTAG_LICENSE, 0, 0, "copyright"}, {RPMTAG_LICENSE, 0, 0, "license"}, {RPMTAG_DISTRIBUTION, 0, 0, "distribution"}, + {RPMTAG_DISTVERSION, 0, 0, "distversion"}, {RPMTAG_DISTURL, 0, 0, "disturl"}, {RPMTAG_VENDOR, 0, 0, "vendor"}, {RPMTAG_GROUP, 0, 1, "group"}, --- rpm/./build/files.c 2004-08-26 18:31:19.000000000 +0000 +++ rpm.new/./build/files.c 2004-08-12 18:17:23.000000000 +0000 @@ -2217,6 +2217,7 @@ case RPMTAG_DESCRIPTION: case RPMTAG_PACKAGER: case RPMTAG_DISTRIBUTION: + case RPMTAG_DISTVERSION: case RPMTAG_DISTURL: case RPMTAG_VENDOR: case RPMTAG_LICENSE: --- rpm/./lib/rpmps.c 2003-12-30 13:14:50.000000000 +0000 +++ rpm.new/./lib/rpmps.c 2004-08-25 20:20:19.000000000 +0000 @@ -268,6 +268,11 @@ altNEVR+2, (prob->ulong1 ? "" : _("(installed) ")), pkgNEVR); break; + case RPMPROB_OLDDISTRO: + rc = snprintf(buf, nb, + _("package %s is for older distribution than already installed %s"), + pkgNEVR, altNEVR); + break; default: rc = snprintf(buf, nb, _("unknown error %d encountered while manipulating package %s"), --- rpm/./lib/transaction.c 2004-05-20 21:23:01.000000000 +0000 +++ rpm.new/./lib/transaction.c 2004-08-26 17:58:46.000000000 +0000 @@ -650,6 +650,52 @@ } /** + * Check if current package is from a newer distribution than installed one. + * @param p current transaction element + * @param h installed header + * @return 1: current is newer than installed + * 0: dist comparison doesn't apply for any reason + * -1: current is older than installed + */ +static int compareDistVersion(const rpmte p, const Header h) +{ + const char * dist, *distversion; + const char * idist, *idistversion; /* installed package */ + int rc; + + rc = rpmExpandNumeric("%{?_dont_compare_distversion}"); + if (rc == 1) + return 0; + + if (!headerGetEntry(h, RPMTAG_DISTRIBUTION, NULL, (void **) &idist, NULL)) + return 0; + if (!(dist = rpmteDist(p))) + return 0; + + if (strcmp(dist, idist) != 0) + return 0; + + rc = rpmExpandNumeric("%{?_distversion_also_for_other_distros}"); + if (rc == 0) { + char * cdist; /* the distro we're running on */ + cdist = rpmExpand("%{?distribution}", NULL); + if (cdist == NULL || *cdist == '\0' || (strcmp(dist, cdist) != 0)) + return 0; + } + + if (!headerGetEntry(h, RPMTAG_DISTVERSION, NULL, + (void **) &idistversion, NULL)) + return 0; + + if (!(distversion = rpmteDistVersion(p))) + return 0; + + rc = rpmvercmp(distversion, idistversion); + + return rc; +} + +/** * Ensure that current package is newer than installed package. * @param ts transaction set * @param p current transaction element @@ -670,6 +716,23 @@ if (p == NULL || h == NULL) return 1; + rc = compareDistVersion(p, h); + if (rc == 1) + return 1; + else if (rc == -1) + { + rpmps ps = rpmtsProblems(ts); + const char * altNEVR = hGetNEVR(h, NULL); + rpmpsAppend(ps, RPMPROB_OLDDISTRO, + rpmteNEVR(p), rpmteKey(p), + NULL, NULL, + altNEVR, + 0); + altNEVR = _free(altNEVR); + ps = rpmpsFree(ps); + return 0; + } + /*@-boundswrite@*/ nb = strlen(rpmteNEVR(p)) + (rpmteE(p) != NULL ? strlen(rpmteE(p)) : 0) + 1; t = alloca(nb); @@ -695,9 +758,9 @@ 0); altNEVR = _free(altNEVR); ps = rpmpsFree(ps); - rc = 1; - } else rc = 0; + } else + rc = 1; return rc; } @@ -1521,12 +1584,15 @@ rpmteO(p)); } - while (rpmdbNextIterator(mi) != NULL) { - rpmpsAppend(ps, RPMPROB_PKG_INSTALLED, - rpmteNEVR(p), rpmteKey(p), - NULL, NULL, - NULL, 0); - /*@innerbreak@*/ break; + Header h; + while ((h = rpmdbNextIterator(mi)) != NULL) { + if(compareDistVersion(p, h) == 0) { + rpmpsAppend(ps, RPMPROB_PKG_INSTALLED, + rpmteNEVR(p), rpmteKey(p), + NULL, NULL, + NULL, 0); + /*@innerbreak@*/ break; + } } mi = rpmdbFreeIterator(mi); } --- rpm/./lib/rpmte.c 2004-04-03 12:30:57.000000000 +0000 +++ rpm.new/./lib/rpmte.c 2004-08-25 20:17:05.000000000 +0000 @@ -93,7 +93,7 @@ HGE_t hge = (HGE_t)headerGetEntryMinMemory; rpmte savep; int_32 * ep; - const char * arch, * os; + const char * arch, * os, * dist, * distversion; char * t; size_t nb; int xx; @@ -110,6 +110,20 @@ */ p->db_instance = 0; + dist = NULL; + xx = hge(h, RPMTAG_DISTRIBUTION, NULL, (void **)&dist, NULL); + if (dist != NULL) + p->dist = xstrdup(dist); + else + p->dist = NULL; + + distversion = NULL; + xx = hge(h, RPMTAG_DISTVERSION, NULL, (void **)&distversion, NULL); + if (distversion != NULL) + p->distversion = xstrdup(distversion); + else + p->distversion = NULL; + arch = NULL; xx = hge(h, RPMTAG_ARCH, NULL, (void **)&arch, NULL); if (arch != NULL) { @@ -279,6 +293,16 @@ return (te != NULL ? te->os : NULL); } +const char * rpmteDist(rpmte te) +{ + return (te != NULL ? te->dist : NULL); +} + +const char * rpmteDistVersion(rpmte te) +{ + return (te != NULL ? te->distversion : NULL); +} + uint_32 rpmteColor(rpmte te) { return (te != NULL ? te->color : 0);