Example #1
0
/*
 * For packages being installed:
 * - verify package arch/os.
 * - verify package epoch:version-release is newer.
 */
static rpmps checkProblems(rpmts ts)
{
    rpm_color_t tscolor = rpmtsColor(ts);
    rpmprobFilterFlags probFilter = rpmtsFilterFlags(ts);
    rpmstrPool tspool = rpmtsPool(ts);
    rpmtsi pi = rpmtsiInit(ts);
    rpmte p;

    /* The ordering doesn't matter here */
    /* XXX Only added packages need be checked. */
    rpmlog(RPMLOG_DEBUG, "sanity checking %d elements\n", rpmtsNElements(ts));
    while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {

	if (!(probFilter & RPMPROB_FILTER_IGNOREARCH) && badArch(rpmteA(p)))
	    rpmteAddProblem(p, RPMPROB_BADARCH, rpmteA(p), NULL, 0);

	if (!(probFilter & RPMPROB_FILTER_IGNOREOS) && badOs(rpmteO(p)))
	    rpmteAddProblem(p, RPMPROB_BADOS, rpmteO(p), NULL, 0);

	if (!(probFilter & RPMPROB_FILTER_OLDPACKAGE)) {
	    Header h;
	    rpmdbMatchIterator mi;
	    mi = rpmtsInitIterator(ts, RPMDBI_NAME, rpmteN(p), 0);
	    while ((h = rpmdbNextIterator(mi)) != NULL)
		ensureOlder(tspool, p, h);
	    rpmdbFreeIterator(mi);
	}

	if (!(probFilter & RPMPROB_FILTER_REPLACEPKG)) {
	    Header h;
	    rpmdbMatchIterator mi;
	    mi = rpmtsPrunedIterator(ts, RPMDBI_NAME, rpmteN(p), 1);
	    rpmdbSetIteratorRE(mi, RPMTAG_EPOCH, RPMMIRE_STRCMP, rpmteE(p));
	    rpmdbSetIteratorRE(mi, RPMTAG_VERSION, RPMMIRE_STRCMP, rpmteV(p));
	    rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, RPMMIRE_STRCMP, rpmteR(p));
	    if (tscolor) {
		rpmdbSetIteratorRE(mi, RPMTAG_ARCH, RPMMIRE_STRCMP, rpmteA(p));
		rpmdbSetIteratorRE(mi, RPMTAG_OS, RPMMIRE_STRCMP, rpmteO(p));
	    }

	    if ((h = rpmdbNextIterator(mi)) != NULL) {
		rpmteAddProblem(p, RPMPROB_PKG_INSTALLED, NULL, NULL,
				headerGetInstance(h));
	    }
	    rpmdbFreeIterator(mi);
	}

	if (!(probFilter & RPMPROB_FILTER_FORCERELOCATE))
	    rpmteAddRelocProblems(p);
    }
    rpmtsiFree(pi);
    return rpmtsProblems(ts);
}
Example #2
0
File: psm.c Project: fingunter/rpm
/**
 * Run trigger scripts in the database that are fired by this header.
 * @param psm		package state machine data
 * @param sense		trigger type
 * @return		0 on success
 */
static rpmRC runTriggers(rpmpsm psm, rpmsenseFlags sense)
{
    const rpmts ts = psm->ts;
    int numPackage = -1;
    const char * N = NULL;
    int nerrors = 0;

    if (psm->te) 	/* XXX can't happen */
	N = rpmteN(psm->te);
    if (N) 		/* XXX can't happen */
	numPackage = rpmdbCountPackages(rpmtsGetRdb(ts), N)
				+ psm->countCorrection;
    if (numPackage < 0)
	return RPMRC_NOTFOUND;

    {	Header triggeredH;
	Header h = rpmteHeader(psm->te);
	rpmdbMatchIterator mi;

	mi = rpmtsInitIterator(ts, RPMDBI_TRIGGERNAME, N, 0);
	while((triggeredH = rpmdbNextIterator(mi)) != NULL) {
	    nerrors += handleOneTrigger(ts, psm->te, sense, h, triggeredH,
					0, numPackage, NULL);
	}
	rpmdbFreeIterator(mi);
	headerFree(h);
    }

    return (nerrors == 0) ? RPMRC_OK : RPMRC_FAIL;
}
Example #3
0
/* Add erase elements for older packages of same color (if any). */
static int addSelfErasures(rpmts ts, rpm_color_t tscolor, int op,
				rpmte p, rpm_color_t hcolor, Header h)
{
    Header oh;
    rpmdbMatchIterator mi = rpmtsInitIterator(ts, RPMDBI_NAME, rpmteN(p), 0);
    int rc = 0;
    int cmp;

    while((oh = rpmdbNextIterator(mi)) != NULL) {
	/* Ignore colored packages not in our rainbow. */
	if (skipColor(tscolor, hcolor, headerGetNumber(oh, RPMTAG_HEADERCOLOR)))
	    continue;

	cmp = rpmVersionCompare(h, oh);

	/* On upgrade, skip packages that contain identical NEVR. */
	if ((op == RPMTE_UPGRADE) && (cmp == 0))
	    continue;

	/* On reinstall, skip packages with differing NEVR. */
	if ((op == RPMTE_REINSTALL) && (cmp != 0))
	    continue;
	
	if (removePackage(ts, oh, p)) {
	    rc = 1;
	    break;
	}
    }
    rpmdbFreeIterator(mi);
    return rc;
}
Example #4
0
/**
 * 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;
}
Example #5
0
static rpmte * rpmalAllSatisfiesDepend(const rpmal al, const rpmds ds)
{
    rpmte * ret = NULL;
    int i, found;
    const char * name;
    availableIndexEntry result;
    int resultCnt;
    int obsolete;

    availablePackage alp;
    int rc;

    if (al == NULL || ds == NULL || (name = rpmdsN(ds)) == NULL)
	return ret;

    if (al->providesHash == NULL && al->fileHash == NULL)
	rpmalMakeIndex(al);

    obsolete = (rpmdsTagN(ds) == RPMTAG_OBSOLETENAME);
    if (!obsolete && *name == '/') {
	/* First, look for files "contained" in package ... */
	ret = rpmalAllFileSatisfiesDepend(al, ds);
	if (ret != NULL && *ret != NULL)
	    return ret;
	/* ... then, look for files "provided" by package. */
	ret = _free(ret);
    }

    rpmalProvidesHashGetEntry(al->providesHash, name, &result,
			      &resultCnt, NULL);

    if (resultCnt==0) return NULL;

    ret = xmalloc((resultCnt+1) * sizeof(*ret));

    for (found=i=0; i<resultCnt; i++) {
	alp = al->list + result[i].pkgNum;
	if (alp->p == NULL) // deleted
	    continue;
	(void) rpmdsSetIx(alp->provides, result[i].entryIx);

	/* Obsoletes are on package name, filter out other provide matches */
	if (obsolete && !rstreq(rpmdsN(alp->provides), rpmteN(alp->p)))
	    continue;

	rc = 0;
	if (rpmdsIx(alp->provides) >= 0)
	    rc = rpmdsCompare(alp->provides, ds);

	if (rc) {
	    rpmdsNotify(ds, "(added provide)", 0);
	    ret[found] = alp->p;
	    found++;
	}
    }
    ret[found] = NULL;

    return ret;
}
Example #6
0
/* Add erase elements for obsoleted packages of same color (if any). */
static int addObsoleteErasures(rpmts ts, rpm_color_t tscolor, rpmte p)
{
    rpmstrPool tspool = rpmtsPool(ts);
    rpmds obsoletes = rpmdsInit(rpmteDS(p, RPMTAG_OBSOLETENAME));
    Header oh;
    int rc = 0;

    while (rpmdsNext(obsoletes) >= 0 && rc == 0) {
	const char * Name;
	rpmdbMatchIterator mi = NULL;

	if ((Name = rpmdsN(obsoletes)) == NULL)
	    continue;	/* XXX can't happen */

	mi = rpmtsPrunedIterator(ts, RPMDBI_NAME, Name, 1);

	while((oh = rpmdbNextIterator(mi)) != NULL) {
	    const char *oarch = headerGetString(oh, RPMTAG_ARCH);
	    int match;

	    /* avoid self-obsoleting packages */
	    if (rstreq(rpmteN(p), Name) && rstreq(rpmteA(p), oarch)) {
		char * ohNEVRA = headerGetAsString(oh, RPMTAG_NEVRA);
		rpmlog(RPMLOG_DEBUG, "  Not obsoleting: %s\n", ohNEVRA);
		free(ohNEVRA);
		continue;
	    }

	    /*
	     * Rpm prior to 3.0.3 does not have versioned obsoletes.
	     * If no obsoletes version info is available, match all names.
	     */
	    match = (rpmdsEVR(obsoletes) == NULL);
	    if (!match)
		match = rpmdsMatches(tspool, oh, -1, obsoletes, 1,
					 _rpmds_nopromote);

	    if (match) {
		char * ohNEVRA = headerGetAsString(oh, RPMTAG_NEVRA);
		rpmlog(RPMLOG_DEBUG, "  Obsoletes: %s\t\terases %s\n",
			rpmdsDNEVR(obsoletes)+2, ohNEVRA);
		free(ohNEVRA);

		if (removePackage(ts, oh, p)) {
		    rc = 1;
		    break;
		}
	    }
	}
	rpmdbFreeIterator(mi);
    }
    return rc;
}
Example #7
0
/**
 * 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);
}
Example #8
0
File: psm.c Project: fingunter/rpm
static rpmpsm rpmpsmNew(rpmts ts, rpmte te, pkgGoal goal)
{
    rpmpsm psm = xcalloc(1, sizeof(*psm));
    psm->ts = rpmtsLink(ts);
    psm->files = rpmteFiles(te);
    psm->te = te; /* XXX rpmte not refcounted yet */
    if (!rpmteIsSource(te)) {
	/*
	 * When we run scripts, we pass an argument which is the number of
	 * versions of this package that will be installed when we are
	 * finished.
	 */
	int npkgs_installed = rpmdbCountPackages(rpmtsGetRdb(ts), rpmteN(te));
	switch (goal) {
	case PKG_INSTALL:
	case PKG_PRETRANS:
	    psm->scriptArg = npkgs_installed + 1;
	    psm->countCorrection = 0;
	    break;
	case PKG_ERASE:
	    psm->scriptArg = npkgs_installed - 1;
	    psm->countCorrection = -1;
	    break;
	case PKG_VERIFY:
	case PKG_POSTTRANS:
	    psm->scriptArg = npkgs_installed;
	    psm->countCorrection = 0;
	    break;
	default:
	    break;
	}
    }

    if (goal == PKG_INSTALL) {
	Header h = rpmteHeader(te);
	psm->total = headerGetNumber(h, RPMTAG_LONGARCHIVESIZE);
	headerFree(h);
    } else if (goal == PKG_ERASE) {
	psm->total = rpmfilesFC(psm->files);
    }
    /* Fake up something for packages with no files */
    if (psm->total == 0)
	psm->total = 100;

    rpmlog(RPMLOG_DEBUG, "%s: %s has %d files\n", pkgGoalString(goal),
	    rpmteNEVRA(psm->te), rpmfilesFC(psm->files));

    return psm;
}
Example #9
0
File: psm.c Project: fingunter/rpm
/*
 * --replacepkgs hack: find the header instance we're replacing and
 * mark it as the db instance of the install element. In PSM_POST,
 * if an install element already has a db instance, it's removed
 * before proceeding with the adding the new header to the db.
 */
static void markReplacedInstance(rpmts ts, rpmte te)
{
    rpmdbMatchIterator mi = rpmtsInitIterator(ts, RPMDBI_NAME, rpmteN(te), 0);
    rpmdbSetIteratorRE(mi, RPMTAG_EPOCH, RPMMIRE_STRCMP, rpmteE(te));
    rpmdbSetIteratorRE(mi, RPMTAG_VERSION, RPMMIRE_STRCMP, rpmteV(te));
    rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, RPMMIRE_STRCMP, rpmteR(te));
    /* XXX shouldn't we also do this on colorless transactions? */
    if (rpmtsColor(ts)) {
	rpmdbSetIteratorRE(mi, RPMTAG_ARCH, RPMMIRE_STRCMP, rpmteA(te));
	rpmdbSetIteratorRE(mi, RPMTAG_OS, RPMMIRE_STRCMP, rpmteO(te));
    }

    while (rpmdbNextIterator(mi) != NULL) {
	rpmteSetDBInstance(te, rpmdbGetIteratorOffset(mi));
	break;
    }
    rpmdbFreeIterator(mi);
}
Example #10
0
/* Add erase elements for older packages of same color (if any). */
static int addUpgradeErasures(rpmts ts, rpm_color_t tscolor,
				rpmte p, rpm_color_t hcolor, Header h)
{
    Header oh;
    rpmdbMatchIterator mi = rpmtsInitIterator(ts, RPMDBI_NAME, rpmteN(p), 0);
    int rc = 0;

    while((oh = rpmdbNextIterator(mi)) != NULL) {
	/* Ignore colored packages not in our rainbow. */
	if (skipColor(tscolor, hcolor, headerGetNumber(oh, RPMTAG_HEADERCOLOR)))
	    continue;

	/* Skip packages that contain identical NEVR. */
	if (rpmVersionCompare(h, oh) == 0)
	    continue;

	if (removePackage(ts, oh, p)) {
	    rc = 1;
	    break;
	}
    }
    rpmdbFreeIterator(mi);
    return rc;
}
Example #11
0
int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
{
    rpm_color_t tscolor = rpmtsColor(ts);
    int i;
    int rc = 0;
    int totalFileCount = 0;
    rpmfi fi;
    fingerPrintCache fpc;
    rpmps ps;
    rpmtsi pi;	rpmte p;
    int numAdded;
    int numRemoved;
    void * lock = NULL;
    int xx;

    /* XXX programmer error segfault avoidance. */
    if (rpmtsNElements(ts) <= 0)
	return -1;

    /* If we are in test mode, then there's no need for transaction lock. */
    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) {
	lock = rpmtsAcquireLock(ts);
	if (lock == NULL)
	    return -1;	/* XXX W2DO? */
    }

    if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOSCRIPTS)
	(void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers));
    if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERS)
	(void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransTriggers));

    if (rpmtsFlags(ts) & RPMTRANS_FLAG_JUSTDB)
	(void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers));

    /* if SELinux isn't enabled or init fails, don't bother... */
    if (!rpmtsSELinuxEnabled(ts)) {
        rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_NOCONTEXTS));
    }

    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS)) {
	char *fn = rpmGetPath("%{?_install_file_context_path}", NULL);
	if (matchpathcon_init(fn) == -1) {
	    rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_NOCONTEXTS));
	}
	free(fn);
    }

    ts->probs = rpmpsFree(ts->probs);
    ts->probs = rpmpsCreate();

    /* XXX Make sure the database is open RDWR for package install/erase. */
    {	int dbmode = (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)
		? O_RDONLY : (O_RDWR|O_CREAT);

	/* Open database RDWR for installing packages. */
	if (rpmtsOpenDB(ts, dbmode)) {
	    rpmtsFreeLock(lock);
	    return -1;	/* XXX W2DO? */
	}
    }

    ts->ignoreSet = ignoreSet;
    {	char * currDir = rpmGetCwd();
	rpmtsSetCurrDir(ts, currDir);
	currDir = _free(currDir);
    }

    (void) rpmtsSetChrootDone(ts, 0);

    {	rpm_tid_t tid = (rpm_tid_t) time(NULL);
	(void) rpmtsSetTid(ts, tid);
    }

    /* Get available space on mounted file systems. */
    xx = rpmtsInitDSI(ts);

    /* ===============================================
     * For packages being installed:
     * - verify package arch/os.
     * - verify package epoch:version-release is newer.
     * - count files.
     * For packages being removed:
     * - count files.
     */

    rpmlog(RPMLOG_DEBUG, "sanity checking %d elements\n", rpmtsNElements(ts));
    ps = rpmtsProblems(ts);
    /* The ordering doesn't matter here */
    pi = rpmtsiInit(ts);
    /* XXX Only added packages need be checked. */
    while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
	rpmdbMatchIterator mi;
	int fc;

	if ((fi = rpmteFI(p)) == NULL)
	    continue;	/* XXX can't happen */
	fc = rpmfiFC(fi);

	if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_IGNOREARCH))
	    if (!archOkay(rpmteA(p)))
		rpmpsAppend(ps, RPMPROB_BADARCH,
			rpmteNEVRA(p), rpmteKey(p),
			rpmteA(p), NULL,
			NULL, 0);

	if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_IGNOREOS))
	    if (!osOkay(rpmteO(p)))
		rpmpsAppend(ps, RPMPROB_BADOS,
			rpmteNEVRA(p), rpmteKey(p),
			rpmteO(p), NULL,
			NULL, 0);

	if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_OLDPACKAGE)) {
	    Header h;
	    mi = rpmtsInitIterator(ts, RPMTAG_NAME, rpmteN(p), 0);
	    while ((h = rpmdbNextIterator(mi)) != NULL)
		xx = ensureOlder(ts, p, h);
	    mi = rpmdbFreeIterator(mi);
	}

	if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEPKG)) {
	    mi = rpmtsInitIterator(ts, RPMTAG_NAME, rpmteN(p), 0);
	    xx = rpmdbSetIteratorRE(mi, RPMTAG_EPOCH, RPMMIRE_STRCMP,
				rpmteE(p));
	    xx = rpmdbSetIteratorRE(mi, RPMTAG_VERSION, RPMMIRE_STRCMP,
				rpmteV(p));
	    xx = rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, RPMMIRE_STRCMP,
				rpmteR(p));
	    if (tscolor) {
		xx = rpmdbSetIteratorRE(mi, RPMTAG_ARCH, RPMMIRE_STRCMP,
				rpmteA(p));
		xx = rpmdbSetIteratorRE(mi, RPMTAG_OS, RPMMIRE_STRCMP,
				rpmteO(p));
	    }

	    while (rpmdbNextIterator(mi) != NULL) {
		rpmpsAppend(ps, RPMPROB_PKG_INSTALLED,
			rpmteNEVRA(p), rpmteKey(p),
			NULL, NULL,
			NULL, 0);
		break;
	    }
	    mi = rpmdbFreeIterator(mi);
	}

	/* Count no. of files (if any). */
	totalFileCount += fc;

    }
    pi = rpmtsiFree(pi);
    ps = rpmpsFree(ps);

    /* The ordering doesn't matter here */
    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, TR_REMOVED)) != NULL) {
	int fc;

	if ((fi = rpmteFI(p)) == NULL)
	    continue;	/* XXX can't happen */
	fc = rpmfiFC(fi);

	totalFileCount += fc;
    }
    pi = rpmtsiFree(pi);


    /* Run pre-transaction scripts, but only if there are no known
     * problems up to this point and not disabled otherwise. */
    if (!((rpmtsFlags(ts) & (RPMTRANS_FLAG_BUILD_PROBS|RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_NOPRE))
     	  || (rpmpsNumProblems(ts->probs) &&
		(okProbs == NULL || rpmpsTrim(ts->probs, okProbs))))) {
	rpmlog(RPMLOG_DEBUG, "running pre-transaction scripts\n");
	runTransScripts(ts, RPMTAG_PRETRANS);
    }

    /* ===============================================
     * Initialize transaction element file info for package:
     */

    /*
     * FIXME?: we'd be better off assembling one very large file list and
     * calling fpLookupList only once. I'm not sure that the speedup is
     * worth the trouble though.
     */
    rpmlog(RPMLOG_DEBUG, "computing %d file fingerprints\n", totalFileCount);

    numAdded = numRemoved = 0;
    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, 0)) != NULL) {
	int fc;

	if ((fi = rpmteFI(p)) == NULL)
	    continue;	/* XXX can't happen */
	fc = rpmfiFC(fi);

	switch (rpmteType(p)) {
	case TR_ADDED:
	    numAdded++;
	    /* Skip netshared paths, not our i18n files, and excluded docs */
	    if (fc > 0)
		skipFiles(ts, p);
	    break;
	case TR_REMOVED:
	    numRemoved++;
	    break;
	}
    }
    pi = rpmtsiFree(pi);

    if (!rpmtsChrootDone(ts)) {
	const char * rootDir = rpmtsRootDir(ts);
	xx = chdir("/");
	if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/') {
	    /* opening db before chroot not optimal, see rhbz#103852 c#3 */
	    xx = rpmdbOpenAll(ts->rdb);
	    if (chroot(rootDir) == -1) {
		rpmlog(RPMLOG_ERR, _("Unable to change root directory: %m\n"));
		return -1;
	    }
	}
	(void) rpmtsSetChrootDone(ts, 1);
    }

    ts->ht = rpmFpHashCreate(totalFileCount/2+1, fpHashFunction, fpEqual,
			     NULL, NULL);
    rpmFpHash symlinks = rpmFpHashCreate(totalFileCount/16+16, fpHashFunction, fpEqual, NULL, NULL);
    fpc = fpCacheCreate(totalFileCount/2 + 10001);

    /* ===============================================
     * Add fingerprint for each file not skipped.
     */
    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, 0)) != NULL) {
	int fc;

	(void) rpmdbCheckSignals();

	if ((fi = rpmteFI(p)) == NULL)
	    continue;	/* XXX can't happen */
	fc = rpmfiFC(fi);

	(void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
	rpmfiFpLookup(fi, fpc);
	/* collect symbolic links */
 	fi = rpmfiInit(fi, 0);
 	if (fi != NULL)		/* XXX lclint */
	while ((i = rpmfiNext(fi)) >= 0) {
	    struct rpmffi_s ffi;
	    char const *linktarget;
	    linktarget = rpmfiFLink(fi);
	    if (!(linktarget && *linktarget != '\0'))
		continue;
	    if (XFA_SKIPPING(rpmfsGetAction(rpmteGetFileStates(p), i)))
		continue;
	    ffi.p = p;
	    ffi.fileno = i;
	    rpmFpHashAddEntry(symlinks, rpmfiFpsIndex(fi, i), ffi);
	}
	(void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), fc);

    }
    pi = rpmtsiFree(pi);

    /* ===============================================
     * Check fingerprints if they contain symlinks
     * and add them to the ts->ht hash table
     */

    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, 0)) != NULL) {
	(void) rpmdbCheckSignals();

	if ((fi = rpmteFI(p)) == NULL)
	    continue;	/* XXX can't happen */
	fi = rpmfiInit(fi, 0);
	(void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
	if (fi != NULL)		/* XXX lclint */
	while ((i = rpmfiNext(fi)) >= 0) {
	    if (XFA_SKIPPING(rpmfsGetAction(rpmteGetFileStates(p), i)))
		continue;
	    fpLookupSubdir(symlinks, ts->ht, fpc, p, i);
	}
	(void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
    }
    pi = rpmtsiFree(pi);

    rpmFpHashFree(symlinks);

    /* ===============================================
     * Compute file disposition for each package in transaction set.
     */
    rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_START, 6, ts->orderCount);

    /* check against files in the rpmdb */
    checkInstalledFiles(ts, fpc);

    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, 0)) != NULL) {

	if ((fi = rpmteFI(p)) == NULL)
	    continue;   /* XXX can't happen */

	(void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
	/* check files in ts against each other and update disk space
	   needs on each partition for this package. */
	handleOverlappedFiles(ts, p, fi);

	/* Check added package has sufficient space on each partition used. */
	if (rpmteType(p) == TR_ADDED) {
	    rpmtsCheckDSIProblems(ts, p);
	}
	(void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
    }
    pi = rpmtsiFree(pi);

    if (rpmtsChrootDone(ts)) {
	const char * rootDir = rpmtsRootDir(ts);
	const char * currDir = rpmtsCurrDir(ts);
	if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/')
	    xx = chroot(".");
	(void) rpmtsSetChrootDone(ts, 0);
	if (currDir != NULL)
	    xx = chdir(currDir);
    }

    rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_STOP, 6, ts->orderCount);

    /* ===============================================
     * Free unused memory as soon as possible.
     */
    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, 0)) != NULL) {
	rpmteSetFI(p, NULL);
    }
    pi = rpmtsiFree(pi);

    fpc = fpCacheFree(fpc);
    ts->ht = rpmFpHashFree(ts->ht);

    /* ===============================================
     * If unfiltered problems exist, free memory and return.
     */
    if ((rpmtsFlags(ts) & RPMTRANS_FLAG_BUILD_PROBS)
     || (rpmpsNumProblems(ts->probs) &&
		(okProbs == NULL || rpmpsTrim(ts->probs, okProbs)))
       )
    {
	rpmtsFreeLock(lock);
	return ts->orderCount;
    }

    /* Actually install and remove packages */
    rc = rpmtsProcess(ts);

    if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_NOPOST))) {
	rpmlog(RPMLOG_DEBUG, "running post-transaction scripts\n");
	runTransScripts(ts, RPMTAG_POSTTRANS);
    }

    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS)) {
	matchpathcon_fini();
    }

    rpmtsFreeLock(lock);

    /* FIX: ts->flList may be NULL */
    if (rc)
    	return -1;
    else
	return 0;
}
Example #12
0
int rpmtsCheck(rpmts ts)
{
    rpm_color_t tscolor = rpmtsColor(ts);
    rpmtsi pi = NULL; rpmte p;
    int closeatexit = 0;
    int rc = 0;
    depCache dcache = NULL;
    filedepHash confilehash = NULL;	/* file conflicts of installed packages */
    filedepHash connotfilehash = NULL;	/* file conflicts of installed packages */
    depexistsHash connothash = NULL;
    filedepHash reqfilehash = NULL;	/* file requires of installed packages */
    filedepHash reqnotfilehash = NULL;	/* file requires of installed packages */
    depexistsHash reqnothash = NULL;
    fingerPrintCache fpc = NULL;
    rpmdb rdb = NULL;
    
    (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_CHECK), 0);

    /* Do lazy, readonly, open of rpm database. */
    rdb = rpmtsGetRdb(ts);
    if (rdb == NULL && rpmtsGetDBMode(ts) != -1) {
	if ((rc = rpmtsOpenDB(ts, rpmtsGetDBMode(ts))) != 0)
	    goto exit;
	rdb = rpmtsGetRdb(ts);
	closeatexit = 1;
    }

    if (rdb)
	rpmdbCtrl(rdb, RPMDB_CTRL_LOCK_RO);

    /* XXX FIXME: figure some kind of heuristic for the cache size */
    dcache = depCacheCreate(5001, rstrhash, strcmp,
				     (depCacheFreeKey)rfree, NULL);

    /* build hashes of all confilict sdependencies */
    confilehash = filedepHashCreate(257, rstrhash, strcmp,
				    (filedepHashFreeKey)rfree,
				    (filedepHashFreeData)rfree);
    connothash = depexistsHashCreate(257, rstrhash, strcmp,
				    (filedepHashFreeKey)rfree);
    connotfilehash = filedepHashCreate(257, rstrhash, strcmp,
				    (filedepHashFreeKey)rfree,
				    (filedepHashFreeData)rfree);
    addIndexToDepHashes(ts, RPMTAG_CONFLICTNAME, NULL, confilehash, connothash, connotfilehash);
    if (!filedepHashNumKeys(confilehash))
	confilehash = filedepHashFree(confilehash);
    if (!depexistsHashNumKeys(connothash))
	connothash= depexistsHashFree(connothash);
    if (!filedepHashNumKeys(connotfilehash))
	connotfilehash = filedepHashFree(connotfilehash);

    /* build hashes of all requires dependencies */
    reqfilehash = filedepHashCreate(8191, rstrhash, strcmp,
				    (filedepHashFreeKey)rfree,
				    (filedepHashFreeData)rfree);
    reqnothash = depexistsHashCreate(257, rstrhash, strcmp,
				    (filedepHashFreeKey)rfree);
    reqnotfilehash = filedepHashCreate(257, rstrhash, strcmp,
				    (filedepHashFreeKey)rfree,
				    (filedepHashFreeData)rfree);
    addIndexToDepHashes(ts, RPMTAG_REQUIRENAME, NULL, reqfilehash, reqnothash, reqnotfilehash);
    if (!filedepHashNumKeys(reqfilehash))
	reqfilehash = filedepHashFree(reqfilehash);
    if (!depexistsHashNumKeys(reqnothash))
	reqnothash= depexistsHashFree(reqnothash);
    if (!filedepHashNumKeys(reqnotfilehash))
	reqnotfilehash = filedepHashFree(reqnotfilehash);

    /*
     * Look at all of the added packages and make sure their dependencies
     * are satisfied.
     */
    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
	rpmds provides = rpmdsInit(rpmteDS(p, RPMTAG_PROVIDENAME));

	rpmlog(RPMLOG_DEBUG, "========== +++ %s %s/%s 0x%x\n",
		rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));

	checkDS(ts, dcache, p, rpmteNEVRA(p), rpmteDS(p, RPMTAG_REQUIRENAME),
		tscolor);
	checkDS(ts, dcache, p, rpmteNEVRA(p), rpmteDS(p, RPMTAG_CONFLICTNAME),
		tscolor);
	checkDS(ts, dcache, p, rpmteNEVRA(p), rpmteDS(p, RPMTAG_OBSOLETENAME),
		tscolor);

	/* Check provides against conflicts in installed packages. */
	while (rpmdsNext(provides) >= 0) {
	    const char *dep = rpmdsN(provides);
	    checkInstDeps(ts, dcache, p, RPMTAG_CONFLICTNAME, dep);
	    if (reqnothash && depexistsHashHasEntry(reqnothash, dep))
		checkNotInstDeps(ts, dcache, p, RPMTAG_REQUIRENAME, dep);
	}

	/* Skip obsoletion checks for source packages (ie build) */
	if (rpmteIsSource(p))
	    continue;

	/* Check package name (not provides!) against installed obsoletes */
	checkInstDeps(ts, dcache, p, RPMTAG_OBSOLETENAME, rpmteN(p));

	/* Check filenames against installed conflicts */
        if (confilehash || reqnotfilehash) {
	    rpmfiles files = rpmteFiles(p);
	    rpmfi fi = rpmfilesIter(files, RPMFI_ITER_FWD);
	    while (rpmfiNext(fi) >= 0) {
		if (confilehash)
		    checkInstFileDeps(ts, dcache, p, RPMTAG_CONFLICTNAME, fi, 0, confilehash, &fpc);
		if (reqnotfilehash)
		    checkInstFileDeps(ts, dcache, p, RPMTAG_REQUIRENAME, fi, 1, reqnotfilehash, &fpc);
	    }
	    rpmfiFree(fi);
	    rpmfilesFree(files);
	}
    }
    rpmtsiFree(pi);

    /*
     * Look at the removed packages and make sure they aren't critical.
     */
    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, TR_REMOVED)) != NULL) {
	rpmds provides = rpmdsInit(rpmteDS(p, RPMTAG_PROVIDENAME));

	rpmlog(RPMLOG_DEBUG, "========== --- %s %s/%s 0x%x\n",
		rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));

	/* Check provides and filenames against installed dependencies. */
	while (rpmdsNext(provides) >= 0) {
	    const char *dep = rpmdsN(provides);
	    checkInstDeps(ts, dcache, p, RPMTAG_REQUIRENAME, dep);
	    if (connothash && depexistsHashHasEntry(connothash, dep))
		checkNotInstDeps(ts, dcache, p, RPMTAG_CONFLICTNAME, dep);
	}

	if (reqfilehash || connotfilehash) {
	    rpmfiles files = rpmteFiles(p);
	    rpmfi fi = rpmfilesIter(files, RPMFI_ITER_FWD);;
	    while (rpmfiNext(fi) >= 0) {
		if (RPMFILE_IS_INSTALLED(rpmfiFState(fi))) {
		    if (reqfilehash)
			checkInstFileDeps(ts, dcache, p, RPMTAG_REQUIRENAME, fi, 0, reqfilehash, &fpc);
		    if (connotfilehash)
			checkInstFileDeps(ts, dcache, p, RPMTAG_CONFLICTNAME, fi, 1, connotfilehash, &fpc);
		}
	    }
	    rpmfiFree(fi);
	    rpmfilesFree(files);
	}
    }
    rpmtsiFree(pi);

    if (rdb)
	rpmdbCtrl(rdb, RPMDB_CTRL_UNLOCK_RO);

exit:
    depCacheFree(dcache);
    filedepHashFree(confilehash);
    filedepHashFree(connotfilehash);
    depexistsHashFree(connothash);
    filedepHashFree(reqfilehash);
    filedepHashFree(reqnotfilehash);
    depexistsHashFree(reqnothash);
    fpCacheFree(fpc);

    (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_CHECK), 0);

    if (closeatexit)
	(void) rpmtsCloseDB(ts);
    return rc;
}
Example #13
0
static rpmRC rpmpsmStage(rpmpsm psm, pkgStage stage)
{
    const rpmts ts = psm->ts;
    rpmfi fi = psm->fi;
    rpmRC rc = RPMRC_OK;

    switch (stage) {
    case PSM_UNKNOWN:
	break;
    case PSM_INIT:
	rpmlog(RPMLOG_DEBUG, "%s: %s has %d files\n",
		psm->goalName, rpmteNEVR(psm->te), rpmfiFC(fi));

	/*
	 * When we run scripts, we pass an argument which is the number of
	 * versions of this package that will be installed when we are
	 * finished.
	 */
	psm->npkgs_installed = rpmdbCountPackages(rpmtsGetRdb(ts), rpmteN(psm->te));
	if (psm->npkgs_installed < 0) {
	    rc = RPMRC_FAIL;
	    break;
	}

	if (psm->goal == PKG_INSTALL) {
	    Header h = rpmteHeader(psm->te);
	    psm->scriptArg = psm->npkgs_installed + 1;

	    psm->amount = 0;
	    psm->total = headerGetNumber(h, RPMTAG_LONGARCHIVESIZE);
	    /* fake up something for packages with no files */
	    if (psm->total == 0)
		psm->total = 100;

	    /* HACK: reinstall abuses te instance to remove old header */
	    if (rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEPKG)
		markReplacedInstance(ts, psm->te);

	    if (rpmfiFC(fi) > 0) {
		struct rpmtd_s filenames;
		rpmTag ftag = RPMTAG_FILENAMES;
	
		if (headerIsEntry(h, RPMTAG_ORIGBASENAMES)) {
		    ftag = RPMTAG_ORIGFILENAMES;
		}
		headerGet(h, ftag, &filenames, HEADERGET_EXT);
		fi->apath = filenames.data; /* Ick.. */
	    }
	    headerFree(h);
	}
	if (psm->goal == PKG_ERASE) {
	    psm->scriptArg = psm->npkgs_installed - 1;

	    psm->amount = 0;
	    psm->total = rpmfiFC(fi) ? rpmfiFC(fi) : 100;
	}
	break;
    case PSM_PRE:
	if (psm->goal == PKG_INSTALL) {
	    psm->scriptTag = RPMTAG_PREIN;
	    psm->sense = RPMSENSE_TRIGGERPREIN;
	    psm->countCorrection = 0;   /* XXX is this correct?!? */

	    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERPREIN)) {
		/* Run triggers in other package(s) this package sets off. */
		rc = rpmpsmNext(psm, PSM_TRIGGERS);
		if (rc) break;

		/* Run triggers in this package other package(s) set off. */
		rc = rpmpsmNext(psm, PSM_IMMED_TRIGGERS);
		if (rc) break;
	    }

	    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPRE)) {
		rc = rpmpsmNext(psm, PSM_SCRIPT);
		if (rc) break;
	    }
	}

	if (psm->goal == PKG_ERASE) {
	    psm->scriptTag = RPMTAG_PREUN;
	    psm->sense = RPMSENSE_TRIGGERUN;
	    psm->countCorrection = -1;

	    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERUN)) {
		/* Run triggers in this package other package(s) set off. */
		rc = rpmpsmNext(psm, PSM_IMMED_TRIGGERS);
		if (rc) break;

		/* Run triggers in other package(s) this package sets off. */
		rc = rpmpsmNext(psm, PSM_TRIGGERS);
		if (rc) break;
	    }

	    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPREUN))
		rc = rpmpsmNext(psm, PSM_SCRIPT);
	}
	break;
    case PSM_PROCESS:
	if (psm->goal == PKG_INSTALL) {
	    int fsmrc = 0;

	    rpmpsmNotify(psm, RPMCALLBACK_INST_START, 0);
	    /* make sure first progress call gets made */
	    rpmpsmNotify(psm, RPMCALLBACK_INST_PROGRESS, 0);

	    if (rpmfiFC(fi) > 0 && !(rpmtsFlags(ts) & RPMTRANS_FLAG_JUSTDB)) {
		FD_t payload = rpmtePayload(psm->te);
		if (payload == NULL) {
		    rc = RPMRC_FAIL;
		    break;
		}

		fsmrc = rpmPackageFilesInstall(psm->ts, psm->te, psm->fi,
				  payload, psm, &psm->failedFile);

		rpmswAdd(rpmtsOp(psm->ts, RPMTS_OP_UNCOMPRESS),
			 fdOp(payload, FDSTAT_READ));
		rpmswAdd(rpmtsOp(psm->ts, RPMTS_OP_DIGEST),
			 fdOp(payload, FDSTAT_DIGEST));

		Fclose(payload);
	    }

	    /* XXX make sure progress reaches 100% */
	    rpmpsmNotify(psm, 0, psm->total);
	    rpmpsmNotify(psm, RPMCALLBACK_INST_STOP, psm->total);

	    if (fsmrc) {
		char *emsg = rpmcpioStrerror(fsmrc);
		rpmlog(RPMLOG_ERR,
			_("unpacking of archive failed%s%s: %s\n"),
			(psm->failedFile != NULL ? _(" on file ") : ""),
			(psm->failedFile != NULL ? psm->failedFile : ""),
			emsg);
		free(emsg);
		rc = RPMRC_FAIL;

		/* XXX notify callback on error. */
		rpmtsNotify(ts, psm->te, RPMCALLBACK_UNPACK_ERROR, 0, 0);
		break;
	    }
	}
	if (psm->goal == PKG_ERASE) {
	    if (rpmtsFlags(ts) & RPMTRANS_FLAG_JUSTDB)	break;

	    rpmpsmNotify(psm, RPMCALLBACK_UNINST_START, 0);
	    /* make sure first progress call gets made */
	    rpmpsmNotify(psm, RPMCALLBACK_UNINST_PROGRESS, 0);

	    /* XXX should't we log errors from here? */
	    if (rpmfiFC(fi) > 0 && !(rpmtsFlags(ts) & RPMTRANS_FLAG_JUSTDB)) {
		rc = rpmPackageFilesRemove(psm->ts, psm->te, psm->fi,
				  psm, &psm->failedFile);
	    }

	    /* XXX make sure progress reaches 100% */
	    rpmpsmNotify(psm, 0, psm->total);
	    rpmpsmNotify(psm, RPMCALLBACK_UNINST_STOP, psm->total);
	}
	break;
    case PSM_POST:
	if (psm->goal == PKG_INSTALL) {
	    rpm_time_t installTime = (rpm_time_t) time(NULL);
	    rpmfs fs = rpmteGetFileStates(psm->te);
	    rpm_count_t fc = rpmfsFC(fs);
	    rpm_fstate_t * fileStates = rpmfsGetStates(fs);
	    Header h = rpmteHeader(psm->te);
	    rpm_color_t tscolor = rpmtsColor(ts);

	    if (fileStates != NULL && fc > 0) {
		headerPutChar(h, RPMTAG_FILESTATES, fileStates, fc);
	    }

	    headerPutUint32(h, RPMTAG_INSTALLTIME, &installTime, 1);
	    headerPutUint32(h, RPMTAG_INSTALLCOLOR, &tscolor, 1);
	    headerFree(h);

	    /*
	     * If this package has already been installed, remove it from
	     * the database before adding the new one.
	     */
	    if (rpmteDBInstance(psm->te)) {
		rc = rpmpsmNext(psm, PSM_RPMDB_REMOVE);
		if (rc) break;
	    }

	    rc = rpmpsmNext(psm, PSM_RPMDB_ADD);
	    if (rc) break;

	    psm->scriptTag = RPMTAG_POSTIN;
	    psm->sense = RPMSENSE_TRIGGERIN;
	    psm->countCorrection = 0;

	    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPOST)) {
		rc = rpmpsmNext(psm, PSM_SCRIPT);
		if (rc) break;
	    }
	    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERIN)) {
		/* Run triggers in other package(s) this package sets off. */
		rc = rpmpsmNext(psm, PSM_TRIGGERS);
		if (rc) break;

		/* Run triggers in this package other package(s) set off. */
		rc = rpmpsmNext(psm, PSM_IMMED_TRIGGERS);
		if (rc) break;
	    }

	    rc = markReplacedFiles(psm);

	}
	if (psm->goal == PKG_ERASE) {

	    psm->scriptTag = RPMTAG_POSTUN;
	    psm->sense = RPMSENSE_TRIGGERPOSTUN;
	    psm->countCorrection = -1;

	    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPOSTUN)) {
		rc = rpmpsmNext(psm, PSM_SCRIPT);
		if (rc) break;
	    }

	    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERPOSTUN)) {
		/* Run triggers in other package(s) this package sets off. */
		rc = rpmpsmNext(psm, PSM_TRIGGERS);
		if (rc) break;
	    }

	    rc = rpmpsmNext(psm, PSM_RPMDB_REMOVE);
	}
	break;
    case PSM_UNDO:
	break;
    case PSM_FINI:
	if (rc) {
	    char *emsg = rpmcpioStrerror(rc);
	    if (psm->failedFile)
		rpmlog(RPMLOG_ERR,
			_("%s failed on file %s: %s\n"),
			psm->goalName, psm->failedFile, emsg);
	    else
		rpmlog(RPMLOG_ERR, _("%s failed: %s\n"),
			psm->goalName, emsg);
	    free(emsg);

	    /* XXX notify callback on error. */
	    rpmtsNotify(ts, psm->te, RPMCALLBACK_CPIO_ERROR, 0, 0);
	}

	psm->failedFile = _free(psm->failedFile);

	fi->apath = _free(fi->apath);
	break;

    case PSM_CREATE:
	break;
    case PSM_DESTROY:
	break;
    case PSM_SCRIPT:	/* Run current package scriptlets. */
	rc = runInstScript(psm);
	break;
    case PSM_TRIGGERS:
	/* Run triggers in other package(s) this package sets off. */
	rc = runTriggers(psm);
	break;
    case PSM_IMMED_TRIGGERS:
	/* Run triggers in this package other package(s) set off. */
	rc = runImmedTriggers(psm);
	break;

    case PSM_RPMDB_ADD: {
	Header h = rpmteHeader(psm->te);

	if (!headerIsEntry(h, RPMTAG_INSTALLTID)) {
	    rpm_tid_t tid = rpmtsGetTid(ts);
	    if (tid != 0 && tid != (rpm_tid_t)-1)
		headerPutUint32(h, RPMTAG_INSTALLTID, &tid, 1);
	}
	
	(void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DBADD), 0);
	rc = (rpmdbAdd(rpmtsGetRdb(ts), h) == 0) ? RPMRC_OK : RPMRC_FAIL;
	(void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DBADD), 0);

	if (rc == RPMRC_OK)
	    rpmteSetDBInstance(psm->te, headerGetInstance(h));
	headerFree(h);
    }   break;

    case PSM_RPMDB_REMOVE:
	(void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DBREMOVE), 0);
	rc = (rpmdbRemove(rpmtsGetRdb(ts), rpmteDBInstance(psm->te)) == 0) ?
						    RPMRC_OK : RPMRC_FAIL;
	(void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DBREMOVE), 0);
	if (rc == RPMRC_OK)
	    rpmteSetDBInstance(psm->te, 0);
	break;

    default:
	break;
   }

    return rc;
}
Example #14
0
static JSBool
rpmte_getprop(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
    void * ptr = JS_GetInstancePrivate(cx, obj, &rpmteClass, NULL);
    rpmte te = ptr;
    jsint tiny = JSVAL_TO_INT(id);

    /* XXX the class has ptr == NULL, instances have ptr != NULL. */
    if (ptr == NULL)
	return JS_TRUE;

    switch (tiny) {
    case _DEBUG:
	*vp = INT_TO_JSVAL(_debug);
	break;
    case _TYPE:
	*vp = INT_TO_JSVAL(rpmteType(te));	/* XXX should be string */
	break;
    case _N:
	*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, rpmteN(te)));
	break;
    case _E:
	*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, rpmteE(te)));
	break;
    case _V:
	*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, rpmteV(te)));
	break;
    case _R:
	*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, rpmteR(te)));
	break;
    case _A:
	*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, rpmteA(te)));
	break;
    case _O:
	*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, rpmteO(te)));
	break;
    case _NEVR:
	*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, rpmteNEVR(te)));
	break;
    case _NEVRA:
	*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, rpmteNEVRA(te)));
	break;
    case _PKGID:
	*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, rpmtePkgid(te)));
	break;
    case _HDRID:
	*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, rpmteHdrid(te)));
	break;
    case _COLOR:
	*vp = INT_TO_JSVAL(rpmteColor(te));
	break;
    case _PKGFSIZE:
	*vp = INT_TO_JSVAL(rpmtePkgFileSize(te));
	break;
    case _BREADTH:
	*vp = INT_TO_JSVAL(rpmteBreadth(te));
	break;
    case _DEPTH:
	*vp = INT_TO_JSVAL(rpmteDepth(te));
	break;
    case _NPREDS:
	*vp = INT_TO_JSVAL(rpmteNpreds(te));
	break;
    case _DEGREE:
	*vp = INT_TO_JSVAL(rpmteDegree(te));
	break;
    case _PARENT:
#ifdef	DYING
	*vp = INT_TO_JSVAL(rpmteColor(te));
#else
	*vp = JSVAL_VOID;
#endif
	break;
    case _TREE:
	*vp = INT_TO_JSVAL(rpmteTree(te));
	break;
    case _ADDEDKEY:
	/* XXX FIXME */
	*vp = INT_TO_JSVAL((int)((long)rpmteAddedKey(te)));
	break;
    case _DBOFFSET:
	*vp = INT_TO_JSVAL(rpmteDBOffset(te));
	break;
#ifdef	NOTYET
    case _KEY:
	*vp = INT_TO_JSVAL(rpmteColor(te));
	break;
#endif
    case _SOURCERPM:
	*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, rpmteSourcerpm(te)));
	break;
    default:
	break;
    }

    return JS_TRUE;
}
Example #15
0
/*************************************************************************
* FUNCTION      :   RPMTransaction_Set::Show                             *
* ARGUMENTS     :   Object to look for                                   *
* RETURNS       :   List of packages found                               *
* EXCEPTIONS    :   none                                                 *
* PURPOSE       :   Show the contents of a transaction set               *
*************************************************************************/
Tcl_Obj *RPMTransaction_Set::Show(Tcl_Obj *item)
{
    Tcl_Obj *sub_obj = Tcl_NewObj();
    Tcl_IncrRefCount(sub_obj);
    // Is this a list?
    if (item && item->typePtr == listtype)
    {
        // OK, go recursive on this
        int count = 0;
        if (Tcl_ListObjLength(_interp,item,&count) != TCL_OK)
            return sub_obj;

        for (int i = 0; i < count; ++i)
        {
            Tcl_Obj *element = 0;
            if (Tcl_ListObjIndex(_interp,item,i,&element) != TCL_OK)
            {
                return sub_obj;
            }
            Tcl_ListObjAppendElement(_interp,sub_obj,Show(element));
        }
        return sub_obj;
    }
    // OK, not a list. were we given ANYTHING? if not, get everything.
    void *name = 0;
    if (item)
    {
        if (item->typePtr == &RPMHeader_Obj::mytype)
        {
            RPMHeader_Obj *header = ( RPMHeader_Obj *)(item->internalRep.otherValuePtr);
            int size = 0;
            int type = 0;
            if (!header->GetEntry(RPMTAG_NAME,type,name,size))
                return sub_obj;
        }
        else // Not a header, interp as a string
        {
            name = (void *)Tcl_GetStringFromObj(item,0);
        }
    }
    rpmtsi matches = rpmtsiInit(transaction);
    if (!matches)
        return sub_obj;

    // OK, go over the list and create a list of items to return

    for(;;)
    {
        rpmte te = rpmtsiNext(matches,(rpmElementType)0);
        if (!te)
            break;

        Tcl_Obj *results[2];

        switch (rpmteType(te))
        {
        case TR_ADDED:
        {
            RPMHeader_Obj *hdr = (RPMHeader_Obj *)rpmteKey(te);
            results[0] = Tcl_NewStringObj("add",-1);
            results[1] = hdr->Get_obj();;
        }
        break;

        case TR_REMOVED:
        {
            results[0] = Tcl_NewStringObj("remove",-1);
            results[1] = Tcl_NewStringObj(rpmteN(te),-1);
        }
        break;
        }

        Tcl_Obj *list = Tcl_NewListObj(2,results);
        Tcl_IncrRefCount(list);
        Tcl_ListObjAppendElement(_interp,sub_obj,list);
    }
    rpmtsiFree(matches);
    return sub_obj;
}
Example #16
0
int rpmtsCheck(rpmts ts)
{
    rpm_color_t tscolor = rpmtsColor(ts);
    rpmtsi pi = NULL; rpmte p;
    int closeatexit = 0;
    int rc = 0;
    depCache dcache = NULL;
    conflictsCache confcache = NULL;
    
    (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_CHECK), 0);

    /* Do lazy, readonly, open of rpm database. */
    if (rpmtsGetRdb(ts) == NULL && rpmtsGetDBMode(ts) != -1) {
	if ((rc = rpmtsOpenDB(ts, rpmtsGetDBMode(ts))) != 0)
	    goto exit;
	closeatexit = 1;
    }

    /* XXX FIXME: figure some kind of heuristic for the cache size */
    dcache = depCacheCreate(5001, rstrhash, strcmp,
				     (depCacheFreeKey)rfree, NULL);

    confcache = conflictsCacheCreate(257, rstrhash, strcmp,
				     (depCacheFreeKey)rfree);
    if (confcache) {
	rpmdbIndexIterator ii = rpmdbIndexIteratorInit(rpmtsGetRdb(ts), RPMTAG_CONFLICTNAME);
	if (ii) {
	    char *key;
	    size_t keylen;
	    while ((rpmdbIndexIteratorNext(ii, (const void**)&key, &keylen)) == 0) {
		char *k;
		if (!key || keylen == 0 || key[0] != '/')
		    continue;
		k = rmalloc(keylen + 1);
		memcpy(k, key, keylen);
		k[keylen] = 0;
		conflictsCacheAddEntry(confcache, k);
	    }
	    rpmdbIndexIteratorFree(ii);
	}
    }

    
    /*
     * Look at all of the added packages and make sure their dependencies
     * are satisfied.
     */
    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
	rpmds provides = rpmdsInit(rpmteDS(p, RPMTAG_PROVIDENAME));

	rpmlog(RPMLOG_DEBUG, "========== +++ %s %s/%s 0x%x\n",
		rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));

	checkDS(ts, dcache, p, rpmteNEVRA(p), rpmteDS(p, RPMTAG_REQUIRENAME),
		NULL, tscolor);
	checkDS(ts, dcache, p, rpmteNEVRA(p), rpmteDS(p, RPMTAG_CONFLICTNAME),
		NULL, tscolor);
	checkDS(ts, dcache, p, rpmteNEVRA(p), rpmteDS(p, RPMTAG_OBSOLETENAME),
		NULL, tscolor);

	/* Check provides against conflicts in installed packages. */
	while (rpmdsNext(provides) >= 0) {
	    checkInstDeps(ts, dcache, p, RPMTAG_CONFLICTNAME, rpmdsN(provides));
	}

	/* Skip obsoletion checks for source packages (ie build) */
	if (rpmteIsSource(p))
	    continue;

	/* Check package name (not provides!) against installed obsoletes */
	checkInstDeps(ts, dcache, p, RPMTAG_OBSOLETENAME, rpmteN(p));

	/* Check filenames against installed conflicts */
        if (conflictsCacheNumKeys(confcache)) {
	    rpmfi fi = rpmfiInit(rpmteFI(p), 0);
	    while (rpmfiNext(fi) >= 0) {
		const char *fn = rpmfiFN(fi);
		if (!conflictsCacheHasEntry(confcache, fn))
		    continue;
		checkInstDeps(ts, dcache, p, RPMTAG_CONFLICTNAME, fn);
	    }
	}
    }
    rpmtsiFree(pi);

    /*
     * Look at the removed packages and make sure they aren't critical.
     */
    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, TR_REMOVED)) != NULL) {
	rpmds provides = rpmdsInit(rpmteDS(p, RPMTAG_PROVIDENAME));
	rpmfi fi = rpmfiInit(rpmteFI(p), 0);

	rpmlog(RPMLOG_DEBUG, "========== --- %s %s/%s 0x%x\n",
		rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));

	/* Check provides and filenames against installed dependencies. */
	while (rpmdsNext(provides) >= 0) {
	    checkInstDeps(ts, dcache, p, RPMTAG_REQUIRENAME, rpmdsN(provides));
	}

	while (rpmfiNext(fi) >= 0) {
	    if (RPMFILE_IS_INSTALLED(rpmfiFState(fi)))
		checkInstDeps(ts, dcache, p, RPMTAG_REQUIRENAME, rpmfiFN(fi));
	}
    }
    rpmtsiFree(pi);

exit:
    depCacheFree(dcache);
    conflictsCacheFree(confcache);

    (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_CHECK), 0);

    if (closeatexit)
	(void) rpmtsCloseDB(ts);
    return rc;
}
Example #17
0
/*
 * 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;
}
Example #18
0
rpmte * rpmalAllSatisfiesDepend(const rpmal al, const rpmds ds)
{
    rpmte * ret = NULL;
    int i, ix, found;
    rpmsid nameId;
    const char *name;
    availableIndexEntry result;
    int resultCnt;
    int obsolete;
    rpmTagVal dtag;
    rpmds filterds = NULL;

    availablePackage alp;
    int rc;

    if (al == NULL || ds == NULL || (nameId = rpmdsNId(ds)) == 0)
	return ret;

    dtag = rpmdsTagN(ds);
    obsolete = (dtag == RPMTAG_OBSOLETENAME);
    if (dtag == RPMTAG_OBSOLETENAME || dtag == RPMTAG_CONFLICTNAME)
	filterds = ds;
    name = rpmstrPoolStr(al->pool, nameId);
    if (!obsolete && *name == '/') {
	/* First, look for files "contained" in package ... */
	ret = rpmalAllFileSatisfiesDepend(al, name, filterds);
	if (ret != NULL && *ret != NULL) {
	    rpmdsNotify(ds, "(added files)", 0);
	    return ret;
	}
	/* ... then, look for files "provided" by package. */
	ret = _free(ret);
    }

    if (al->providesHash == NULL)
	rpmalMakeProvidesIndex(al);

    rpmalDepHashGetEntry(al->providesHash, nameId, &result,
			      &resultCnt, NULL);

    if (resultCnt==0) return NULL;

    ret = xmalloc((resultCnt+1) * sizeof(*ret));

    for (found=i=0; i<resultCnt; i++) {
	alp = al->list + result[i].pkgNum;
	if (alp->p == NULL) /* deleted */
	    continue;
	/* ignore self-conflicts/obsoletes */
	if (filterds && rpmteDS(alp->p, rpmdsTagN(filterds)) == filterds)
	    continue;
	ix = result[i].entryIx;

	if (obsolete) {
	    /* Obsoletes are on package NEVR only */
	    rpmds thisds;
	    if (!rstreq(rpmdsNIndex(alp->provides, ix), rpmteN(alp->p)))
		continue;
	    thisds = rpmteDS(alp->p, RPMTAG_NAME);
	    rc = rpmdsCompareIndex(thisds, rpmdsIx(thisds), ds, rpmdsIx(ds));
	} else {
	    rc = rpmdsCompareIndex(alp->provides, ix, ds, rpmdsIx(ds));
	}

	if (rc)
	    ret[found++] = alp->p;
    }

    if (found) {
	rpmdsNotify(ds, "(added provide)", 0);
	ret[found] = NULL;
    } else {
	ret = _free(ret);
    }

    return ret;
}