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; }
/** * 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 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; }
static rpmRC writeModuleToHeader(ModuleRec mod, Package pkg) { rpmRC rc = RPMRC_FAIL; ARGV_t av; uint32_t count; struct rpmtd_s policies; struct rpmtd_s policynames; struct rpmtd_s policyflags; struct rpmtd_s policytypes; struct rpmtd_s policytypesidx; rpmtdReset(&policies); rpmtdReset(&policynames); rpmtdReset(&policyflags); rpmtdReset(&policytypes); rpmtdReset(&policytypesidx); if (!mod || !pkg) { goto exit; } /* check for duplicates */ if (headerIsEntry(pkg->header, RPMTAG_POLICYNAMES)) { int typeCount; const char *name; char *type; int i; int idx; headerGet(pkg->header, RPMTAG_POLICYNAMES, &policynames, HEADERGET_MINMEM); headerGet(pkg->header, RPMTAG_POLICYFLAGS, &policyflags, HEADERGET_ARGV | HEADERGET_MINMEM); headerGet(pkg->header, RPMTAG_POLICYTYPES, &policytypes, HEADERGET_ARGV | HEADERGET_MINMEM); headerGet(pkg->header, RPMTAG_POLICYTYPESINDEXES, &policytypesidx, HEADERGET_ARGV | HEADERGET_MINMEM); typeCount = rpmtdCount(&policytypes); while ((name = rpmtdNextString(&policynames))) { int overlappingtypes = 0; idx = rpmtdGetIndex(&policynames); for (i = 0; i < typeCount; i++) { if (((int *) policytypesidx.data)[i] != idx) { continue; } type = ((char **) policytypes.data)[i]; if (rstreq(type, RPMPOL_TYPE_DEFAULT) || argvSearch(mod->types, type, NULL) || argvSearch(mod->types, RPMPOL_TYPE_DEFAULT, NULL)) { overlappingtypes = 1; break; } } if (!overlappingtypes) { continue; } if (rstreq(mod->name, name)) { rpmlog(RPMLOG_ERR, _("Policy module '%s' duplicated with overlapping types\n"), name); goto exit; } if ((mod->flags && RPMPOL_FLAG_BASE) && (((int *) policyflags.data)[idx] & RPMPOL_FLAG_BASE)) { rpmlog(RPMLOG_ERR, _("Base modules '%s' and '%s' have overlapping types\n"), mod->name, name); goto exit; } } } if (headerIsEntry(pkg->header, RPMTAG_POLICIES)) { if (!headerGet(pkg->header, RPMTAG_POLICIES, &policies, HEADERGET_MINMEM)) { rpmlog(RPMLOG_ERR, _("Failed to get policies from header\n")); goto exit; } count = rpmtdCount(&policies); } else { count = 0; } /* save everything to the header */ headerPutString(pkg->header, RPMTAG_POLICIES, mod->data); headerPutString(pkg->header, RPMTAG_POLICYNAMES, mod->name); headerPutUint32(pkg->header, RPMTAG_POLICYFLAGS, &mod->flags, 1); for (av = mod->types; av && *av; av++) { headerPutString(pkg->header, RPMTAG_POLICYTYPES, *av); headerPutUint32(pkg->header, RPMTAG_POLICYTYPESINDEXES, &count, 1); } rc = RPMRC_OK; exit: rpmtdFreeData(&policies); rpmtdFreeData(&policynames); rpmtdFreeData(&policyflags); rpmtdFreeData(&policytypes); rpmtdFreeData(&policytypesidx); return rc; }
rpmRC rpmInstallSourcePackage(rpmts ts, FD_t fd, char ** specFilePtr, char ** cookie) { rpmfi fi = NULL; char * specFile = NULL; const char *rootdir = rpmtsRootDir(ts); Header h = NULL; rpmpsm psm = NULL; rpmte te = NULL; rpmRC rpmrc; int specix = -1; struct rpmtd_s filenames; rpmtdReset(&filenames); rpmrc = rpmReadPackageFile(ts, fd, NULL, &h); switch (rpmrc) { case RPMRC_NOTTRUSTED: case RPMRC_NOKEY: case RPMRC_OK: break; default: goto exit; break; } if (h == NULL) goto exit; rpmrc = RPMRC_FAIL; /* assume failure */ if (!headerIsSource(h)) { rpmlog(RPMLOG_ERR, _("source package expected, binary found\n")); goto exit; } /* src.rpm install can require specific rpmlib features, check them */ if (!rpmlibDeps(h)) goto exit; if (headerGet(h, RPMTAG_BASENAMES, &filenames, HEADERGET_ALLOC)) { struct rpmtd_s td; const char *str; const char *_cookie = headerGetString(h, RPMTAG_COOKIE); if (cookie && _cookie) *cookie = xstrdup(_cookie); /* Try to find spec by file flags */ if (_cookie && headerGet(h, RPMTAG_FILEFLAGS, &td, HEADERGET_MINMEM)) { rpmfileAttrs *flags; while (specix < 0 && (flags = rpmtdNextUint32(&td))) { if (*flags & RPMFILE_SPECFILE) specix = rpmtdGetIndex(&td); } } /* Still no spec? Look by filename. */ while (specix < 0 && (str = rpmtdNextString(&filenames))) { if (rpmFileHasSuffix(str, ".spec")) specix = rpmtdGetIndex(&filenames); } } if (rootdir && rstreq(rootdir, "/")) rootdir = NULL; /* Macros need to be added before trying to create directories */ rpmInstallLoadMacros(h); if (specix >= 0) { const char *bn; headerDel(h, RPMTAG_BASENAMES); headerDel(h, RPMTAG_DIRNAMES); headerDel(h, RPMTAG_DIRINDEXES); rpmtdInit(&filenames); for (int i = 0; (bn = rpmtdNextString(&filenames)); i++) { int spec = (i == specix); char *fn = rpmGenPath(rpmtsRootDir(ts), spec ? "%{_specdir}" : "%{_sourcedir}", bn); headerPutString(h, RPMTAG_OLDFILENAMES, fn); if (spec) specFile = xstrdup(fn); free(fn); } headerConvert(h, HEADERCONV_COMPRESSFILELIST); } else { rpmlog(RPMLOG_ERR, _("source package contains no .spec file\n")); goto exit; }; if (rpmtsAddInstallElement(ts, h, NULL, 0, NULL)) { goto exit; } te = rpmtsElement(ts, 0); if (te == NULL) { /* XXX can't happen */ goto exit; } rpmteSetFd(te, fd); rpmteSetHeader(te, h); fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, RPMFI_KEEPHEADER); h = headerFree(h); if (fi == NULL) { goto exit; } fi->apath = filenames.data; /* Ick */ rpmteSetFI(te, fi); fi = rpmfiFree(fi); if (rpmMkdirs(rpmtsRootDir(ts), "%{_topdir}:%{_sourcedir}:%{_specdir}")) { goto exit; } { /* set all files to be installed */ rpmfs fs = rpmteGetFileStates(te); int i; unsigned int fc = rpmfiFC(fi); for (i=0; i<fc; i++) rpmfsSetAction(fs, i, FA_CREATE); } psm = rpmpsmNew(ts, te); psm->goal = PKG_INSTALL; /* FIX: psm->fi->dnl should be owned. */ if (rpmpsmStage(psm, PSM_PROCESS) == RPMRC_OK) rpmrc = RPMRC_OK; (void) rpmpsmStage(psm, PSM_FINI); rpmpsmFree(psm); exit: if (specFilePtr && specFile && rpmrc == RPMRC_OK) *specFilePtr = specFile; else free(specFile); headerFree(h); rpmfiFree(fi); /* XXX nuke the added package(s). */ rpmtsClean(ts); return rpmrc; }
static rpmRC rpmsinfoInit(rpmtd td, const char *origin, struct rpmsinfo_s *sinfo, char **msg) { rpmRC rc = RPMRC_FAIL; const void *data = NULL; const struct vfytag_s *tinfo; const struct vfyinfo_s *vinfo; rpm_count_t dlen = 0; int ix; if ((ix = sinfoLookup(td->tag)) == -1) { /* anything unknown just falls through for now */ rc = RPMRC_OK; goto exit; } vinfo = &rpmvfyitems[ix]; tinfo = &rpmvfytags[ix]; assert(tinfo->tag == vinfo->tag); *sinfo = rpmvfyitems[ix].vi; /* struct assignment */ if (tinfo->tagtype && tinfo->tagtype != td->type) { rasprintf(msg, _("%s tag %u: invalid type %u"), origin, td->tag, td->type); goto exit; } if (tinfo->tagcount && tinfo->tagcount != td->count) { rasprintf(msg, _("%s: tag %u: invalid count %u"), origin, td->tag, td->count); goto exit; } switch (td->type) { case RPM_STRING_TYPE: case RPM_STRING_ARRAY_TYPE: data = rpmtdGetString(td); if (data) dlen = strlen(data); break; case RPM_BIN_TYPE: data = td->data; dlen = td->count; break; } /* MD5 has data length of 16, everything else is (much) larger */ if (sinfo->hashalgo && (data == NULL || dlen < 16)) { rasprintf(msg, _("%s tag %u: invalid data %p (%u)"), origin, td->tag, data, dlen); goto exit; } if (td->type == RPM_STRING_TYPE && td->size == 0) td->size = dlen + 1; if (tinfo->tagsize && (td->flags & RPMTD_IMMUTABLE) && tinfo->tagsize != td->size) { rasprintf(msg, _("%s tag %u: invalid size %u"), origin, td->tag, td->size); goto exit; } if (sinfo->type == RPMSIG_SIGNATURE_TYPE) { if (pgpPrtParams(data, dlen, PGPTAG_SIGNATURE, &sinfo->sig)) { rasprintf(msg, _("%s tag %u: invalid OpenPGP signature"), origin, td->tag); goto exit; } sinfo->hashalgo = pgpDigParamsAlgo(sinfo->sig, PGPVAL_HASHALGO); sinfo->keyid = pgpGrab(sinfo->sig->signid+4, 4); } else if (sinfo->type == RPMSIG_DIGEST_TYPE) { if (td->type == RPM_BIN_TYPE) { sinfo->dig = pgpHexStr(data, dlen); } else { if (!validHex(data, dlen)) { rasprintf(msg, _("%s: tag %u: invalid hex"), origin, td->tag); goto exit; } sinfo->dig = xstrdup(data); } } if (sinfo->hashalgo) sinfo->id = (td->tag << 16) | rpmtdGetIndex(td); rc = RPMRC_OK; exit: return rc; }