3 * Routine(s) to handle an "rpmte" transaction element.
7 #include <rpm/rpmtypes.h>
8 #include <rpm/rpmlib.h> /* RPM_MACHTABLE_* */
10 #include <rpm/rpmfi.h>
11 #include <rpm/rpmts.h>
12 #include <rpm/rpmdb.h>
14 #include "lib/rpmte_internal.h"
21 void rpmteCleanDS(rpmte te)
23 te->this = rpmdsFree(te->this);
24 te->provides = rpmdsFree(te->provides);
25 te->requires = rpmdsFree(te->requires);
26 te->conflicts = rpmdsFree(te->conflicts);
27 te->obsoletes = rpmdsFree(te->obsoletes);
31 * Destroy transaction element data.
32 * @param p transaction element
34 static void delTE(rpmte p)
39 for (r = p->relocs; (r->oldPath || r->newPath); r++) {
40 r->oldPath = _free(r->oldPath);
41 r->newPath = _free(r->newPath);
43 p->relocs = _free(p->relocs);
48 p->fi = rpmfiFree(p->fi);
51 p->fd = fdFree(p->fd, RPMDBG_M("delTE"));
54 p->arch = _free(p->arch);
55 p->epoch = _free(p->epoch);
56 p->name = _free(p->name);
57 p->version = _free(p->version);
58 p->release = _free(p->release);
59 p->NEVR = _free(p->NEVR);
60 p->NEVRA = _free(p->NEVRA);
62 p->h = headerFree(p->h);
64 memset(p, 0, sizeof(*p)); /* XXX trash and burn */
65 /* FIX: p->{NEVR,name} annotations */
70 * Initialize transaction element data from header.
71 * @param ts transaction set
72 * @param p transaction element
74 * @param key (TR_ADDED) package retrieval key (e.g. file name)
75 * @param relocs (TR_ADDED) package file relocations
77 static void addTE(rpmts ts, rpmte p, Header h,
79 rpmRelocation * relocs)
82 const char *name, *version, *release, *arch, *os;
86 name = version = release = arch = NULL;
87 headerNEVRA(h, &name, NULL, &version, &release, &arch);
90 p->name = xstrdup(name);
91 p->version = xstrdup(version);
92 p->release = xstrdup(release);
94 if (headerGet(h, RPMTAG_EPOCH, &td, HEADERGET_MINMEM)) {
95 p->epoch = rpmtdFormat(&td, RPMTD_FORMAT_STRING, NULL);
100 p->arch = arch ? xstrdup(arch) : NULL;
101 p->archScore = arch ? rpmMachineScore(RPM_MACHTABLE_INSTARCH, arch) : 0;
103 headerGet(h, RPMTAG_OS, &td, HEADERGET_MINMEM);
104 os = rpmtdGetString(&td);
105 p->os = os ? xstrdup(os) : NULL;
106 p->osScore = p->os ? rpmMachineScore(RPM_MACHTABLE_INSTOS, p->os) : 0;
108 p->isSource = headerIsSource(h);
110 p->NEVR = headerGetNEVR(h, NULL);
111 p->NEVRA = headerGetNEVRA(h, NULL);
115 if (relocs != NULL) {
119 for (r = relocs; r->oldPath || r->newPath; r++)
121 p->relocs = xmalloc((p->nrelocs + 1) * sizeof(*p->relocs));
123 for (i = 0, r = relocs; r->oldPath || r->newPath; i++, r++) {
124 p->relocs[i].oldPath = r->oldPath ? xstrdup(r->oldPath) : NULL;
125 p->relocs[i].newPath = r->newPath ? xstrdup(r->newPath) : NULL;
127 p->relocs[i].oldPath = NULL;
128 p->relocs[i].newPath = NULL;
131 p->db_instance = headerGetInstance(h);
137 p->this = rpmdsThis(h, RPMTAG_PROVIDENAME, RPMSENSE_EQUAL);
138 p->provides = rpmdsNew(h, RPMTAG_PROVIDENAME, 0);
139 p->requires = rpmdsNew(h, RPMTAG_REQUIRENAME, 0);
140 p->conflicts = rpmdsNew(h, RPMTAG_CONFLICTNAME, 0);
141 p->obsoletes = rpmdsNew(h, RPMTAG_OBSOLETENAME, 0);
143 fiflags = (p->type == TR_ADDED) ? (RPMFI_NOHEADER | RPMFI_FLAGS_INSTALL) :
144 (RPMFI_NOHEADER | RPMFI_FLAGS_ERASE);
145 savep = rpmtsSetRelocateElement(ts, p);
146 p->fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, fiflags);
147 (void) rpmtsSetRelocateElement(ts, savep);
149 /* See if we have pre/posttrans scripts. */
150 p->transscripts |= (headerIsEntry(h, RPMTAG_PRETRANS) &&
151 headerIsEntry(h, RPMTAG_PRETRANSPROG)) ?
152 RPMTE_HAVE_PRETRANS : 0;
153 p->transscripts |= (headerIsEntry(h, RPMTAG_POSTTRANS) &&
154 headerIsEntry(h, RPMTAG_POSTTRANSPROG)) ?
155 RPMTE_HAVE_POSTTRANS : 0;
157 rpmteColorDS(p, RPMTAG_PROVIDENAME);
158 rpmteColorDS(p, RPMTAG_REQUIRENAME);
162 rpmte rpmteFree(rpmte te)
171 rpmte rpmteNew(const rpmts ts, Header h,
174 rpmRelocation * relocs,
178 rpmte p = xcalloc(1, sizeof(*p));
184 addTE(ts, p, h, key, relocs);
187 headerGet(h, RPMTAG_SIGSIZE, &size, HEADERGET_DEFAULT);
188 if ((ep = rpmtdGetUint32(&size))) {
189 p->pkgFileSize += 96 + 256 + *ep;
199 unsigned int rpmteDBInstance(rpmte te)
201 return (te != NULL ? te->db_instance : 0);
204 void rpmteSetDBInstance(rpmte te, unsigned int instance)
207 te->db_instance = instance;
210 Header rpmteHeader(rpmte te)
212 return (te != NULL && te->h != NULL ? headerLink(te->h) : NULL);
215 Header rpmteSetHeader(rpmte te, Header h)
218 te->h = headerFree(te->h);
220 te->h = headerLink(h);
225 rpmElementType rpmteType(rpmte te)
227 /* XXX returning negative for unsigned type */
228 return (te != NULL ? te->type : -1);
231 const char * rpmteN(rpmte te)
233 return (te != NULL ? te->name : NULL);
236 const char * rpmteE(rpmte te)
238 return (te != NULL ? te->epoch : NULL);
241 const char * rpmteV(rpmte te)
243 return (te != NULL ? te->version : NULL);
246 const char * rpmteR(rpmte te)
248 return (te != NULL ? te->release : NULL);
251 const char * rpmteA(rpmte te)
253 return (te != NULL ? te->arch : NULL);
256 const char * rpmteO(rpmte te)
258 return (te != NULL ? te->os : NULL);
261 int rpmteIsSource(rpmte te)
263 return (te != NULL ? te->isSource : 0);
266 rpm_color_t rpmteColor(rpmte te)
268 return (te != NULL ? te->color : 0);
271 rpm_color_t rpmteSetColor(rpmte te, rpm_color_t color)
273 rpm_color_t ocolor = 0;
281 rpm_loff_t rpmtePkgFileSize(rpmte te)
283 return (te != NULL ? te->pkgFileSize : 0);
286 int rpmteDepth(rpmte te)
288 return (te != NULL ? te->depth : 0);
291 int rpmteSetDepth(rpmte te, int ndepth)
301 int rpmteBreadth(rpmte te)
303 return (te != NULL ? te->depth : 0);
306 int rpmteSetBreadth(rpmte te, int nbreadth)
310 obreadth = te->breadth;
311 te->breadth = nbreadth;
316 int rpmteNpreds(rpmte te)
318 return (te != NULL ? te->npreds : 0);
321 int rpmteSetNpreds(rpmte te, int npreds)
331 int rpmteTree(rpmte te)
333 return (te != NULL ? te->tree : 0);
336 int rpmteSetTree(rpmte te, int ntree)
346 rpmte rpmteParent(rpmte te)
348 return (te != NULL ? te->parent : NULL);
351 rpmte rpmteSetParent(rpmte te, rpmte pte)
361 int rpmteDegree(rpmte te)
363 return (te != NULL ? te->degree : 0);
366 int rpmteSetDegree(rpmte te, int ndegree)
370 odegree = te->degree;
371 te->degree = ndegree;
376 tsortInfo rpmteTSI(rpmte te)
381 void rpmteFreeTSI(rpmte te)
383 if (te != NULL && rpmteTSI(te) != NULL) {
386 /* Clean up tsort remnants (if any). */
387 while ((tsi = rpmteTSI(te)->tsi_next) != NULL) {
388 rpmteTSI(te)->tsi_next = tsi->tsi_next;
389 tsi->tsi_next = NULL;
392 te->tsi = _free(te->tsi);
394 /* FIX: te->tsi is NULL */
398 void rpmteNewTSI(rpmte te)
402 te->tsi = xcalloc(1, sizeof(*te->tsi));
406 rpmalKey rpmteAddedKey(rpmte te)
408 return (te != NULL && te->type == TR_ADDED ? te->pkgKey : RPMAL_NOMATCH);
411 rpmalKey rpmteSetAddedKey(rpmte te, rpmalKey npkgKey)
413 rpmalKey opkgKey = RPMAL_NOMATCH;
414 if (te != NULL && te->type == TR_ADDED) {
415 opkgKey = te->pkgKey;
416 te->pkgKey = npkgKey;
422 rpmalKey rpmteDependsOnKey(rpmte te)
424 return (te != NULL && te->type == TR_REMOVED ? te->pkgKey : RPMAL_NOMATCH);
427 int rpmteDBOffset(rpmte te)
429 return rpmteDBInstance(te);
432 const char * rpmteEVR(rpmte te)
434 return (te != NULL ? te->NEVR + strlen(te->name) + 1 : NULL);
437 const char * rpmteNEVR(rpmte te)
439 return (te != NULL ? te->NEVR : NULL);
442 const char * rpmteNEVRA(rpmte te)
444 return (te != NULL ? te->NEVRA : NULL);
447 FD_t rpmteFd(rpmte te)
449 return (te != NULL ? te->fd : NULL);
452 fnpyKey rpmteKey(rpmte te)
454 return (te != NULL ? te->key : NULL);
457 rpmds rpmteDS(rpmte te, rpmTag tag)
462 if (tag == RPMTAG_NAME)
465 if (tag == RPMTAG_PROVIDENAME)
468 if (tag == RPMTAG_REQUIRENAME)
471 if (tag == RPMTAG_CONFLICTNAME)
472 return te->conflicts;
474 if (tag == RPMTAG_OBSOLETENAME)
475 return te->obsoletes;
480 rpmfi rpmteFI(rpmte te)
485 return te->fi; /* XXX take fi reference here? */
488 void rpmteColorDS(rpmte te, rpmTag tag)
490 rpmfi fi = rpmteFI(te);
491 rpmds ds = rpmteDS(te, tag);
494 const uint32_t * ddict;
495 rpm_color_t * colors;
503 if (!(te && (Count = rpmdsCount(ds)) > 0 && rpmfiFC(fi) > 0))
510 case RPMTAG_PROVIDENAME:
513 case RPMTAG_REQUIRENAME:
518 colors = xcalloc(Count, sizeof(*colors));
519 nb = Count * sizeof(*refs);
520 refs = memset(xmalloc(nb), -1, nb);
522 /* Calculate dependency color and reference count. */
523 fi = rpmfiInit(fi, 0);
525 while (rpmfiNext(fi) >= 0) {
526 val = rpmfiFColor(fi);
528 ndx = rpmfiFDepends(fi, &ddict);
532 mydt = ((ix >> 24) & 0xff);
542 /* Set color/refs values in dependency set. */
544 while ((i = rpmdsNext(ds)) >= 0) {
547 (void) rpmdsSetColor(ds, val);
551 (void) rpmdsSetRefs(ds, val);
557 int rpmtsiOc(rpmtsi tsi)
562 rpmtsi rpmtsiFree(rpmtsi tsi)
564 /* XXX watchout: a funky recursion segfaults here iff nrefs is wrong. */
566 tsi->ts = rpmtsFree(tsi->ts);
570 rpmtsi rpmtsiInit(rpmts ts)
574 tsi = xcalloc(1, sizeof(*tsi));
575 tsi->ts = rpmtsLink(ts, RPMDBG_M("rpmtsi"));
576 tsi->reverse = ((rpmtsFlags(ts) & RPMTRANS_FLAG_REVERSE) ? 1 : 0);
577 tsi->oc = (tsi->reverse ? (rpmtsNElements(ts) - 1) : 0);
578 tsi->ocsave = tsi->oc;
583 * Return next transaction element.
584 * @param tsi transaction element iterator
585 * @return transaction element, NULL on termination
588 rpmte rpmtsiNextElement(rpmtsi tsi)
593 if (tsi == NULL || tsi->ts == NULL || rpmtsNElements(tsi->ts) <= 0)
597 if (tsi->oc >= 0) oc = tsi->oc--;
599 if (tsi->oc < rpmtsNElements(tsi->ts)) oc = tsi->oc++;
603 te = rpmtsElement(tsi->ts, oc);
607 rpmte rpmtsiNext(rpmtsi tsi, rpmElementType type)
611 while ((te = rpmtsiNextElement(tsi)) != NULL) {
612 if (type == 0 || (te->type & type) != 0)
618 int rpmteOpen(rpmte te, rpmts ts)
621 if (te == NULL || ts == NULL)
624 rpmteSetHeader(te, NULL);
628 te->fd = rpmtsNotify(ts, te, RPMCALLBACK_INST_OPEN_FILE, 0, 0);
629 if (te->fd != NULL) {
633 ovsflags = rpmtsSetVSFlags(ts, rpmtsVSFlags(ts) | RPMVSF_NEEDPAYLOAD);
634 pkgrc = rpmReadPackageFile(ts, rpmteFd(te), rpmteNEVRA(te), &h);
635 rpmtsSetVSFlags(ts, ovsflags);
640 case RPMRC_NOTTRUSTED:
648 unsigned int rec = rpmteDBInstance(te);
649 rpmdbMatchIterator mi;
651 /* eventually we'll want notifications for erase open too */
652 mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, &rec, sizeof(rec));
653 /* iterator returns weak refs, grab hold of header */
654 if ((h = rpmdbNextIterator(mi)))
656 mi = rpmdbFreeIterator(mi);
661 rpmteSetHeader(te, h);
669 int rpmteClose(rpmte te, rpmts ts)
671 if (te == NULL || ts == NULL)
676 rpmtsNotify(ts, te, RPMCALLBACK_INST_CLOSE_FILE, 0, 0);
680 /* eventually we'll want notifications for erase open too */
683 rpmteSetHeader(te, NULL);
687 int rpmteMarkFailed(rpmte te, rpmts ts)
689 rpmtsi pi = rpmtsiInit(ts);
692 rpmalKey key = rpmteAddedKey(te);
695 /* XXX we can do a much better here than this... */
696 while ((p = rpmtsiNext(pi, TR_REMOVED))) {
697 if (rpmteDependsOnKey(p) == key) {
705 int rpmteFailed(rpmte te)
707 return (te != NULL) ? te->failed : -1;