コード例 #1
0
ファイル: rpmds.c プロジェクト: PerilousApricot/rpm
rpmRC rpmdsParseRichDep(rpmds dep, rpmds *leftds, rpmds *rightds, rpmrichOp *op, char **emsg)
{
    rpmRC rc;
    struct rpmdsParseRichDepData data;
    const char *depstr = rpmdsN(dep);
    memset(&data, 0, sizeof(data));
    data.dep = dep;
    data.op = RPMRICHOP_SINGLE;
    data.depflags = rpmdsFlags(dep) & ~(RPMSENSE_SENSEMASK | RPMSENSE_RICH | RPMSENSE_MISSINGOK);
    rc = rpmrichParse(&depstr, emsg, rpmdsParseRichDepCB, &data);
    if (rc == RPMRC_OK && *depstr) {
	if (emsg)
	    rasprintf(emsg, _("Junk after rich dependency"));
	rc = RPMRC_FAIL;
    }
    if (rc != RPMRC_OK) {
	rpmdsFree(data.leftds);
	rpmdsFree(data.rightds);
    } else {
	*leftds = data.leftds;
	*rightds = data.rightds;
	*op = data.op;
    }
    return rc;
}
コード例 #2
0
ファイル: rpmtriggers.c プロジェクト: Conan-Kudo/rpm
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);
}
コード例 #3
0
ファイル: legacy.c プロジェクト: OlegGirko/rpm
/*
 * 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);
}
コード例 #4
0
ファイル: rpmte-js.c プロジェクト: hahnakane/junkcode
/* --- Object methods */
static JSBool
rpmte_ds(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
    void * ptr = JS_GetInstancePrivate(cx, obj, &rpmteClass, NULL);
    rpmte te = ptr;
    rpmTag tagN = RPMTAG_NAME;
    JSBool ok = JS_FALSE;

_METHOD_DEBUG_ENTRY(_debug);

    if (!(ok = JS_ConvertArguments(cx, argc, argv, "/i", &tagN)))
        goto exit;
    {	rpmds ds = NULL;
	JSObject *dso = NULL;
	if ((ds = rpmteDS(te, tagN)) == NULL)
	    *rval = JSVAL_NULL;
	else
	if ((dso = JS_NewObject(cx, &rpmdsClass, NULL, NULL)) != NULL
	 && JS_SetPrivate(cx, dso, rpmdsLink(ds, __FUNCTION__)))
	    *rval = OBJECT_TO_JSVAL(dso);
	else {
	    ds = rpmdsFree(ds);
	    *rval = JSVAL_VOID;
	}
    }
    ok = JS_TRUE;
exit:
    return ok;
}
コード例 #5
0
ファイル: transaction.c プロジェクト: xrg/RPM
/**
 * 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;
}
コード例 #6
0
ファイル: spec.c プロジェクト: cmjonze/rpm5_tarballs
static void pkgFini(void * _pkg)
	/*@modifies _pkg @*/
{
    Package pkg = _pkg;

    if (pkg == NULL) return;	/* XXX assert? */
    
    pkg->preInFile = _free(pkg->preInFile);
    pkg->postInFile = _free(pkg->postInFile);
    pkg->preUnFile = _free(pkg->preUnFile);
    pkg->postUnFile = _free(pkg->postUnFile);
    pkg->verifyFile = _free(pkg->verifyFile);
    pkg->sanityCheckFile = _free(pkg->sanityCheckFile);

    (void)headerFree(pkg->header);
    pkg->header = NULL;
    (void)rpmdsFree(pkg->ds);
    pkg->ds = NULL;
    pkg->fileList = rpmiobFree(pkg->fileList);
    pkg->fileFile = _free(pkg->fileFile);
    if (pkg->fi != NULL) {
	rpmfi fi = pkg->fi;
	pkg->fi = NULL;
	fi = rpmfiFree(fi);
    }

    pkg->specialDoc = rpmiobFree(pkg->specialDoc);
    pkg->triggerFiles = freeTriggerFiles(pkg->triggerFiles);
}
コード例 #7
0
ファイル: rpmds-rb.c プロジェクト: hahnakane/junkcode
/* --- Object ctors/dtors */
static void
rpmds_free(rpmds ds)
{
if (_debug)
fprintf(stderr, "==> %s(%p)\n", __FUNCTION__, ds);
    ds = rpmdsFree(ds);
}
コード例 #8
0
ファイル: depends.c プロジェクト: Distrotech/rpm
/* Check a given dependency against installed packages */
static void checkInstDeps(rpmts ts, depCache dcache, rpmte te,
			  rpmTag depTag, const char *dep)
{
    Header h;
    rpmdbMatchIterator mi = rpmtsPrunedIterator(ts, depTag, dep, 1);
    rpmstrPool pool = rpmtsPool(ts);
    /* require-problems are unsatisfied, others appear "satisfied" */
    int is_problem = (depTag == RPMTAG_REQUIRENAME);

    while ((h = rpmdbNextIterator(mi)) != NULL) {
	char * pkgNEVRA;
	rpmds ds;

	/* Ignore self-obsoletes and self-conflicts */
	if (depTag == RPMTAG_OBSOLETENAME || depTag == RPMTAG_CONFLICTNAME) {
	    unsigned int instance = headerGetInstance(h);
	    if (instance && instance == rpmteDBInstance(te))
		continue;
	}

	pkgNEVRA = headerGetAsString(h, RPMTAG_NEVRA);
	ds = rpmdsNewPool(pool, h, depTag, 0);
	rpmdsSetIx(ds, rpmdbGetIteratorFileNum(mi));

	if (unsatisfiedDepend(ts, dcache, ds) == is_problem)
	    rpmteAddDepProblem(te, pkgNEVRA, ds, NULL);

	rpmdsFree(ds);
	free(pkgNEVRA);
    }
    rpmdbFreeIterator(mi);
}
コード例 #9
0
ファイル: rpmds.c プロジェクト: akozumpl/rpm
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;
}
コード例 #10
0
ファイル: tagexts.c プロジェクト: Distrotech/rpm
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);
}
コード例 #11
0
ファイル: rpmds-py.c プロジェクト: pombredanne/rpm-python
/** \ingroup py_c
 */
static void rpmds_free(rpmdsObject * s)
{
    debug("%p -- ds %p\n", s, s->ds);
    s->ds = rpmdsFree(s->ds);

    PyObject_Del((PyObject *)s);
}
コード例 #12
0
ファイル: rpmds-py.c プロジェクト: pombredanne/rpm-python
static void
rpmds_dealloc(rpmdsObject * s)
{
    if (s) {
	s->ds = rpmdsFree(s->ds);
	PyObject_Del(s);
    }
}
コード例 #13
0
ファイル: tagexts.c プロジェクト: Distrotech/rpm
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;
}
コード例 #14
0
ファイル: rpmds.c プロジェクト: akozumpl/rpm
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;
}
コード例 #15
0
ファイル: rpmal.c プロジェクト: Distrotech/rpm
rpmal rpmalFree(rpmal al)
{
    availablePackage alp;
    int i;

    if (al == NULL)
	return NULL;

    if ((alp = al->list) != NULL)
    for (i = 0; i < al->size; i++, alp++) {
	alp->obsoletes = rpmdsFree(alp->obsoletes);
	alp->provides = rpmdsFree(alp->provides);
	alp->fi = rpmfilesFree(alp->fi);
    }
    al->pool = rpmstrPoolFree(al->pool);
    al->list = _free(al->list);
    al->alloced = 0;

    rpmalFreeIndex(al);
    al = _free(al);
    return NULL;
}
コード例 #16
0
ファイル: rpmds.c プロジェクト: akozumpl/rpm
int rpmdsNVRMatchesDep(const Header h, const rpmds req, int nopromote)
{
    rpmds pkg;
    int rc = 1;	/* XXX assume match, names already match here */

    /* Get package information from header */
    pkg = rpmdsThis(h, RPMTAG_PROVIDENAME, RPMSENSE_EQUAL);
    rpmdsSetNoPromote(pkg, nopromote);
    rc = rpmdsCompare(pkg, req);
    rpmdsFree(pkg);

    return rc;
}
コード例 #17
0
ファイル: transaction.c プロジェクト: akozumpl/rpm
/**
 * 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);
}
コード例 #18
0
ファイル: rpmds.c プロジェクト: PerilousApricot/rpm
static rpmRC rpmdsParseRichDepCB(void *cbdata, rpmrichParseType type,
		const char *n, int nl, const char *e, int el, rpmsenseFlags sense,
		rpmrichOp op, char **emsg) {
    struct rpmdsParseRichDepData *data = cbdata;
    rpmds ds = 0;

    if (type == RPMRICH_PARSE_ENTER)
	data->depth++;
    else if (type == RPMRICH_PARSE_LEAVE) {
	if (--data->depth == 0 && data->dochain && data->rightstart) {
	    /* chain op hack, construct a sub-ds from the right side of the chain */
	    char *right = xmalloc(n + nl - data->rightstart + 2);
	    right[0] = '(';
	    strncpy(right + 1, data->rightstart, n + nl - data->rightstart);
	    right[n + nl - data->rightstart + 1] = 0;
	    data->rightds = rpmdsFree(data->rightds);
	    ds = singleDS(data->dep->pool, data->dep->tagN, 0, 0, RPMSENSE_RICH | data->depflags, 0, 0, 0);
	    ds->N[0] = rpmstrPoolId(ds->pool, right, 1);
	    ds->EVR[0] = rpmstrPoolId(ds->pool, "", 1);
	    data->rightds = ds;
	    free(right);
	}
    }
    if (data->depth != 1)
	return RPMRC_OK;	/* we're only interested in top-level parsing */
    if ((type == RPMRICH_PARSE_SIMPLE || type == RPMRICH_PARSE_LEAVE) && !data->dochain) {
	if (type == RPMRICH_PARSE_LEAVE)
	    sense = RPMSENSE_RICH;
	else if (data->dep->tagN == RPMTAG_REQUIRENAME && nl > 7 &&
			 rstreqn(n, "rpmlib(", sizeof("rpmlib(")-1))
	    sense |= RPMSENSE_RPMLIB;
	ds = singleDS(data->dep->pool, data->dep->tagN, 0, 0, sense | data->depflags, 0, 0, 0);
	ds->N[0] = rpmstrPoolIdn(ds->pool, n, nl, 1);
	ds->EVR[0] = rpmstrPoolIdn(ds->pool, e ? e : "", el, 1);
	if (!data->leftds)
	    data->leftds = ds;
	else {
	    data->rightds = ds;
	    data->rightstart = n;
	}
    }
    if (type == RPMRICH_PARSE_OP) {
	if (data->op != RPMRICHOP_SINGLE)
	    data->dochain = 1;	/* this is a chained op */
	else
	    data->op = op;
    }
    return RPMRC_OK;
}
コード例 #19
0
ファイル: psm.c プロジェクト: fingunter/rpm
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;
}
コード例 #20
0
ファイル: rpmds.c プロジェクト: akozumpl/rpm
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;
}
コード例 #21
0
ファイル: depends.c プロジェクト: OlegGirko/rpm
/* Check a given dependency type against installed packages */
static void checkInstDeps(rpmts ts, depCache dcache, rpmte te,
			  rpmTag depTag, const char *dep)
{
    Header h;
    rpmdbMatchIterator mi = rpmtsPrunedIterator(ts, depTag, dep, 1);
    rpmstrPool pool = rpmtsPool(ts);

    while ((h = rpmdbNextIterator(mi)) != NULL) {
	char * pkgNEVRA = headerGetAsString(h, RPMTAG_NEVRA);
	rpmds ds = rpmdsNewPool(pool, h, depTag, 0);

	checkDS(ts, dcache, te, pkgNEVRA, ds, dep, 0);

	rpmdsFree(ds);
	free(pkgNEVRA);
    }
    rpmdbFreeIterator(mi);
}
コード例 #22
0
ファイル: rpmts.c プロジェクト: OlegGirko/rpm
void rpmtsClean(rpmts ts)
{
    rpmtsi pi; rpmte p;
    tsMembers tsmem = rpmtsMembers(ts);

    if (ts == NULL)
	return;

    /* Clean up after dependency checks. */
    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, 0)) != NULL)
	rpmteCleanDS(p);
    rpmtsiFree(pi);

    tsmem->addedPackages = rpmalFree(tsmem->addedPackages);
    tsmem->rpmlib = rpmdsFree(tsmem->rpmlib);

    rpmtsCleanProblems(ts);
}
コード例 #23
0
ファイル: tagexts.c プロジェクト: Distrotech/rpm
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);
}
コード例 #24
0
ファイル: rpmds.c プロジェクト: PerilousApricot/rpm
int rpmdsRpmlibPool(rpmstrPool pool, 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 = rpmdsSinglePool(pool, RPMTAG_PROVIDENAME, rlp->featureName,
			rlp->featureEVR, rlp->featureFlags);
	rc = rpmdsMerge(dsp, ds);
	rpmdsFree(ds);
    }
    /* freeze the pool to save memory, but only if private pool */
    if (*dsp && (*dsp)->pool != pool)
	rpmstrPoolFreeze((*dsp)->pool, 0);
    return (rc < 0) ? -1 : 0;
}
コード例 #25
0
ファイル: reqprov.c プロジェクト: Distrotech/rpm
int addReqProv(Package pkg, rpmTagVal tagN,
		const char * N, const char * EVR, rpmsenseFlags Flags,
		uint32_t index)
{
    rpmds newds, *dsp = NULL;

    dsp = packageDependencies(pkg, tagN);

    /* rpmlib() dependency sanity: only requires permitted, ensure sense bit */
    if (rstreqn(N, "rpmlib(", sizeof("rpmlib(")-1)) {
	if (tagN != RPMTAG_REQUIRENAME) return 1;
	Flags |= RPMSENSE_RPMLIB;
    }

    newds = rpmdsSinglePoolTix(pkg->pool, tagN, N, EVR,
			       rpmSanitizeDSFlags(tagN, Flags), index);

    rpmdsMerge(dsp, newds);
    rpmdsFree(newds);

    return 0;
}
コード例 #26
0
ファイル: rpmds.c プロジェクト: PerilousApricot/rpm
int rpmdsMatches(rpmstrPool pool, Header h, int prix,
		 rpmds req, int selfevr, int nopromote)
{
    rpmds provides;
    rpmTagVal tag = RPMTAG_PROVIDENAME;
    int result = 0;

    /* Get provides information from header */
    if (selfevr)
	provides = rpmdsThisPool(pool, h, tag, RPMSENSE_EQUAL);
    else
	provides = rpmdsNewPool(pool, h, tag, 0);

    rpmdsSetNoPromote(provides, nopromote);

    /*
     * For a self-provide and indexed provide, we only need one comparison.
     * Otherwise loop through the provides until match or end.
     */
    if (prix >= 0 || selfevr) {
	if (prix >= 0)
	    rpmdsSetIx(provides, prix);
	result = rpmdsCompare(provides, req);
    } else {
	provides = rpmdsInit(provides);
	while (rpmdsNext(provides) >= 0) {
	    result = rpmdsCompare(provides, req);
	    /* If this provide matches the require, we're done. */
	    if (result)
		break;
	}
    }

    rpmdsFree(provides);
    return result;
}
コード例 #27
0
ファイル: depends.c プロジェクト: Distrotech/rpm
/**
 * Check dep for an unsatisfied dependency.
 * @param ts		transaction set
 * @param dcache	dependency cache
 * @param dep		dependency
 * @return		0 if satisfied, 1 if not satisfied
 */
static int unsatisfiedDepend(rpmts ts, depCache dcache, rpmds dep)
{
    tsMembers tsmem = rpmtsMembers(ts);
    int rc;
    int retrying = 0;
    int adding = (rpmdsInstance(dep) == 0);
    rpmsenseFlags dsflags = rpmdsFlags(dep);

retry:
    rc = 0;	/* assume dependency is satisfied */

    /*
     * New features in rpm packaging implicitly add versioned dependencies
     * on rpmlib provides. The dependencies look like "rpmlib(YaddaYadda)".
     * Check those dependencies now.
     */
    if (dsflags & RPMSENSE_RPMLIB) {
	if (tsmem->rpmlib == NULL)
	    rpmdsRpmlibPool(rpmtsPool(ts), &(tsmem->rpmlib), NULL);
	
	if (tsmem->rpmlib != NULL && rpmdsSearch(tsmem->rpmlib, dep) >= 0) {
	    rpmdsNotify(dep, "(rpmlib provides)", rc);
	    goto exit;
	}
	goto unsatisfied;
    }

    /* Dont look at pre-requisites of already installed packages */
    if (!adding && isInstallPreReq(dsflags) && !isErasePreReq(dsflags))
	goto exit;

    /* Handle rich dependencies */
    if (rpmdsIsRich(dep)) {
	rpmds ds1, ds2; 
	rpmrichOp op;
	char *emsg = 0; 
	if (rpmdsParseRichDep(dep, &ds1, &ds2, &op, &emsg) != RPMRC_OK) {
	    rc = rpmdsTagN(dep) == RPMTAG_CONFLICTNAME ? 0 : 1;
	    if (rpmdsInstance(dep) != 0)
		rc = !rc;	/* ignore errors for installed packages */
	    rpmdsNotify(dep, emsg ? emsg : "(parse error)", rc);  
	    _free(emsg);
	    goto exit;
	}
	if (op == RPMRICHOP_IF) {
	    if (rpmdsIsRich(ds2)) {
		/* check if this is a IF...ELSE combination */
		rpmds ds21 = NULL, ds22 = NULL;
		rpmrichOp op2;
		if (rpmdsParseRichDep(ds2, &ds21, &ds22, &op2, NULL) == RPMRC_OK && op2 == RPMRICHOP_ELSE) {
		    rc = unsatisfiedDepend(ts, dcache, ds21);
		    if (rc) {
			rpmdsFree(ds1);
			ds1 = ds22;
			ds22 = NULL;
		    }
		    rc = 1;
		}
		rpmdsFree(ds21);
		rpmdsFree(ds22);
	    }
	    if (!rc)
		rc = !unsatisfiedDepend(ts, dcache, ds2);
	}
	if (op != RPMRICHOP_IF || rc)
	    rc = unsatisfiedDepend(ts, dcache, ds1);
	if ((rc && op == RPMRICHOP_OR) || (!rc && op == RPMRICHOP_AND))
	    rc = unsatisfiedDepend(ts, dcache, ds2);
	ds1 = rpmdsFree(ds1);
	ds2 = rpmdsFree(ds2);
	rpmdsNotify(dep, "(rich)", rc);
	goto exit;
    }

    /* Pretrans dependencies can't be satisfied by added packages. */
    if (!(dsflags & RPMSENSE_PRETRANS)) {
	rpmte *matches = rpmalAllSatisfiesDepend(tsmem->addedPackages, dep);
	int match = matches && *matches;
	_free(matches);
	if (match)
	    goto exit;
    }

    /* See if the rpmdb provides it */
    if (rpmdbProvides(ts, dcache, dep) == 0)
	goto exit;

    /* Search for an unsatisfied dependency. */
    if (adding && !retrying && !(dsflags & RPMSENSE_PRETRANS)) {
	int xx = rpmtsSolve(ts, dep);
	if (xx == 0)
	    goto exit;
	if (xx == -1) {
	    retrying = 1;
	    goto retry;
	}
    }

unsatisfied:
    if (dsflags & RPMSENSE_MISSINGOK) {
	/* note the result, but missingok deps are never unsatisfied */
	rpmdsNotify(dep, "(missingok)", 1);
    } else {
	/* dependency is unsatisfied */
	rc = 1;
	rpmdsNotify(dep, NULL, rc);
    }

exit:
    return rc;
}
コード例 #28
0
ファイル: psm.c プロジェクト: fingunter/rpm
/**
 * 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;
}
コード例 #29
0
ファイル: depends.c プロジェクト: Distrotech/rpm
/*
 * Check for previously added versions and obsoletions.
 * Return index where to place this element, or -1 to skip.
 * XXX OBSOLETENAME is a bit of a hack, but gives us what
 * we want from rpmal: we're only interested in added package
 * names here, not their provides.
 */
static int findPos(rpmts ts, rpm_color_t tscolor, rpmte te, int upgrade)
{
    tsMembers tsmem = rpmtsMembers(ts);
    int oc = tsmem->orderCount;
    int skip = 0;
    const char * name = rpmteN(te);
    const char * evr = rpmteEVR(te);
    rpmte p;
    rpmstrPool tspool = rpmtsPool(ts);
    rpmds oldChk = rpmdsSinglePool(tspool, RPMTAG_OBSOLETENAME,
				   name, evr, (RPMSENSE_LESS));
    rpmds newChk = rpmdsSinglePool(tspool, RPMTAG_OBSOLETENAME,
				   name, evr, (RPMSENSE_GREATER));
    rpmds sameChk = rpmdsSinglePool(tspool, RPMTAG_OBSOLETENAME,
				    name, evr, (RPMSENSE_EQUAL));
    rpmds obsChk = rpmteDS(te, RPMTAG_OBSOLETENAME);

    /* If obsoleting package has already been added, skip this. */
    if ((p = checkObsoleted(tsmem->addedPackages, rpmteDS(te, RPMTAG_NAME)))) {
	skip = 1;
	goto exit;
    }

    /* If obsoleted package has already been added, replace with this. */
    rpmdsInit(obsChk);
    while (rpmdsNext(obsChk) >= 0) {
	/* XXX Obsoletes are not colored */
	if ((p = checkAdded(tsmem->addedPackages, 0, te, obsChk))) {
	    goto exit;
	}
    }

    /* If same NEVR has already been added, skip this. */
    if ((p = checkAdded(tsmem->addedPackages, tscolor, te, sameChk))) {
	skip = 1;
	goto exit;
    }

    /* On upgrades... */
    if (upgrade) {
	/* ...if newer NEVR has already been added, skip this. */
	if ((p = checkAdded(tsmem->addedPackages, tscolor, te, newChk))) {
	    skip = 1;
	    goto exit;
	}

	/* ...if older NEVR has already been added, replace with this. */
	if ((p = checkAdded(tsmem->addedPackages, tscolor, te, oldChk))) {
	    goto exit;
	}
    }

exit:
    /* If we found a previous element we've something to say */
    if (p != NULL && rpmIsVerbose()) {
	const char *msg = skip ?
		    _("package %s was already added, skipping %s\n") :
		    _("package %s was already added, replacing with %s\n");
	rpmlog(RPMLOG_WARNING, msg, rpmteNEVRA(p), rpmteNEVRA(te));
    }

    /* If replacing a previous element, find out where it is. Pooh. */
    if (!skip && p != NULL) {
	for (oc = 0; oc < tsmem->orderCount; oc++) {
	    if (p == tsmem->order[oc])
		break;
	}
    }

    rpmdsFree(oldChk);
    rpmdsFree(newChk);
    rpmdsFree(sameChk);
    return (skip) ? -1 : oc;
}
コード例 #30
0
ファイル: rpmtriggers.c プロジェクト: Conan-Kudo/rpm
/*
 * 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;
}