/* Get a rpmdbMatchIterator containing all files in * the rpmdb that share the basename with one from * the transaction. * @param ts transaction set * @return rpmdbMatchIterator sorted by (package, fileNum) */ static rpmdbMatchIterator rpmFindBaseNamesInDB(rpmts ts) { rpmtsi pi; rpmte p; rpmfi fi; int fc=0; rpmdbMatchIterator mi; int i, xx; const char * baseName; /* get number of files in transaction */ // XXX move to ts pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, 0)) != NULL) { if ((fi = rpmteFI(p)) == NULL) continue; /* XXX can't happen */ fc += rpmfiFC(fi); } pi = rpmtsiFree(pi); rpmStringSet baseNames = rpmStringSetCreate(fc, hashFunctionString, strcmp, NULL); mi = rpmdbInitIterator(rpmtsGetRdb(ts), RPMTAG_BASENAMES, NULL, 0); pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, 0)) != NULL) { (void) rpmdbCheckSignals(); if ((fi = rpmteFI(p)) == NULL) continue; /* XXX can't happen */ rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_PROGRESS, rpmtsiOc(pi), ts->orderCount); /* Gather all installed headers with matching basename's. */ fi = rpmfiInit(fi, 0); while ((i = rpmfiNext(fi)) >= 0) { size_t keylen; baseName = rpmfiBN(fi); if (rpmStringSetHasEntry(baseNames, baseName)) continue; keylen = strlen(baseName); if (keylen == 0) keylen++; /* XXX "/" fixup. */ xx = rpmdbExtendIterator(mi, baseName, keylen); rpmStringSetAddEntry(baseNames, baseName); } } pi = rpmtsiFree(pi); rpmStringSetFree(baseNames); rpmdbSortIterator(mi); /* iterator is now sorted by (recnum, filenum) */ return mi; }
/* * 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; }
static JSBool rpmts_enumerate(JSContext *cx, JSObject *obj, JSIterateOp op, jsval *statep, jsid *idp) { void * ptr = JS_GetInstancePrivate(cx, obj, &rpmtsClass, NULL); rpmts ts = ptr; rpmtsi tsi; JSObject *tsio = NULL; JSBool ok = JS_FALSE; _ENUMERATE_DEBUG_ENTRY(_debug); switch (op) { case JSENUMERATE_INIT: if ((tsio = JS_NewObject(cx, &rpmtsiClass, NULL, obj)) == NULL) goto exit; if ((tsi = rpmtsiInit(ts)) == NULL) goto exit; if (!JS_SetPrivate(cx, tsio, (void *)tsi)) { tsi = rpmtsiFree(tsi); goto exit; } *statep = OBJECT_TO_JSVAL(tsio); if (idp) *idp = JSVAL_ZERO; if (_debug) fprintf(stderr, "\tINIT tsio %p tsi %p\n", tsio, tsi); break; case JSENUMERATE_NEXT: tsio = (JSObject *) JSVAL_TO_OBJECT(*statep); tsi = JS_GetInstancePrivate(cx, tsio, &rpmtsiClass, NULL); if (rpmtsiNext(tsi, 0) != NULL) { int oc = rpmtsiOc(tsi); if (_debug) fprintf(stderr, "\tNEXT tsio %p tsi %p[%d]\n", tsio, tsi, oc); JS_ValueToId(cx, INT_TO_JSVAL(oc), idp); } else *idp = JSVAL_VOID; if (*idp != JSVAL_VOID) break; /*@fallthrough@*/ case JSENUMERATE_DESTROY: tsio = (JSObject *) JSVAL_TO_OBJECT(*statep); tsi = JS_GetInstancePrivate(cx, tsio, &rpmtsiClass, NULL); if (_debug) fprintf(stderr, "\tFINI tsio %p tsi %p\n", tsio, tsi); /* Allow our iterator object to be GC'd. */ *statep = JSVAL_NULL; break; } ok = JS_TRUE; exit: return ok; }