rpm/rpm-5.4.7-rpmv3-support.patch

371 lines
8.8 KiB
Diff
Raw Normal View History

2012-08-01 14:59:23 +04:00
--- rpm-5.4.7/rpmdb/package.c.rpmv3~ 2012-04-12 13:08:29.214493302 +0200
+++ rpm-5.4.7/rpmdb/package.c 2012-04-12 16:33:05.021039135 +0200
@@ -19,6 +19,8 @@
#include "rpmts.h"
+#define _RPMEVR_INTERNAL
+#include <rpmevr.h>
#include "debug.h"
#define alloca_strdup(_s) strcpy(alloca(strlen(_s)+1), (_s))
@@ -79,6 +81,349 @@ static int pgpStashKeyid(pgpDig dig)
}
#endif
+/*@-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 @*/
+{
+ HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
+
+ char ** fileNames;
+ const char ** dirNames;
+ const char ** baseNames;
+ int32_t * 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)) {
+ he->tag = RPMTAG_OLDFILENAMES;
+ headerDel(h, he, 0);
+ return; /* Already converted. */
+ }
+
+ he->tag = RPMTAG_OLDFILENAMES;
+ if (!headerGet(h, he, 0))
+ return;
+
+ fileNames = he->p.ptr;
+ if (he->c <= 0)
+ return;
+ count = he->c;
+
+ 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) {
+
+ he->tag = RPMTAG_DIRINDEXES;
+ if (headerGet(h, he, 0))
+ dirIndexes = he->p.ptr;
+ he->tag = RPMTAG_BASENAMES;
+ if (headerGet(h, he, 0))
+ baseNames = he->p.ptr;
+ he->tag = RPMTAG_DIRNAMES;
+ if (headerGet(h, he, 0))
+ dirNames = he->p.ptr;
+
+ he->tag = RPMTAG_DIRINDEXES;
+ he->t = RPM_UINT32_TYPE;
+ he->p.ptr = dirIndexes;
+ he->c = count;
+ headerPut(h, he, 0);
+
+ he->tag = RPMTAG_BASENAMES;
+ he->t = RPM_STRING_ARRAY_TYPE;
+ he->p.ptr = baseNames;
+ he->c = count;
+ headerPut(h, he, 0);
+
+ he->tag = RPMTAG_DIRNAMES;
+ he->t = RPM_STRING_ARRAY_TYPE;
+ he->p.ptr = dirNames;
+ he->c = dirIndex +1;
+ headerPut(h,he,0);
+ }
+
+ fileNames = _free(fileNames);
+
+ he->tag = RPMTAG_OLDFILENAMES;
+ headerDel(h, he, 0);
+
+}
+/*@=bounds@*/
+
+/* copied verbatim from build/pack.c */
+static void providePackageNVR(Header h)
+{
+ HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
+ const char *N, *V, *R;
+#ifdef RPM_VENDOR_MANDRIVA
+ const char *D;
+ int gotD;
+#endif
+ rpmuint32_t E;
+ int gotE;
+ const char *pEVR;
+ char *p;
+ rpmuint32_t pFlags = RPMSENSE_EQUAL;
+ const char ** provides = NULL;
+ const char ** providesEVR = NULL;
+ rpmuint32_t * provideFlags = NULL;
+ int providesCount;
+ int bingo = 1;
+ size_t nb;
+ int xx;
+ int i;
+
+ /* Generate provides for this package N-V-R. */
+ xx = headerNEVRA(h, &N, NULL, &V, &R, NULL);
+ if (!(N && V && R))
+ return;
+
+ nb = 21 + strlen(V) + 1 + strlen(R) + 1;
+#ifdef RPM_VENDOR_MANDRIVA
+ he->tag = RPMTAG_DISTEPOCH;
+ gotD = headerGet(h, he, 0);
+ D = (he->p.str ? he->p.str : NULL);
+ nb += (gotD ? strlen(D) + 1 : 0);
+#endif
+ pEVR = p = alloca(nb);
+ *p = '\0';
+ he->tag = RPMTAG_EPOCH;
+ gotE = headerGet(h, he, 0);
+ E = (he->p.ui32p ? he->p.ui32p[0] : 0);
+ he->p.ptr = _free(he->p.ptr);
+ if (gotE) {
+ sprintf(p, "%d:", E);
+ p += strlen(p);
+ }
+ p = stpcpy( stpcpy( stpcpy(p, V) , "-") , R);
+#ifdef RPM_VENDOR_MANDRIVA
+ if (gotD) {
+ p = stpcpy( stpcpy( p, ":"), D);
+ D = _free(D);
+ //(void) rpmlibNeedsFeature(h, "DistEpoch", "5.4.7-1");
+ }
+#endif
+ V = _free(V);
+ R = _free(R);
+
+ /*
+ * Rpm prior to 3.0.3 does not have versioned provides.
+ * If no provides at all are available, we can just add.
+ */
+ he->tag = RPMTAG_PROVIDENAME;
+/*@-nullstate@*/
+ xx = headerGet(h, he, 0);
+/*@=nullstate@*/
+ provides = he->p.argv;
+ providesCount = he->c;
+ if (!xx)
+ goto exit;
+
+ /*
+ * Otherwise, fill in entries on legacy packages.
+ */
+ he->tag = RPMTAG_PROVIDEVERSION;
+/*@-nullstate@*/
+ xx = headerGet(h, he, 0);
+/*@=nullstate@*/
+ providesEVR = he->p.argv;
+ if (!xx) {
+ for (i = 0; i < providesCount; i++) {
+ /*@observer@*/
+ static const char * vdummy = "";
+ static rpmsenseFlags fdummy = RPMSENSE_ANY;
+
+ he->tag = RPMTAG_PROVIDEVERSION;
+ he->t = RPM_STRING_ARRAY_TYPE;
+ he->p.argv = &vdummy;
+ he->c = 1;
+ he->append = 1;
+/*@-nullstate@*/
+ xx = headerPut(h, he, 0);
+/*@=nullstate@*/
+ he->append = 0;
+
+ he->tag = RPMTAG_PROVIDEFLAGS;
+ he->t = RPM_UINT32_TYPE;
+ he->p.ui32p = (void *) &fdummy;
+ he->c = 1;
+ he->append = 1;
+/*@-nullstate@*/
+ xx = headerPut(h, he, 0);
+/*@=nullstate@*/
+ he->append = 0;
+ }
+ goto exit;
+ }
+
+ he->tag = RPMTAG_PROVIDEFLAGS;
+/*@-nullstate@*/
+ xx = headerGet(h, he, 0);
+/*@=nullstate@*/
+ provideFlags = he->p.ui32p;
+
+ /*@-nullderef@*/ /* LCL: providesEVR is not NULL */
+ if (provides && providesEVR && provideFlags)
+ for (i = 0; i < providesCount; i++) {
+ if (!(provides[i] && providesEVR[i]))
+ continue;
+ if (!(provideFlags[i] == RPMSENSE_EQUAL &&
+ !strcmp(N, provides[i]) && !strcmp(pEVR, providesEVR[i])))
+ continue;
+ bingo = 0;
+ break;
+ }
+ /*@=nullderef@*/
+
+exit:
+/*@-usereleased@*/
+ provides = _free(provides);
+ providesEVR = _free(providesEVR);
+ provideFlags = _free(provideFlags);
+/*@=usereleased@*/
+
+ if (bingo) {
+ he->tag = RPMTAG_PROVIDENAME;
+ he->t = RPM_STRING_ARRAY_TYPE;
+ he->p.argv = &N;
+ he->c = 1;
+ he->append = 1;
+/*@-nullstate@*/
+ xx = headerPut(h, he, 0);
+/*@=nullstate@*/
+ he->append = 0;
+
+ /* XXX succeeds only at allocating the necessary appended space,
+ * not copying to it..? */
+ xx = headerGet(h, he, 0);
+ he->p.argv[providesCount] = N;
+ xx = headerPut(h, he, 0);
+ _free(he->p.ptr);
+
+ he->tag = RPMTAG_PROVIDEVERSION;
+ he->t = RPM_STRING_ARRAY_TYPE;
+ he->p.argv = &pEVR;
+ he->c = 1;
+ he->append = 1;
+/*@-nullstate@*/
+ xx = headerPut(h, he, 0);
+/*@=nullstate@*/
+ he->append = 0;
+
+ he->tag = RPMTAG_PROVIDEFLAGS;
+ he->t = RPM_UINT32_TYPE;
+ he->p.ui32p = &pFlags;
+ he->c = 1;
+ he->append = 1;
+/*@-nullstate@*/
+ xx = headerPut(h, he, 0);
+/*@=nullstate@*/
+ he->append = 0;
+ }
+ N = _free(N);
+}
+
+static void add_RPMTAG_SOURCERPM(Header h)
+{
+ if (!headerIsEntry(h, RPMTAG_SOURCERPM) && !headerIsEntry(h, RPMTAG_SOURCEPACKAGE)) {
+ /* we have no way to know if this is a srpm or an rpm with no SOURCERPM */
+ /* but since this is an old v3 rpm, we suppose it's not a srpm */
+ HE_t he = (HE_t)memset(alloca(sizeof(*he)), 0, sizeof(*he));
+
+ he->tag = RPMTAG_SOURCERPM;
+ he->t = RPM_STRING_TYPE;
+ he->p.str = "\0";
+ he->c = 1;
+ headerPut(h, he, 0);
+ }
+}
+
+/* rpm v3 compatibility */
+static void rpm3to4(Header h) {
+ const char * rpmversion = NULL;
+ HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
+
+ he->tag = RPMTAG_RPMVERSION;
+ if (headerGet(h, he, 0)) {
+ rpmversion = he->p.str;
+ }
+
+ if ((!rpmversion) || rpmversion[0] < '4') {
+ add_RPMTAG_SOURCERPM(h);
+ providePackageNVR(h);
+ compressFilelist(h);
+ }
+ rpmversion = _free(rpmversion);
+ return;
+}
+
/*@-mods@*/
rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char * fn, Header * hdrp)
{
@@ -383,6 +728,8 @@ exit:
/* Append (and remap) signature tags to the metadata. */
headerMergeLegacySigs(h, sigh);
+ rpm3to4(h);
+
/* Bump reference count for return. */
*hdrp = headerLink(h);
}