/** * Ensure that current package is newer than installed package. * @param ts transaction set * @param p current transaction element * @param h installed header * @return 0 if not newer, 1 if okay */ static int ensureOlder(rpmts ts, const rpmte p, const Header h) { rpmsenseFlags reqFlags = (RPMSENSE_LESS | RPMSENSE_EQUAL); rpmds req; int rc; if (p == NULL || h == NULL) return 1; req = rpmdsSingle(RPMTAG_REQUIRENAME, rpmteN(p), rpmteEVR(p), reqFlags); rc = rpmdsNVRMatchesDep(h, req, _rpmds_nopromote); req = rpmdsFree(req); if (rc == 0) { rpmps ps = rpmtsProblems(ts); char * altNEVR = headerGetNEVRA(h, NULL); rpmpsAppend(ps, RPMPROB_OLDPACKAGE, rpmteNEVRA(p), rpmteKey(p), NULL, NULL, altNEVR, 0); altNEVR = _free(altNEVR); ps = rpmpsFree(ps); rc = 1; } else rc = 0; return rc; }
/* * 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); }
/** * Ensure that current package is newer than installed package. * @param p current transaction element * @param h installed header * @param ps problem set */ static void ensureOlder(const rpmte p, const Header h) { rpmsenseFlags reqFlags = (RPMSENSE_LESS | RPMSENSE_EQUAL); rpmds req; req = rpmdsSingle(RPMTAG_REQUIRENAME, rpmteN(p), rpmteEVR(p), reqFlags); if (rpmdsNVRMatchesDep(h, req, _rpmds_nopromote) == 0) { char * altNEVR = headerGetAsString(h, RPMTAG_NEVRA); rpmteAddProblem(p, RPMPROB_OLDPACKAGE, altNEVR, NULL, headerGetInstance(h)); free(altNEVR); } rpmdsFree(req); }
int rpmdsRpmlib(rpmds * dsp, const void * tblp) { const struct rpmlibProvides_s * rltblp = tblp; const struct rpmlibProvides_s * rlp; int rc = 0; if (rltblp == NULL) rltblp = rpmlibProvides; for (rlp = rltblp; rlp->featureName != NULL && rc == 0; rlp++) { rpmds ds = rpmdsSingle(RPMTAG_PROVIDENAME, rlp->featureName, rlp->featureEVR, rlp->featureFlags); rc = rpmdsMerge(dsp, ds); rpmdsFree(ds); } return rc; }
/** \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);; }
rpmRC parseRCPOT(rpmSpec spec, Package pkg, const char *field, rpmTagVal tagN, int index, rpmsenseFlags tagflags) { const char *r, *re, *v, *ve; char *emsg = NULL; char * N = NULL, * EVR = NULL; rpmTagVal nametag = RPMTAG_NOT_FOUND; rpmsenseFlags Flags; rpmRC rc = RPMRC_FAIL; /* assume failure */ switch (tagN) { default: case RPMTAG_REQUIREFLAGS: nametag = RPMTAG_REQUIRENAME; tagflags |= RPMSENSE_ANY; break; case RPMTAG_RECOMMENDFLAGS: nametag = RPMTAG_RECOMMENDNAME; break; case RPMTAG_SUGGESTFLAGS: nametag = RPMTAG_SUGGESTNAME; break; case RPMTAG_SUPPLEMENTFLAGS: nametag = RPMTAG_SUPPLEMENTNAME; break; case RPMTAG_ENHANCEFLAGS: nametag = RPMTAG_ENHANCENAME; break; case RPMTAG_PROVIDEFLAGS: nametag = RPMTAG_PROVIDENAME; break; case RPMTAG_OBSOLETEFLAGS: nametag = RPMTAG_OBSOLETENAME; break; case RPMTAG_CONFLICTFLAGS: nametag = RPMTAG_CONFLICTNAME; break; case RPMTAG_ORDERFLAGS: nametag = RPMTAG_ORDERNAME; break; case RPMTAG_PREREQ: /* XXX map legacy PreReq into Requires(pre,preun) */ nametag = RPMTAG_REQUIRENAME; tagflags |= (RPMSENSE_SCRIPT_PRE|RPMSENSE_SCRIPT_PREUN); break; case RPMTAG_TRIGGERPREIN: nametag = RPMTAG_TRIGGERNAME; tagflags |= RPMSENSE_TRIGGERPREIN; break; case RPMTAG_TRIGGERIN: nametag = RPMTAG_TRIGGERNAME; tagflags |= RPMSENSE_TRIGGERIN; break; case RPMTAG_TRIGGERPOSTUN: nametag = RPMTAG_TRIGGERNAME; tagflags |= RPMSENSE_TRIGGERPOSTUN; break; case RPMTAG_TRIGGERUN: nametag = RPMTAG_TRIGGERNAME; tagflags |= RPMSENSE_TRIGGERUN; break; case RPMTAG_BUILDPREREQ: case RPMTAG_BUILDREQUIRES: nametag = RPMTAG_REQUIRENAME; tagflags |= RPMSENSE_ANY; break; case RPMTAG_BUILDCONFLICTS: nametag = RPMTAG_CONFLICTNAME; break; case RPMTAG_FILETRIGGERIN: nametag = RPMTAG_FILETRIGGERNAME; tagflags |= RPMSENSE_TRIGGERIN; break; case RPMTAG_FILETRIGGERUN: nametag = RPMTAG_FILETRIGGERNAME; tagflags |= RPMSENSE_TRIGGERUN; break; case RPMTAG_FILETRIGGERPOSTUN: nametag = RPMTAG_FILETRIGGERNAME; tagflags |= RPMSENSE_TRIGGERPOSTUN; break; case RPMTAG_TRANSFILETRIGGERIN: nametag = RPMTAG_TRANSFILETRIGGERNAME; tagflags |= RPMSENSE_TRIGGERIN; break; case RPMTAG_TRANSFILETRIGGERUN: nametag = RPMTAG_TRANSFILETRIGGERNAME; tagflags |= RPMSENSE_TRIGGERUN; break; case RPMTAG_TRANSFILETRIGGERPOSTUN: nametag = RPMTAG_TRANSFILETRIGGERNAME; tagflags |= RPMSENSE_TRIGGERPOSTUN; break; } for (r = field; *r != '\0'; r = re) { SKIPWHITE(r); if (*r == '\0') break; Flags = (tagflags & ~RPMSENSE_SENSEMASK); if (r[0] == '(') { struct parseRCPOTRichData data; if (nametag != RPMTAG_REQUIRENAME && nametag != RPMTAG_CONFLICTNAME && nametag != RPMTAG_RECOMMENDNAME && nametag != RPMTAG_SUPPLEMENTNAME && nametag != RPMTAG_SUGGESTNAME && nametag != RPMTAG_ENHANCENAME) { rasprintf(&emsg, _("No rich dependencies allowed for this type")); goto exit; } data.spec = spec; data.sb = newStringBuf(); if (rpmrichParse(&r, &emsg, parseRCPOTRichCB, &data) != RPMRC_OK) { freeStringBuf(data.sb); goto exit; } if (addReqProv(pkg, nametag, getStringBuf(data.sb), NULL, Flags | RPMSENSE_RICH, index)) { rasprintf(&emsg, _("invalid dependency")); freeStringBuf(data.sb); goto exit; } freeStringBuf(data.sb); re = r; continue; } re = r; SKIPNONWHITE(re); N = xmalloc((re-r) + 1); rstrlcpy(N, r, (re-r) + 1); /* Parse EVR */ EVR = NULL; v = re; SKIPWHITE(v); ve = v; SKIPNONWHITE(ve); re = v; /* ==> next token (if no EVR found) starts here */ /* Check for possible logical operator */ if (ve > v) { rpmsenseFlags sense = rpmParseDSFlags(v, ve - v); if (sense) { Flags |= sense; /* now parse EVR */ v = ve; SKIPWHITE(v); ve = v; SKIPNONWHITE(ve); if (*v == '\0' || ve == v) { rasprintf(&emsg, _("Version required")); goto exit; } EVR = xmalloc((ve-v) + 1); rstrlcpy(EVR, v, (ve-v) + 1); re = ve; /* ==> next token after EVR string starts here */ } } /* check that dependency is well-formed */ if (checkDep(spec, N, EVR, &emsg)) goto exit; if (nametag == RPMTAG_FILETRIGGERNAME || nametag == RPMTAG_TRANSFILETRIGGERNAME) { if (N[0] != '/') { rasprintf(&emsg, _("Only absolute paths are allowed in " "file triggers")); } } /* Deny more "normal" triggers fired by the same pakage. File triggers are ok */ if (nametag == RPMTAG_TRIGGERNAME) { rpmds *pdsp = packageDependencies(pkg, nametag); rpmds newds = rpmdsSingle(nametag, N, EVR, Flags); rpmdsInit(*pdsp); while (rpmdsNext(*pdsp) >= 0) { if (rpmdsCompare(*pdsp, newds) && (rpmdsFlags(*pdsp) & tagflags )) { rasprintf(&emsg, _("Trigger fired by the same package " "is already defined in spec file")); break; } } rpmdsFree(newds); if (emsg) goto exit; } if (addReqProv(pkg, nametag, N, EVR, Flags, index)) { rasprintf(&emsg, _("invalid dependency")); goto exit; } N = _free(N); EVR = _free(EVR); } rc = RPMRC_OK; exit: if (emsg) { int lvl = (rc == RPMRC_OK) ? RPMLOG_WARNING : RPMLOG_ERR; /* Automatic dependencies don't relate to spec lines */ if (tagflags & (RPMSENSE_FIND_REQUIRES|RPMSENSE_FIND_PROVIDES)) { rpmlog(lvl, "%s: %s\n", emsg, r); } else { rpmlog(lvl, _("line %d: %s: %s\n"), spec->lineNum, emsg, spec->line); } free(emsg); } _free(N); _free(EVR); return rc; }