rpmScript rpmScriptFromTriggerTag(Header h, rpmTagVal triggerTag, uint32_t ix) { rpmScript script = NULL; struct rpmtd_s tscripts, tprogs, tflags; headerGetFlags hgflags = HEADERGET_MINMEM; headerGet(h, RPMTAG_TRIGGERSCRIPTS, &tscripts, hgflags); headerGet(h, RPMTAG_TRIGGERSCRIPTPROG, &tprogs, hgflags); headerGet(h, RPMTAG_TRIGGERSCRIPTFLAGS, &tflags, hgflags); if (rpmtdSetIndex(&tscripts, ix) >= 0 && rpmtdSetIndex(&tprogs, ix) >= 0) { rpmscriptFlags sflags = 0; const char *prog = rpmtdGetString(&tprogs); if (rpmtdSetIndex(&tflags, ix) >= 0) sflags = rpmtdGetNumber(&tflags); script = rpmScriptNew(h, triggerTag, rpmtdGetString(&tscripts), sflags); /* hack up a hge-style NULL-terminated array */ script->args = xmalloc(2 * sizeof(*script->args) + strlen(prog) + 1); script->args[0] = (char *)(script->args + 2); script->args[1] = NULL; strcpy(script->args[0], prog); } rpmtdFreeData(&tscripts); rpmtdFreeData(&tprogs); rpmtdFreeData(&tflags); return script; }
static void unloadImmutableRegion(Header *hdrp, rpmTagVal tag) { struct rpmtd_s copytd, td; rpmtd utd = &td; Header nh; Header oh; HeaderIterator hi; if (headerGet(*hdrp, tag, utd, HEADERGET_DEFAULT)) { nh = headerNew(); oh = headerCopyLoad(utd->data); hi = headerInitIterator(oh); while (headerNext(hi, ©td)) { if (copytd.data) headerPut(nh, ©td, HEADERPUT_DEFAULT); rpmtdFreeData(©td); } headerFreeIterator(hi); headerFree(oh); rpmtdFreeData(utd); headerFree(*hdrp); *hdrp = headerLink(nh); headerFree(nh); } }
int headerFindSpec(Header h) { struct rpmtd_s filenames; int specix = -1; if (headerGet(h, RPMTAG_BASENAMES, &filenames, HEADERGET_MINMEM)) { struct rpmtd_s td; const char *str; /* Try to find spec by file flags */ if (headerGet(h, RPMTAG_FILEFLAGS, &td, HEADERGET_MINMEM)) { rpmfileAttrs *flags; while (specix < 0 && (flags = rpmtdNextUint32(&td))) { if (*flags & RPMFILE_SPECFILE) specix = rpmtdGetIndex(&td); } rpmtdFreeData(&td); } /* Still no spec? Look by filename. */ while (specix < 0 && (str = rpmtdNextString(&filenames))) { if (rpmFileHasSuffix(str, ".spec")) specix = rpmtdGetIndex(&filenames); } rpmtdFreeData(&filenames); } return specix; }
/** * This assumes the order of list matches the order of the new headers, and * throws an exception if that isn't true. */ static int rpmMergeHeaders(PyObject * list, FD_t fd, int matchTag) { Header h; HeaderIterator hi; rpmTagVal newMatch, oldMatch; hdrObject * hdr; rpm_count_t count = 0; int rc = 1; /* assume failure */ rpmtd td = rpmtdNew(); Py_BEGIN_ALLOW_THREADS h = headerRead(fd, HEADER_MAGIC_YES); Py_END_ALLOW_THREADS while (h) { if (!headerGet(h, matchTag, td, HEADERGET_MINMEM)) { PyErr_SetString(pyrpmError, "match tag missing in new header"); goto exit; } newMatch = rpmtdTag(td); rpmtdFreeData(td); hdr = (hdrObject *) PyList_GetItem(list, count++); if (!hdr) goto exit; if (!headerGet(hdr->h, matchTag, td, HEADERGET_MINMEM)) { PyErr_SetString(pyrpmError, "match tag missing in new header"); goto exit; } oldMatch = rpmtdTag(td); rpmtdFreeData(td); if (newMatch != oldMatch) { PyErr_SetString(pyrpmError, "match tag mismatch"); goto exit; } for (hi = headerInitIterator(h); headerNext(hi, td); rpmtdFreeData(td)) { /* could be dupes */ headerDel(hdr->h, rpmtdTag(td)); headerPut(hdr->h, td, HEADERPUT_DEFAULT); } headerFreeIterator(hi); h = headerFree(h); Py_BEGIN_ALLOW_THREADS h = headerRead(fd, HEADER_MAGIC_YES); Py_END_ALLOW_THREADS } rc = 0; exit: rpmtdFree(td); return rc; }
static int addPrefixes(Header h, rpmRelocation *relocations, int numRelocations) { struct rpmtd_s validRelocs; const char *validprefix; const char ** actualRelocations; int numActual = 0; headerGet(h, RPMTAG_PREFIXES, &validRelocs, HEADERGET_MINMEM); /* * If no relocations are specified (usually the case), then return the * original header. If there are prefixes, however, then INSTPREFIXES * should be added for RPM_INSTALL_PREFIX environ variables in scriptlets, * but, since relocateFileList() can be called more than once for * the same header, don't bother if already present. */ if (relocations == NULL || numRelocations == 0) { if (rpmtdCount(&validRelocs) > 0) { if (!headerIsEntry(h, RPMTAG_INSTPREFIXES)) { rpmtdSetTag(&validRelocs, RPMTAG_INSTPREFIXES); headerPut(h, &validRelocs, HEADERPUT_DEFAULT); } rpmtdFreeData(&validRelocs); } return 0; } actualRelocations = xmalloc(rpmtdCount(&validRelocs) * sizeof(*actualRelocations)); rpmtdInit(&validRelocs); while ((validprefix = rpmtdNextString(&validRelocs))) { int j; for (j = 0; j < numRelocations; j++) { if (relocations[j].oldPath == NULL || /* XXX can't happen */ !rstreq(validprefix, relocations[j].oldPath)) continue; /* On install, a relocate to NULL means skip the path. */ if (relocations[j].newPath) { actualRelocations[numActual] = relocations[j].newPath; numActual++; } break; } if (j == numRelocations) { actualRelocations[numActual] = validprefix; numActual++; } } rpmtdFreeData(&validRelocs); if (numActual) { headerPutStringArray(h, RPMTAG_INSTPREFIXES, actualRelocations, numActual); } free(actualRelocations); /* When any relocations are present there'll be more work to do */ return 1; }
rpmfi rpmfiNewPool(rpmstrPool pool, Header h, rpmTagVal tagN, rpmfiFlags flags) { rpmfi fi = xcalloc(1, sizeof(*fi)); struct rpmtd_s bn, dn, dx; fi->magic = RPMFIMAGIC; fi->i = -1; fi->fiflags = flags; /* * Grab and validate file triplet data. Headers with no files simply * fall through here and an empty file set is returned. */ if (headerGet(h, RPMTAG_BASENAMES, &bn, HEADERGET_MINMEM)) { headerGet(h, RPMTAG_DIRNAMES, &dn, HEADERGET_MINMEM); headerGet(h, RPMTAG_DIRINDEXES, &dx, HEADERGET_ALLOC); if (indexSane(&bn, &dn, &dx)) { /* private or shared pool? */ fi->pool = (pool != NULL) ? rpmstrPoolLink(pool) : rpmstrPoolCreate(); /* init the file triplet data */ fi->fc = rpmtdCount(&bn); fi->dc = rpmtdCount(&dn); fi->bnid = rpmtdToPool(&bn, fi->pool); fi->dnid = rpmtdToPool(&dn, fi->pool); /* steal index data from the td (pooh...) */ fi->dil = dx.data; dx.data = NULL; /* populate the rest of the stuff */ rpmfiPopulate(fi, h, flags); /* freeze the pool to save memory, but only if private pool */ if (fi->pool != pool) rpmstrPoolFreeze(fi->pool, 0); fi->h = (fi->fiflags & RPMFI_KEEPHEADER) ? headerLink(h) : NULL; } else { /* broken data, free and return NULL */ fi = _free(fi); } rpmtdFreeData(&bn); rpmtdFreeData(&dn); rpmtdFreeData(&dx); } return rpmfiLink(fi); }
/** * Print package size (debug purposes only) * @param fd package file handle * @param sigh signature header */ static void printSize(FD_t fd, Header sigh) { struct stat st; int fdno = Fileno(fd); size_t siglen = headerSizeof(sigh, HEADER_MAGIC_YES); size_t pad = (8 - (siglen % 8)) % 8; /* 8-byte pad */ struct rpmtd_s sizetag; rpm_loff_t datalen = 0; /* Print package component sizes. */ if (headerGet(sigh, RPMSIGTAG_LONGSIZE, &sizetag, HEADERGET_DEFAULT)) { rpm_loff_t *tsize = rpmtdGetUint64(&sizetag); datalen = (tsize) ? *tsize : 0; } else if (headerGet(sigh, RPMSIGTAG_SIZE, &sizetag, HEADERGET_DEFAULT)) { rpm_off_t *tsize = rpmtdGetUint32(&sizetag); datalen = (tsize) ? *tsize : 0; } rpmtdFreeData(&sizetag); rpmlog(RPMLOG_DEBUG, "Expected size: %12" PRIu64 \ " = lead(%d)+sigs(%zd)+pad(%zd)+data(%" PRIu64 ")\n", RPMLEAD_SIZE+siglen+pad+datalen, RPMLEAD_SIZE, siglen, pad, datalen); if (fstat(fdno, &st) == 0) { rpmlog(RPMLOG_DEBUG, " Actual size: %12" PRIu64 "\n", (rpm_loff_t) st.st_size); } }
static int isNewDep(rpmds *dsp, rpmds bds, Header h, rpmTagVal indextag, uint32_t index) { int isnew = 1; if (!indextag) { /* With normal deps, we can just merge and see if anything got added */ isnew = (rpmdsMerge(dsp, bds) > 0); } else { struct rpmtd_s idx; rpmds ads = *dsp; headerGet(h, indextag, &idx, HEADERGET_MINMEM); /* rpmdsFind/Merge() probably isn't realiable with triggers... */ rpmdsInit(ads); while (isnew && rpmdsNext(ads) >= 0) { if (!rstreq(rpmdsN(ads), rpmdsN(bds))) continue; if (!rstreq(rpmdsEVR(ads), rpmdsEVR(bds))) continue; if (rpmdsFlags(ads) != rpmdsFlags(bds)) continue; if (indextag && rpmtdSetIndex(&idx, rpmdsIx(ads)) >= 0 && rpmtdGetNumber(&idx) != index) continue; isnew = 0; } rpmtdFreeData(&idx); rpmdsMerge(dsp, bds); } return isnew; }
/* * Helper to convert 32bit tag to 64bit version. * If header has new 64bit tag then just return the data, * otherwise convert 32bit old tag data to 64bit values. * For consistency, always return malloced data. */ static int get64(Header h, rpmtd td, rpmTag newtag, rpmTag oldtag) { int rc; if (headerIsEntry(h, newtag)) { rc = headerGet(h, newtag, td, HEADERGET_ALLOC); } else { struct rpmtd_s olddata; uint32_t *d32 = NULL; uint64_t *d64 = NULL; headerGet(h, oldtag, &olddata, HEADERGET_MINMEM); if (rpmtdType(&olddata) == RPM_INT32_TYPE) { td->type = RPM_INT64_TYPE; td->count = olddata.count; td->flags = RPMTD_ALLOCED; td->data = xmalloc(sizeof(*d64) * td->count); d64 = td->data; while ((d32 = rpmtdNextUint32(&olddata))) { *d64++ = *d32; } } rpmtdFreeData(&olddata); rc = d64 ? 1 : 0; } return rc; }
/** * Define or undefine per-header macros. * @param h header * @param define define/undefine? * @return 0 always */ static void rpmInstallLoadMacros(Header h, int define) { const struct tagMacro * tagm; for (tagm = tagMacros; tagm->macroname != NULL; tagm++) { struct rpmtd_s td; char *body; if (!headerGet(h, tagm->tag, &td, HEADERGET_DEFAULT)) continue; /* * Undefine doesn't need the actual data for anything, but * this way ensures we only undefine what was defined earlier. */ switch (rpmtdType(&td)) { default: if (define) { body = rpmtdFormat(&td, RPMTD_FORMAT_STRING, NULL); addMacro(NULL, tagm->macroname, NULL, body, -1); free(body); } else { delMacro(NULL, tagm->macroname); } break; case RPM_NULL_TYPE: break; } rpmtdFreeData(&td); } }
/* * Source rpms only contain basenames, on install the full paths are * constructed with %{_specdir} and %{_sourcedir} macros. Because * of that regular relocation wont work, we need to do it the hard * way. Return spec file index on success, -1 on errors. */ int rpmRelocateSrpmFileList(Header h, const char *rootDir) { int specix = headerFindSpec(h); if (specix >= 0) { const char *bn; struct rpmtd_s filenames; /* save original file names */ saveOrig(h); headerDel(h, RPMTAG_BASENAMES); headerDel(h, RPMTAG_DIRNAMES); headerDel(h, RPMTAG_DIRINDEXES); /* Macros need to be added before trying to create directories */ rpmInstallLoadMacros(h, 1); /* ALLOC is needed as we modify the header */ headerGet(h, RPMTAG_ORIGBASENAMES, &filenames, HEADERGET_ALLOC); for (int i = 0; (bn = rpmtdNextString(&filenames)); i++) { int spec = (i == specix); char *fn = rpmGenPath(rootDir, spec ? "%{_specdir}" : "%{_sourcedir}", bn); headerPutString(h, RPMTAG_OLDFILENAMES, fn); free(fn); } rpmtdFreeData(&filenames); headerConvert(h, HEADERCONV_COMPRESSFILELIST); rpmInstallLoadMacros(h, 0); } return specix; }
/** * Retrieve trigger type info. * @param h header * @retval td tag data container * @return 1 on success */ static int triggertypeTag(Header h, rpmtd td, headerGetFlags hgflags) { int i; char ** conds; struct rpmtd_s indices, flags, scripts; if (!headerGet(h, RPMTAG_TRIGGERINDEX, &indices, HEADERGET_MINMEM)) { return 0; } headerGet(h, RPMTAG_TRIGGERFLAGS, &flags, HEADERGET_MINMEM); headerGet(h, RPMTAG_TRIGGERSCRIPTS, &scripts, HEADERGET_MINMEM); td->flags = RPMTD_ALLOCED | RPMTD_PTR_ALLOCED; td->count = rpmtdCount(&scripts); td->data = conds = xmalloc(sizeof(*conds) * td->count); td->type = RPM_STRING_ARRAY_TYPE; while ((i = rpmtdNext(&scripts)) >= 0) { rpm_flag_t *flag; rpmtdInit(&indices); rpmtdInit(&flags); while (rpmtdNext(&indices) >= 0 && rpmtdNext(&flags) >= 0) { if (*rpmtdGetUint32(&indices) != i) continue; flag = rpmtdGetUint32(&flags); if (*flag & RPMSENSE_TRIGGERPREIN) conds[i] = xstrdup("prein"); else if (*flag & RPMSENSE_TRIGGERIN) conds[i] = xstrdup("in"); else if (*flag & RPMSENSE_TRIGGERUN) conds[i] = xstrdup("un"); else if (*flag & RPMSENSE_TRIGGERPOSTUN) conds[i] = xstrdup("postun"); else conds[i] = xstrdup(""); break; } } rpmtdFreeData(&indices); rpmtdFreeData(&flags); rpmtdFreeData(&scripts); return 1; }
/** \ingroup py_c */ static void rpmtd_dealloc(rpmtdObject * s) { if (s) { rpmtdFreeData(s->td); rpmtdFree(s->td); PyObject_Del(s); } }
rpmds rpmdsNewPool(rpmstrPool pool, Header h, rpmTagVal tagN, int flags) { rpmTagVal tagEVR, tagF, tagTi; rpmds ds = NULL; const char * Type; struct rpmtd_s names; if (dsType(tagN, &Type, &tagEVR, &tagF, &tagTi)) goto exit; if (headerGet(h, tagN, &names, HEADERGET_MINMEM)) { struct rpmtd_s evr, flags, tindices; ds = rpmdsCreate(pool, tagN, Type, rpmtdCount(&names), headerGetInstance(h)); ds->N = rpmtdToPool(&names, ds->pool); headerGet(h, tagEVR, &evr, HEADERGET_MINMEM); ds->EVR = rpmtdToPool(&evr, ds->pool); headerGet(h, tagF, &flags, HEADERGET_ALLOC); ds->Flags = flags.data; if (tagTi != RPMTAG_NOT_FOUND) { headerGet(h, tagTi, &tindices, HEADERGET_ALLOC); ds->ti = tindices.data; } /* ensure rpmlib() requires always have RPMSENSE_RPMLIB flag set */ if (tagN == RPMTAG_REQUIRENAME && ds->Flags) { for (int i = 0; i < ds->Count; i++) { if (!(rpmdsFlagsIndex(ds, i) & RPMSENSE_RPMLIB)) { const char *N = rpmdsNIndex(ds, i); if (rstreqn(N, "rpmlib(", sizeof("rpmlib(")-1)) ds->Flags[i] |= RPMSENSE_RPMLIB; } } } rpmtdFreeData(&names); rpmtdFreeData(&evr); /* freeze the pool to save memory, but only if private pool */ if (ds->pool != pool) rpmstrPoolFreeze(ds->pool, 0); } exit: return ds; }
/** * Run triggers from this header that are fired by headers in the database. * @param psm package state machine data * @param sense trigger type * @return 0 on success */ static rpmRC runImmedTriggers(rpmpsm psm, rpmsenseFlags sense) { const rpmts ts = psm->ts; unsigned char * triggersRun; struct rpmtd_s tnames, tindexes; Header h = rpmteHeader(psm->te); int nerrors = 0; if (!(headerGet(h, RPMTAG_TRIGGERNAME, &tnames, HEADERGET_MINMEM) && headerGet(h, RPMTAG_TRIGGERINDEX, &tindexes, HEADERGET_MINMEM))) { goto exit; } triggersRun = xcalloc(rpmtdCount(&tindexes), sizeof(*triggersRun)); { Header sourceH = NULL; const char *trigName; rpm_count_t *triggerIndices = tindexes.data; while ((trigName = rpmtdNextString(&tnames))) { rpmdbMatchIterator mi; int i = rpmtdGetIndex(&tnames); if (triggersRun[triggerIndices[i]] != 0) continue; mi = rpmtsInitIterator(ts, RPMDBI_NAME, trigName, 0); while((sourceH = rpmdbNextIterator(mi)) != NULL) { nerrors += handleOneTrigger(psm->ts, psm->te, sense, sourceH, h, psm->countCorrection, rpmdbGetIteratorCount(mi), triggersRun); } rpmdbFreeIterator(mi); } } rpmtdFreeData(&tnames); rpmtdFreeData(&tindexes); free(triggersRun); exit: headerFree(h); return (nerrors == 0) ? RPMRC_OK : RPMRC_FAIL; }
static void saveOrig(Header h) { struct rpmtd_s td; headerGet(h, RPMTAG_BASENAMES, &td, HEADERGET_MINMEM); rpmtdSetTag(&td, RPMTAG_ORIGBASENAMES); headerPut(h, &td, HEADERPUT_DEFAULT); rpmtdFreeData(&td); headerGet(h, RPMTAG_DIRNAMES, &td, HEADERGET_MINMEM); rpmtdSetTag(&td, RPMTAG_ORIGDIRNAMES); headerPut(h, &td, HEADERPUT_DEFAULT); rpmtdFreeData(&td); headerGet(h, RPMTAG_DIRINDEXES, &td, HEADERGET_MINMEM); rpmtdSetTag(&td, RPMTAG_ORIGDIRINDEXES); headerPut(h, &td, HEADERPUT_DEFAULT); rpmtdFreeData(&td); }
static rpmsid * tag2pool(rpmstrPool pool, Header h, rpmTag tag) { rpmsid *sids = NULL; struct rpmtd_s td; if (headerGet(h, tag, &td, HEADERGET_MINMEM)) { sids = rpmtdToPool(&td, pool); rpmtdFreeData(&td); } return sids; }
static int makeHDRDigest(Header sigh, const char * file, rpmTagVal sigTag) { Header h = NULL; FD_t fd = NULL; char * SHA1 = NULL; int ret = -1; /* assume failure. */ switch (sigTag) { case RPMSIGTAG_SHA1: fd = Fopen(file, "r.fdio"); if (fd == NULL || Ferror(fd)) goto exit; h = headerRead(fd, HEADER_MAGIC_YES); if (h == NULL) goto exit; if (headerIsEntry(h, RPMTAG_HEADERIMMUTABLE)) { DIGEST_CTX ctx; struct rpmtd_s utd; if (!headerGet(h, RPMTAG_HEADERIMMUTABLE, &utd, HEADERGET_DEFAULT) || utd.data == NULL) { rpmlog(RPMLOG_ERR, _("Immutable header region could not be read. " "Corrupted package?\n")); goto exit; } ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE); (void) rpmDigestUpdate(ctx, rpm_header_magic, sizeof(rpm_header_magic)); (void) rpmDigestUpdate(ctx, utd.data, utd.count); (void) rpmDigestFinal(ctx, (void **)&SHA1, NULL, 1); rpmtdFreeData(&utd); } else { rpmlog(RPMLOG_ERR, _("Cannot sign RPM v3 packages\n")); goto exit; } if (SHA1 == NULL) goto exit; if (!sighdrPut(sigh, RPMSIGTAG_SHA1, RPM_STRING_TYPE, SHA1, 1)) goto exit; ret = 0; break; default: break; } exit: free(SHA1); headerFree(h); if (fd != NULL) (void) Fclose(fd); return ret; }
/** * Retrieve signature from header tag * @param sigh signature header * @param sigtag signature tag * @return parsed pgp dig or NULL */ static pgpDigParams getSig(Header sigh, rpmTagVal sigtag) { struct rpmtd_s pkt; pgpDigParams sig = NULL; if (headerGet(sigh, sigtag, &pkt, HEADERGET_DEFAULT) && pkt.data != NULL) { pgpPrtParams(pkt.data, pkt.count, PGPTAG_SIGNATURE, &sig); rpmtdFreeData(&pkt); } return sig; }
static PyObject * hdrGetTag(Header h, rpmTagVal tag) { PyObject *res = NULL; struct rpmtd_s td; /* rpmtd_AsPyObj() knows how to handle empty containers and all */ (void) headerGet(h, tag, &td, HEADERGET_EXT); res = rpmtd_AsPyobj(&td); rpmtdFreeData(&td); return res; }
/* * Up to rpm 3.0.4, packages implicitly provided their own name-version-release. * Retrofit an explicit "Provides: name = epoch:version-release. */ static void providePackageNVR(Header h) { const char *name = headerGetString(h, RPMTAG_NAME); char *pEVR = headerGetAsString(h, RPMTAG_EVR); rpmsenseFlags pFlags = RPMSENSE_EQUAL; int bingo = 1; struct rpmtd_s pnames; rpmds hds, nvrds; /* Generate provides for this package name-version-release. */ if (!(name && pEVR)) return; /* * Rpm prior to 3.0.3 does not have versioned provides. * If no provides at all are available, we can just add. */ if (!headerGet(h, RPMTAG_PROVIDENAME, &pnames, HEADERGET_MINMEM)) { goto exit; } /* * Otherwise, fill in entries on legacy packages. */ if (!headerIsEntry(h, RPMTAG_PROVIDEVERSION)) { while (rpmtdNext(&pnames) >= 0) { rpmsenseFlags fdummy = RPMSENSE_ANY; headerPutString(h, RPMTAG_PROVIDEVERSION, ""); headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &fdummy, 1); } goto exit; } /* see if we already have this provide */ hds = rpmdsNew(h, RPMTAG_PROVIDENAME, 0); nvrds = rpmdsSingle(RPMTAG_PROVIDENAME, name, pEVR, pFlags); if (rpmdsFind(hds, nvrds) >= 0) { bingo = 0; } rpmdsFree(hds); rpmdsFree(nvrds); exit: if (bingo) { headerPutString(h, RPMTAG_PROVIDENAME, name); headerPutString(h, RPMTAG_PROVIDEVERSION, pEVR); headerPutUint32(h, RPMTAG_PROVIDEFLAGS, &pFlags, 1); } rpmtdFreeData(&pnames); free(pEVR); }
static int depContainsTilde(Header h, rpmTagVal tagEVR) { struct rpmtd_s evrs; const char *evr = NULL; if (headerGet(h, tagEVR, &evrs, HEADERGET_MINMEM)) { while ((evr = rpmtdNextString(&evrs)) != NULL) if (strchr(evr, '~')) break; rpmtdFreeData(&evrs); } return evr != NULL; }
uint64_t headerGetNumber(Header h, rpmTag tag) { uint64_t res = 0; struct rpmtd_s td; if (headerGet(h, tag, &td, HEADERGET_EXT)) { if (rpmtdCount(&td) == 1) { res = rpmtdGetNumber(&td); } rpmtdFreeData(&td); } return res; }
const char * headerGetString(Header h, rpmTag tag) { const char *res = NULL; struct rpmtd_s td; if (headerGet(h, tag, &td, HEADERGET_MINMEM)) { if (rpmtdCount(&td) == 1) { res = rpmtdGetString(&td); } rpmtdFreeData(&td); } return res; }
char * headerGetAsString(Header h, rpmTag tag) { char *res = NULL; struct rpmtd_s td; if (headerGet(h, tag, &td, HEADERGET_EXT)) { if (rpmtdCount(&td) == 1) { res = rpmtdFormat(&td, RPMTD_FORMAT_STRING, NULL); } rpmtdFreeData(&td); } return res; }
static void saveRelocs(Header h, rpmtd bnames, rpmtd dnames, rpmtd dindexes) { struct rpmtd_s td; headerGet(h, RPMTAG_BASENAMES, &td, HEADERGET_MINMEM); rpmtdSetTag(&td, RPMTAG_ORIGBASENAMES); headerPut(h, &td, HEADERPUT_DEFAULT); rpmtdFreeData(&td); headerGet(h, RPMTAG_DIRNAMES, &td, HEADERGET_MINMEM); rpmtdSetTag(&td, RPMTAG_ORIGDIRNAMES); headerPut(h, &td, HEADERPUT_DEFAULT); rpmtdFreeData(&td); headerGet(h, RPMTAG_DIRINDEXES, &td, HEADERGET_MINMEM); rpmtdSetTag(&td, RPMTAG_ORIGDIRINDEXES); headerPut(h, &td, HEADERPUT_DEFAULT); rpmtdFreeData(&td); headerMod(h, bnames); headerMod(h, dnames); headerMod(h, dindexes); }
static void initSourceHeader(rpmSpec spec) { Package sourcePkg = spec->sourcePackage; struct Source *srcPtr; if (headerIsEntry(sourcePkg->header, RPMTAG_NAME)) return; /* Only specific tags are added to the source package header */ headerCopyTags(spec->packages->header, sourcePkg->header, sourceTags); /* Add the build restrictions */ for (int i=0; i<PACKAGE_NUM_DEPS; i++) { rpmdsPutToHeader(sourcePkg->dependencies[i], sourcePkg->header); } { HeaderIterator hi = headerInitIterator(spec->buildRestrictions); struct rpmtd_s td; while (headerNext(hi, &td)) { if (rpmtdCount(&td) > 0) { (void) headerPut(sourcePkg->header, &td, HEADERPUT_DEFAULT); } rpmtdFreeData(&td); } headerFreeIterator(hi); } if (spec->BANames && spec->BACount > 0) { headerPutStringArray(sourcePkg->header, RPMTAG_BUILDARCHS, spec->BANames, spec->BACount); } /* Add tags for sources and patches */ for (srcPtr = spec->sources; srcPtr != NULL; srcPtr = srcPtr->next) { if (srcPtr->flags & RPMBUILD_ISSOURCE) { headerPutString(sourcePkg->header, RPMTAG_SOURCE, srcPtr->source); if (srcPtr->flags & RPMBUILD_ISNO) { headerPutUint32(sourcePkg->header, RPMTAG_NOSOURCE, &srcPtr->num, 1); } } if (srcPtr->flags & RPMBUILD_ISPATCH) { headerPutString(sourcePkg->header, RPMTAG_PATCH, srcPtr->source); if (srcPtr->flags & RPMBUILD_ISNO) { headerPutUint32(sourcePkg->header, RPMTAG_NOPATCH, &srcPtr->num, 1); } } } }
static int headercolorTag(Header h, rpmtd td, headerGetFlags hgflags) { rpm_color_t *fcolor, hcolor = 0; struct rpmtd_s fcolors; headerGet(h, RPMTAG_FILECOLORS, &fcolors, HEADERGET_MINMEM); while ((fcolor = rpmtdNextUint32(&fcolors)) != NULL) { hcolor |= *fcolor; } rpmtdFreeData(&fcolors); hcolor &= 0x0f; return numberTag(td, hcolor); }
static int haveLangTag(Header h, rpmTagVal tag, const char *lang) { int rc = 0; /* assume tag not present */ int langNum = -1; if (lang && *lang) { /* See if the language is in header i18n table */ struct rpmtd_s langtd; const char *s = NULL; headerGet(h, RPMTAG_HEADERI18NTABLE, &langtd, HEADERGET_MINMEM); while ((s = rpmtdNextString(&langtd)) != NULL) { if (rstreq(s, lang)) { langNum = rpmtdGetIndex(&langtd); break; } } rpmtdFreeData(&langtd); } else { /* C locale */ langNum = 0; } /* If locale is present, check the actual tag content */ if (langNum >= 0) { struct rpmtd_s td; headerGet(h, tag, &td, HEADERGET_MINMEM|HEADERGET_RAW); if (rpmtdSetIndex(&td, langNum) == langNum) { const char *s = rpmtdGetString(&td); /* non-empty string means a dupe */ if (s && *s) rc = 1; } rpmtdFreeData(&td); }; return rc; }
/* Helper to push header tag data into a string cache */ static scidx_t *cacheTag(strcache cache, Header h, rpmTag tag) { scidx_t *idx = NULL; struct rpmtd_s td; if (headerGet(h, tag, &td, HEADERGET_MINMEM)) { idx = xmalloc(sizeof(*idx) * rpmtdCount(&td)); int i = 0; const char *str; while ((str = rpmtdNextString(&td))) { idx[i++] = strcachePut(cache, str); } rpmtdFreeData(&td); } return idx; }