예제 #1
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);
}
예제 #2
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;
}
예제 #3
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;
}
예제 #4
0
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);
}
예제 #5
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;
}
예제 #6
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);
}
예제 #7
0
파일: rpmhdr-rb.c 프로젝트: avokhmin/RPM5
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) );
}
예제 #8
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);
}
예제 #9
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);;
}
예제 #10
0
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);
}
예제 #11
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;
}
예제 #12
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;
}
예제 #13
0
/*
 * 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;
}