]>
Commit | Line | Data |
---|---|---|
de6920d5 | 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 | |
3 | @@ -10,6 +10,7 @@ | |
4 | #include <rpmlib.h> | |
5 | ||
6 | #include "rpmts.h" | |
7 | +#include "rpmevr.h" | |
8 | ||
9 | #include "misc.h" /* XXX stripTrailingChar() */ | |
10 | #include "rpmlead.h" | |
11 | @@ -94,6 +95,148 @@ | |
12 | */ | |
13 | #define hdrchkRange(_dl, _off) ((_off) < 0 || (_off) > (_dl)) | |
14 | ||
15 | +/*@-boundsread@*/ | |
16 | +static int dncmp(const void * a, const void * b) | |
17 | + /*@*/ | |
18 | +{ | |
19 | + const char *const * first = a; | |
20 | + const char *const * second = b; | |
21 | + return strcmp(*first, *second); | |
22 | +} | |
23 | +/*@=boundsread@*/ | |
24 | + | |
25 | +/*@-bounds@*/ | |
26 | +/** | |
27 | + * Convert absolute path tag to (dirname,basename,dirindex) tags. | |
28 | + * @param h header | |
29 | + */ | |
30 | +static void compressFilelist(Header h) | |
31 | + /*@modifies h @*/ | |
32 | +{ | |
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; | |
37 | + char ** fileNames; | |
38 | + const char ** dirNames; | |
39 | + const char ** baseNames; | |
40 | + int_32 * dirIndexes; | |
41 | + rpmTagType fnt; | |
42 | + int count; | |
43 | + int i, xx; | |
44 | + int dirIndex = -1; | |
45 | + | |
46 | + /* | |
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 | |
49 | + * a bit faster. | |
50 | + */ | |
51 | + | |
52 | + if (headerIsEntry(h, RPMTAG_DIRNAMES)) { | |
53 | + xx = hre(h, RPMTAG_OLDFILENAMES); | |
54 | + return; /* Already converted. */ | |
55 | + } | |
56 | + | |
57 | + if (!hge(h, RPMTAG_OLDFILENAMES, &fnt, (void **) &fileNames, &count)) | |
58 | + return; /* no file list */ | |
59 | + if (fileNames == NULL || count <= 0) | |
60 | + return; | |
61 | + | |
62 | + dirNames = alloca(sizeof(*dirNames) * count); /* worst case */ | |
63 | + baseNames = alloca(sizeof(*dirNames) * count); | |
64 | + dirIndexes = alloca(sizeof(*dirIndexes) * count); | |
65 | + | |
66 | + if (fileNames[0][0] != '/') { | |
67 | + /* HACK. Source RPM, so just do things differently */ | |
68 | + dirIndex = 0; | |
69 | + dirNames[dirIndex] = ""; | |
70 | + for (i = 0; i < count; i++) { | |
71 | + dirIndexes[i] = dirIndex; | |
72 | + baseNames[i] = fileNames[i]; | |
73 | + } | |
74 | + goto exit; | |
75 | + } | |
76 | + | |
77 | + /*@-branchstate@*/ | |
78 | + for (i = 0; i < count; i++) { | |
79 | + const char ** needle; | |
80 | + char savechar; | |
81 | + char * baseName; | |
82 | + int len; | |
83 | + | |
84 | + if (fileNames[i] == NULL) /* XXX can't happen */ | |
85 | + continue; | |
86 | + baseName = strrchr(fileNames[i], '/') + 1; | |
87 | + len = baseName - fileNames[i]; | |
88 | + needle = dirNames; | |
89 | + savechar = *baseName; | |
90 | + *baseName = '\0'; | |
91 | +/*@-compdef@*/ | |
92 | + if (dirIndex < 0 || | |
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); | |
96 | + s[len] = '\0'; | |
97 | + dirIndexes[i] = ++dirIndex; | |
98 | + dirNames[dirIndex] = s; | |
99 | + } else | |
100 | + dirIndexes[i] = needle - dirNames; | |
101 | +/*@=compdef@*/ | |
102 | + | |
103 | + *baseName = savechar; | |
104 | + baseNames[i] = baseName; | |
105 | + } | |
106 | + /*@=branchstate@*/ | |
107 | + | |
108 | +exit: | |
109 | + if (count > 0) { | |
110 | + xx = hae(h, RPMTAG_DIRINDEXES, RPM_INT32_TYPE, dirIndexes, count); | |
111 | + xx = hae(h, RPMTAG_BASENAMES, RPM_STRING_ARRAY_TYPE, | |
112 | + baseNames, count); | |
113 | + xx = hae(h, RPMTAG_DIRNAMES, RPM_STRING_ARRAY_TYPE, | |
114 | + dirNames, dirIndex + 1); | |
115 | + } | |
116 | + | |
117 | + fileNames = hfd(fileNames, fnt); | |
118 | + | |
119 | + xx = hre(h, RPMTAG_OLDFILENAMES); | |
120 | +} | |
121 | +/*@=bounds@*/ | |
122 | + | |
123 | +/* rpm v3 compatibility */ | |
124 | +static void rpm3to4(Header h) { | |
125 | + char * rpmversion; | |
126 | + int_32 rpmversion_type; | |
127 | + | |
128 | + (void) headerGetEntry(h, RPMTAG_RPMVERSION, NULL, (void **) &rpmversion, &rpmversion_type); | |
129 | + | |
130 | + if ((!rpmversion) || rpmversion[0] < '4') { | |
131 | + int *epoch; | |
132 | + const char * name, *version, *release; | |
133 | + const char *pEVR; | |
134 | + char *p; | |
135 | + int_32 pFlags = RPMSENSE_EQUAL; | |
136 | + | |
137 | + if (headerNVR(h, &name, &version, &release) == 0) { | |
138 | + pEVR = p = alloca(21 + strlen(version) + 1 + strlen(release) + 1); | |
139 | + *p = '\0'; | |
140 | + if (headerGetEntry(h, RPMTAG_EPOCH, NULL, (void **) &epoch, NULL)) { | |
141 | + sprintf(p, "%d:", *epoch); | |
142 | + while (*p != '\0') | |
143 | + p++; | |
144 | + } | |
145 | + (void) stpcpy( stpcpy( stpcpy(p, version) , "-") , release); | |
146 | + | |
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); | |
150 | + } | |
151 | + compressFilelist(h); | |
152 | + } | |
153 | + headerFreeTag(h, (void *) rpmversion, rpmversion_type); | |
154 | + return; | |
155 | +} | |
156 | + | |
157 | void headerMergeLegacySigs(Header h, const Header sigh) | |
158 | { | |
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); | |
163 | ||
164 | + rpm3to4(h); | |
165 | + | |
166 | /* Bump reference count for return. */ | |
167 | /*@-boundswrite@*/ | |
168 | *hdrp = headerLink(h); |