/** * Return exit code from running verify script from header. * @todo malloc/free/refcount handling is fishy here. * @param qva parsed query/verify options * @param ts transaction set * @param fi file info set * @param scriptFd file handle to use for stderr (or NULL) * @return 0 on success */ static int rpmVerifyScript(/*@unused@*/ QVA_t qva, rpmts ts, rpmfi fi, /*@null@*/ FD_t scriptFd) /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ /*@modifies ts, fi, scriptFd, rpmGlobalMacroContext, fileSystem, internalState @*/ { rpmpsm psm; rpmRC rc; int ec = 0; if (scriptFd != NULL) rpmtsSetScriptFd(ts, scriptFd); psm = rpmpsmNew(ts, NULL, fi); rc = rpmpsmScriptStage(psm, RPMTAG_VERIFYSCRIPT, RPMTAG_VERIFYSCRIPTPROG); if (rc != RPMRC_OK) ec = 1; rc = rpmpsmScriptStage(psm, RPMTAG_SANITYCHECK, RPMTAG_SANITYCHECKPROG); if (rc != RPMRC_OK) ec = 1; psm = rpmpsmFree(psm, __FUNCTION__); if (scriptFd != NULL) rpmtsSetScriptFd(ts, NULL); return ec; }
/** * Return exit code from running verify script from header. * @todo malloc/free/refcount handling is fishy here. * @param qva parsed query/verify options * @param ts transaction set * @param h header * @param scriptFd file handle to use for stderr (or NULL) * @return 0 on success */ static int rpmVerifyScript(QVA_t qva, rpmts ts, Header h, FD_t scriptFd) { rpmpsm psm = NULL; rpmte te = NULL; int rc = 0; /* fake up a erasure transaction element */ rc = rpmtsAddEraseElement(ts, h, -1); te = rpmtsElement(ts, 0); rpmteOpen(te, ts, 0); if (scriptFd != NULL) rpmtsSetScriptFd(ts, scriptFd); /* create psm to run the script */ psm = rpmpsmNew(ts, te); rpmpsmScriptStage(psm, RPMTAG_VERIFYSCRIPT, RPMTAG_VERIFYSCRIPTPROG); rc = rpmpsmStage(psm, PSM_SCRIPT); psm = rpmpsmFree(psm); if (scriptFd != NULL) rpmtsSetScriptFd(ts, NULL); /* clean up our fake transaction bits */ rpmteClose(te, ts, 0); rpmtsEmpty(ts); return rc; }
/* * 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 rpmpsmRun(rpmts ts, rpmte te, pkgGoal goal) { rpmpsm psm = NULL; rpmRC rc = RPMRC_FAIL; /* Psm can't fail in test mode, just return early */ if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) return RPMRC_OK; psm = rpmpsmNew(ts, te); if (rpmChrootIn() == 0) { rpmtsOpX op; psm->goal = goal; psm->goalName = pkgGoalString(goal); switch (goal) { case PKG_INSTALL: case PKG_ERASE: /* Run pre transaction element hook for all plugins */ if (rpmpluginsCallPsmPre(ts->plugins, te) != RPMRC_FAIL) { op = (goal == PKG_INSTALL) ? RPMTS_OP_INSTALL : RPMTS_OP_ERASE; rpmswEnter(rpmtsOp(psm->ts, op), 0); rc = rpmpsmNext(psm, PSM_INIT); if (!rc) rc = rpmpsmNext(psm, PSM_PRE); if (!rc) rc = rpmpsmNext(psm, PSM_PROCESS); if (!rc) rc = rpmpsmNext(psm, PSM_POST); (void) rpmpsmNext(psm, PSM_FINI); rpmswExit(rpmtsOp(psm->ts, op), 0); } /* Run post transaction element hook for all plugins */ rpmpluginsCallPsmPost(ts->plugins, te, rc); break; case PKG_PRETRANS: case PKG_POSTTRANS: case PKG_VERIFY: psm->scriptTag = goal; rc = rpmpsmStage(psm, PSM_SCRIPT); break; default: break; } /* XXX an error here would require a full abort */ (void) rpmChrootOut(); } rpmpsmFree(psm); return rc; }
rpmRC rpmpsmRun(rpmts ts, rpmte te, pkgGoal goal) { rpmpsm psm = NULL; rpmRC rc = RPMRC_FAIL; /* Psm can't fail in test mode, just return early */ if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) return RPMRC_OK; psm = rpmpsmNew(ts, te, goal); if (rpmChrootIn() == 0) { /* Run pre transaction element hook for all plugins */ rc = rpmpluginsCallPsmPre(rpmtsPlugins(ts), te); if (!rc) { switch (goal) { case PKG_INSTALL: rc = rpmPackageInstall(ts, psm); break; case PKG_ERASE: rc = rpmPackageErase(ts, psm); break; case PKG_PRETRANS: case PKG_POSTTRANS: case PKG_VERIFY: rc = runInstScript(psm, goal); break; case PKG_TRANSFILETRIGGERIN: rc = runImmedFileTriggers(ts, te, RPMSENSE_TRIGGERIN, RPMSCRIPT_TRANSFILETRIGGER, 0); break; case PKG_TRANSFILETRIGGERUN: rc = runImmedFileTriggers(ts, te, RPMSENSE_TRIGGERUN, RPMSCRIPT_TRANSFILETRIGGER, 0); break; default: break; } } /* Run post transaction element hook for all plugins */ rpmpluginsCallPsmPost(rpmtsPlugins(ts), te, rc); /* XXX an error here would require a full abort */ (void) rpmChrootOut(); } rpmpsmFree(psm); return rc; }
/* * Run pre/post transaction scripts for transaction set * param ts Transaction set * param stag RPMTAG_PRETRANS or RPMTAG_POSTTRANS * return 0 on success, -1 on error (invalid script tag) */ static int runTransScripts(rpmts ts, rpmTag stag) { rpmtsi pi; rpmte p; rpmpsm psm; int xx; pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) { rpmTag progtag = RPMTAG_NOT_FOUND; /* If no pre/post-transaction script, then don't bother. */ if (!rpmteHaveTransScript(p, stag)) continue; switch (stag) { case RPMTAG_PRETRANS: progtag = RPMTAG_PRETRANSPROG; break; case RPMTAG_POSTTRANS: progtag = RPMTAG_POSTTRANSPROG; break; default: assert(progtag != RPMTAG_NOT_FOUND); break; } if (rpmteOpen(p, ts, 0)) { psm = rpmpsmNew(ts, p); xx = rpmpsmScriptStage(psm, stag, progtag); psm = rpmpsmFree(psm); rpmteClose(p, ts, 0); } } pi = rpmtsiFree(pi); return 0; }
rpmRC rpmInstallSourcePackage(rpmts ts, FD_t fd, char ** specFilePtr, char ** cookie) { Header h = NULL; rpmpsm psm = NULL; rpmte te = NULL; rpmRC rpmrc; int specix = -1; rpmrc = rpmReadPackageFile(ts, fd, NULL, &h); switch (rpmrc) { case RPMRC_NOTTRUSTED: case RPMRC_NOKEY: case RPMRC_OK: break; default: goto exit; break; } if (h == NULL) goto exit; rpmrc = RPMRC_FAIL; /* assume failure */ if (!headerIsSource(h)) { rpmlog(RPMLOG_ERR, _("source package expected, binary found\n")); goto exit; } /* src.rpm install can require specific rpmlib features, check them */ if (!rpmlibDeps(h)) goto exit; specix = headerFindSpec(h); if (specix < 0) { rpmlog(RPMLOG_ERR, _("source package contains no .spec file\n")); goto exit; }; if (rpmtsAddInstallElement(ts, h, NULL, 0, NULL)) { goto exit; } te = rpmtsElement(ts, 0); if (te == NULL) { /* XXX can't happen */ goto exit; } rpmteSetFd(te, fd); rpmteSetHeader(te, h); { /* set all files to be installed */ rpmfs fs = rpmteGetFileStates(te); int fc = rpmfsFC(fs); for (int i = 0; i < fc; i++) rpmfsSetAction(fs, i, FA_CREATE); } psm = rpmpsmNew(ts, te, PKG_INSTALL); if (rpmpsmUnpack(psm) == RPMRC_OK) rpmrc = RPMRC_OK; rpmpsmFree(psm); exit: if (rpmrc == RPMRC_OK && specix >= 0) { if (cookie) *cookie = headerGetAsString(h, RPMTAG_COOKIE); if (specFilePtr) { rpmfiles files = rpmteFiles(te); *specFilePtr = rpmfilesFN(files, specix); rpmfilesFree(files); } } /* XXX nuke the added package(s). */ headerFree(h); rpmtsEmpty(ts); return rpmrc; }
rpmRC rpmInstallSourcePackage(rpmts ts, FD_t fd, char ** specFilePtr, char ** cookie) { rpmfi fi = NULL; char * specFile = NULL; const char *rootdir = rpmtsRootDir(ts); Header h = NULL; rpmpsm psm = NULL; rpmte te = NULL; rpmRC rpmrc; int specix = -1; struct rpmtd_s filenames; rpmtdReset(&filenames); rpmrc = rpmReadPackageFile(ts, fd, NULL, &h); switch (rpmrc) { case RPMRC_NOTTRUSTED: case RPMRC_NOKEY: case RPMRC_OK: break; default: goto exit; break; } if (h == NULL) goto exit; rpmrc = RPMRC_FAIL; /* assume failure */ if (!headerIsSource(h)) { rpmlog(RPMLOG_ERR, _("source package expected, binary found\n")); goto exit; } /* src.rpm install can require specific rpmlib features, check them */ if (!rpmlibDeps(h)) goto exit; if (headerGet(h, RPMTAG_BASENAMES, &filenames, HEADERGET_ALLOC)) { struct rpmtd_s td; const char *str; const char *_cookie = headerGetString(h, RPMTAG_COOKIE); if (cookie && _cookie) *cookie = xstrdup(_cookie); /* Try to find spec by file flags */ if (_cookie && headerGet(h, RPMTAG_FILEFLAGS, &td, HEADERGET_MINMEM)) { rpmfileAttrs *flags; while (specix < 0 && (flags = rpmtdNextUint32(&td))) { if (*flags & RPMFILE_SPECFILE) specix = rpmtdGetIndex(&td); } } /* Still no spec? Look by filename. */ while (specix < 0 && (str = rpmtdNextString(&filenames))) { if (rpmFileHasSuffix(str, ".spec")) specix = rpmtdGetIndex(&filenames); } } if (rootdir && rstreq(rootdir, "/")) rootdir = NULL; /* Macros need to be added before trying to create directories */ rpmInstallLoadMacros(h); if (specix >= 0) { const char *bn; headerDel(h, RPMTAG_BASENAMES); headerDel(h, RPMTAG_DIRNAMES); headerDel(h, RPMTAG_DIRINDEXES); rpmtdInit(&filenames); for (int i = 0; (bn = rpmtdNextString(&filenames)); i++) { int spec = (i == specix); char *fn = rpmGenPath(rpmtsRootDir(ts), spec ? "%{_specdir}" : "%{_sourcedir}", bn); headerPutString(h, RPMTAG_OLDFILENAMES, fn); if (spec) specFile = xstrdup(fn); free(fn); } headerConvert(h, HEADERCONV_COMPRESSFILELIST); } else { rpmlog(RPMLOG_ERR, _("source package contains no .spec file\n")); goto exit; }; if (rpmtsAddInstallElement(ts, h, NULL, 0, NULL)) { goto exit; } te = rpmtsElement(ts, 0); if (te == NULL) { /* XXX can't happen */ goto exit; } rpmteSetFd(te, fd); rpmteSetHeader(te, h); fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, RPMFI_KEEPHEADER); h = headerFree(h); if (fi == NULL) { goto exit; } fi->apath = filenames.data; /* Ick */ rpmteSetFI(te, fi); fi = rpmfiFree(fi); if (rpmMkdirs(rpmtsRootDir(ts), "%{_topdir}:%{_sourcedir}:%{_specdir}")) { goto exit; } { /* set all files to be installed */ rpmfs fs = rpmteGetFileStates(te); int i; unsigned int fc = rpmfiFC(fi); for (i=0; i<fc; i++) rpmfsSetAction(fs, i, FA_CREATE); } psm = rpmpsmNew(ts, te); psm->goal = PKG_INSTALL; /* FIX: psm->fi->dnl should be owned. */ if (rpmpsmStage(psm, PSM_PROCESS) == RPMRC_OK) rpmrc = RPMRC_OK; (void) rpmpsmStage(psm, PSM_FINI); rpmpsmFree(psm); exit: if (specFilePtr && specFile && rpmrc == RPMRC_OK) *specFilePtr = specFile; else free(specFile); headerFree(h); rpmfiFree(fi); /* XXX nuke the added package(s). */ rpmtsClean(ts); return rpmrc; }