+++ /dev/null
---- ./lib/package.c 2006-07-26 14:45:41.000000000 +0200
-+++ rpm-4.4.9/lib/package.c 2008-10-26 17:56:29.000000000 +0200
-@@ -10,6 +10,7 @@
- #include <rpmlib.h>
-
- #include "rpmts.h"
-+#include "rpmevr.h"
-
- #include "misc.h" /* XXX stripTrailingChar() */
- #include "rpmlead.h"
-@@ -94,6 +95,148 @@
- */
- #define hdrchkRange(_dl, _off) ((_off) < 0 || (_off) > (_dl))
-
-+/*@-boundsread@*/
-+static int dncmp(const void * a, const void * b)
-+ /*@*/
-+{
-+ const char *const * first = a;
-+ const char *const * second = b;
-+ return strcmp(*first, *second);
-+}
-+/*@=boundsread@*/
-+
-+/*@-bounds@*/
-+/**
-+ * Convert absolute path tag to (dirname,basename,dirindex) tags.
-+ * @param h header
-+ */
-+static void compressFilelist(Header h)
-+ /*@modifies h @*/
-+{
-+ HGE_t hge = (HGE_t)headerGetEntryMinMemory;
-+ HAE_t hae = (HAE_t)headerAddEntry;
-+ HRE_t hre = (HRE_t)headerRemoveEntry;
-+ HFD_t hfd = headerFreeData;
-+ char ** fileNames;
-+ const char ** dirNames;
-+ const char ** baseNames;
-+ int_32 * dirIndexes;
-+ rpmTagType fnt;
-+ int count;
-+ int i, xx;
-+ int dirIndex = -1;
-+
-+ /*
-+ * This assumes the file list is already sorted, and begins with a
-+ * single '/'. That assumption isn't critical, but it makes things go
-+ * a bit faster.
-+ */
-+
-+ if (headerIsEntry(h, RPMTAG_DIRNAMES)) {
-+ xx = hre(h, RPMTAG_OLDFILENAMES);
-+ return; /* Already converted. */
-+ }
-+
-+ if (!hge(h, RPMTAG_OLDFILENAMES, &fnt, (void **) &fileNames, &count))
-+ return; /* no file list */
-+ if (fileNames == NULL || count <= 0)
-+ return;
-+
-+ dirNames = alloca(sizeof(*dirNames) * count); /* worst case */
-+ baseNames = alloca(sizeof(*dirNames) * count);
-+ dirIndexes = alloca(sizeof(*dirIndexes) * count);
-+
-+ if (fileNames[0][0] != '/') {
-+ /* HACK. Source RPM, so just do things differently */
-+ dirIndex = 0;
-+ dirNames[dirIndex] = "";
-+ for (i = 0; i < count; i++) {
-+ dirIndexes[i] = dirIndex;
-+ baseNames[i] = fileNames[i];
-+ }
-+ goto exit;
-+ }
-+
-+ /*@-branchstate@*/
-+ for (i = 0; i < count; i++) {
-+ const char ** needle;
-+ char savechar;
-+ char * baseName;
-+ int len;
-+
-+ if (fileNames[i] == NULL) /* XXX can't happen */
-+ continue;
-+ baseName = strrchr(fileNames[i], '/') + 1;
-+ len = baseName - fileNames[i];
-+ needle = dirNames;
-+ savechar = *baseName;
-+ *baseName = '\0';
-+/*@-compdef@*/
-+ if (dirIndex < 0 ||
-+ (needle = bsearch(&fileNames[i], dirNames, dirIndex + 1, sizeof(dirNames[0]), dncmp)) == NULL) {
-+ char *s = alloca(len + 1);
-+ memcpy(s, fileNames[i], len + 1);
-+ s[len] = '\0';
-+ dirIndexes[i] = ++dirIndex;
-+ dirNames[dirIndex] = s;
-+ } else
-+ dirIndexes[i] = needle - dirNames;
-+/*@=compdef@*/
-+
-+ *baseName = savechar;
-+ baseNames[i] = baseName;
-+ }
-+ /*@=branchstate@*/
-+
-+exit:
-+ if (count > 0) {
-+ xx = hae(h, RPMTAG_DIRINDEXES, RPM_INT32_TYPE, dirIndexes, count);
-+ xx = hae(h, RPMTAG_BASENAMES, RPM_STRING_ARRAY_TYPE,
-+ baseNames, count);
-+ xx = hae(h, RPMTAG_DIRNAMES, RPM_STRING_ARRAY_TYPE,
-+ dirNames, dirIndex + 1);
-+ }
-+
-+ fileNames = hfd(fileNames, fnt);
-+
-+ xx = hre(h, RPMTAG_OLDFILENAMES);
-+}
-+/*@=bounds@*/
-+
-+/* rpm v3 compatibility */
-+static void rpm3to4(Header h) {
-+ char * rpmversion;
-+ int_32 rpmversion_type;
-+
-+ (void) headerGetEntry(h, RPMTAG_RPMVERSION, NULL, (void **) &rpmversion, &rpmversion_type);
-+
-+ if ((!rpmversion) || rpmversion[0] < '4') {
-+ int *epoch;
-+ const char * name, *version, *release;
-+ const char *pEVR;
-+ char *p;
-+ int_32 pFlags = RPMSENSE_EQUAL;
-+
-+ if (headerNVR(h, &name, &version, &release) == 0) {
-+ pEVR = p = alloca(21 + strlen(version) + 1 + strlen(release) + 1);
-+ *p = '\0';
-+ if (headerGetEntry(h, RPMTAG_EPOCH, NULL, (void **) &epoch, NULL)) {
-+ sprintf(p, "%d:", *epoch);
-+ while (*p != '\0')
-+ p++;
-+ }
-+ (void) stpcpy( stpcpy( stpcpy(p, version) , "-") , release);
-+
-+ headerAddOrAppendEntry(h, RPMTAG_PROVIDENAME, RPM_STRING_ARRAY_TYPE, &name, 1);
-+ headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE, &pFlags, 1);
-+ headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION, RPM_STRING_ARRAY_TYPE, &pEVR, 1);
-+ }
-+ compressFilelist(h);
-+ }
-+ headerFreeTag(h, (void *) rpmversion, rpmversion_type);
-+ return;
-+}
-+
- void headerMergeLegacySigs(Header h, const Header sigh)
- {
- HFD_t hfd = (HFD_t) headerFreeData;
-@@ -1062,6 +1205,8 @@
- /* Append (and remap) signature tags to the metadata. */
- headerMergeLegacySigs(h, sigh);
-
-+ rpm3to4(h);
-+
- /* Bump reference count for return. */
- /*@-boundswrite@*/
- *hdrp = headerLink(h);