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; }
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 rpmRC addOrAppendListEntry(Header h, rpmTagVal tag, const char * line) { int xx; int argc; const char **argv; if ((xx = poptParseArgvString(line, &argc, &argv))) { rpmlog(RPMLOG_ERR, _("Error parsing tag field: %s\n"), poptStrerror(xx)); return RPMRC_FAIL; } if (argc) headerPutStringArray(h, tag, argv, argc); argv = _free(argv); return RPMRC_OK; }
static void compressFilelist(Header h) { struct rpmtd_s fileNames; char ** dirNames; const char ** baseNames; uint32_t * dirIndexes; rpm_count_t count; int i; 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)) { headerDel(h, RPMTAG_OLDFILENAMES); return; /* Already converted. */ } if (!headerGet(h, RPMTAG_OLDFILENAMES, &fileNames, HEADERGET_MINMEM)) return; count = rpmtdCount(&fileNames); if (count < 1) return; dirNames = xmalloc(sizeof(*dirNames) * count); /* worst case */ baseNames = xmalloc(sizeof(*dirNames) * count); dirIndexes = xmalloc(sizeof(*dirIndexes) * count); /* HACK. Source RPM, so just do things differently */ { const char *fn = rpmtdGetString(&fileNames); if (fn && *fn != '/') { dirIndex = 0; dirNames[dirIndex] = xstrdup(""); while ((i = rpmtdNext(&fileNames)) >= 0) { dirIndexes[i] = dirIndex; baseNames[i] = rpmtdGetString(&fileNames); } goto exit; } } /* * XXX EVIL HACK, FIXME: * This modifies (and then restores) a const string from rpmtd * through basename retrieved from strrchr() which silently * casts away const on return. */ while ((i = rpmtdNext(&fileNames)) >= 0) { char ** needle; char savechar; char * baseName; size_t len; char *filename = (char *) rpmtdGetString(&fileNames); /* HACK HACK */ if (filename == NULL) /* XXX can't happen */ continue; baseName = strrchr(filename, '/') + 1; len = baseName - filename; needle = dirNames; savechar = *baseName; *baseName = '\0'; if (dirIndex < 0 || (needle = bsearch(&filename, dirNames, dirIndex + 1, sizeof(dirNames[0]), dncmp)) == NULL) { char *s = xmalloc(len + 1); rstrlcpy(s, filename, len + 1); dirIndexes[i] = ++dirIndex; dirNames[dirIndex] = s; } else dirIndexes[i] = needle - dirNames; *baseName = savechar; baseNames[i] = baseName; } exit: if (count > 0) { headerPutUint32(h, RPMTAG_DIRINDEXES, dirIndexes, count); headerPutStringArray(h, RPMTAG_BASENAMES, baseNames, count); headerPutStringArray(h, RPMTAG_DIRNAMES, (const char **) dirNames, dirIndex + 1); } rpmtdFreeData(&fileNames); for (i = 0; i <= dirIndex; i++) { free(dirNames[i]); } free(dirNames); free(baseNames); free(dirIndexes); headerDel(h, RPMTAG_OLDFILENAMES); }