Example #1
0
/* Cached rpmdb provide lookup, returns 0 if satisfied, 1 otherwise */
static int rpmdbProvides(rpmts ts, depCache dcache, rpmds dep)
{
    const char * Name = rpmdsN(dep);
    const char * DNEVR = rpmdsDNEVR(dep);
    rpmTagVal deptag = rpmdsTagN(dep);
    int *cachedrc = NULL;
    rpmdbMatchIterator mi = NULL;
    Header h = NULL;
    int rc = 0;
    /* pretrans deps are provided by current packages, don't prune erasures */
    int prune = (rpmdsFlags(dep) & RPMSENSE_PRETRANS) ? 0 : 1;
    unsigned int keyhash = 0;

    /* See if we already looked this up */
    if (prune) {
	keyhash = depCacheKeyHash(dcache, DNEVR);
	if (depCacheGetHEntry(dcache, DNEVR, keyhash, &cachedrc, NULL, NULL)) {
	    rc = *cachedrc;
	    rpmdsNotify(dep, "(cached)", rc);
	    return rc;
	}
    }

    /*
     * See if a filename dependency is a real file in some package,
     * taking file state into account: replaced, wrong colored and
     * not installed files can not satisfy a dependency.
     */
    if (deptag != RPMTAG_OBSOLETENAME && Name[0] == '/') {
	mi = rpmtsPrunedIterator(ts, RPMDBI_INSTFILENAMES, Name, prune);
	while ((h = rpmdbNextIterator(mi)) != NULL) {
	    /* Ignore self-conflicts */
	    if (deptag == RPMTAG_CONFLICTNAME) {
		unsigned int instance = headerGetInstance(h);
		if (instance && instance == rpmdsInstance(dep))
		    continue;
	    }
	    rpmdsNotify(dep, "(db files)", rc);
	    break;
	}
	rpmdbFreeIterator(mi);
    }

    /* Otherwise look in provides no matter what the dependency looks like */
    if (h == NULL) {
	rpmstrPool tspool = rpmtsPool(ts);
	/* Obsoletes use just name alone, everything else uses provides */
	rpmTagVal dbtag = RPMDBI_PROVIDENAME;
	int selfevr = 0;
	if (deptag == RPMTAG_OBSOLETENAME) {
	    dbtag = RPMDBI_NAME;
	    selfevr = 1;
	}

	mi = rpmtsPrunedIterator(ts, dbtag, Name, prune);
	while ((h = rpmdbNextIterator(mi)) != NULL) {
	    /* Provide-indexes can't be used with nevr-only matching */
	    int prix = (selfevr) ? -1 : rpmdbGetIteratorFileNum(mi);
	    int match = rpmdsMatches(tspool, h, prix, dep, selfevr,
					_rpmds_nopromote);
	    /* Ignore self-obsoletes and self-conflicts */
	    if (match && (deptag == RPMTAG_OBSOLETENAME || deptag == RPMTAG_CONFLICTNAME)) {
		unsigned int instance = headerGetInstance(h);
		if (instance && instance == rpmdsInstance(dep))
		    match = 0;
	    }
	    if (match) {
		rpmdsNotify(dep, "(db provides)", rc);
		break;
	    }
	}
	rpmdbFreeIterator(mi);
    }
    rc = (h != NULL) ? 0 : 1;

    /* Cache the relatively expensive rpmdb lookup results */
    /* Caching the oddball non-pruned case would mess up other results */
    if (prune)
	depCacheAddHEntry(dcache, xstrdup(DNEVR), keyhash, rc);
    return rc;
}
Example #2
0
/**
 * 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;
}
Example #3
0
/**
 * Check dep for an unsatisfied dependency.
 * @param ts		transaction set
 * @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;

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

	/*
	 * Handle definitive matches within the added package set.
	 * Self-obsoletes and -conflicts fall through here as we need to 
	 * check for possible other matches in the rpmdb.
	 */
	for (rpmte *m = matches; m && *m; m++) {
	    rpmTagVal dtag = rpmdsTagN(dep);
	    /* Requires match, look no further */
	    if (dtag == RPMTAG_REQUIRENAME) {
		match = 1;
		break;
	    }

	    /* Conflicts/obsoletes match on another package, look no further */
	    if (rpmteDS(*m, dtag) != dep) {
		match = 1;
		break;
	    }
	}
	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;
}