Sophie

Sophie

distrib > Mandriva > 2008.0 > x86_64 > by-pkgid > a35732d620cfac4812adc8d6b2992f07 > files > 30

rpm-4.4.8-22.1mdv2008.0.src.rpm

--- rpm-4.4.6/lib/package.c.pix	2006-04-03 01:09:07.000000000 +0200
+++ rpm-4.4.6/lib/package.c	2007-01-08 14:31:04.000000000 +0100
@@ -94,6 +94,223 @@
  */
 #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@*/
+
+
+/* copied verbatim from build/pack.c */
+static void providePackageNVR(Header h)
+	/*@modifies h @*/
+{
+    HGE_t hge = (HGE_t)headerGetEntryMinMemory;
+    HFD_t hfd = headerFreeData;
+    const char *name, *version, *release;
+    int_32 * epoch;
+    const char *pEVR;
+    char *p;
+    int_32 pFlags = RPMSENSE_EQUAL;
+    const char ** provides = NULL;
+    const char ** providesEVR = NULL;
+    rpmTagType pnt, pvt;
+    int_32 * provideFlags = NULL;
+    int providesCount;
+    int i, xx;
+    int bingo = 1;
+
+    /* Generate provides for this package name-version-release. */
+    xx = headerNVR(h, &name, &version, &release);
+    if (!(name && version && release))
+	return;
+    pEVR = p = alloca(21 + strlen(version) + 1 + strlen(release) + 1);
+    *p = '\0';
+    if (hge(h, RPMTAG_EPOCH, NULL, (void **) &epoch, NULL)) {
+	sprintf(p, "%d:", *epoch);
+	while (*p != '\0')
+	    p++;
+    }
+    (void) stpcpy( stpcpy( stpcpy(p, version) , "-") , release);
+
+    /*
+     * Rpm prior to 3.0.3 does not have versioned provides.
+     * If no provides at all are available, we can just add.
+     */
+    if (!hge(h, RPMTAG_PROVIDENAME, &pnt, (void **) &provides, &providesCount))
+	goto exit;
+
+    /*
+     * Otherwise, fill in entries on legacy packages.
+     */
+    if (!hge(h, RPMTAG_PROVIDEVERSION, &pvt, (void **) &providesEVR, NULL)) {
+	for (i = 0; i < providesCount; i++) {
+	    char * vdummy = "";
+	    int_32 fdummy = RPMSENSE_ANY;
+	    xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION, RPM_STRING_ARRAY_TYPE,
+			&vdummy, 1);
+	    xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE,
+			&fdummy, 1);
+	}
+	goto exit;
+    }
+
+    xx = hge(h, RPMTAG_PROVIDEFLAGS, NULL, (void **) &provideFlags, NULL);
+
+    /*@-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(name, provides[i]) && !strcmp(pEVR, providesEVR[i])))
+	    continue;
+	bingo = 0;
+	break;
+    }
+    /*@=nullderef@*/
+
+exit:
+    provides = hfd(provides, pnt);
+    providesEVR = hfd(providesEVR, pvt);
+
+    if (bingo) {
+	xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDENAME, RPM_STRING_ARRAY_TYPE,
+		&name, 1);
+	xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE,
+		&pFlags, 1);
+	xx = headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION, RPM_STRING_ARRAY_TYPE,
+		&pEVR, 1);
+    }
+}
+
+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 */
+    headerAddEntry(h, RPMTAG_SOURCERPM, RPM_STRING_TYPE, "\0", 1);
+  }
+}
+
+/* rpm v3 compatibility */
+static void rpm3to4(Header h) {
+    char * rpmversion;
+    rpmTagType rpmversion_type;
+
+    (void) headerGetEntry(h, RPMTAG_RPMVERSION, NULL, (void **) &rpmversion, &rpmversion_type);
+
+    if ((!rpmversion) || rpmversion[0] < '4') {
+        add_RPMTAG_SOURCERPM(h);
+        providePackageNVR(h);
+        compressFilelist(h);
+    }
+    headerFreeTag(h, (void *) rpmversion, rpmversion_type);
+    return;
+}
+
 void headerMergeLegacySigs(Header h, const Header sigh)
 {
     HFD_t hfd = (HFD_t) headerFreeData;
@@ -1062,6 +1279,8 @@
 	/* Append (and remap) signature tags to the metadata. */
 	headerMergeLegacySigs(h, sigh);
 
+    rpm3to4(h);
+
 	/* Bump reference count for return. */
 /*@-boundswrite@*/
 	*hdrp = headerLink(h);