1 /** \ingroup rpmts payload
3 * Package state machine to handle a package from a transaction set.
10 #include <rpm/rpmlib.h> /* rpmvercmp and others */
11 #include <rpm/rpmmacro.h>
12 #include <rpm/rpmds.h>
13 #include <rpm/rpmts.h>
14 #include <rpm/rpmfileutil.h>
15 #include <rpm/rpmdb.h>
16 #include <rpm/rpmlog.h>
17 #include <rpm/rpmstring.h>
20 #include "lib/fsm.h" /* XXX CPIO_FOO/FSM_FOO constants */
21 #include "lib/rpmchroot.h"
22 #include "lib/rpmfi_internal.h" /* XXX replaced/states... */
23 #include "lib/rpmte_internal.h" /* XXX internal apis */
24 #include "lib/rpmdb_internal.h" /* rpmdbAdd/Remove */
25 #include "lib/rpmts_internal.h" /* rpmtsPlugins() etc */
26 #include "lib/rpmds_internal.h" /* rpmdsFilterTi() */
27 #include "lib/rpmscript.h"
29 #include "lib/rpmtriggers.h"
31 #include "lib/rpmplugins.h"
36 rpmts ts; /*!< transaction set */
37 rpmte te; /*!< current transaction element */
38 rpmfiles files; /*!< transaction element file info */
39 int scriptArg; /*!< Scriptlet package arg. */
40 int countCorrection; /*!< 0 if installing, -1 if removing. */
41 rpmCallbackType what; /*!< Callback type. */
42 rpm_loff_t amount; /*!< Callback amount. */
43 rpm_loff_t total; /*!< Callback total. */
45 int nrefs; /*!< Reference count. */
48 static rpmpsm rpmpsmNew(rpmts ts, rpmte te, pkgGoal goal);
49 static rpmRC rpmpsmUnpack(rpmpsm psm);
50 static rpmpsm rpmpsmFree(rpmpsm psm);
51 static const char * pkgGoalString(pkgGoal goal);
54 * Adjust file states in database for files shared with this package:
55 * currently either "replaced" or "wrong color".
56 * @param psm package state machine data
59 static rpmRC markReplacedFiles(const rpmpsm psm)
61 const rpmts ts = psm->ts;
62 rpmfs fs = rpmteGetFileStates(psm->te);
63 sharedFileInfo replaced = rpmfsGetReplaced(fs);
65 rpmdbMatchIterator mi;
67 unsigned int * offsets;
75 for (sfi = replaced; sfi; sfi=rpmfsNextReplaced(fs, sfi)) {
76 if (prev && prev == sfi->otherPkg)
84 offsets = xmalloc(num * sizeof(*offsets));
87 for (sfi = replaced; sfi; sfi=rpmfsNextReplaced(fs, sfi)) {
88 if (prev && prev == sfi->otherPkg)
91 offsets[num++] = sfi->otherPkg;
94 mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, NULL, 0);
95 rpmdbAppendIterator(mi, offsets, num);
96 rpmdbSetIteratorRewrite(mi, 1);
99 while ((h = rpmdbNextIterator(mi)) != NULL) {
101 struct rpmtd_s secStates;
104 if (!headerGet(h, RPMTAG_FILESTATES, &secStates, HEADERGET_MINMEM))
107 prev = rpmdbGetIteratorOffset(mi);
109 while (sfi && sfi->otherPkg == prev) {
110 int ix = rpmtdSetIndex(&secStates, sfi->otherFileNum);
113 char *state = rpmtdGetChar(&secStates);
114 if (state && *state != sfi->rstate) {
115 *state = sfi->rstate;
117 /* Modified header will be rewritten. */
119 rpmdbSetIteratorModified(mi, modified);
123 sfi=rpmfsNextReplaced(fs, sfi);
125 rpmtdFreeData(&secStates);
127 rpmdbFreeIterator(mi);
133 static int rpmlibDeps(Header h)
135 rpmds req = rpmdsInit(rpmdsNew(h, RPMTAG_REQUIRENAME, 0));
137 rpmdsRpmlib(&rpmlib, NULL);
140 while (rpmdsNext(req) >= 0) {
141 if (!(rpmdsFlags(req) & RPMSENSE_RPMLIB))
143 if (rpmdsSearch(rpmlib, req) < 0) {
145 nvr = headerGetAsString(h, RPMTAG_NEVRA);
146 rpmlog(RPMLOG_ERR, _("Missing rpmlib features for %s:\n"), nvr);
148 rpmlog(RPMLOG_ERR, "\t%s\n", rpmdsDNEVR(req)+2);
158 rpmRC rpmInstallSourcePackage(rpmts ts, FD_t fd,
159 char ** specFilePtr, char ** cookie)
167 rpmrc = rpmReadPackageFile(ts, fd, NULL, &h);
169 case RPMRC_NOTTRUSTED:
180 rpmrc = RPMRC_FAIL; /* assume failure */
182 if (!headerIsSource(h)) {
183 rpmlog(RPMLOG_ERR, _("source package expected, binary found\n"));
187 /* src.rpm install can require specific rpmlib features, check them */
191 specix = headerFindSpec(h);
194 rpmlog(RPMLOG_ERR, _("source package contains no .spec file\n"));
198 if (rpmtsAddInstallElement(ts, h, NULL, 0, NULL)) {
202 te = rpmtsElement(ts, 0);
203 if (te == NULL) { /* XXX can't happen */
208 rpmteSetHeader(te, h);
211 /* set all files to be installed */
212 rpmfs fs = rpmteGetFileStates(te);
213 int fc = rpmfsFC(fs);
214 for (int i = 0; i < fc; i++)
215 rpmfsSetAction(fs, i, FA_CREATE);
218 psm = rpmpsmNew(ts, te, PKG_INSTALL);
220 if (rpmpsmUnpack(psm) == RPMRC_OK)
226 if (rpmrc == RPMRC_OK && specix >= 0) {
228 *cookie = headerGetAsString(h, RPMTAG_COOKIE);
230 rpmfiles files = rpmteFiles(te);
231 *specFilePtr = rpmfilesFN(files, specix);
236 /* XXX nuke the added package(s). */
243 static rpmRC runInstScript(rpmpsm psm, rpmTagVal scriptTag)
247 Header h = rpmteHeader(psm->te);
248 rpmScript script = rpmScriptFromTag(h, scriptTag);
251 headerGet(h, RPMTAG_INSTPREFIXES, &pfx, HEADERGET_ALLOC|HEADERGET_ARGV);
252 rc = runScript(psm->ts, psm->te, h, pfx.data, script, psm->scriptArg, -1);
256 rpmScriptFree(script);
264 * @todo Trigger on any provides, not just package NVR.
265 * @param ts transaction set
266 * @param te transaction element
267 * @param sense trigger type
268 * @param sourceH header of trigger source
269 * @param trigH header of triggered package
271 * @param triggersAlreadyRun
274 static rpmRC handleOneTrigger(rpmts ts, rpmte te, rpmsenseFlags sense,
275 Header sourceH, Header trigH, int countCorrection,
276 int arg2, unsigned char * triggersAlreadyRun)
278 rpmds trigger = rpmdsInit(rpmdsNew(trigH, RPMTAG_TRIGGERNAME, 0));
280 const char * sourceName = headerGetString(sourceH, RPMTAG_NAME);
281 const char * triggerName = headerGetString(trigH, RPMTAG_NAME);
288 headerGet(trigH, RPMTAG_INSTPREFIXES, &pfx, HEADERGET_ALLOC|HEADERGET_ARGV);
289 (void) rpmdsSetNoPromote(trigger, 1);
291 while ((i = rpmdsNext(trigger)) >= 0) {
294 if (!(rpmdsFlags(trigger) & sense))
297 if (!rstreq(rpmdsN(trigger), sourceName))
300 /* XXX Trigger on any provided dependency, not just the package NEVR */
301 if (!rpmdsAnyMatchesDep(sourceH, trigger, 1))
304 tix = rpmdsTi(trigger);
305 if (triggersAlreadyRun == NULL || triggersAlreadyRun[tix] == 0) {
306 int arg1 = rpmdbCountPackages(rpmtsGetRdb(ts), triggerName);
309 /* XXX W2DO? fails as "execution of script failed" */
312 rpmScript script = rpmScriptFromTriggerTag(trigH,
313 triggertag(sense), RPMSCRIPT_NORMALTRIGGER, tix);
314 arg1 += countCorrection;
315 rc = runScript(ts, te, trigH, pfx.data, script, arg1, arg2);
316 if (triggersAlreadyRun != NULL)
317 triggersAlreadyRun[tix] = 1;
319 rpmScriptFree(script);
324 * Each target/source header pair can only result in a single
337 * Run trigger scripts in the database that are fired by this header.
338 * @param psm package state machine data
339 * @param sense trigger type
340 * @return 0 on success
342 static rpmRC runTriggers(rpmpsm psm, rpmsenseFlags sense)
344 const rpmts ts = psm->ts;
346 const char * N = NULL;
349 if (psm->te) /* XXX can't happen */
351 if (N) /* XXX can't happen */
352 numPackage = rpmdbCountPackages(rpmtsGetRdb(ts), N)
353 + psm->countCorrection;
355 return RPMRC_NOTFOUND;
358 Header h = rpmteHeader(psm->te);
359 rpmdbMatchIterator mi;
361 mi = rpmtsInitIterator(ts, RPMDBI_TRIGGERNAME, N, 0);
362 while ((triggeredH = rpmdbNextIterator(mi)) != NULL) {
363 nerrors += handleOneTrigger(ts, NULL, sense, h, triggeredH,
364 0, numPackage, NULL);
366 rpmdbFreeIterator(mi);
370 return (nerrors == 0) ? RPMRC_OK : RPMRC_FAIL;
374 * Run triggers from this header that are fired by headers in the database.
375 * @param psm package state machine data
376 * @param sense trigger type
377 * @return 0 on success
379 static rpmRC runImmedTriggers(rpmpsm psm, rpmsenseFlags sense)
381 const rpmts ts = psm->ts;
382 unsigned char * triggersRun;
383 struct rpmtd_s tnames, tindexes;
384 Header h = rpmteHeader(psm->te);
387 if (!(headerGet(h, RPMTAG_TRIGGERNAME, &tnames, HEADERGET_MINMEM) &&
388 headerGet(h, RPMTAG_TRIGGERINDEX, &tindexes, HEADERGET_MINMEM))) {
392 triggersRun = xcalloc(rpmtdCount(&tindexes), sizeof(*triggersRun));
393 { Header sourceH = NULL;
394 const char *trigName;
395 rpm_count_t *triggerIndices = tindexes.data;
397 while ((trigName = rpmtdNextString(&tnames))) {
398 rpmdbMatchIterator mi;
399 int i = rpmtdGetIndex(&tnames);
401 if (triggersRun[triggerIndices[i]] != 0) continue;
403 mi = rpmtsInitIterator(ts, RPMDBI_NAME, trigName, 0);
405 while ((sourceH = rpmdbNextIterator(mi)) != NULL) {
406 nerrors += handleOneTrigger(psm->ts, psm->te,
408 psm->countCorrection,
409 rpmdbGetIteratorCount(mi),
413 rpmdbFreeIterator(mi);
416 rpmtdFreeData(&tnames);
417 rpmtdFreeData(&tindexes);
422 return (nerrors == 0) ? RPMRC_OK : RPMRC_FAIL;
425 static rpmpsm rpmpsmFree(rpmpsm psm)
428 rpmfilesFree(psm->files);
430 /* XXX rpmte not refcounted yet */
431 memset(psm, 0, sizeof(*psm)); /* XXX trash and burn */
437 static rpmpsm rpmpsmNew(rpmts ts, rpmte te, pkgGoal goal)
439 rpmpsm psm = xcalloc(1, sizeof(*psm));
440 psm->ts = rpmtsLink(ts);
441 psm->files = rpmteFiles(te);
442 psm->te = te; /* XXX rpmte not refcounted yet */
443 if (!rpmteIsSource(te)) {
445 * When we run scripts, we pass an argument which is the number of
446 * versions of this package that will be installed when we are
449 int npkgs_installed = rpmdbCountPackages(rpmtsGetRdb(ts), rpmteN(te));
453 psm->scriptArg = npkgs_installed + 1;
454 psm->countCorrection = 0;
457 psm->scriptArg = npkgs_installed - 1;
458 psm->countCorrection = -1;
462 psm->scriptArg = npkgs_installed;
463 psm->countCorrection = 0;
470 if (goal == PKG_INSTALL) {
471 Header h = rpmteHeader(te);
472 psm->total = headerGetNumber(h, RPMTAG_LONGARCHIVESIZE);
474 } else if (goal == PKG_ERASE) {
475 psm->total = rpmfilesFC(psm->files);
477 /* Fake up something for packages with no files */
481 if (goal == PKG_INSTALL || goal == PKG_ERASE) {
482 rpmlog(RPMLOG_DEBUG, "%s: %s has %d files\n", pkgGoalString(goal),
483 rpmteNEVRA(psm->te), rpmfilesFC(psm->files));
489 void rpmpsmNotify(rpmpsm psm, int what, rpm_loff_t amount)
493 if (amount > psm->amount) {
494 psm->amount = amount;
497 if (what && what != psm->what) {
502 rpmtsNotify(psm->ts, psm->te, psm->what, psm->amount, psm->total);
508 * --replacepkgs hack: find the header instance we're replacing and
509 * mark it as the db instance of the install element. In PSM_POST,
510 * if an install element already has a db instance, it's removed
511 * before proceeding with the adding the new header to the db.
513 static void markReplacedInstance(rpmts ts, rpmte te)
515 rpmdbMatchIterator mi = rpmtsInitIterator(ts, RPMDBI_NAME, rpmteN(te), 0);
516 rpmdbSetIteratorRE(mi, RPMTAG_EPOCH, RPMMIRE_STRCMP, rpmteE(te));
517 rpmdbSetIteratorRE(mi, RPMTAG_VERSION, RPMMIRE_STRCMP, rpmteV(te));
518 rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, RPMMIRE_STRCMP, rpmteR(te));
519 /* XXX shouldn't we also do this on colorless transactions? */
520 if (rpmtsColor(ts)) {
521 rpmdbSetIteratorRE(mi, RPMTAG_ARCH, RPMMIRE_STRCMP, rpmteA(te));
522 rpmdbSetIteratorRE(mi, RPMTAG_OS, RPMMIRE_STRCMP, rpmteO(te));
525 while (rpmdbNextIterator(mi) != NULL) {
526 rpmteSetDBInstance(te, rpmdbGetIteratorOffset(mi));
529 rpmdbFreeIterator(mi);
532 static rpmRC dbAdd(rpmts ts, rpmte te)
534 Header h = rpmteHeader(te);
535 rpm_time_t installTime = (rpm_time_t) time(NULL);
536 rpmfs fs = rpmteGetFileStates(te);
537 rpm_count_t fc = rpmfsFC(fs);
538 rpm_fstate_t * fileStates = rpmfsGetStates(fs);
539 rpm_color_t tscolor = rpmtsColor(ts);
540 rpm_tid_t tid = rpmtsGetTid(ts);
543 if (fileStates != NULL && fc > 0) {
544 headerPutChar(h, RPMTAG_FILESTATES, fileStates, fc);
547 headerPutUint32(h, RPMTAG_INSTALLTID, &tid, 1);
548 headerPutUint32(h, RPMTAG_INSTALLTIME, &installTime, 1);
549 headerPutUint32(h, RPMTAG_INSTALLCOLOR, &tscolor, 1);
551 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DBADD), 0);
552 rc = (rpmdbAdd(rpmtsGetRdb(ts), h) == 0) ? RPMRC_OK : RPMRC_FAIL;
553 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DBADD), 0);
555 if (rc == RPMRC_OK) {
556 rpmteSetDBInstance(te, headerGetInstance(h));
557 packageHashAddEntry(ts->members->installedPackages,
558 headerGetInstance(h), te);
564 static rpmRC dbRemove(rpmts ts, rpmte te)
568 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_DBREMOVE), 0);
569 rc = (rpmdbRemove(rpmtsGetRdb(ts), rpmteDBInstance(te)) == 0) ?
570 RPMRC_OK : RPMRC_FAIL;
571 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_DBREMOVE), 0);
574 rpmteSetDBInstance(te, 0);
578 static rpmRC rpmpsmUnpack(rpmpsm psm)
580 char *failedFile = NULL;
585 rpmpsmNotify(psm, RPMCALLBACK_INST_START, 0);
586 /* make sure first progress call gets made */
587 rpmpsmNotify(psm, RPMCALLBACK_INST_PROGRESS, 0);
589 if (!(rpmtsFlags(psm->ts) & RPMTRANS_FLAG_JUSTDB)) {
590 if (rpmfilesFC(psm->files) > 0) {
591 fsmrc = rpmPackageFilesInstall(psm->ts, psm->te, psm->files,
597 /* XXX make sure progress reaches 100% */
598 rpmpsmNotify(psm, RPMCALLBACK_INST_PROGRESS, psm->total);
599 rpmpsmNotify(psm, RPMCALLBACK_INST_STOP, psm->total);
604 emsg = rpmfileStrerror(fsmrc);
606 _("unpacking of archive failed%s%s: %s\n"),
607 (failedFile != NULL ? _(" on file ") : ""),
608 (failedFile != NULL ? failedFile : ""),
613 /* XXX notify callback on error. */
614 rpmtsNotify(psm->ts, psm->te, RPMCALLBACK_UNPACK_ERROR, 0, 0);
620 static rpmRC rpmpsmRemove(rpmpsm psm)
622 char *failedFile = NULL;
625 rpmpsmNotify(psm, RPMCALLBACK_UNINST_START, 0);
626 /* make sure first progress call gets made */
627 rpmpsmNotify(psm, RPMCALLBACK_UNINST_PROGRESS, 0);
629 /* XXX should't we log errors from here? */
630 if (!(rpmtsFlags(psm->ts) & RPMTRANS_FLAG_JUSTDB)) {
631 if (rpmfilesFC(psm->files) > 0) {
632 fsmrc = rpmPackageFilesRemove(psm->ts, psm->te, psm->files,
636 /* XXX make sure progress reaches 100% */
637 rpmpsmNotify(psm, RPMCALLBACK_UNINST_PROGRESS, psm->total);
638 rpmpsmNotify(psm, RPMCALLBACK_UNINST_STOP, psm->total);
641 return (fsmrc == 0) ? RPMRC_OK : RPMRC_FAIL;
644 static rpmRC rpmPackageInstall(rpmts ts, rpmpsm psm)
649 rpmswEnter(rpmtsOp(psm->ts, RPMTS_OP_INSTALL), 0);
651 /* HACK: replacepkgs abuses te instance to remove old header */
652 if (rpmtsFilterFlags(psm->ts) & RPMPROB_FILTER_REPLACEPKG)
653 markReplacedInstance(ts, psm->te);
656 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERPREIN)) {
657 /* Run triggers in other package(s) this package sets off. */
658 rc = runTriggers(psm, RPMSENSE_TRIGGERPREIN);
661 /* Run triggers in this package other package(s) set off. */
662 rc = runImmedTriggers(psm, RPMSENSE_TRIGGERPREIN);
666 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPRE)) {
667 rc = runInstScript(psm, RPMTAG_PREIN);
671 rc = rpmpsmUnpack(psm);
675 * If this package has already been installed, remove it from
676 * the database before adding the new one.
678 if (rpmteDBInstance(psm->te)) {
679 rc = dbRemove(ts, psm->te);
683 rc = dbAdd(ts, psm->te);
686 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERIN)) {
687 /* Run upper file triggers i. e. with higher priorities */
688 /* Run file triggers in other package(s) this package sets off. */
689 rc = runFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERIN,
690 RPMSCRIPT_FILETRIGGER, 1);
693 /* Run file triggers in this package other package(s) set off. */
694 rc = runImmedFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERIN,
695 RPMSCRIPT_FILETRIGGER, 1);
699 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPOST)) {
700 rc = runInstScript(psm, RPMTAG_POSTIN);
704 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERIN)) {
705 /* Run triggers in other package(s) this package sets off. */
706 rc = runTriggers(psm, RPMSENSE_TRIGGERIN);
709 /* Run triggers in this package other package(s) set off. */
710 rc = runImmedTriggers(psm, RPMSENSE_TRIGGERIN);
713 /* Run lower file triggers i. e. with lower priorities */
714 /* Run file triggers in other package(s) this package sets off. */
715 rc = runFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERIN,
716 RPMSCRIPT_FILETRIGGER, 2);
719 /* Run file triggers in this package other package(s) set off. */
720 rc = runImmedFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERIN,
721 RPMSCRIPT_FILETRIGGER, 2);
725 rc = markReplacedFiles(psm);
728 rpmswExit(rpmtsOp(psm->ts, RPMTS_OP_INSTALL), 0);
733 static rpmRC rpmPackageErase(rpmts ts, rpmpsm psm)
738 rpmswEnter(rpmtsOp(psm->ts, RPMTS_OP_ERASE), 0);
741 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERUN)) {
742 /* Run file triggers in this package other package(s) set off. */
743 rc = runImmedFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERUN,
744 RPMSCRIPT_FILETRIGGER, 1);
747 /* Run file triggers in other package(s) this package sets off. */
748 rc = runFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERUN,
749 RPMSCRIPT_FILETRIGGER, 1);
752 /* Run triggers in this package other package(s) set off. */
753 rc = runImmedTriggers(psm, RPMSENSE_TRIGGERUN);
756 /* Run triggers in other package(s) this package sets off. */
757 rc = runTriggers(psm, RPMSENSE_TRIGGERUN);
761 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPREUN)) {
762 rc = runInstScript(psm, RPMTAG_PREUN);
766 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERUN)) {
767 /* Run file triggers in this package other package(s) set off. */
768 rc = runImmedFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERUN,
769 RPMSCRIPT_FILETRIGGER, 2);
772 /* Run file triggers in other package(s) this package sets off. */
773 rc = runFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERUN,
774 RPMSCRIPT_FILETRIGGER, 2);
778 rc = rpmpsmRemove(psm);
781 /* Run file triggers in other package(s) this package sets off. */
782 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERPOSTUN)) {
783 rc = runFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERPOSTUN,
784 RPMSCRIPT_FILETRIGGER, 1);
787 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPOSTUN)) {
788 rc = runInstScript(psm, RPMTAG_POSTUN);
792 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERPOSTUN)) {
793 /* Run triggers in other package(s) this package sets off. */
794 rc = runTriggers(psm, RPMSENSE_TRIGGERPOSTUN);
797 /* Run file triggers in other package(s) this package sets off. */
798 rc = runFileTriggers(psm->ts, psm->te, RPMSENSE_TRIGGERPOSTUN,
799 RPMSCRIPT_FILETRIGGER, 2);
803 if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOSTTRANS|RPMTRANS_FLAG_NOTRIGGERPOSTUN))) {
804 /* Prepare post transaction uninstall triggers */
805 rpmtriggersPrepPostUnTransFileTrigs(psm->ts, psm->te);
808 rc = dbRemove(ts, psm->te);
811 rpmswExit(rpmtsOp(psm->ts, RPMTS_OP_ERASE), 0);
816 static const char * pkgGoalString(pkgGoal goal)
819 case PKG_INSTALL: return " install";
820 case PKG_ERASE: return " erase";
821 case PKG_VERIFY: return " verify";
822 case PKG_PRETRANS: return " pretrans";
823 case PKG_POSTTRANS: return "posttrans";
824 default: return "unknown";
828 rpmRC rpmpsmRun(rpmts ts, rpmte te, pkgGoal goal)
831 rpmRC rc = RPMRC_FAIL;
833 /* Psm can't fail in test mode, just return early */
834 if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)
837 psm = rpmpsmNew(ts, te, goal);
838 if (rpmChrootIn() == 0) {
839 /* Run pre transaction element hook for all plugins */
840 rc = rpmpluginsCallPsmPre(rpmtsPlugins(ts), te);
845 rc = rpmPackageInstall(ts, psm);
848 rc = rpmPackageErase(ts, psm);
853 rc = runInstScript(psm, goal);
855 case PKG_TRANSFILETRIGGERIN:
856 rc = runImmedFileTriggers(ts, te, RPMSENSE_TRIGGERIN,
857 RPMSCRIPT_TRANSFILETRIGGER, 0);
859 case PKG_TRANSFILETRIGGERUN:
860 rc = runImmedFileTriggers(ts, te, RPMSENSE_TRIGGERUN,
861 RPMSCRIPT_TRANSFILETRIGGER, 0);
867 /* Run post transaction element hook for all plugins */
868 rpmpluginsCallPsmPost(rpmtsPlugins(ts), te, rc);
870 /* XXX an error here would require a full abort */
871 (void) rpmChrootOut();