static PyObject * rpmts_Match(rpmtsObject * s, PyObject * args, PyObject * kwds) { PyObject *Key = NULL; PyObject *str = NULL; PyObject *mio = NULL; char *key = NULL; /* XXX lkey *must* be a 32 bit integer, int "works" on all known platforms. */ int lkey = 0; int len = 0; rpmDbiTagVal tag = RPMDBI_PACKAGES; char * kwlist[] = {"tagNumber", "key", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&O:Match", kwlist, tagNumFromPyObject, &tag, &Key)) return NULL; if (Key) { if (PyInt_Check(Key)) { lkey = PyInt_AsLong(Key); key = (char *)&lkey; len = sizeof(lkey); } else if (utf8FromPyObject(Key, &str)) { key = PyBytes_AsString(str); len = PyBytes_Size(str); } else { PyErr_SetString(PyExc_TypeError, "unknown key type"); return NULL; } /* One of the conversions above failed, exception is set already */ if (PyErr_Occurred()) goto exit; } /* XXX If not already opened, open the database O_RDONLY now. */ /* XXX FIXME: lazy default rdonly open also done by rpmtsInitIterator(). */ if (rpmtsGetRdb(s->ts) == NULL) { int rc = rpmtsOpenDB(s->ts, O_RDONLY); if (rc || rpmtsGetRdb(s->ts) == NULL) { PyErr_SetString(pyrpmError, "rpmdb open failed"); goto exit; } } mio = rpmmi_Wrap(&rpmmi_Type, rpmtsInitIterator(s->ts, tag, key, len), (PyObject*)s); exit: Py_XDECREF(str); return mio; }
static JSObject * rpmtsLoadNVRA(JSContext *cx, JSObject *obj) { void * ptr = JS_GetInstancePrivate(cx, obj, &rpmtsClass, NULL); rpmts ts = ptr; JSObject * NVRA = JS_NewArrayObject(cx, 0, NULL); ARGV_t keys = NULL; int nkeys; int xx; int i; if (ts->rdb == NULL) (void) rpmtsOpenDB(ts, O_RDONLY); xx = rpmdbMireApply(rpmtsGetRdb(ts), RPMTAG_NVRA, RPMMIRE_STRCMP, NULL, &keys); nkeys = argvCount(keys); if (keys) for (i = 0; i < nkeys; i++) { JSString * valstr = JS_NewStringCopyZ(cx, keys[i]); jsval id = STRING_TO_JSVAL(valstr); JS_SetElement(cx, NVRA, i, &id); } JS_DefineProperty(cx, obj, "NVRA", OBJECT_TO_JSVAL(NVRA), NULL, NULL, JSPROP_ENUMERATE); if (_debug) fprintf(stderr, "==> %s(%p,%p) ptr %p NVRA %p\n", __FUNCTION__, cx, obj, ptr, NVRA); return NVRA; }
/** * 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; }
static rpmRC dbAdd(rpmts ts, rpmte te) { Header h = rpmteHeader(te); rpm_time_t installTime = (rpm_time_t) time(NULL); rpmfs fs = rpmteGetFileStates(te); rpm_count_t fc = rpmfsFC(fs); rpm_fstate_t * fileStates = rpmfsGetStates(fs); rpm_color_t tscolor = rpmtsColor(ts); rpm_tid_t tid = rpmtsGetTid(ts); rpmRC rc; if (fileStates != NULL && fc > 0) { headerPutChar(h, RPMTAG_FILESTATES, fileStates, fc); } headerPutUint32(h, RPMTAG_INSTALLTID, &tid, 1); headerPutUint32(h, RPMTAG_INSTALLTIME, &installTime, 1); headerPutUint32(h, RPMTAG_INSTALLCOLOR, &tscolor, 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(te, headerGetInstance(h)); headerFree(h); return rc; }
static void addIndexToDepHashes(rpmts ts, rpmDbiTag tag, depexistsHash dephash, filedepHash filehash, depexistsHash depnothash, filedepHash filenothash) { char *key; size_t keylen; rpmdbIndexIterator ii = rpmdbIndexIteratorInit(rpmtsGetRdb(ts), tag); if (!ii) return; while ((rpmdbIndexIteratorNext(ii, (const void**)&key, &keylen)) == 0) { if (!key || !keylen) continue; if (*key == '!' && keylen > 1) { key++; keylen--; if (*key == '/' && filenothash) addFileDepToHash(filenothash, key, keylen); if (depnothash) addDepToHash(depnothash, key, keylen); } else { if (*key == '/' && filehash) addFileDepToHash(filehash, key, keylen); if (dephash) addDepToHash(dephash, key, keylen); } } rpmdbIndexIteratorFree(ii); }
int rpmtsSetDBMode(rpmts ts, int dbmode) { int rc = 1; /* mode setting only permitted on non-open db */ if (ts != NULL && rpmtsGetRdb(ts) == NULL) { ts->dbmode = dbmode; rc = 0; } return rc; }
/* 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; }
rpmRC rpmtsImportHeader(rpmtxn txn, Header h, rpmFlags flags) { rpmRC rc = RPMRC_FAIL; if (txn && h && rpmtsOpenDB(txn->ts, (O_RDWR|O_CREAT)) == 0) { if (rpmdbAdd(rpmtsGetRdb(txn->ts), h) == 0) { rc = RPMRC_OK; } } return rc; }
int rpmcliVerify(rpmts ts, QVA_t qva, char * const * argv) { rpmVSFlags vsflags, ovsflags; int ec = 0, xx; const char * rootDir = rpmtsRootDir(ts); /* * Open the DB + indices explicitly before possible chroot, * otherwises BDB is going to be unhappy... */ rpmtsOpenDB(ts, O_RDONLY); rpmdbOpenAll(rpmtsGetRdb(ts)); if (rootDir && strcmp(rootDir, "/") != 0) { if (chroot(rootDir) == -1) { rpmlog(RPMLOG_ERR, _("Unable to change root directory: %m\n")); ec = 1; goto exit; } else { rpmtsSetChrootDone(ts, 1); } } if (qva->qva_showPackage == NULL) qva->qva_showPackage = showVerifyPackage; /* XXX verify flags are inverted from query. */ vsflags = rpmExpandNumeric("%{?_vsflags_verify}"); if (!(qva->qva_flags & VERIFY_DIGEST)) vsflags |= _RPMVSF_NODIGESTS; if (!(qva->qva_flags & VERIFY_SIGNATURE)) vsflags |= _RPMVSF_NOSIGNATURES; if (!(qva->qva_flags & VERIFY_HDRCHK)) vsflags |= RPMVSF_NOHDRCHK; vsflags &= ~RPMVSF_NEEDPAYLOAD; ovsflags = rpmtsSetVSFlags(ts, vsflags); ec = rpmcliArgIter(ts, qva, argv); vsflags = rpmtsSetVSFlags(ts, ovsflags); if (qva->qva_showPackage == showVerifyPackage) qva->qva_showPackage = NULL; rpmtsEmpty(ts); if (rpmtsChrootDone(ts)) { /* only done if previous chroot succeeded, assume success */ xx = chroot("."); rpmtsSetChrootDone(ts, 0); } exit: return ec; }
/* return DSI of the device the rpmdb lives on */ static rpmDiskSpaceInfo rpmtsDbDSI(const rpmts ts) { const char *dbhome = rpmdbHome(rpmtsGetRdb(ts)); struct stat sb; int rc; rc = stat(dbhome, &sb); if (rc) { return NULL; } return rpmtsGetDSI(ts, sb.st_dev, dbhome); }
static const char *matchFilesNext(matchFilesIter mfi) { const char *matchFile = NULL; int fx = 0; /* Decide if we iterate over given files (mfi->files) */ if (!mfi->ts) do { /* Get next file from mfi->fi */ rpmfiNext(mfi->fi); matchFile = rpmfiFN(mfi->fi); if (strlen(matchFile)) break; matchFile = NULL; /* If we are done with current mfi->fi, create mfi->fi for next prefix */ fx = rpmdsNext(mfi->rpmdsTrigger); mfi->pfx = rpmdsN(mfi->rpmdsTrigger); rpmfiFree(mfi->fi); mfi->fi = rpmfilesFindPrefix(mfi->files, mfi->pfx); } while (fx >= 0); /* or we iterate over files in rpmdb */ else do { rpmfiNext(mfi->fi); matchFile = rpmfiFN(mfi->fi); if (strlen(matchFile)) break; matchFile = NULL; /* If we are done with current mfi->fi, create mfi->fi for next package */ rpmfilesFree(mfi->files); rpmfiFree(mfi->fi); mfi->files = rpmtsNextFiles(mfi->ts, mfi->pi); mfi->fi = rpmfilesFindPrefix(mfi->files, mfi->pfx); if (mfi->files) continue; /* If we are done with all packages, go through packages with new prefix */ fx = rpmdsNext(mfi->rpmdsTrigger); mfi->pfx = rpmdsN(mfi->rpmdsTrigger); rpmdbFreeIterator(mfi->pi); mfi->pi = rpmdbInitPrefixIterator(rpmtsGetRdb(mfi->ts), RPMDBI_DIRNAMES, mfi->pfx, 0); rpmdbFilterIterator(mfi->pi, mfi->tranPkgs, 0); } while (fx >= 0); return matchFile; }
/* 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, uint64_t fileCount) { tsMembers tsmem = rpmtsMembers(ts); rpmstrPool tspool = rpmtsPool(ts); rpmtsi pi; rpmte p; rpmfiles files; rpmfi fi; rpmdbMatchIterator mi; int oc = 0; const char * baseName; rpmsid baseNameId; rpmStringSet baseNames = rpmStringSetCreate(fileCount, sidHash, sidCmp, NULL); mi = rpmdbNewIterator(rpmtsGetRdb(ts), RPMDBI_BASENAMES); pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, 0)) != NULL) { (void) rpmdbCheckSignals(); rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_PROGRESS, oc++, tsmem->orderCount); /* Gather all installed headers with matching basename's. */ files = rpmteFiles(p); fi = rpmfilesIter(files, RPMFI_ITER_FWD); while (rpmfiNext(fi) >= 0) { size_t keylen; baseNameId = rpmfiBNId(fi); if (rpmStringSetHasEntry(baseNames, baseNameId)) continue; keylen = rpmstrPoolStrlen(tspool, baseNameId); baseName = rpmstrPoolStr(tspool, baseNameId); if (keylen == 0) keylen++; /* XXX "/" fixup. */ rpmdbExtendIterator(mi, baseName, keylen); rpmStringSetAddEntry(baseNames, baseNameId); } rpmfiFree(fi); rpmfilesFree(files); } rpmtsiFree(pi); rpmStringSetFree(baseNames); rpmdbSortIterator(mi); /* iterator is now sorted by (recnum, filenum) */ return mi; }
static rpmRC dbRemove(rpmts ts, rpmte te) { rpmRC rc; (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DBREMOVE), 0); rc = (rpmdbRemove(rpmtsGetRdb(ts), rpmteDBInstance(te)) == 0) ? RPMRC_OK : RPMRC_FAIL; (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DBREMOVE), 0); if (rc == RPMRC_OK) rpmteSetDBInstance(te, 0); return rc; }
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; }
int getPackageStr(rpmts ts, const char *NVRA, rpmTag tag, char **value) { int rc = -1; rpmmi mi = rpmmiInit(rpmtsGetRdb(ts), RPMTAG_NVRA, NVRA, 0); Header h; if ((h = rpmmiNext(mi)) != NULL) { HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he)); he->tag = tag; rc = (headerGet(h, he, 0) != 1); if(rc==0) *value = strdup((char *)he->p.ptr); } (void)rpmmiFree(mi); return rc; }
int rpmcliVerify(rpmts ts, QVA_t qva, char * const * argv) { rpmVSFlags vsflags, ovsflags; int ec = 0; FD_t scriptFd = fdDup(STDOUT_FILENO); /* * Open the DB + indices explicitly before possible chroot, * otherwises BDB is going to be unhappy... */ rpmtsOpenDB(ts, O_RDONLY); rpmdbOpenAll(rpmtsGetRdb(ts)); if (rpmChrootSet(rpmtsRootDir(ts)) || rpmChrootIn()) { ec = 1; goto exit; } if (qva->qva_showPackage == NULL) qva->qva_showPackage = showVerifyPackage; vsflags = rpmExpandNumeric("%{?_vsflags_verify}"); if (rpmcliQueryFlags & VERIFY_DIGEST) vsflags |= _RPMVSF_NODIGESTS; if (rpmcliQueryFlags & VERIFY_SIGNATURE) vsflags |= _RPMVSF_NOSIGNATURES; if (rpmcliQueryFlags & VERIFY_HDRCHK) vsflags |= RPMVSF_NOHDRCHK; vsflags &= ~RPMVSF_NEEDPAYLOAD; rpmtsSetScriptFd(ts, scriptFd); ovsflags = rpmtsSetVSFlags(ts, vsflags); ec = rpmcliArgIter(ts, qva, argv); vsflags = rpmtsSetVSFlags(ts, ovsflags); rpmtsSetScriptFd(ts, NULL); if (qva->qva_showPackage == showVerifyPackage) qva->qva_showPackage = NULL; rpmtsEmpty(ts); if (rpmChrootOut() || rpmChrootSet(NULL)) ec = 1; exit: Fclose(scriptFd); return ec; }
rpmRC rpmtsImportPubkey(const rpmts ts, const unsigned char * pkt, size_t pktlen) { Header h = NULL; rpmRC rc = RPMRC_FAIL; /* assume failure */ rpmPubkey pubkey = NULL; rpmVSFlags oflags = rpmtsVSFlags(ts); rpmKeyring keyring; int krc; /* XXX keyring wont load if sigcheck disabled, force it temporarily */ rpmtsSetVSFlags(ts, (oflags & ~_RPMVSF_NOSIGNATURES)); keyring = rpmtsGetKeyring(ts, 1); rpmtsSetVSFlags(ts, oflags); if ((pubkey = rpmPubkeyNew(pkt, pktlen)) == NULL) goto exit; krc = rpmKeyringAddKey(keyring, pubkey); if (krc < 0) goto exit; /* If we dont already have the key, make a persistent record of it */ if (krc == 0) { rpm_tid_t tid = rpmtsGetTid(ts); if (makePubkeyHeader(ts, pubkey, &h) != 0) goto exit; headerPutUint32(h, RPMTAG_INSTALLTIME, &tid, 1); headerPutUint32(h, RPMTAG_INSTALLTID, &tid, 1); /* Add header to database. */ if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) { if (rpmtsOpenDB(ts, (O_RDWR|O_CREAT))) goto exit; if (rpmdbAdd(rpmtsGetRdb(ts), h) != 0) goto exit; } } rc = RPMRC_OK; exit: /* Clean up. */ headerFree(h); rpmPubkeyFree(pubkey); rpmKeyringFree(keyring); return rc; }
/* 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, uint64_t fileCount) { tsMembers tsmem = rpmtsMembers(ts); rpmtsi pi; rpmte p; rpmfi fi; rpmdbMatchIterator mi; int xx; int oc = 0; const char * baseName; rpmStringSet baseNames = rpmStringSetCreate(fileCount, hashFunctionString, strcmp, NULL); mi = rpmdbNewIterator(rpmtsGetRdb(ts), RPMDBI_BASENAMES); pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, 0)) != NULL) { (void) rpmdbCheckSignals(); rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_PROGRESS, oc++, tsmem->orderCount); /* Gather all installed headers with matching basename's. */ fi = rpmfiInit(rpmteFI(p), 0); while (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; }
int lookupProvider(rpmts ts, const char *req, char **provider) { int rc = 0; rpmmi provmi = rpmmiInit(rpmtsGetRdb(ts), RPMTAG_PROVIDENAME, req, 0); if(provmi) { Header h; if ((h = rpmmiNext(provmi)) != NULL) { HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he)); he->tag = RPMTAG_NAME; rc = (headerGet(h, he, 0) != 1); if(rc==0) *provider = strdup((char *)he->p.ptr); } (void)rpmmiFree(provmi); } else { rc = -1; } return rc; }
/* Return true if any added/removed file in ts starts with pfx */ static int matchFilesInTran(rpmts ts, rpmte te, const char *pfx, rpmsenseFlags sense) { int rc = 1; rpmdbMatchIterator pi; /* Get all files from rpmdb starting with pfx */ pi = rpmdbInitPrefixIterator(rpmtsGetRdb(ts), RPMDBI_DIRNAMES, pfx, 0); if (sense & RPMSENSE_TRIGGERIN) /* Leave in pi only files installed in ts */ rpmdbFilterIterator(pi, ts->members->installedPackages, 0); else /* Leave in pi only files removed in ts */ rpmdbFilterIterator(pi, ts->members->removedPackages, 0); rc = rpmdbGetIteratorCount(pi); rpmdbFreeIterator(pi); return rc; }
int runPostUnTransFileTrigs(rpmts ts) { int i; Header trigH; struct rpmtd_s installPrefixes; rpmScript script; rpmtriggers trigs = ts->trigs2run; int nerrors = 0; if (rpmChrootIn() != 0) return -1; rpmtriggersSortAndUniq(trigs); /* Iterate over stored triggers */ for (i = 0; i < trigs->count; i++) { /* Get header containing trigger script */ trigH = rpmdbGetHeaderAt(rpmtsGetRdb(ts), trigs->triggerInfo[i].hdrNum); /* Maybe package with this trigger is already uninstalled */ if (trigH == NULL) continue; /* Prepare and run script */ script = rpmScriptFromTriggerTag(trigH, RPMSENSE_TRIGGERPOSTUN, RPMSCRIPT_TRANSFILETRIGGER, trigs->triggerInfo[i].tix); headerGet(trigH, RPMTAG_INSTPREFIXES, &installPrefixes, HEADERGET_ALLOC|HEADERGET_ARGV); nerrors += runScript(ts, NULL, installPrefixes.data, script, 0, 0); rpmtdFreeData(&installPrefixes); rpmScriptFree(script); headerFree(trigH); } rpmChrootOut(); return nerrors; }
/* * 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++; } (void) rpmdbSync(rpmtsGetRdb(ts)); } rpmtsiFree(pi); return rc; }
/** * Execute triggers. * @todo Trigger on any provides, not just package NVR. * @param ts transaction set * @param te transaction element * @param sense trigger type * @param sourceH header of trigger source * @param trigH header of triggered package * @param arg2 * @param triggersAlreadyRun * @return */ static rpmRC handleOneTrigger(rpmts ts, rpmte te, rpmsenseFlags sense, Header sourceH, Header trigH, int countCorrection, int arg2, unsigned char * triggersAlreadyRun) { rpmds trigger = rpmdsInit(rpmdsNew(trigH, RPMTAG_TRIGGERNAME, 0)); struct rpmtd_s pfx; const char * sourceName = headerGetString(sourceH, RPMTAG_NAME); const char * triggerName = headerGetString(trigH, RPMTAG_NAME); rpmRC rc = RPMRC_OK; int i; if (trigger == NULL) return rc; headerGet(trigH, RPMTAG_INSTPREFIXES, &pfx, HEADERGET_ALLOC|HEADERGET_ARGV); (void) rpmdsSetNoPromote(trigger, 1); while ((i = rpmdsNext(trigger)) >= 0) { uint32_t tix; if (!(rpmdsFlags(trigger) & sense)) continue; if (!rstreq(rpmdsN(trigger), sourceName)) continue; /* XXX Trigger on any provided dependency, not just the package NEVR */ if (!rpmdsAnyMatchesDep(sourceH, trigger, 1)) continue; tix = rpmdsTi(trigger); if (triggersAlreadyRun == NULL || triggersAlreadyRun[tix] == 0) { int arg1 = rpmdbCountPackages(rpmtsGetRdb(ts), triggerName); if (arg1 < 0) { /* XXX W2DO? fails as "execution of script failed" */ rc = RPMRC_FAIL; } else { rpmScript script = rpmScriptFromTriggerTag(trigH, triggertag(sense), tix); arg1 += countCorrection; rc = runScript(ts, te, pfx.data, script, arg1, arg2); if (triggersAlreadyRun != NULL) triggersAlreadyRun[tix] = 1; rpmScriptFree(script); } } /* * Each target/source header pair can only result in a single * script being run. */ break; } rpmtdFreeData(&pfx); rpmdsFree(trigger); return rc; }
static int rpmtsPrepare(rpmts ts) { tsMembers tsmem = rpmtsMembers(ts); rpmtsi pi; rpmte p; int rc = 0; uint64_t fileCount = countFiles(ts); const char *dbhome = NULL; struct stat dbstat; fingerPrintCache fpc = fpCacheCreate(fileCount/2 + 10001, rpmtsPool(ts)); rpmlog(RPMLOG_DEBUG, "computing %" PRIu64 " file fingerprints\n", fileCount); /* Reset actions, set skip for netshared paths and excluded files */ pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, 0)) != NULL) { rpmfiles files = rpmteFiles(p); if (rpmfilesFC(files) > 0) { rpmfs fs = rpmteGetFileStates(p); /* Ensure clean state, this could get called more than once. */ rpmfsResetActions(fs); if (rpmteType(p) == TR_ADDED) { skipInstallFiles(ts, files, fs); } else { skipEraseFiles(ts, files, fs); } } rpmfilesFree(files); } rpmtsiFree(pi); /* Open rpmdb & enter chroot for fingerprinting if necessary */ if (rpmdbOpenAll(ts->rdb) || rpmChrootIn()) { rc = -1; goto exit; } rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_START, 6, tsmem->orderCount); /* Add fingerprint for each file not skipped. */ fpCachePopulate(fpc, ts, fileCount); /* check against files in the rpmdb */ checkInstalledFiles(ts, fileCount, fpc); dbhome = rpmdbHome(rpmtsGetRdb(ts)); /* If we can't stat, ignore db growth. Probably not right but... */ if (dbhome && stat(dbhome, &dbstat)) dbhome = NULL; pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, 0)) != NULL) { rpmfiles files = rpmteFiles(p);; if (files == 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, fpc, p, files); /* Check added package has sufficient space on each partition used. */ if (rpmteType(p) == TR_ADDED) { /* * Try to estimate space needed for rpmdb growth: guess that the * db grows 4 times the header size (indexes and all). */ if (dbhome) { int64_t hsize = rpmteHeaderSize(p) * 4; rpmtsUpdateDSI(ts, dbstat.st_dev, dbhome, hsize, 0, 0, FA_CREATE); } rpmtsCheckDSIProblems(ts, p); } (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0); rpmfilesFree(files); } rpmtsiFree(pi); rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_STOP, 6, tsmem->orderCount); /* return from chroot if done earlier */ if (rpmChrootOut()) rc = -1; /* On actual transaction, file info sets are not needed after this */ if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS))) { pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, 0)) != NULL) { rpmteCleanFiles(p); } rpmtsiFree(pi); } exit: fpCacheFree(fpc); rpmtsFreeDSI(ts); return rc; }
rpmRC runFileTriggers(rpmts ts, rpmte te, rpmsenseFlags sense, rpmscriptTriggerModes tm, int priorityClass) { int nerrors = 0, i; rpmdbIndexIterator ii; const void *key; char *pfx; size_t keylen; Header trigH; int (*matchFunc)(rpmts, rpmte, const char*, rpmsenseFlags sense); rpmTagVal priorityTag; rpmtriggers triggers = rpmtriggersCreate(10); /* Decide if we match triggers against files in te or in whole ts */ if (tm == RPMSCRIPT_FILETRIGGER) { matchFunc = matchFilesInPkg; priorityTag = RPMTAG_FILETRIGGERPRIORITIES; } else { matchFunc = matchFilesInTran; priorityTag = RPMTAG_TRANSFILETRIGGERPRIORITIES; } ii = rpmdbIndexIteratorInit(rpmtsGetRdb(ts), triggerDsTag(tm)); /* Loop over all file triggers in rpmdb */ while ((rpmdbIndexIteratorNext(ii, &key, &keylen)) == 0) { pfx = xmalloc(keylen + 1); memcpy(pfx, key, keylen); pfx[keylen] = '\0'; /* Check if file trigger is fired by any file in ts/te */ if (matchFunc(ts, te, pfx, sense)) { for (i = 0; i < rpmdbIndexIteratorNumPkgs(ii); i++) { struct rpmtd_s priorities; unsigned int priority; unsigned int offset = rpmdbIndexIteratorPkgOffset(ii, i); unsigned int tix = rpmdbIndexIteratorTagNum(ii, i); /* * Don't handle transaction triggers installed in current * transaction to avoid executing the same script two times. * These triggers are handled in runImmedFileTriggers(). */ if (tm == RPMSCRIPT_TRANSFILETRIGGER && (packageHashHasEntry(ts->members->removedPackages, offset) || packageHashHasEntry(ts->members->installedPackages, offset))) continue; /* Get priority of trigger from header */ trigH = rpmdbGetHeaderAt(rpmtsGetRdb(ts), offset); headerGet(trigH, priorityTag, &priorities, HEADERGET_MINMEM); rpmtdSetIndex(&priorities, tix); priority = *rpmtdGetUint32(&priorities); headerFree(trigH); /* Store file trigger in array */ rpmtriggersAdd(triggers, offset, tix, priority); } } free(pfx); } rpmdbIndexIteratorFree(ii); /* Sort triggers by priority, offset, trigger index */ rpmtriggersSortAndUniq(triggers); if (rpmChrootIn() != 0) { rpmtriggersFree(triggers); return RPMRC_FAIL; } /* Handle stored triggers */ for (i = 0; i < triggers->count; i++) { if (priorityClass == 1) { if (triggers->triggerInfo[i].priority < TRIGGER_PRIORITY_BOUND) continue; } else if (priorityClass == 2) { if (triggers->triggerInfo[i].priority >= TRIGGER_PRIORITY_BOUND) continue; } trigH = rpmdbGetHeaderAt(rpmtsGetRdb(ts), triggers->triggerInfo[i].hdrNum); if (tm == RPMSCRIPT_FILETRIGGER) nerrors += runHandleTriggersInPkg(ts, te, trigH, sense, tm, 0, triggers->triggerInfo[i].tix); else nerrors += runHandleTriggersInPkg(ts, te, trigH, sense, tm, 1, triggers->triggerInfo[i].tix); headerFree(trigH); } rpmtriggersFree(triggers); /* XXX an error here would require a full abort */ (void) rpmChrootOut(); return (nerrors == 0) ? RPMRC_OK : RPMRC_FAIL; }
static JSBool rpmts_dbkeys(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { void * ptr = JS_GetInstancePrivate(cx, obj, &rpmtsClass, NULL); rpmts ts = ptr; jsval tagid = JSVAL_VOID; jsval v = JSVAL_VOID; rpmTag tag = RPMTAG_NVRA; rpmMireMode _mode = RPMMIRE_PCRE; const char * _pat = "^a.*$"; ARGV_t _av = NULL; JSBool ok = JS_FALSE; int xx; _METHOD_DEBUG_ENTRY(_debug); if (!(ok = JS_ConvertArguments(cx, argc, argv, "/vvu", &v, &tagid, &v, &_mode))) goto exit; if (!JSVAL_IS_VOID(tagid)) { /* XXX TODO: make sure both tag and key were specified. */ tag = JSVAL_IS_INT(tagid) ? (rpmTag) JSVAL_TO_INT(tagid) : tagValue(JS_GetStringBytes(JS_ValueToString(cx, tagid))); } if (JSVAL_IS_VOID(v)) _pat = "^.*$"; else if (JSVAL_IS_NULL(v)) _pat = NULL; else if (JSVAL_IS_STRING(v)) _pat = JS_GetStringBytes(JS_ValueToString(cx, v)); #ifdef NOTYET else if (JSVAL_IS_NUMBER(v)) { uint32_t _u = 0; if (!JS_ValueToECMAUint32(cx, v, &_u)) { *rval = JSVAL_VOID; goto exit; } } else ; #endif switch (_mode) { default: *rval = JSVAL_VOID; goto exit; break; case RPMMIRE_DEFAULT: case RPMMIRE_STRCMP: case RPMMIRE_REGEX: case RPMMIRE_GLOB: case RPMMIRE_PCRE: break; } if (rpmtsGetRdb(ts) == NULL) xx = rpmtsOpenDB(ts, O_RDONLY); if (rpmdbMireApply(rpmtsGetRdb(ts), tag, _mode, _pat, &_av)) *rval = JSVAL_VOID; else if (_av == NULL || _av[0] == NULL) *rval = JSVAL_NULL; else { int _ac = argvCount(_av); int i; JSObject * arr = JS_NewArrayObject(cx, 0, NULL); *rval = OBJECT_TO_JSVAL(arr); for (i = 0; i < _ac; i++) { v = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, _av[i])); ok = JS_SetElement(cx, arr, i, &v); } } exit: ok = JS_TRUE; _av = argvFree(_av); return ok; }
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; }
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; }
static int addPackage(rpmts ts, Header h, fnpyKey key, int op, rpmRelocation * relocs) { tsMembers tsmem = rpmtsMembers(ts); rpm_color_t tscolor = rpmtsColor(ts); rpmte p = NULL; int isSource = headerIsSource(h); int ec = 0; int oc = tsmem->orderCount; /* Check for supported payload format if it's a package */ if (key && headerCheckPayloadFormat(h) != RPMRC_OK) { ec = 1; goto exit; } /* Source packages are never "upgraded" */ if (isSource) op = RPMTE_INSTALL; /* Do lazy (readonly?) open of rpm database for upgrades. */ if (op != RPMTE_INSTALL && rpmtsGetRdb(ts) == NULL && rpmtsGetDBMode(ts) != -1) { if ((ec = rpmtsOpenDB(ts, rpmtsGetDBMode(ts))) != 0) goto exit; } p = rpmteNew(ts, h, TR_ADDED, key, relocs); if (p == NULL) { ec = 1; goto exit; } /* Check binary packages for redundancies in the set */ if (!isSource) { oc = findPos(ts, tscolor, p, (op == RPMTE_UPGRADE)); /* If we're replacing a previously added element, free the old one */ if (oc >= 0 && oc < tsmem->orderCount) { rpmalDel(tsmem->addedPackages, tsmem->order[oc]); tsmem->order[oc] = rpmteFree(tsmem->order[oc]); /* If newer NEVR was already added, we're done */ } else if (oc < 0) { p = rpmteFree(p); goto exit; } } if (oc >= tsmem->orderAlloced) { tsmem->orderAlloced += (oc - tsmem->orderAlloced) + tsmem->delta; tsmem->order = xrealloc(tsmem->order, tsmem->orderAlloced * sizeof(*tsmem->order)); } tsmem->order[oc] = p; if (oc == tsmem->orderCount) { tsmem->orderCount++; } if (tsmem->addedPackages == NULL) { tsmem->addedPackages = rpmalCreate(rpmtsPool(ts), 5, rpmtsFlags(ts), tscolor, rpmtsPrefColor(ts)); } rpmalAdd(tsmem->addedPackages, p); /* Add erasure elements for old versions and obsoletions on upgrades */ /* XXX TODO: If either of these fails, we'd need to undo all additions */ if (op != RPMTE_INSTALL) addSelfErasures(ts, tscolor, op, p, rpmteColor(p), h); if (op == RPMTE_UPGRADE) addObsoleteErasures(ts, tscolor, p); exit: return ec; }