1 --- ./lib/package.c 2006-07-26 14:45:41.000000000 +0200
2 +++ rpm-4.4.9/lib/package.c 2008-10-26 17:56:29.000000000 +0200
9 #include "misc.h" /* XXX stripTrailingChar() */
13 #define hdrchkRange(_dl, _off) ((_off) < 0 || (_off) > (_dl))
16 +static int dncmp(const void * a, const void * b)
19 + const char *const * first = a;
20 + const char *const * second = b;
21 + return strcmp(*first, *second);
27 + * Convert absolute path tag to (dirname,basename,dirindex) tags.
30 +static void compressFilelist(Header h)
33 + HGE_t hge = (HGE_t)headerGetEntryMinMemory;
34 + HAE_t hae = (HAE_t)headerAddEntry;
35 + HRE_t hre = (HRE_t)headerRemoveEntry;
36 + HFD_t hfd = headerFreeData;
38 + const char ** dirNames;
39 + const char ** baseNames;
40 + int_32 * dirIndexes;
47 + * This assumes the file list is already sorted, and begins with a
48 + * single '/'. That assumption isn't critical, but it makes things go
52 + if (headerIsEntry(h, RPMTAG_DIRNAMES)) {
53 + xx = hre(h, RPMTAG_OLDFILENAMES);
54 + return; /* Already converted. */
57 + if (!hge(h, RPMTAG_OLDFILENAMES, &fnt, (void **) &fileNames, &count))
58 + return; /* no file list */
59 + if (fileNames == NULL || count <= 0)
62 + dirNames = alloca(sizeof(*dirNames) * count); /* worst case */
63 + baseNames = alloca(sizeof(*dirNames) * count);
64 + dirIndexes = alloca(sizeof(*dirIndexes) * count);
66 + if (fileNames[0][0] != '/') {
67 + /* HACK. Source RPM, so just do things differently */
69 + dirNames[dirIndex] = "";
70 + for (i = 0; i < count; i++) {
71 + dirIndexes[i] = dirIndex;
72 + baseNames[i] = fileNames[i];
78 + for (i = 0; i < count; i++) {
79 + const char ** needle;
84 + if (fileNames[i] == NULL) /* XXX can't happen */
86 + baseName = strrchr(fileNames[i], '/') + 1;
87 + len = baseName - fileNames[i];
89 + savechar = *baseName;
93 + (needle = bsearch(&fileNames[i], dirNames, dirIndex + 1, sizeof(dirNames[0]), dncmp)) == NULL) {
94 + char *s = alloca(len + 1);
95 + memcpy(s, fileNames[i], len + 1);
97 + dirIndexes[i] = ++dirIndex;
98 + dirNames[dirIndex] = s;
100 + dirIndexes[i] = needle - dirNames;
103 + *baseName = savechar;
104 + baseNames[i] = baseName;
110 + xx = hae(h, RPMTAG_DIRINDEXES, RPM_INT32_TYPE, dirIndexes, count);
111 + xx = hae(h, RPMTAG_BASENAMES, RPM_STRING_ARRAY_TYPE,
113 + xx = hae(h, RPMTAG_DIRNAMES, RPM_STRING_ARRAY_TYPE,
114 + dirNames, dirIndex + 1);
117 + fileNames = hfd(fileNames, fnt);
119 + xx = hre(h, RPMTAG_OLDFILENAMES);
123 +/* rpm v3 compatibility */
124 +static void rpm3to4(Header h) {
126 + int_32 rpmversion_type;
128 + (void) headerGetEntry(h, RPMTAG_RPMVERSION, NULL, (void **) &rpmversion, &rpmversion_type);
130 + if ((!rpmversion) || rpmversion[0] < '4') {
132 + const char * name, *version, *release;
135 + int_32 pFlags = RPMSENSE_EQUAL;
137 + if (headerNVR(h, &name, &version, &release) == 0) {
138 + pEVR = p = alloca(21 + strlen(version) + 1 + strlen(release) + 1);
140 + if (headerGetEntry(h, RPMTAG_EPOCH, NULL, (void **) &epoch, NULL)) {
141 + sprintf(p, "%d:", *epoch);
145 + (void) stpcpy( stpcpy( stpcpy(p, version) , "-") , release);
147 + headerAddOrAppendEntry(h, RPMTAG_PROVIDENAME, RPM_STRING_ARRAY_TYPE, &name, 1);
148 + headerAddOrAppendEntry(h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE, &pFlags, 1);
149 + headerAddOrAppendEntry(h, RPMTAG_PROVIDEVERSION, RPM_STRING_ARRAY_TYPE, &pEVR, 1);
151 + compressFilelist(h);
153 + headerFreeTag(h, (void *) rpmversion, rpmversion_type);
157 void headerMergeLegacySigs(Header h, const Header sigh)
159 HFD_t hfd = (HFD_t) headerFreeData;
160 @@ -1062,6 +1205,8 @@
161 /* Append (and remap) signature tags to the metadata. */
162 headerMergeLegacySigs(h, sigh);
166 /* Bump reference count for return. */
168 *hdrp = headerLink(h);