示例#1
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;
}
示例#2
0
文件: depends.c 项目: OlegGirko/rpm
/**
 * 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;
}