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>
13 #include "lib/rpmte_internal.h"
20 void rpmteCleanDS(rpmte te)
22 te->this = rpmdsFree(te->this);
23 te->provides = rpmdsFree(te->provides);
24 te->requires = rpmdsFree(te->requires);
25 te->conflicts = rpmdsFree(te->conflicts);
26 te->obsoletes = rpmdsFree(te->obsoletes);
30 * Destroy transaction element data.
31 * @param p transaction element
33 static void delTE(rpmte p)
38 for (r = p->relocs; (r->oldPath || r->newPath); r++) {
39 r->oldPath = _free(r->oldPath);
40 r->newPath = _free(r->newPath);
42 p->relocs = _free(p->relocs);
47 p->fi = rpmfiFree(p->fi);
50 p->fd = fdFree(p->fd, RPMDBG_M("delTE"));
53 p->arch = _free(p->arch);
54 p->epoch = _free(p->epoch);
55 p->name = _free(p->name);
56 p->version = _free(p->version);
57 p->release = _free(p->release);
58 p->NEVR = _free(p->NEVR);
59 p->NEVRA = _free(p->NEVRA);
61 p->h = headerFree(p->h);
63 memset(p, 0, sizeof(*p)); /* XXX trash and burn */
64 /* FIX: p->{NEVR,name} annotations */
69 * Initialize transaction element data from header.
70 * @param ts transaction set
71 * @param p transaction element
73 * @param key (TR_ADDED) package retrieval key (e.g. file name)
74 * @param relocs (TR_ADDED) package file relocations
76 static void addTE(rpmts ts, rpmte p, Header h,
78 rpmRelocation * relocs)
81 const char *name, *version, *release, *arch, *os;
84 name = version = release = arch = NULL;
85 headerNEVRA(h, &name, NULL, &version, &release, &arch);
88 p->name = xstrdup(name);
89 p->version = xstrdup(version);
90 p->release = xstrdup(release);
92 if (headerGet(h, RPMTAG_EPOCH, &td, HEADERGET_MINMEM)) {
93 p->epoch = rpmtdFormat(&td, RPMTD_FORMAT_STRING, NULL);
98 p->arch = arch ? xstrdup(arch) : NULL;
99 p->archScore = arch ? rpmMachineScore(RPM_MACHTABLE_INSTARCH, arch) : 0;
101 headerGet(h, RPMTAG_OS, &td, HEADERGET_MINMEM);
102 os = rpmtdGetString(&td);
103 p->os = os ? xstrdup(os) : NULL;
104 p->osScore = p->os ? rpmMachineScore(RPM_MACHTABLE_INSTOS, p->os) : 0;
106 p->isSource = headerIsSource(h);
108 p->NEVR = headerGetNEVR(h, NULL);
109 p->NEVRA = headerGetNEVRA(h, NULL);
113 if (relocs != NULL) {
117 for (r = relocs; r->oldPath || r->newPath; r++)
119 p->relocs = xmalloc((p->nrelocs + 1) * sizeof(*p->relocs));
121 for (i = 0, r = relocs; r->oldPath || r->newPath; i++, r++) {
122 p->relocs[i].oldPath = r->oldPath ? xstrdup(r->oldPath) : NULL;
123 p->relocs[i].newPath = r->newPath ? xstrdup(r->newPath) : NULL;
125 p->relocs[i].oldPath = NULL;
126 p->relocs[i].newPath = NULL;
129 p->db_instance = headerGetInstance(h);
135 p->this = rpmdsThis(h, RPMTAG_PROVIDENAME, RPMSENSE_EQUAL);
136 p->provides = rpmdsNew(h, RPMTAG_PROVIDENAME, 0);
137 p->requires = rpmdsNew(h, RPMTAG_REQUIRENAME, 0);
138 p->conflicts = rpmdsNew(h, RPMTAG_CONFLICTNAME, 0);
139 p->obsoletes = rpmdsNew(h, RPMTAG_OBSOLETENAME, 0);
141 savep = rpmtsSetRelocateElement(ts, p);
142 p->fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, RPMFI_NOHEADER|RPMFI_NOFILECLASS);
143 (void) rpmtsSetRelocateElement(ts, savep);
145 rpmteColorDS(p, RPMTAG_PROVIDENAME);
146 rpmteColorDS(p, RPMTAG_REQUIRENAME);
150 rpmte rpmteFree(rpmte te)
154 memset(te, 0, sizeof(*te)); /* XXX trash and burn */
160 rpmte rpmteNew(const rpmts ts, Header h,
163 rpmRelocation * relocs,
167 rpmte p = xcalloc(1, sizeof(*p));
173 addTE(ts, p, h, key, relocs);
176 headerGet(h, RPMTAG_SIGSIZE, &size, HEADERGET_DEFAULT);
177 if ((ep = rpmtdGetUint32(&size))) {
178 p->pkgFileSize += 96 + 256 + *ep;
188 unsigned int rpmteDBInstance(rpmte te)
190 return (te != NULL ? te->db_instance : 0);
193 void rpmteSetDBInstance(rpmte te, unsigned int instance)
196 te->db_instance = instance;
199 Header rpmteHeader(rpmte te)
201 return (te != NULL && te->h != NULL ? headerLink(te->h) : NULL);
204 Header rpmteSetHeader(rpmte te, Header h)
207 te->h = headerFree(te->h);
209 te->h = headerLink(h);
214 rpmElementType rpmteType(rpmte te)
216 /* XXX returning negative for unsigned type */
217 return (te != NULL ? te->type : -1);
220 const char * rpmteN(rpmte te)
222 return (te != NULL ? te->name : NULL);
225 const char * rpmteE(rpmte te)
227 return (te != NULL ? te->epoch : NULL);
230 const char * rpmteV(rpmte te)
232 return (te != NULL ? te->version : NULL);
235 const char * rpmteR(rpmte te)
237 return (te != NULL ? te->release : NULL);
240 const char * rpmteA(rpmte te)
242 return (te != NULL ? te->arch : NULL);
245 const char * rpmteO(rpmte te)
247 return (te != NULL ? te->os : NULL);
250 int rpmteIsSource(rpmte te)
252 return (te != NULL ? te->isSource : 0);
255 rpm_color_t rpmteColor(rpmte te)
257 return (te != NULL ? te->color : 0);
260 rpm_color_t rpmteSetColor(rpmte te, rpm_color_t color)
262 rpm_color_t ocolor = 0;
270 rpm_loff_t rpmtePkgFileSize(rpmte te)
272 return (te != NULL ? te->pkgFileSize : 0);
275 int rpmteDepth(rpmte te)
277 return (te != NULL ? te->depth : 0);
280 int rpmteSetDepth(rpmte te, int ndepth)
290 int rpmteBreadth(rpmte te)
292 return (te != NULL ? te->depth : 0);
295 int rpmteSetBreadth(rpmte te, int nbreadth)
299 obreadth = te->breadth;
300 te->breadth = nbreadth;
305 int rpmteNpreds(rpmte te)
307 return (te != NULL ? te->npreds : 0);
310 int rpmteSetNpreds(rpmte te, int npreds)
320 int rpmteTree(rpmte te)
322 return (te != NULL ? te->tree : 0);
325 int rpmteSetTree(rpmte te, int ntree)
335 rpmte rpmteParent(rpmte te)
337 return (te != NULL ? te->parent : NULL);
340 rpmte rpmteSetParent(rpmte te, rpmte pte)
350 int rpmteDegree(rpmte te)
352 return (te != NULL ? te->degree : 0);
355 int rpmteSetDegree(rpmte te, int ndegree)
359 odegree = te->degree;
360 te->degree = ndegree;
365 tsortInfo rpmteTSI(rpmte te)
370 void rpmteFreeTSI(rpmte te)
372 if (te != NULL && rpmteTSI(te) != NULL) {
375 /* Clean up tsort remnants (if any). */
376 while ((tsi = rpmteTSI(te)->tsi_next) != NULL) {
377 rpmteTSI(te)->tsi_next = tsi->tsi_next;
378 tsi->tsi_next = NULL;
381 te->tsi = _free(te->tsi);
383 /* FIX: te->tsi is NULL */
387 void rpmteNewTSI(rpmte te)
391 te->tsi = xcalloc(1, sizeof(*te->tsi));
395 rpmalKey rpmteAddedKey(rpmte te)
397 return (te != NULL && te->type == TR_ADDED ? te->pkgKey : RPMAL_NOMATCH);
400 rpmalKey rpmteSetAddedKey(rpmte te, rpmalKey npkgKey)
402 rpmalKey opkgKey = RPMAL_NOMATCH;
403 if (te != NULL && te->type == TR_ADDED) {
404 opkgKey = te->pkgKey;
405 te->pkgKey = npkgKey;
411 rpmalKey rpmteDependsOnKey(rpmte te)
413 return (te != NULL && te->type == TR_REMOVED ? te->pkgKey : RPMAL_NOMATCH);
416 int rpmteDBOffset(rpmte te)
418 return rpmteDBInstance(te);
421 const char * rpmteEVR(rpmte te)
423 return (te != NULL ? te->NEVR + strlen(te->name) + 1 : NULL);
426 const char * rpmteNEVR(rpmte te)
428 return (te != NULL ? te->NEVR : NULL);
431 const char * rpmteNEVRA(rpmte te)
433 return (te != NULL ? te->NEVRA : NULL);
436 FD_t rpmteFd(rpmte te)
438 return (te != NULL ? te->fd : NULL);
441 fnpyKey rpmteKey(rpmte te)
443 return (te != NULL ? te->key : NULL);
446 rpmds rpmteDS(rpmte te, rpmTag tag)
451 if (tag == RPMTAG_NAME)
454 if (tag == RPMTAG_PROVIDENAME)
457 if (tag == RPMTAG_REQUIRENAME)
460 if (tag == RPMTAG_CONFLICTNAME)
461 return te->conflicts;
463 if (tag == RPMTAG_OBSOLETENAME)
464 return te->obsoletes;
469 rpmfi rpmteFI(rpmte te, rpmTag tag)
474 if (tag == RPMTAG_BASENAMES)
480 void rpmteColorDS(rpmte te, rpmTag tag)
482 rpmfi fi = rpmteFI(te, RPMTAG_BASENAMES);
483 rpmds ds = rpmteDS(te, tag);
486 const uint32_t * ddict;
487 rpm_color_t * colors;
495 if (!(te && (Count = rpmdsCount(ds)) > 0 && rpmfiFC(fi) > 0))
502 case RPMTAG_PROVIDENAME:
505 case RPMTAG_REQUIRENAME:
510 colors = xcalloc(Count, sizeof(*colors));
511 nb = Count * sizeof(*refs);
512 refs = memset(xmalloc(nb), -1, nb);
514 /* Calculate dependency color and reference count. */
515 fi = rpmfiInit(fi, 0);
517 while (rpmfiNext(fi) >= 0) {
518 val = rpmfiFColor(fi);
520 ndx = rpmfiFDepends(fi, &ddict);
524 mydt = ((ix >> 24) & 0xff);
534 /* Set color/refs values in dependency set. */
536 while ((i = rpmdsNext(ds)) >= 0) {
539 (void) rpmdsSetColor(ds, val);
543 (void) rpmdsSetRefs(ds, val);
549 int rpmtsiOc(rpmtsi tsi)
554 rpmtsi rpmtsiFree(rpmtsi tsi)
556 /* XXX watchout: a funky recursion segfaults here iff nrefs is wrong. */
558 tsi->ts = rpmtsFree(tsi->ts);
562 rpmtsi rpmtsiInit(rpmts ts)
566 tsi = xcalloc(1, sizeof(*tsi));
567 tsi->ts = rpmtsLink(ts, RPMDBG_M("rpmtsi"));
568 tsi->reverse = ((rpmtsFlags(ts) & RPMTRANS_FLAG_REVERSE) ? 1 : 0);
569 tsi->oc = (tsi->reverse ? (rpmtsNElements(ts) - 1) : 0);
570 tsi->ocsave = tsi->oc;
575 * Return next transaction element.
576 * @param tsi transaction element iterator
577 * @return transaction element, NULL on termination
580 rpmte rpmtsiNextElement(rpmtsi tsi)
585 if (tsi == NULL || tsi->ts == NULL || rpmtsNElements(tsi->ts) <= 0)
589 if (tsi->oc >= 0) oc = tsi->oc--;
591 if (tsi->oc < rpmtsNElements(tsi->ts)) oc = tsi->oc++;
595 te = rpmtsElement(tsi->ts, oc);
599 rpmte rpmtsiNext(rpmtsi tsi, rpmElementType type)
603 while ((te = rpmtsiNextElement(tsi)) != NULL) {
604 if (type == 0 || (te->type & type) != 0)
610 int rpmteOpen(rpmte te, rpmts ts)
613 if (te == NULL || ts == NULL)
617 te->fd = rpmtsNotify(ts, te, RPMCALLBACK_INST_OPEN_FILE, 0, 0);
618 if (te->fd != NULL) {
622 ovsflags = rpmtsSetVSFlags(ts, rpmtsVSFlags(ts) | RPMVSF_NEEDPAYLOAD);
623 pkgrc = rpmReadPackageFile(ts, rpmteFd(te), rpmteNEVRA(te), &te->h);
624 rpmtsSetVSFlags(ts, ovsflags);
629 case RPMRC_NOTTRUSTED:
641 int rpmteClose(rpmte te, rpmts ts)
644 if (te != NULL && ts != NULL) {
645 rpmtsNotify(ts, te, RPMCALLBACK_INST_CLOSE_FILE, 0, 0);
647 te->h = headerFree(te->h);