3 * Routine(s) to handle an "rpmte" transaction element.
7 #include <rpm/rpmtypes.h>
8 #include <rpm/rpmlib.h> /* RPM_MACHTABLE_* */
9 #include <rpm/rpmmacro.h>
10 #include <rpm/rpmds.h>
11 #include <rpm/rpmfi.h>
12 #include <rpm/rpmts.h>
13 #include <rpm/rpmdb.h>
14 #include <rpm/rpmlog.h>
16 #include "lib/rpmplugins.h"
17 #include "lib/rpmte_internal.h"
18 /* strpool-related interfaces */
19 #include "lib/rpmfi_internal.h"
20 #include "lib/rpmds_internal.h"
21 #include "lib/rpmts_internal.h"
26 * A single package instance to be installed/removed atomically.
29 rpmElementType type; /*!< Package disposition (installed/removed). */
31 Header h; /*!< Package header. */
32 char * NEVR; /*!< Package name-version-release. */
33 char * NEVRA; /*!< Package name-version-release.arch. */
34 char * name; /*!< Name: */
36 char * version; /*!< Version: */
37 char * release; /*!< Release: */
38 char * arch; /*!< Architecture hint. */
39 char * os; /*!< Operating system hint. */
40 int isSource; /*!< (TR_ADDED) source rpm? */
42 rpmte depends; /*!< Package updated by this package (ERASE te) */
43 rpmte parent; /*!< Parent transaction element. */
44 unsigned int db_instance; /*!< Database instance (of removed pkgs) */
45 tsortInfo tsi; /*!< Dependency ordering chains. */
47 rpmds thisds; /*!< This package's provided NEVR. */
48 rpmds provides; /*!< Provides: dependencies. */
49 rpmds requires; /*!< Requires: dependencies. */
50 rpmds conflicts; /*!< Conflicts: dependencies. */
51 rpmds obsoletes; /*!< Obsoletes: dependencies. */
52 rpmds order; /*!< Order: dependencies. */
53 rpmfi fi; /*!< File information. */
54 rpmps probs; /*!< Problems (relocations) */
55 rpmts ts; /*!< Parent transaction */
57 rpm_color_t color; /*!< Color bit(s) from package dependencies. */
58 rpm_loff_t pkgFileSize; /*!< No. of bytes in package file (approx). */
59 unsigned int headerSize; /*!< No. of bytes in package header */
61 fnpyKey key; /*!< (TR_ADDED) Retrieval key. */
62 rpmRelocation * relocs; /*!< (TR_ADDED) Payload file relocations. */
63 int nrelocs; /*!< (TR_ADDED) No. of relocations. */
64 uint8_t *badrelocs; /*!< (TR_ADDED) Bad relocations (or NULL) */
65 FD_t fd; /*!< (TR_ADDED) Payload file descriptor. */
67 #define RPMTE_HAVE_PRETRANS (1 << 0)
68 #define RPMTE_HAVE_POSTTRANS (1 << 1)
69 int transscripts; /*!< pre/posttrans script existence */
70 int failed; /*!< (parent) install/erase failed */
74 ARGV_t lastInCollectionsAny; /*!< list of collections this te is the last to be installed or removed */
75 ARGV_t lastInCollectionsAdd; /*!< list of collections this te is the last to be only installed */
76 ARGV_t firstInCollectionsRemove; /*!< list of collections this te is the first to be only removed */
77 ARGV_t collections; /*!< list of collections */
80 /* forward declarations */
81 static void rpmteColorDS(rpmte te, rpmTag tag);
82 static int rpmteClose(rpmte te, int reset_fi);
84 void rpmteCleanDS(rpmte te)
86 te->thisds = rpmdsFree(te->thisds);
87 te->provides = rpmdsFree(te->provides);
88 te->requires = rpmdsFree(te->requires);
89 te->conflicts = rpmdsFree(te->conflicts);
90 te->obsoletes = rpmdsFree(te->obsoletes);
91 te->order = rpmdsFree(te->order);
94 static rpmfi getFI(rpmte p, Header h)
97 fiflags = (p->type == TR_ADDED) ? (RPMFI_NOHEADER | RPMFI_FLAGS_INSTALL) :
98 (RPMFI_NOHEADER | RPMFI_FLAGS_ERASE);
100 /* relocate stuff in header if necessary */
101 if (rpmteType(p) == TR_ADDED && rpmfsFC(p->fs) > 0 && p->nrelocs) {
102 if (!headerIsSource(h) && !headerIsEntry(h, RPMTAG_ORIGBASENAMES)) {
103 rpmRelocateFileList(p->relocs, p->nrelocs, p->fs, h);
106 return rpmfiNewPool(rpmtsPool(p->ts), h, RPMTAG_BASENAMES, fiflags);
109 /* stupid bubble sort, but it's probably faster here */
110 static void sortRelocs(rpmRelocation *relocations, int numRelocations)
112 for (int i = 0; i < numRelocations; i++) {
114 for (int j = 1; j < numRelocations; j++) {
115 rpmRelocation tmpReloc;
116 if (relocations[j - 1].oldPath == NULL || /* XXX can't happen */
117 relocations[j ].oldPath == NULL || /* XXX can't happen */
118 strcmp(relocations[j - 1].oldPath, relocations[j].oldPath) <= 0)
120 tmpReloc = relocations[j - 1];
121 relocations[j - 1] = relocations[j];
122 relocations[j] = tmpReloc;
125 if (!madeSwap) break;
129 static char * stripTrailingChar(char * s, char c)
132 for (t = s + strlen(s) - 1; *t == c && t >= s; t--)
137 static void buildRelocs(rpmte p, Header h, rpmRelocation *relocs)
140 struct rpmtd_s validRelocs;
142 for (rpmRelocation *r = relocs; r->oldPath || r->newPath; r++)
145 headerGet(h, RPMTAG_PREFIXES, &validRelocs, HEADERGET_MINMEM);
146 p->relocs = xmalloc(sizeof(*p->relocs) * (p->nrelocs+1));
148 /* Build sorted relocation list from raw relocations. */
149 for (i = 0; i < p->nrelocs; i++) {
153 * Default relocations (oldPath == NULL) are handled in the UI,
156 if (relocs[i].oldPath == NULL) continue; /* XXX can't happen */
158 /* FIXME: Trailing /'s will confuse us greatly. Internal ones will
159 too, but those are more trouble to fix up. :-( */
160 t = xstrdup(relocs[i].oldPath);
161 p->relocs[i].oldPath = (t[0] == '/' && t[1] == '\0')
163 : stripTrailingChar(t, '/');
165 /* An old path w/o a new path is valid, and indicates exclusion */
166 if (relocs[i].newPath) {
168 const char *validprefix;
170 t = xstrdup(relocs[i].newPath);
171 p->relocs[i].newPath = (t[0] == '/' && t[1] == '\0')
173 : stripTrailingChar(t, '/');
175 /* FIX: relocations[i].oldPath == NULL */
176 /* Verify that the relocation's old path is in the header. */
177 rpmtdInit(&validRelocs);
178 while ((validprefix = rpmtdNextString(&validRelocs))) {
179 if (rstreq(validprefix, p->relocs[i].oldPath)) {
186 if (p->badrelocs == NULL)
187 p->badrelocs = xcalloc(p->nrelocs, sizeof(*p->badrelocs));
191 p->relocs[i].newPath = NULL;
194 p->relocs[i].oldPath = NULL;
195 p->relocs[i].newPath = NULL;
196 sortRelocs(p->relocs, p->nrelocs);
198 rpmtdFreeData(&validRelocs);
202 * Initialize transaction element data from header.
203 * @param p transaction element
205 * @param key (TR_ADDED) package retrieval key (e.g. file name)
206 * @param relocs (TR_ADDED) package file relocations
208 static int addTE(rpmte p, Header h, fnpyKey key, rpmRelocation * relocs)
210 rpmstrPool tspool = rpmtsPool(p->ts);
211 struct rpmtd_s colls, bnames;
212 int rc = 1; /* assume failure */
214 p->name = headerGetAsString(h, RPMTAG_NAME);
215 p->version = headerGetAsString(h, RPMTAG_VERSION);
216 p->release = headerGetAsString(h, RPMTAG_RELEASE);
218 /* name, version and release are required in all packages */
219 if (p->name == NULL || p->version == NULL || p->release == NULL)
222 p->epoch = headerGetAsString(h, RPMTAG_EPOCH);
224 p->arch = headerGetAsString(h, RPMTAG_ARCH);
225 p->os = headerGetAsString(h, RPMTAG_OS);
227 /* gpg-pubkey's dont have os or arch (sigh), for others they are required */
228 if (!rstreq(p->name, "gpg-pubkey") && (p->arch == NULL || p->os == NULL))
231 p->isSource = headerIsSource(h);
233 p->NEVR = headerGetAsString(h, RPMTAG_NEVR);
234 p->NEVRA = headerGetAsString(h, RPMTAG_NEVRA);
240 buildRelocs(p, h, relocs);
242 p->db_instance = headerGetInstance(h);
247 p->headerSize = headerSizeof(h, HEADER_MAGIC_NO);
249 p->thisds = rpmdsThisPool(tspool, h, RPMTAG_PROVIDENAME, RPMSENSE_EQUAL);
250 p->provides = rpmdsNewPool(tspool, h, RPMTAG_PROVIDENAME, 0);
251 p->requires = rpmdsNewPool(tspool, h, RPMTAG_REQUIRENAME, 0);
252 p->conflicts = rpmdsNewPool(tspool, h, RPMTAG_CONFLICTNAME, 0);
253 p->obsoletes = rpmdsNewPool(tspool, h, RPMTAG_OBSOLETENAME, 0);
254 p->order = rpmdsNewPool(tspool, h, RPMTAG_ORDERNAME, 0);
256 /* Relocation needs to know file count before rpmfiNew() */
257 headerGet(h, RPMTAG_BASENAMES, &bnames, HEADERGET_MINMEM);
258 p->fs = rpmfsNew(rpmtdCount(&bnames), (p->type == TR_ADDED));
259 rpmtdFreeData(&bnames);
263 /* Packages with no files return an empty file info set, NULL is an error */
267 /* See if we have pre/posttrans scripts. */
268 p->transscripts |= (headerIsEntry(h, RPMTAG_PRETRANS) ||
269 headerIsEntry(h, RPMTAG_PRETRANSPROG)) ?
270 RPMTE_HAVE_PRETRANS : 0;
271 p->transscripts |= (headerIsEntry(h, RPMTAG_POSTTRANS) ||
272 headerIsEntry(h, RPMTAG_POSTTRANSPROG)) ?
273 RPMTE_HAVE_POSTTRANS : 0;
275 p->lastInCollectionsAny = NULL;
276 p->lastInCollectionsAdd = NULL;
277 p->firstInCollectionsRemove = NULL;
278 p->collections = NULL;
279 if (headerGet(h, RPMTAG_COLLECTIONS, &colls, HEADERGET_MINMEM)) {
280 const char *collname;
281 while ((collname = rpmtdNextString(&colls))) {
282 argvAdd(&p->collections, collname);
284 argvSort(p->collections, NULL);
285 rpmtdFreeData(&colls);
288 rpmteColorDS(p, RPMTAG_PROVIDENAME);
289 rpmteColorDS(p, RPMTAG_REQUIRENAME);
291 if (p->type == TR_ADDED)
292 p->pkgFileSize = headerGetNumber(h, RPMTAG_LONGSIGSIZE) + 96 + 256;
300 rpmte rpmteFree(rpmte te)
304 for (int i = 0; i < te->nrelocs; i++) {
305 free(te->relocs[i].oldPath);
306 free(te->relocs[i].newPath);
325 rpmpsFree(te->probs);
328 argvFree(te->collections);
329 argvFree(te->lastInCollectionsAny);
330 argvFree(te->lastInCollectionsAdd);
331 argvFree(te->firstInCollectionsRemove);
333 memset(te, 0, sizeof(*te)); /* XXX trash and burn */
339 rpmte rpmteNew(rpmts ts, Header h, rpmElementType type, fnpyKey key,
340 rpmRelocation * relocs)
342 rpmte p = xcalloc(1, sizeof(*p));
346 if (addTE(p, h, key, relocs)) {
354 unsigned int rpmteDBInstance(rpmte te)
356 return (te != NULL ? te->db_instance : 0);
359 void rpmteSetDBInstance(rpmte te, unsigned int instance)
362 te->db_instance = instance;
365 Header rpmteHeader(rpmte te)
367 return (te != NULL && te->h != NULL ? headerLink(te->h) : NULL);
370 Header rpmteSetHeader(rpmte te, Header h)
373 te->h = headerFree(te->h);
375 te->h = headerLink(h);
380 rpmElementType rpmteType(rpmte te)
382 /* XXX returning negative for unsigned type */
383 return (te != NULL ? te->type : -1);
386 const char * rpmteN(rpmte te)
388 return (te != NULL ? te->name : NULL);
391 const char * rpmteE(rpmte te)
393 return (te != NULL ? te->epoch : NULL);
396 const char * rpmteV(rpmte te)
398 return (te != NULL ? te->version : NULL);
401 const char * rpmteR(rpmte te)
403 return (te != NULL ? te->release : NULL);
406 const char * rpmteA(rpmte te)
408 return (te != NULL ? te->arch : NULL);
411 const char * rpmteO(rpmte te)
413 return (te != NULL ? te->os : NULL);
416 int rpmteIsSource(rpmte te)
418 return (te != NULL ? te->isSource : 0);
421 rpm_color_t rpmteColor(rpmte te)
423 return (te != NULL ? te->color : 0);
426 rpm_color_t rpmteSetColor(rpmte te, rpm_color_t color)
428 rpm_color_t ocolor = 0;
436 ARGV_const_t rpmteCollections(rpmte te)
438 return (te != NULL) ? te->collections : NULL;
441 int rpmteHasCollection(rpmte te, const char *collname)
443 return (argvSearch(rpmteCollections(te), collname, NULL) != NULL);
446 int rpmteAddToLastInCollectionAdd(rpmte te, const char *collname)
449 argvAdd(&te->lastInCollectionsAdd, collname);
450 argvSort(te->lastInCollectionsAdd, NULL);
456 int rpmteAddToLastInCollectionAny(rpmte te, const char *collname)
459 argvAdd(&te->lastInCollectionsAny, collname);
460 argvSort(te->lastInCollectionsAny, NULL);
466 int rpmteAddToFirstInCollectionRemove(rpmte te, const char *collname)
469 argvAdd(&te->firstInCollectionsRemove, collname);
470 argvSort(te->firstInCollectionsRemove, NULL);
476 rpm_loff_t rpmtePkgFileSize(rpmte te)
478 return (te != NULL ? te->pkgFileSize : 0);
481 unsigned int rpmteHeaderSize(rpmte te)
483 return (te != NULL ? te->headerSize : 0);
486 rpmte rpmteParent(rpmte te)
488 return (te != NULL ? te->parent : NULL);
491 rpmte rpmteSetParent(rpmte te, rpmte pte)
501 tsortInfo rpmteTSI(rpmte te)
506 void rpmteSetTSI(rpmte te, tsortInfo tsi)
511 void rpmteSetDependsOn(rpmte te, rpmte depends)
513 te->depends = depends;
516 rpmte rpmteDependsOn(rpmte te)
521 int rpmteDBOffset(rpmte te)
523 return rpmteDBInstance(te);
526 const char * rpmteEVR(rpmte te)
528 return (te != NULL ? te->NEVR + strlen(te->name) + 1 : NULL);
531 const char * rpmteNEVR(rpmte te)
533 return (te != NULL ? te->NEVR : NULL);
536 const char * rpmteNEVRA(rpmte te)
538 return (te != NULL ? te->NEVRA : NULL);
541 FD_t rpmteSetFd(rpmte te, FD_t fd)
545 te->fd = fdFree(te->fd);
552 fnpyKey rpmteKey(rpmte te)
554 return (te != NULL ? te->key : NULL);
557 rpmds rpmteDS(rpmte te, rpmTagVal tag)
563 case RPMTAG_NAME: return te->thisds;
564 case RPMTAG_PROVIDENAME: return te->provides;
565 case RPMTAG_REQUIRENAME: return te->requires;
566 case RPMTAG_CONFLICTNAME: return te->conflicts;
567 case RPMTAG_OBSOLETENAME: return te->obsoletes;
568 case RPMTAG_ORDERNAME: return te->order;
574 rpmfi rpmteSetFI(rpmte te, rpmfi fi)
577 te->fi = rpmfiFree(te->fi);
579 te->fi = rpmfiLink(fi);
584 rpmfi rpmteFI(rpmte te)
589 return te->fi; /* XXX take fi reference here? */
592 static void rpmteColorDS(rpmte te, rpmTag tag)
594 rpmfi fi = rpmteFI(te);
595 rpmds ds = rpmteDS(te, tag);
598 const uint32_t * ddict;
599 rpm_color_t * colors;
605 if (!(te && (Count = rpmdsCount(ds)) > 0 && rpmfiFC(fi) > 0))
612 case RPMTAG_PROVIDENAME:
615 case RPMTAG_REQUIRENAME:
620 colors = xcalloc(Count, sizeof(*colors));
622 /* Calculate dependency color. */
623 fi = rpmfiInit(fi, 0);
625 while (rpmfiNext(fi) >= 0) {
626 val = rpmfiFColor(fi);
628 ndx = rpmfiFDepends(fi, &ddict);
632 mydt = ((ix >> 24) & 0xff);
641 /* Set color values in dependency set. */
643 while ((i = rpmdsNext(ds)) >= 0) {
646 (void) rpmdsSetColor(ds, val);
651 static Header rpmteDBHeader(rpmte te)
654 rpmdbMatchIterator mi;
656 mi = rpmtsInitIterator(te->ts, RPMDBI_PACKAGES,
657 &te->db_instance, sizeof(te->db_instance));
658 /* iterator returns weak refs, grab hold of header */
659 if ((h = rpmdbNextIterator(mi)))
661 rpmdbFreeIterator(mi);
665 static Header rpmteFDHeader(rpmte te)
668 te->fd = rpmtsNotify(te->ts, te, RPMCALLBACK_INST_OPEN_FILE, 0, 0);
669 if (te->fd != NULL) {
673 ovsflags = rpmtsSetVSFlags(te->ts,
674 rpmtsVSFlags(te->ts) | RPMVSF_NEEDPAYLOAD);
675 pkgrc = rpmReadPackageFile(te->ts, te->fd, rpmteNEVRA(te), &h);
676 rpmtsSetVSFlags(te->ts, ovsflags);
681 case RPMRC_NOTTRUSTED:
690 static int rpmteOpen(rpmte te, int reload_fi)
692 int rc = 0; /* assume failure */
694 if (te == NULL || te->ts == NULL || rpmteFailed(te))
697 rpmteSetHeader(te, NULL);
699 switch (rpmteType(te)) {
701 h = rpmteDBInstance(te) ? rpmteDBHeader(te) : rpmteFDHeader(te);
704 h = rpmteDBHeader(te);
709 /* This can fail if we get a different, bad header from callback */
710 te->fi = getFI(te, h);
711 rc = (te->fi != NULL);
716 rpmteSetHeader(te, h);
724 static int rpmteClose(rpmte te, int reset_fi)
726 if (te == NULL || te->ts == NULL)
732 rpmtsNotify(te->ts, te, RPMCALLBACK_INST_CLOSE_FILE, 0, 0);
737 /* eventually we'll want notifications for erase open too */
740 rpmteSetHeader(te, NULL);
742 rpmteSetFI(te, NULL);
747 FD_t rpmtePayload(rpmte te)
750 if (te->fd && te->h) {
751 const char *compr = headerGetString(te->h, RPMTAG_PAYLOADCOMPRESSOR);
752 char *ioflags = rstrscat(NULL, "r.", compr ? compr : "gzip", NULL);
753 payload = Fdopen(fdDup(Fileno(te->fd)), ioflags);
759 static int rpmteMarkFailed(rpmte te)
761 rpmtsi pi = rpmtsiInit(te->ts);
765 /* XXX we can do a much better here than this... */
766 while ((p = rpmtsiNext(pi, TR_REMOVED))) {
767 if (rpmteDependsOn(p) == te) {
775 int rpmteFailed(rpmte te)
777 return (te != NULL) ? te->failed : -1;
780 int rpmteHaveTransScript(rpmte te, rpmTagVal tag)
783 if (tag == RPMTAG_PRETRANS) {
784 rc = (te->transscripts & RPMTE_HAVE_PRETRANS);
785 } else if (tag == RPMTAG_POSTTRANS) {
786 rc = (te->transscripts & RPMTE_HAVE_POSTTRANS);
791 rpmps rpmteProblems(rpmte te)
793 return (te != NULL) ? rpmpsLink(te->probs) : NULL;
796 void rpmteCleanProblems(rpmte te)
798 if (te != NULL && te->probs != NULL) {
799 te->probs = rpmpsFree(te->probs);
803 static void appendProblem(rpmte te, rpmProblemType type,
804 fnpyKey key, const char * altNEVR,
805 const char * str, uint64_t number)
808 rpmProblem p = rpmProblemCreate(type, te->NEVRA, key, altNEVR, str, number);
809 rpmpsi psi = rpmpsInitIterator(te->probs);
811 /* Only add new, unique problems to the set */
812 while ((o = rpmpsiNext(psi))) {
813 if (rpmProblemCompare(p, o) == 0)
816 rpmpsFreeIterator(psi);
819 if (te->probs == NULL)
820 te->probs = rpmpsCreate();
821 rpmpsAppendProblem(te->probs, p);
826 void rpmteAddProblem(rpmte te, rpmProblemType type,
827 const char *altNEVR, const char *str, uint64_t number)
830 appendProblem(te, type, rpmteKey(te), altNEVR, str, number);
834 void rpmteAddDepProblem(rpmte te, const char * altNEVR, rpmds ds,
835 fnpyKey * suggestedKeys)
838 const char * DNEVR = rpmdsDNEVR(ds);
840 fnpyKey key = (suggestedKeys ? suggestedKeys[0] : NULL);
842 switch ((unsigned)DNEVR[0]) {
843 case 'O': type = RPMPROB_OBSOLETES; break;
844 case 'C': type = RPMPROB_CONFLICT; break;
846 case 'R': type = RPMPROB_REQUIRES; break;
849 appendProblem(te, type, key, altNEVR, DNEVR+2, rpmdsInstance(ds));
853 void rpmteAddRelocProblems(rpmte te)
855 if (te && te->badrelocs) {
856 for (int i = 0; i < te->nrelocs; i++) {
857 if (te->badrelocs[i]) {
858 rpmteAddProblem(te, RPMPROB_BADRELOCATE, NULL,
859 te->relocs[i].oldPath, 0);
865 const char * rpmteTypeString(rpmte te)
867 switch(rpmteType(te)) {
868 case TR_ADDED: return _("install");
869 case TR_REMOVED: return _("erase");
870 default: return "???";
874 rpmfs rpmteGetFileStates(rpmte te)
879 rpmRC rpmteSetupCollectionPlugins(rpmte te)
881 ARGV_const_t colls = rpmteCollections(te);
882 rpmPlugins plugins = rpmtsPlugins(te->ts);
890 for (; colls && *colls; colls++) {
891 if (!rpmpluginsPluginAdded(plugins, *colls)) {
892 rc = rpmpluginsAddPlugin(plugins, "collection", *colls);
893 if (rc != RPMRC_OK) {
897 rc = rpmpluginsCallOpenTE(plugins, *colls, te);
898 if (rc != RPMRC_OK) {
907 static rpmRC rpmteRunAllCollections(rpmte te, rpmPluginHook hook)
910 rpmRC(*collHook) (rpmPlugins, const char *);
913 if (rpmtsFlags(te->ts) & RPMTRANS_FLAG_NOCOLLECTIONS) {
918 case PLUGINHOOK_COLL_POST_ADD:
919 colls = te->lastInCollectionsAdd;
920 collHook = rpmpluginsCallCollectionPostAdd;
922 case PLUGINHOOK_COLL_POST_ANY:
923 colls = te->lastInCollectionsAny;
924 collHook = rpmpluginsCallCollectionPostAny;
926 case PLUGINHOOK_COLL_PRE_REMOVE:
927 colls = te->firstInCollectionsRemove;
928 collHook = rpmpluginsCallCollectionPreRemove;
934 for (; colls && *colls; colls++) {
935 rc = collHook(rpmtsPlugins(te->ts), *colls);
942 int rpmteProcess(rpmte te, pkgGoal goal)
944 /* Only install/erase resets pkg file info */
945 int scriptstage = (goal != PKG_INSTALL && goal != PKG_ERASE);
946 int test = (rpmtsFlags(te->ts) & RPMTRANS_FLAG_TEST);
947 int reset_fi = (scriptstage == 0 && test == 0);
950 /* Dont bother opening for elements without pre/posttrans scripts */
951 if (goal == PKG_PRETRANS || goal == PKG_POSTTRANS) {
952 if (!rpmteHaveTransScript(te, goal)) {
958 rpmteRunAllCollections(te, PLUGINHOOK_COLL_PRE_REMOVE);
961 if (rpmteOpen(te, reset_fi)) {
962 failed = rpmpsmRun(te->ts, te, goal);
963 rpmteClose(te, reset_fi);
967 rpmteRunAllCollections(te, PLUGINHOOK_COLL_POST_ADD);
968 rpmteRunAllCollections(te, PLUGINHOOK_COLL_POST_ANY);
972 failed = rpmteMarkFailed(te);