static int depnevrsTagFiltered(Header h, rpmtd td, headerGetFlags hgflags, rpmTagVal tag, int strong) { rpmds ds = rpmdsNew(h, tag, 0); int ndeps = rpmdsCount(ds); if (ndeps > 0) { char **deps = xmalloc(sizeof(*deps) * ndeps); ndeps = 0; while (rpmdsNext(ds) >= 0) { if ((rpmdsFlags(ds) & RPMSENSE_STRONG) == (strong ? RPMSENSE_STRONG : 0)) deps[ndeps++] = rpmdsNewDNEVR(NULL, ds); } if (ndeps) { td->data = deps; td->type = RPM_STRING_ARRAY_TYPE; td->count = ndeps; td->flags |= (RPMTD_ALLOCED | RPMTD_PTR_ALLOCED); } else { _free(deps); } } rpmdsFree(ds); return (ndeps > 0); }
int rpmdsAnyMatchesDep (const Header h, const rpmds req, int nopromote) { rpmds provides = NULL; int result = 0; /* Get provides information from header */ provides = rpmdsInit(rpmdsNew(h, RPMTAG_PROVIDENAME, 0)); if (provides == NULL) goto exit; /* XXX should never happen */ (void) rpmdsSetNoPromote(provides, nopromote); while (rpmdsNext(provides) >= 0) { result = rpmdsCompare(provides, req); /* If this provide matches the require, we're done. */ if (result) break; } exit: rpmdsFree(provides); return result; }
static int filedepTag(Header h, rpmTag tagN, rpmtd td, headerGetFlags hgflags) { rpmfi fi = rpmfiNew(NULL, h, RPMTAG_BASENAMES, RPMFI_NOHEADER); rpmds ds = NULL; char **fdeps = NULL; int numfiles; char deptype = 'R'; int fileix; int rc = 0; numfiles = rpmfiFC(fi); if (numfiles <= 0) { goto exit; } if (tagN == RPMTAG_PROVIDENAME) deptype = 'P'; else if (tagN == RPMTAG_REQUIRENAME) deptype = 'R'; ds = rpmdsNew(h, tagN, 0); fdeps = xmalloc(numfiles * sizeof(*fdeps)); while ((fileix = rpmfiNext(fi)) >= 0) { ARGV_t deps = NULL; const uint32_t * ddict = NULL; int ndx = rpmfiFDepends(fi, &ddict); if (ddict != NULL) { while (ndx-- > 0) { const char * DNEVR; unsigned dix = *ddict++; char mydt = ((dix >> 24) & 0xff); if (mydt != deptype) continue; dix &= 0x00ffffff; (void) rpmdsSetIx(ds, dix-1); if (rpmdsNext(ds) < 0) continue; DNEVR = rpmdsDNEVR(ds); if (DNEVR != NULL) { argvAdd(&deps, DNEVR + 2); } } } fdeps[fileix] = deps ? argvJoin(deps, " ") : xstrdup(""); argvFree(deps); } td->data = fdeps; td->count = numfiles; td->flags = RPMTD_ALLOCED | RPMTD_PTR_ALLOCED; td->type = RPM_STRING_ARRAY_TYPE; rc = 1; exit: rpmfiFree(fi); rpmdsFree(ds); return rc; }
void rpmtriggersPrepPostUnTransFileTrigs(rpmts ts, rpmte te) { rpmdbMatchIterator mi; rpmdbIndexIterator ii; Header trigH; const void *key; size_t keylen; rpmfiles files; rpmds rpmdsTriggers; rpmds rpmdsTrigger; int tix = 0; ii = rpmdbIndexIteratorInit(rpmtsGetRdb(ts), RPMDBI_TRANSFILETRIGGERNAME); mi = rpmdbNewIterator(rpmtsGetRdb(ts), RPMDBI_PACKAGES); files = rpmteFiles(te); /* Iterate over file triggers in rpmdb */ while ((rpmdbIndexIteratorNext(ii, &key, &keylen)) == 0) { char pfx[keylen + 1]; memcpy(pfx, key, keylen); pfx[keylen] = '\0'; /* Check if file trigger matches any file in this te */ rpmfi fi = rpmfilesFindPrefix(files, pfx); if (rpmfiFC(fi) > 0) { /* If yes then store it */ rpmdbAppendIterator(mi, rpmdbIndexIteratorPkgOffsets(ii), rpmdbIndexIteratorNumPkgs(ii)); } rpmfiFree(fi); } rpmdbIndexIteratorFree(ii); if (rpmdbGetIteratorCount(mi)) { /* Filter triggers and save only trans postun triggers into ts */ while((trigH = rpmdbNextIterator(mi)) != NULL) { rpmdsTriggers = rpmdsNew(trigH, RPMTAG_TRANSFILETRIGGERNAME, 0); while ((rpmdsTrigger = rpmdsFilterTi(rpmdsTriggers, tix))) { if ((rpmdsNext(rpmdsTrigger) >= 0) && (rpmdsFlags(rpmdsTrigger) & RPMSENSE_TRIGGERPOSTUN)) { struct rpmtd_s priorities; headerGet(trigH, RPMTAG_TRANSFILETRIGGERPRIORITIES, &priorities, HEADERGET_MINMEM); rpmtdSetIndex(&priorities, tix); rpmtriggersAdd(ts->trigs2run, rpmdbGetIteratorOffset(mi), tix, *rpmtdGetUint32(&priorities)); } rpmdsFree(rpmdsTrigger); tix++; } rpmdsFree(rpmdsTriggers); } } rpmdbFreeIterator(mi); }
int rpmdsMatchesDep (const Header h, int ix, const rpmds req, int nopromote) { /* Get provides information from header */ rpmds provides = rpmdsInit(rpmdsNew(h, RPMTAG_PROVIDENAME, 0)); int result = 0; rpmdsSetIx(provides,ix); result = rpmdsCompare(provides, req); rpmdsFree(provides); return result; }
/* * 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 VALUE rpmhdr_ds(int argc, VALUE *argv, VALUE s) { VALUE v_tag; Header h = rpmhdr_ptr(s); rpmTag tag = RPMTAG_PROVIDENAME; int flags = 0; rb_scan_args(argc, argv, "01", &v_tag); if (!NIL_P(v_tag)) tag = FIX2INT(v_tag); if (_debug) fprintf(stderr, "==> %s(0x%lx) h %p\n", __FUNCTION__, s, h); return rpmrbDsWrap( rpmdsNew(h, tag, flags) ); }
static int depnevrsTag(Header h, rpmtd td, headerGetFlags hgflags, rpmTagVal tag) { rpmds ds = rpmdsNew(h, tag, 0); int ndeps = rpmdsCount(ds); if (ndeps > 0) { char **deps = xmalloc(sizeof(*deps) * ndeps); int i; while ((i = rpmdsNext(ds)) >= 0) { deps[i] = rpmdsNewDNEVR(NULL, ds); } td->data = deps; td->type = RPM_STRING_ARRAY_TYPE; td->count = ndeps; td->flags |= (RPMTD_ALLOCED | RPMTD_PTR_ALLOCED); } rpmdsFree(ds); return (ndeps > 0); }
/** \ingroup py_c */ static PyObject * rpmds_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds) { PyObject * po = NULL; PyObject * to = NULL; rpmTag tagN = RPMTAG_REQUIRENAME; rpmsenseFlags flags = RPMSENSE_ANY; rpmds ds = NULL; char * kwlist[] = {"obj", "tag", "flags", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oi:rpmds_init", kwlist, &po, &to, &flags)) { return NULL; } if (to != NULL && (tagN = tagNumFromPyObject(to)) == RPMTAG_NOT_FOUND) { return NULL; } if (PyTuple_Check(po) && PyTuple_Size(po) == 2) { char *n = PyString_AsString(PyTuple_GetItem(po, 0)); char *evr = PyString_AsString(PyTuple_GetItem(po, 1)); if (n && evr) { ds = rpmdsSingle(tagN, n, evr, flags); } } else if (hdrObject_Check(po)) { Header h = hdrGetHeader((hdrObject*) po); if (tagN == RPMTAG_NAME) { ds = rpmdsThis(h, RPMTAG_PROVIDENAME, RPMSENSE_EQUAL); } else { ds = rpmdsNew(h, tagN, flags); } } if (ds == NULL) { PyErr_SetString(PyExc_TypeError, "(n,evr) tuple or header expected"); return NULL; } return rpmds_Wrap(ds);; }
static VALUE rpmds_new(int argc, VALUE *argv, VALUE s) { VALUE v_hdr, v_tag; rpmTag tag = RPMTAG_NAME; int flags = 0; rpmds ds; rb_scan_args(argc, argv, "02", &v_hdr, &v_tag); if (!NIL_P(v_tag)) tag = FIX2INT(v_tag); if (!NIL_P(v_hdr)) { Header h = rpmds_ptr(v_hdr); ds = rpmdsNew(h, tag, flags); } else (void) rpmdsRpmlib(&ds, NULL); if (_debug) fprintf(stderr, "==> %s(%p[%d], 0x%lx) mi %p\n", __FUNCTION__, argv, argc, s, ds); return Data_Wrap_Struct(s, 0, rpmds_free, ds); }
static int rpmlibDeps(Header h) { rpmds req = rpmdsInit(rpmdsNew(h, RPMTAG_REQUIRENAME, 0)); rpmds rpmlib = NULL; rpmdsRpmlib(&rpmlib, NULL); int rc = 1; char *nvr = NULL; while (rpmdsNext(req) >= 0) { if (!(rpmdsFlags(req) & RPMSENSE_RPMLIB)) continue; if (rpmdsSearch(rpmlib, req) < 0) { if (!nvr) { nvr = headerGetAsString(h, RPMTAG_NEVRA); rpmlog(RPMLOG_ERR, _("Missing rpmlib features for %s:\n"), nvr); } rpmlog(RPMLOG_ERR, "\t%s\n", rpmdsDNEVR(req)+2); rc = 0; } } rpmdsFree(req); rpmdsFree(rpmlib); free(nvr); return rc; }
/** * Execute triggers. * @todo Trigger on any provides, not just package NVR. * @param ts transaction set * @param te transaction element * @param sense trigger type * @param sourceH header of trigger source * @param trigH header of triggered package * @param arg2 * @param triggersAlreadyRun * @return */ static rpmRC handleOneTrigger(rpmts ts, rpmte te, rpmsenseFlags sense, Header sourceH, Header trigH, int countCorrection, int arg2, unsigned char * triggersAlreadyRun) { rpmds trigger = rpmdsInit(rpmdsNew(trigH, RPMTAG_TRIGGERNAME, 0)); struct rpmtd_s pfx; const char * sourceName = headerGetString(sourceH, RPMTAG_NAME); const char * triggerName = headerGetString(trigH, RPMTAG_NAME); rpmRC rc = RPMRC_OK; int i; if (trigger == NULL) return rc; headerGet(trigH, RPMTAG_INSTPREFIXES, &pfx, HEADERGET_ALLOC|HEADERGET_ARGV); (void) rpmdsSetNoPromote(trigger, 1); while ((i = rpmdsNext(trigger)) >= 0) { uint32_t tix; if (!(rpmdsFlags(trigger) & sense)) continue; if (!rstreq(rpmdsN(trigger), sourceName)) continue; /* XXX Trigger on any provided dependency, not just the package NEVR */ if (!rpmdsAnyMatchesDep(sourceH, trigger, 1)) continue; tix = rpmdsTi(trigger); if (triggersAlreadyRun == NULL || triggersAlreadyRun[tix] == 0) { int arg1 = rpmdbCountPackages(rpmtsGetRdb(ts), triggerName); if (arg1 < 0) { /* XXX W2DO? fails as "execution of script failed" */ rc = RPMRC_FAIL; } else { rpmScript script = rpmScriptFromTriggerTag(trigH, triggertag(sense), tix); arg1 += countCorrection; rc = runScript(ts, te, pfx.data, script, arg1, arg2); if (triggersAlreadyRun != NULL) triggersAlreadyRun[tix] = 1; rpmScriptFree(script); } } /* * Each target/source header pair can only result in a single * script being run. */ break; } rpmtdFreeData(&pfx); rpmdsFree(trigger); return rc; }
/* * Run all file triggers in header h * @param searchMode 0 match trigger prefixes against files in te * 1 match trigger prefixes against files in whole ts * 2 match trigger prefixes against files in whole * rpmdb */ static int runHandleTriggersInPkg(rpmts ts, rpmte te, Header h, rpmsenseFlags sense, rpmscriptTriggerModes tm, int searchMode, int ti) { int nerrors = 0; rpmds rpmdsTriggers, rpmdsTrigger; rpmfiles files = NULL; matchFilesIter mfi = NULL; rpmScript script; struct rpmtd_s installPrefixes; char *(*inputFunc)(void *); rpmdsTriggers = rpmdsNew(h, triggerDsTag(tm), 0); rpmdsTrigger = rpmdsFilterTi(rpmdsTriggers, ti); /* * Now rpmdsTrigger contains all dependencies belonging to one trigger * with trigger index tix. Have a look at the first one to check flags. */ if ((rpmdsNext(rpmdsTrigger) >= 0) && (rpmdsFlags(rpmdsTrigger) & sense)) { switch (searchMode) { case 0: /* Create iterator over files in te that this trigger matches */ files = rpmteFiles(te); mfi = matchFilesIterator(rpmdsTrigger, files); break; case 1: /* Create iterator over files in ts that this trigger matches */ mfi = matchDBFilesIterator(rpmdsTrigger, ts, 1); break; case 2: /* Create iterator over files in whole rpmd that this trigger matches */ mfi = matchDBFilesIterator(rpmdsTrigger, ts, 0); break; } /* If this trigger matches any file then run trigger script */ if (!matchFilesEmpty(mfi)) { script = rpmScriptFromTriggerTag(h, triggertag(sense), tm, ti); headerGet(h, RPMTAG_INSTPREFIXES, &installPrefixes, HEADERGET_ALLOC|HEADERGET_ARGV); /* * As input function set function to get next file from * matching file iterator. As parameter for this function * set matching file iterator. Input function will be called * during execution of trigger script in order to get data * that will be passed as stdin to trigger script. To get * these data from lua script function rpm.input() can be used. */ inputFunc = (char *(*)(void *)) matchFilesNext; rpmScriptSetNextFileFunc(script, inputFunc, mfi); nerrors += runScript(ts, te, installPrefixes.data, script, 0, 0); rpmtdFreeData(&installPrefixes); rpmScriptFree(script); } rpmfilesFree(files); matchFilesIteratorFree(mfi); } rpmdsFree(rpmdsTrigger); rpmdsFree(rpmdsTriggers); return nerrors; }