rpm 5.3.12
|
00001 00005 #include "system.h" 00006 00007 #include <rpmiotypes.h> 00008 #include <rpmmacro.h> 00009 00010 #define _RPMTAG_INTERNAL 00011 #include "header_internal.h" /* XXX hdrchkType(), hdrchkData() */ 00012 00013 #include "debug.h" 00014 00019 /*@observer@*/ /*@unchecked@*/ 00020 static struct tagMacro { 00021 /*@observer@*/ /*@null@*/ 00022 const char *macroname; 00023 rpmTag tag; 00024 } tagMacros[] = { 00025 { "name", RPMTAG_NAME }, 00026 { "version", RPMTAG_VERSION }, 00027 { "release", RPMTAG_RELEASE }, 00028 { "distepoch", RPMTAG_DISTEPOCH }, 00029 { "epoch", RPMTAG_EPOCH }, 00030 { "arch", RPMTAG_ARCH }, 00031 { "os", RPMTAG_OS }, 00032 { NULL, 0 } 00033 }; 00034 00035 /*@-globs -mods -incondefs@*/ 00036 int headerMacrosLoad(Header h) 00037 /*@globals rpmGlobalMacroContext @*/ 00038 /*@modifies rpmGlobalMacroContext @*/ 00039 { 00040 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 00041 struct tagMacro * tagm; 00042 char numbuf[64]; 00043 const char * val; 00044 rpmuint64_t ival; 00045 int xx; 00046 00047 numbuf[0] = '\0'; 00048 /* XXX pre-expand %{buildroot} (if any) */ 00049 { const char *s = rpmExpand("%{?buildroot}", NULL); 00050 if (s && *s) 00051 (void) addMacro(NULL, "..buildroot", NULL, s, -1); 00052 s = _free(s); 00053 } 00054 { const char *s = rpmExpand("%{?_builddir}", NULL); 00055 if (s && *s) 00056 (void) addMacro(NULL, ".._builddir", NULL, s, -1); 00057 s = _free(s); 00058 } 00059 00060 for (tagm = tagMacros; tagm->macroname != NULL; tagm++) { 00061 he->tag = tagm->tag; 00062 xx = headerGet(h, he, 0); 00063 if (!xx) 00064 continue; 00065 val = NULL; 00066 ival = 0; 00067 switch (he->t) { 00068 case RPM_UINT8_TYPE: 00069 ival = (rpmuint64_t)he->p.ui8p[0]; 00070 val = numbuf; 00071 /*@switchbreak@*/ break; 00072 case RPM_UINT16_TYPE: 00073 ival = (rpmuint64_t)he->p.ui16p[0]; 00074 val = numbuf; 00075 /*@switchbreak@*/ break; 00076 case RPM_UINT32_TYPE: 00077 ival = (rpmuint64_t)he->p.ui32p[0]; 00078 val = numbuf; 00079 /*@switchbreak@*/ break; 00080 case RPM_UINT64_TYPE: 00081 ival = he->p.ui64p[0]; 00082 val = numbuf; 00083 /*@switchbreak@*/ break; 00084 case RPM_STRING_TYPE: 00085 val = he->p.str; 00086 /*@switchbreak@*/ break; 00087 case RPM_STRING_ARRAY_TYPE: 00088 case RPM_I18NSTRING_TYPE: 00089 case RPM_BIN_TYPE: 00090 default: 00091 /*@switchbreak@*/ break; 00092 } 00093 00094 if (val) { 00095 /*@-duplicatequals@*/ 00096 if (val == numbuf) 00097 sprintf(numbuf, "%llu", (unsigned long long)ival); 00098 /*@=duplicatequals@*/ 00099 addMacro(NULL, tagm->macroname, NULL, val, -1); 00100 } 00101 he->p.ptr = _free(he->p.ptr); 00102 } 00103 return 0; 00104 } 00105 /*@=globs =mods =incondefs@*/ 00106 00107 /*@-globs -mods -incondefs@*/ 00108 int headerMacrosUnload(Header h) 00109 /*@globals rpmGlobalMacroContext @*/ 00110 /*@modifies rpmGlobalMacroContext @*/ 00111 { 00112 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 00113 struct tagMacro * tagm; 00114 int xx; 00115 00116 for (tagm = tagMacros; tagm->macroname != NULL; tagm++) { 00117 he->tag = tagm->tag; 00118 xx = headerGet(h, he, 0); 00119 if (!xx) 00120 continue; 00121 switch (he->t) { 00122 case RPM_UINT32_TYPE: 00123 delMacro(NULL, tagm->macroname); 00124 /*@switchbreak@*/ break; 00125 case RPM_STRING_TYPE: 00126 delMacro(NULL, tagm->macroname); 00127 /*@switchbreak@*/ break; 00128 case RPM_STRING_ARRAY_TYPE: 00129 case RPM_I18NSTRING_TYPE: 00130 case RPM_BIN_TYPE: 00131 case RPM_UINT8_TYPE: 00132 case RPM_UINT16_TYPE: 00133 case RPM_UINT64_TYPE: 00134 default: 00135 /*@switchbreak@*/ break; 00136 } 00137 he->p.ptr = _free(he->p.ptr); 00138 } 00139 00140 /* XXX restore previous %{buildroot} (if any) */ 00141 { const char *s = rpmExpand("%{?_builddir}", NULL); 00142 if (s && *s) 00143 (void) delMacro(NULL, "_builddir"); 00144 s = _free(s); 00145 } 00146 { const char *s = rpmExpand("%{?buildroot}", NULL); 00147 if (s && *s) 00148 (void) delMacro(NULL, "buildroot"); 00149 s = _free(s); 00150 } 00151 00152 return 0; 00153 } 00154 /*@=globs =mods =incondefs@*/ 00155 00156 int headerNEVRA(Header h, const char **np, /*@unused@*/ const char **ep, 00157 const char **vp, const char **rp, const char **ap) 00158 { 00159 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 00160 00161 /*@-onlytrans@*/ 00162 if (np) { 00163 he->tag = RPMTAG_NAME; 00164 if (headerGet(h, he, 0) 00165 && he->t == RPM_STRING_TYPE && he->c == 1) 00166 *np = xstrdup(he->p.str); 00167 else 00168 *np = NULL; 00169 he->p.ptr = _free(he->p.ptr); 00170 } 00171 if (vp) { 00172 he->tag = RPMTAG_VERSION; 00173 if (headerGet(h, he, 0) 00174 && he->t == RPM_STRING_TYPE && he->c == 1) 00175 *vp = xstrdup(he->p.str); 00176 else 00177 *vp = NULL; 00178 he->p.ptr = _free(he->p.ptr); 00179 } 00180 if (rp) { 00181 he->tag = RPMTAG_RELEASE; 00182 if (headerGet(h, he, 0) 00183 && he->t == RPM_STRING_TYPE && he->c == 1) 00184 *rp = xstrdup(he->p.str); 00185 else 00186 *rp = NULL; 00187 he->p.ptr = _free(he->p.ptr); 00188 } 00189 if (ap) { 00190 #if !defined(RPM_VENDOR_OPENPKG) /* no-architecture-expose */ 00191 /* do not expose the architecture as this is too less 00192 information, as in OpenPKG the "platform" is described by the 00193 architecture+operating-system combination. But as the whole 00194 "platform" information is actually overkill, just revert to the 00195 RPM 4 behaviour and do not expose any such information at all. */ 00196 he->tag = RPMTAG_ARCH; 00197 /*@-observertrans -readonlytrans@*/ 00198 if (!headerIsEntry(h, he->tag)) 00199 *ap = xstrdup("pubkey"); 00200 else 00201 if (!headerIsEntry(h, RPMTAG_SOURCERPM)) 00202 *ap = xstrdup("src"); 00203 /*@=observertrans =readonlytrans@*/ 00204 else 00205 if (headerGet(h, he, 0) 00206 && he->t == RPM_STRING_TYPE && he->c == 1) 00207 *ap = xstrdup(he->p.str); 00208 else 00209 #endif 00210 *ap = NULL; 00211 he->p.ptr = _free(he->p.ptr); 00212 } 00213 /*@=onlytrans@*/ 00214 return 0; 00215 } 00216 00217 rpmuint32_t hGetColor(Header h) 00218 { 00219 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 00220 rpmuint32_t hcolor = 0; 00221 int xx; 00222 00223 he->tag = RPMTAG_FILECOLORS; 00224 xx = headerGet(h, he, 0); 00225 if (xx && he->p.ptr != NULL && he->c > 0) { 00226 unsigned i; 00227 for (i = 0; i < (unsigned) he->c; i++) 00228 hcolor |= he->p.ui32p[i]; 00229 } 00230 he->p.ptr = _free(he->p.ptr); 00231 hcolor &= 0x0f; 00232 00233 return hcolor; 00234 } 00235 00236 void headerMergeLegacySigs(Header h, const Header sigh) 00237 { 00238 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 00239 HeaderIterator hi; 00240 int xx; 00241 00242 if (h == NULL || sigh == NULL) 00243 return; 00244 00245 for (hi = headerInit(sigh); 00246 headerNext(hi, he, 0); 00247 he->p.ptr = _free(he->p.ptr)) 00248 { 00249 /* XXX Translate legacy signature tag values. */ 00250 switch ((rpmSigTag)he->tag) { 00251 case RPMSIGTAG_SIZE: 00252 he->tag = RPMTAG_SIGSIZE; 00253 /*@switchbreak@*/ break; 00254 case RPMSIGTAG_MD5: 00255 he->tag = RPMTAG_SIGMD5; 00256 /*@switchbreak@*/ break; 00257 case RPMSIGTAG_PAYLOADSIZE: 00258 he->tag = RPMTAG_ARCHIVESIZE; 00259 /*@switchbreak@*/ break; 00260 case RPMSIGTAG_SHA1: 00261 case RPMSIGTAG_DSA: 00262 case RPMSIGTAG_RSA: 00263 default: 00264 /* Skip all unknown tags that are not in the signature tag range. */ 00265 if (!(he->tag >= HEADER_SIGBASE && he->tag < HEADER_TAGBASE)) 00266 continue; 00267 /*@switchbreak@*/ break; 00268 } 00269 assert(he->p.ptr != NULL); 00270 if (!headerIsEntry(h, he->tag)) { 00271 if (hdrchkType(he->t)) 00272 continue; 00273 if (hdrchkData(he->c)) 00274 continue; 00275 switch(he->t) { 00276 default: 00277 assert(0); /* XXX keep gcc quiet */ 00278 /*@switchbreak@*/ break; 00279 case RPM_UINT8_TYPE: 00280 case RPM_UINT16_TYPE: 00281 case RPM_UINT32_TYPE: 00282 case RPM_UINT64_TYPE: 00283 if (he->c != 1) 00284 continue; 00285 /*@switchbreak@*/ break; 00286 case RPM_STRING_TYPE: 00287 case RPM_BIN_TYPE: 00288 if (he->c >= 16*1024) 00289 continue; 00290 /*@switchbreak@*/ break; 00291 case RPM_STRING_ARRAY_TYPE: 00292 case RPM_I18NSTRING_TYPE: 00293 continue; 00294 /*@notreached@*/ /*@switchbreak@*/ break; 00295 } 00296 xx = headerPut(h, he, 0); 00297 assert(xx == 1); 00298 } 00299 } 00300 hi = headerFini(hi); 00301 } 00302 00303 Header headerRegenSigHeader(const Header h, int noArchiveSize) 00304 { 00305 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 00306 Header sigh = headerNew(); 00307 HeaderIterator hi; 00308 int xx; 00309 00310 for (hi = headerInit(h); 00311 headerNext(hi, he, 0); 00312 he->p.ptr = _free(he->p.ptr)) 00313 { 00314 /* XXX Translate legacy signature tag values. */ 00315 switch (he->tag) { 00316 case RPMTAG_SIGSIZE: 00317 he->tag = (rpmTag) RPMSIGTAG_SIZE; 00318 /*@switchbreak@*/ break; 00319 case RPMTAG_SIGMD5: 00320 he->tag = (rpmTag) RPMSIGTAG_MD5; 00321 /*@switchbreak@*/ break; 00322 case RPMTAG_ARCHIVESIZE: 00323 /* XXX rpm-4.1 and later has archive size in signature header. */ 00324 if (noArchiveSize) 00325 continue; 00326 he->tag = (rpmTag) RPMSIGTAG_PAYLOADSIZE; 00327 /*@switchbreak@*/ break; 00328 case RPMTAG_SHA1HEADER: 00329 case RPMTAG_DSAHEADER: 00330 case RPMTAG_RSAHEADER: 00331 default: 00332 /* Skip all unknown tags that are not in the signature tag range. */ 00333 if (!(he->tag >= HEADER_SIGBASE && he->tag < HEADER_TAGBASE)) 00334 continue; 00335 /*@switchbreak@*/ break; 00336 } 00337 assert(he->p.ptr != NULL); 00338 if (!headerIsEntry(sigh, he->tag)) { 00339 xx = headerPut(sigh, he, 0); 00340 assert(xx == 1); 00341 } 00342 } 00343 hi = headerFini(hi); 00344 return sigh; 00345 }