Esempio n. 1
0
/*
 * Transaction main loop: install and remove packages
 */
static int rpmtsProcess(rpmts ts)
{
    rpmtsi pi;	rpmte p;
    int rc = 0;

    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, 0)) != NULL) {
	int failed = 1;
	rpmElementType tetype = rpmteType(p);
	rpmtsOpX op = (tetype == TR_ADDED) ? RPMTS_OP_INSTALL : RPMTS_OP_ERASE;

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

	if (rpmteFailed(p)) {
	    /* XXX this should be a warning, need a better message though */
	    rpmlog(RPMLOG_DEBUG, "element %s marked as failed, skipping\n",
					rpmteNEVRA(p));
	    rc++;
	    continue;
	}
	
	if (rpmteOpen(p, ts, 1)) {
	    rpmpsm psm = NULL;
	    pkgStage stage = PSM_UNKNOWN;
	    int async = (rpmtsiOc(pi) >= rpmtsUnorderedSuccessors(ts, -1)) ? 
			1 : 0;

	    switch (tetype) {
	    case TR_ADDED:
		stage = PSM_PKGINSTALL;
		break;
	    case TR_REMOVED:
		stage = PSM_PKGERASE;
		break;
	    }
	    psm = rpmpsmNew(ts, p);
	    rpmpsmSetAsync(psm, async);

	    (void) rpmswEnter(rpmtsOp(ts, op), 0);
	    failed = rpmpsmStage(psm, stage);
	    (void) rpmswExit(rpmtsOp(ts, op), 0);
	    psm = rpmpsmFree(psm);
	    rpmteClose(p, ts, 1);
	}
	if (failed) {
	    rpmteMarkFailed(p, ts);
	    rc++;
	}
	(void) rpmdbSync(rpmtsGetRdb(ts));
    }
    pi = rpmtsiFree(pi);
    return rc;
}
Esempio n. 2
0
/*
 * Transaction main loop: install and remove packages
 */
static int rpmtsProcess(rpmts ts)
{
    rpmtsi pi;	rpmte p;
    int rc = 0;

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

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

	failed = rpmteProcess(p, rpmteType(p));
	if (failed) {
	    rpmlog(RPMLOG_ERR, "%s: %s %s\n", rpmteNEVRA(p),
		   rpmteTypeString(p), failed > 1 ? _("skipped") : _("failed"));
	    rc++;
	}
    }
    rpmtsiFree(pi);
    return rc;
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}
Esempio n. 5
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;
}
Esempio n. 6
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;
}