rpm  5.4.10
rpmte.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 
7 #include <rpmio.h>
8 #include <rpmiotypes.h> /* XXX fnpyKey */
9 
10 #include <rpmtypes.h>
11 #include <rpmtag.h>
12 #include <rpmdb.h> /* rpmmiFoo */
13 #include <pkgio.h> /* rpmReadPackageFile */
14 
15 #include "rpmds.h"
16 #define _RPMFI_INTERNAL /* pre/post trans scripts */
17 #include "rpmfi.h"
18 
19 #define _RPMTE_INTERNAL
20 #include "rpmte.h"
21 #include "rpmts.h"
22 
23 #include "debug.h"
24 
25 /*@unchecked@*/
26 int _rpmte_debug = 0;
27 
28 /*@access alKey @*/
29 /*@access rpmts @*/ /* XXX cast */
30 /*@access rpmtsi @*/
31 
32 #ifdef __cplusplus
33 GENfree(rpmtsi)
34 GENfree(sharedFileInfo)
35 GENfree(tsortInfo)
36 #endif /* __cplusplus */
37 
39 {
40  te->PRCO = rpmdsFreePRCO(te->PRCO);
41 }
42 
47 static void delTE(rpmte p)
48  /*@globals fileSystem @*/
49  /*@modifies p, fileSystem @*/
50 {
51  p->relocs = rpmfiFreeRelocations(p->relocs);
52 
53  rpmteCleanDS(p);
54 
55 /*@-refcounttrans@*/ /* FIX: XfdFree annotation */
56  if (p->fd != NULL)
57  p->fd = fdFree(p->fd, "delTE");
58 /*@=refcounttrans@*/
59 
60  p->os = _free(p->os);
61  p->arch = _free(p->arch);
62  p->epoch = _free(p->epoch);
63  p->name = _free(p->name);
64  p->version = _free(p->version);
65  p->release = _free(p->release);
66 #ifdef RPM_VENDOR_MANDRIVA
67  p->distepoch = _free(p->distepoch);
68 #endif
69  p->NEVR = _free(p->NEVR);
70  p->NEVRA = _free(p->NEVRA);
71  p->pkgid = _free(p->pkgid);
72  p->hdrid = _free(p->hdrid);
73  p->sourcerpm = _free(p->sourcerpm);
74 
75  p->replaced = _free(p->replaced);
76 
77  p->flink.NEVRA = argvFree(p->flink.NEVRA);
78  p->flink.Pkgid = argvFree(p->flink.Pkgid);
79  p->flink.Hdrid = argvFree(p->flink.Hdrid);
80  p->blink.NEVRA = argvFree(p->blink.NEVRA);
81  p->blink.Pkgid = argvFree(p->blink.Pkgid);
82  p->blink.Hdrid = argvFree(p->blink.Hdrid);
83 
84 assert(p->txn == NULL); /* XXX FIXME */
85  p->txn = NULL;
86  p->fi = rpmfiFree(p->fi);
87 
88  (void)headerFree(p->h);
89  p->h = NULL;
90 
91  /*@-nullstate@*/ /* FIX: p->{NEVR,name} annotations */
92  return;
93  /*@=nullstate@*/
94 }
95 
104 static void addTE(rpmts ts, rpmte p, Header h,
105  /*@dependent@*/ /*@null@*/ fnpyKey key,
106  /*@null@*/ rpmRelocation relocs)
107  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
108  /*@modifies ts, p, h,
109  rpmGlobalMacroContext, fileSystem, internalState @*/
110 {
111  int scareMem = 0;
112  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
113  int xx;
114 
115  he->tag = RPMTAG_NVRA;
116  xx = headerGet(h, he, 0);
117 assert(he->p.str != NULL);
118  p->NEVR = (xx ? he->p.str : xstrdup("?N-?V-?R.?A"));
119 
120  he->tag = RPMTAG_NAME;
121  xx = headerGet(h, he, 0);
122  p->name = (xx ? he->p.str : xstrdup("?RPMTAG_NAME?"));
123  he->tag = RPMTAG_VERSION;
124  xx = headerGet(h, he, 0);
125  p->version = (char *)(xx ? he->p.str : xstrdup("?RPMTAG_VERSION?"));
126  he->tag = RPMTAG_RELEASE;
127  xx = headerGet(h, he, 0);
128  p->release = (char *)(xx ? he->p.str : xstrdup("?RPMTAG_RELEASE?"));
129 
130  p->db_instance = 0;
131 
132  he->tag = RPMTAG_PKGID;
133  xx = headerGet(h, he, 0);
134  if (he->p.ui8p != NULL) {
135  static const char hex[] = "0123456789abcdef";
136  char * t;
137  rpmuint32_t i;
138 
139  p->pkgid = t = (char *) xmalloc((2*he->c) + 1);
140  for (i = 0 ; i < he->c; i++) {
141  *t++ = hex[ (unsigned)((he->p.ui8p[i] >> 4) & 0x0f) ];
142  *t++ = hex[ (unsigned)((he->p.ui8p[i] ) & 0x0f) ];
143  }
144  *t = '\0';
145  he->p.ptr = _free(he->p.ptr);
146  } else
147  p->pkgid = NULL;
148 
149  he->tag = RPMTAG_HDRID;
150  xx = headerGet(h, he, 0);
151  p->hdrid = (xx ? he->p.str : xstrdup("?RPMTAG_HDRID?"));
152 
153  he->tag = RPMTAG_SOURCERPM;
154  xx = headerGet(h, he, 0);
155  p->sourcerpm = (xx ? he->p.str : NULL);
156 
157  he->tag = RPMTAG_ARCH;
158  xx = headerGet(h, he, 0);
159  p->arch = (xx ? he->p.str : xstrdup("?RPMTAG_ARCH?"));
160 
161  he->tag = RPMTAG_OS;
162  xx = headerGet(h, he, 0);
163  p->os = (xx ? he->p.str : xstrdup("?RPMTAG_OS?"));
164 
165  p->isSource =
166  (headerIsEntry(h, RPMTAG_SOURCERPM) == 0 &&
167  headerIsEntry(h, RPMTAG_ARCH) != 0);
168 
169  p->NEVRA = xstrdup(p->NEVR);
170 
171  he->tag = RPMTAG_EPOCH;
172  xx = headerGet(h, he, 0);
173  if (he->p.ui32p != NULL) {
174  p->epoch = (char *) xmalloc(20);
175  sprintf(p->epoch, "%u", he->p.ui32p[0]);
176  he->p.ptr = _free(he->p.ptr);
177  } else
178  p->epoch = NULL;
179 
180 #ifdef RPM_VENDOR_MANDRIVA
181  he->tag = RPMTAG_DISTEPOCH;
182  xx = headerGet(h, he, 0);
183  if (he->p.str != NULL) {
184  p->distepoch = (char*)(xx ? he->p.str : xstrdup("?RPMTAG_DISTEPOCH?"));
185  } else
186  p->distepoch = NULL;
187 #endif
188 
189  p->installed = 0;
190 
191  p->relocs = rpmfiDupeRelocations(relocs, &p->nrelocs);
192  p->autorelocatex = -1;
193 
194  p->key = key;
195  p->fd = NULL;
196 
197  p->replaced = NULL;
198 
199  p->pkgFileSize = 0;
200  memset(p->originTid, 0, sizeof(p->originTid));
201  memset(p->originTime, 0, sizeof(p->originTime));
202 
203  p->PRCO = rpmdsNewPRCO(h);
204 
205  { rpmte savep = rpmtsSetRelocateElement(ts, p);
206  p->fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
207  (void) rpmtsSetRelocateElement(ts, savep);
208  }
209  p->txn = NULL;
210 
213 /*@-compdef@*/
214  return;
215 /*@=compdef@*/
216 }
217 
218 static void rpmteFini(void * _te)
219  /*@modifies _te @*/
220 {
221  rpmte te = (rpmte) _te;
222 
223  delTE(te);
224 }
225 
226 /*@unchecked@*/ /*@only@*/ /*@null@*/
228 
229 static rpmte rpmteGetPool(/*@null@*/ rpmioPool pool)
230  /*@globals _rpmtePool, fileSystem, internalState @*/
231  /*@modifies pool, _rpmtePool, fileSystem, internalState @*/
232 {
233  rpmte te;
234 
235  if (_rpmtePool == NULL) {
236  _rpmtePool = rpmioNewPool("te", sizeof(*te), -1, _rpmte_debug,
237  NULL, NULL, rpmteFini);
238  pool = _rpmtePool;
239  }
240  te = (rpmte) rpmioGetPool(pool, sizeof(*te));
241  memset(((char *)te)+sizeof(te->_item), 0, sizeof(*te)-sizeof(te->_item));
242  return te;
243 }
244 
246  rpmElementType type,
247  fnpyKey key,
248  rpmRelocation relocs,
249  uint32_t dboffset,
250  alKey pkgKey)
251 {
252  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
253  rpmte p = rpmteGetPool(_rpmtePool);
254  int xx;
255 
256  p->type = type;
257 
258  addTE(ts, p, h, key, relocs);
259  switch (type) {
260  case TR_ADDED:
261  p->u.addedKey = pkgKey;
262  /* XXX 256 is only an estimate of signature header. */
263  p->pkgFileSize = 96 + 256;
264  he->tag = RPMTAG_SIGSIZE;
265  xx = headerGet(h, he, 0);
266  if (xx && he->p.ui32p)
267  p->pkgFileSize += *he->p.ui32p;
268  he->p.ptr = _free(he->p.ptr);
269  break;
270  case TR_REMOVED:
271  p->u.addedKey = pkgKey;
272  p->u.removed.dboffset = dboffset;
273  break;
274  }
275  return p;
276 }
277 
278 /* Get the DB Instance value */
279 uint32_t rpmteDBInstance(rpmte te)
280 {
281  return (te != NULL ? te->db_instance : 0);
282 }
283 
284 /* Set the DB Instance value */
285 void rpmteSetDBInstance(rpmte te, unsigned int instance)
286 {
287  if (te != NULL)
288  te->db_instance = instance;
289 }
290 
292 {
293 /*@-castexpose -retalias -retexpose @*/
294  return (te != NULL && te->h != NULL ? headerLink(te->h) : NULL);
295 /*@=castexpose =retalias =retexpose @*/
296 }
297 
299 {
300  if (te != NULL) {
301  (void)headerFree(te->h);
302  te->h = NULL;
303 /*@-assignexpose -castexpose @*/
304  if (h != NULL)
305  te->h = headerLink(h);
306 /*@=assignexpose =castexpose @*/
307  }
308  return NULL;
309 }
310 
312 {
313  return (te != NULL ? te->type : (rpmElementType)-1);
314 }
315 
316 const char * rpmteN(rpmte te)
317 {
318  return (te != NULL ? te->name : NULL);
319 }
320 
321 const char * rpmteE(rpmte te)
322 {
323  return (te != NULL ? te->epoch : NULL);
324 }
325 
326 const char * rpmteV(rpmte te)
327 {
328  return (te != NULL ? te->version : NULL);
329 }
330 
331 const char * rpmteR(rpmte te)
332 {
333  return (te != NULL ? te->release : NULL);
334 }
335 
336 const char * rpmteD(rpmte te)
337 {
338 #ifdef RPM_VENDOR_MANDRIVA
339  return (te != NULL ? te->distepoch : NULL);
340 #else
341  return NULL;
342 #endif
343 }
344 
345 const char * rpmteA(rpmte te)
346 {
347  return (te != NULL ? te->arch : NULL);
348 }
349 
350 const char * rpmteO(rpmte te)
351 {
352  return (te != NULL ? te->os : NULL);
353 }
354 
356 {
357  return (te != NULL ? te->isSource : 0);
358 }
359 
361 {
362  return (te != NULL ? te->color : 0);
363 }
364 
366 {
367  int ocolor = 0;
368  if (te != NULL) {
369  ocolor = te->color;
370  te->color = color;
371  }
372  return ocolor;
373 }
374 
376 {
377  return (te != NULL ? te->pkgFileSize : 0);
378 }
379 
381 {
382  return te->originTid;
383 }
384 
386 {
387  return te->originTime;
388 }
389 
391 {
392  return (te != NULL ? te->depth : 0);
393 }
394 
395 int rpmteSetDepth(rpmte te, int ndepth)
396 {
397  int odepth = 0;
398  if (te != NULL) {
399  odepth = te->depth;
400  te->depth = ndepth;
401  }
402  return odepth;
403 }
404 
406 {
407  return (te != NULL ? te->depth : 0);
408 }
409 
410 int rpmteSetBreadth(rpmte te, int nbreadth)
411 {
412  int obreadth = 0;
413  if (te != NULL) {
414  obreadth = te->breadth;
415  te->breadth = nbreadth;
416  }
417  return obreadth;
418 }
419 
421 {
422  return (te != NULL ? te->npreds : 0);
423 }
424 
425 int rpmteSetNpreds(rpmte te, int npreds)
426 {
427  int opreds = 0;
428  if (te != NULL) {
429  opreds = te->npreds;
430  te->npreds = npreds;
431  }
432  return opreds;
433 }
434 
436 {
437  return (te != NULL ? te->tree : 0);
438 }
439 
440 int rpmteSetTree(rpmte te, int ntree)
441 {
442  int otree = 0;
443  if (te != NULL) {
444  otree = te->tree;
445  te->tree = ntree;
446  }
447  return otree;
448 }
449 
451 {
452  return (te != NULL ? te->parent : NULL);
453 }
454 
456 {
457  rpmte opte = NULL;
458  if (te != NULL) {
459  opte = te->parent;
460  /*@-assignexpose -temptrans@*/
461  te->parent = pte;
462  /*@=assignexpose =temptrans@*/
463  }
464  return opte;
465 }
466 
468 {
469  return (te != NULL ? te->degree : 0);
470 }
471 
472 int rpmteSetDegree(rpmte te, int ndegree)
473 {
474  int odegree = 0;
475  if (te != NULL) {
476  odegree = te->degree;
477  te->degree = ndegree;
478  }
479  return odegree;
480 }
481 
483 {
484  /*@-compdef -retalias -retexpose -usereleased @*/
485  return te->tsi;
486  /*@=compdef =retalias =retexpose =usereleased @*/
487 }
488 
490 {
491  if (te != NULL && rpmteTSI(te) != NULL) {
492  tsortInfo tsi;
493 
494  /* Clean up tsort remnants (if any). */
495  while ((tsi = rpmteTSI(te)->tsi_next) != NULL) {
496  rpmteTSI(te)->tsi_next = tsi->tsi_next;
497  tsi->tsi_next = NULL;
498  tsi = _free(tsi);
499  }
500  te->tsi = _free(te->tsi);
501  }
502  /*@-nullstate@*/ /* FIX: te->tsi is NULL */
503  return;
504  /*@=nullstate@*/
505 }
506 
508 {
509  if (te != NULL) {
510  rpmteFreeTSI(te);
511  te->tsi = (tsortInfo) xcalloc(1, sizeof(*te->tsi));
512  }
513 }
514 
516 {
517  return (te != NULL ? te->u.addedKey : RPMAL_NOMATCH);
518 }
519 
521 {
522  alKey opkgKey = RPMAL_NOMATCH;
523  if (te != NULL) {
524  opkgKey = te->u.addedKey;
525  te->u.addedKey = npkgKey;
526  }
527  return opkgKey;
528 }
529 
530 
532 {
533  return (te != NULL ? te->u.removed.dboffset : 0);
534 }
535 
536 const char * rpmteNEVR(rpmte te)
537 {
538  return (te != NULL ? te->NEVR : NULL);
539 }
540 
541 const char * rpmteNEVRA(rpmte te)
542 {
543  return (te != NULL ? te->NEVRA : NULL);
544 }
545 
546 const char * rpmtePkgid(rpmte te)
547 {
548  return (te != NULL ? te->pkgid : NULL);
549 }
550 
551 const char * rpmteHdrid(rpmte te)
552 {
553  return (te != NULL ? te->hdrid : NULL);
554 }
555 
556 const char * rpmteSourcerpm(rpmte te)
557 {
558  return (te != NULL ? te->sourcerpm : NULL);
559 }
560 
562 {
563  /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
564  return (te != NULL ? te->fd : NULL);
565  /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
566 }
567 
569 {
570  return (te != NULL ? te->key : NULL);
571 }
572 
574 {
575  return (te != NULL ? rpmdsFromPRCO(te->PRCO, tag) : NULL);
576 }
577 
578 #ifdef REFERENCE
579 rpmfi rpmteFI(rpmte te)
580 {
581  if (te == NULL)
582  return NULL;
583 
584  return te->fi; /* XXX take fi reference here? */
585 }
586 #else
588 {
589  /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
590  if (te == NULL)
591  return NULL;
592 
593  if (tag == RPMTAG_BASENAMES)
594  return te->fi;
595  else
596  return NULL;
597  /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
598 }
599 #endif
600 
602 {
603  if (te != NULL) {
604  te->fi = rpmfiFree(te->fi);
605 /*@-assignexpose -castexpose @*/
606  if (fi != NULL)
607  te->fi = rpmfiLink(fi, __FUNCTION__);
608 /*@=assignexpose =castexpose @*/
609  }
610  return NULL;
611 }
612 
613 void rpmteColorDS(rpmte te, rpmTag tag)
614 {
615  rpmfi fi = rpmteFI(te, RPMTAG_BASENAMES);
616  rpmds ds = rpmteDS(te, tag);
617  char deptype = 'R';
618  char mydt;
619  const rpmuint32_t * ddict;
620  rpmuint32_t * colors;
621  rpmuint32_t * refs;
622  rpmuint32_t val;
623  int Count;
624  size_t nb;
625  unsigned ix;
626  int ndx, i;
627 
628  if (!(te && (Count = rpmdsCount(ds)) > 0 && rpmfiFC(fi) > 0))
629  return;
630 
631  switch (tag) {
632  default:
633  return;
634  /*@notreached@*/ break;
635  case RPMTAG_PROVIDENAME:
636  deptype = 'P';
637  break;
638  case RPMTAG_REQUIRENAME:
639  deptype = 'R';
640  break;
641  }
642 
643  nb = Count * sizeof(*colors);
644  colors = (rpmuint32_t *) memset(alloca(nb), 0, nb);
645  nb = Count * sizeof(*refs);
646  refs = (rpmuint32_t *) memset(alloca(nb), -1, nb);
647 
648  /* Calculate dependency color and reference count. */
649  fi = rpmfiInit(fi, 0);
650  if (fi != NULL)
651  while (rpmfiNext(fi) >= 0) {
652  val = rpmfiFColor(fi);
653  ddict = NULL;
654  ndx = rpmfiFDepends(fi, &ddict);
655  if (ddict != NULL)
656  while (ndx-- > 0) {
657  ix = *ddict++;
658  mydt = (char)((ix >> 24) & 0xff);
659  if (mydt != deptype)
660  /*@innercontinue@*/ continue;
661  ix &= 0x00ffffff;
662 assert ((int)ix < Count);
663  colors[ix] |= val;
664  refs[ix]++;
665  }
666  }
667 
668  /* Set color/refs values in dependency set. */
669  ds = rpmdsInit(ds);
670  while ((i = rpmdsNext(ds)) >= 0) {
671  val = colors[i];
672  te->color |= val;
673  (void) rpmdsSetColor(ds, val);
674  val = refs[i];
675  (void) rpmdsSetRefs(ds, val);
676  }
677 }
678 
679 /*@unchecked@*/
680 static int __mydebug = 0;
681 
682 int rpmteChain(rpmte p, rpmte q, Header oh, const char * msg)
683 {
684  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
685  const char * blinkNEVRA = NULL;
686  const char * blinkPkgid = NULL;
687  const char * blinkHdrid = NULL;
688  int xx;
689 
690  if (msg == NULL)
691  msg = "";
692  he->tag = RPMTAG_NVRA;
693  xx = headerGet(oh, he, 0);
694 assert(he->p.str != NULL);
695  blinkNEVRA = he->p.str;
696 
697  /*
698  * Convert binary pkgid to a string.
699  * XXX Yum's borken conception of a "header" doesn't have signature
700  * tags appended.
701  */
702  he->tag = RPMTAG_PKGID;
703  xx = headerGet(oh, he, 0);
704  if (xx && he->p.ui8p != NULL) {
705  static const char hex[] = "0123456789abcdef";
706  char * t;
707  rpmuint32_t i;
708 
709  blinkPkgid = t = (char *) xmalloc((2*he->c) + 1);
710  for (i = 0 ; i < he->c; i++) {
711  *t++ = hex[ ((he->p.ui8p[i] >> 4) & 0x0f) ];
712  *t++ = hex[ ((he->p.ui8p[i] ) & 0x0f) ];
713  }
714  *t = '\0';
715  he->p.ptr = _free(he->p.ptr);
716  } else
717  blinkPkgid = NULL;
718 
719  he->tag = RPMTAG_HDRID;
720  xx = headerGet(oh, he, 0);
721  blinkHdrid = he->p.str;
722 
723 /*@-modfilesys@*/
724 if (__mydebug)
725 fprintf(stderr, "%s argvAdd(&q->flink.NEVRA, \"%s\")\n", msg, p->NEVRA);
726  xx = argvAdd(&q->flink.NEVRA, p->NEVRA);
727 if (__mydebug)
728 fprintf(stderr, "%s argvAdd(&p->blink.NEVRA, \"%s\")\n", msg, blinkNEVRA);
729  xx = argvAdd(&p->blink.NEVRA, blinkNEVRA);
730 if (__mydebug)
731 fprintf(stderr, "%s argvAdd(&q->flink.Pkgid, \"%s\")\n", msg, p->pkgid);
732  if (p->pkgid != NULL)
733  xx = argvAdd(&q->flink.Pkgid, p->pkgid);
734 if (__mydebug)
735 fprintf(stderr, "%s argvAdd(&p->blink.Pkgid, \"%s\")\n", msg, blinkPkgid);
736  if (blinkPkgid != NULL)
737  xx = argvAdd(&p->blink.Pkgid, blinkPkgid);
738 if (__mydebug)
739 fprintf(stderr, "%s argvAdd(&q->flink.Hdrid, \"%s\")\n", msg, p->hdrid);
740  if (p->hdrid != NULL)
741  xx = argvAdd(&q->flink.Hdrid, p->hdrid);
742 if (__mydebug)
743 fprintf(stderr, "%s argvAdd(&p->blink.Hdrid, \"%s\")\n", msg, blinkHdrid);
744  if (blinkHdrid != NULL)
745  xx = argvAdd(&p->blink.Hdrid, blinkHdrid);
746 /*@=modfilesys@*/
747 
748  blinkNEVRA = _free(blinkNEVRA);
749  blinkPkgid = _free(blinkPkgid);
750  blinkHdrid = _free(blinkHdrid);
751 
752  return 0;
753 }
754 
755 int rpmtsiOc(rpmtsi tsi)
756 {
757  return tsi->ocsave;
758 }
759 
760 /*@-mustmod@*/
761 static void rpmtsiFini(void * _tsi)
762  /*@modifies _tsi @*/
763 {
764  rpmtsi tsi = (rpmtsi) _tsi;
765 /*@-internalglobs@*/
766  (void)rpmtsFree(tsi->ts);
767  tsi->ts = NULL;
768 /*@=internalglobs@*/
769 }
770 /*@=mustmod@*/
771 
772 /*@unchecked@*/ /*@only@*/ /*@null@*/
774 
775 static rpmtsi rpmtsiGetPool(/*@null@*/ rpmioPool pool)
776  /*@globals _rpmtsiPool, fileSystem, internalState @*/
777  /*@modifies pool, _rpmtsiPool, fileSystem, internalState @*/
778 {
779  rpmtsi tsi;
780 
781  if (_rpmtsiPool == NULL) {
782  _rpmtsiPool = rpmioNewPool("tsi", sizeof(*tsi), -1, _rpmte_debug,
783  NULL, NULL, rpmtsiFini);/* XXX _rpmtsi_debug? */
784  pool = _rpmtsiPool;
785  }
786  tsi = (rpmtsi) rpmioGetPool(pool, sizeof(*tsi));
787  memset(((char *)tsi)+sizeof(tsi->_item), 0, sizeof(*tsi)-sizeof(tsi->_item));
788  return tsi;
789 }
790 
791 rpmtsi XrpmtsiInit(rpmts ts, const char * fn, unsigned int ln)
792 {
793  rpmtsi tsi = rpmtsiGetPool(_rpmtsiPool);
794 
795 /*@-assignexpose -castexpose @*/
796  tsi->ts = rpmtsLink(ts, "rpmtsi");
797 /*@=assignexpose =castexpose @*/
798  tsi->reverse = 0;
799  tsi->oc = (tsi->reverse ? (rpmtsNElements(ts) - 1) : 0);
800  tsi->ocsave = tsi->oc;
801 
802  return (rpmtsi) rpmioLinkPoolItem((rpmioItem)tsi, "rpmtsiInit", fn, ln);
803 }
804 
810 static /*@null@*/ /*@dependent@*/
812  /*@modifies tsi @*/
813 {
814  rpmte te = NULL;
815  int oc = -1;
816 
817  if (tsi == NULL || tsi->ts == NULL || rpmtsNElements(tsi->ts) <= 0)
818  return te;
819 
820  if (tsi->reverse) {
821  if (tsi->oc >= 0) oc = tsi->oc--;
822  } else {
823  if (tsi->oc < rpmtsNElements(tsi->ts)) oc = tsi->oc++;
824  }
825  tsi->ocsave = oc;
826  if (oc != -1)
827  te = rpmtsElement(tsi->ts, oc);
828  return te;
829 }
830 
832 {
833  rpmte te;
834 
835  while ((te = rpmtsiNextElement(tsi)) != NULL) {
836  if (type == 0 || (te->type & type) != 0)
837  break;
838  }
839  return te;
840 }
841 
842 /*@-mods@*/
843 Header rpmteDBHeader(rpmts ts, uint32_t rec)
844 {
845  rpmmi mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, &rec, sizeof(rec));
846  Header h;
847 
848  /* iterator returns weak refs, grab hold of header */
849  if ((h = rpmmiNext(mi)) != NULL)
850  h = headerLink(h);
851  mi = rpmmiFree(mi);
852  return h;
853 }
854 /*@=mods@*/
855 
857 {
858  Header h = NULL;
859  te->fd = (FD_t) rpmtsNotify(ts, te, RPMCALLBACK_INST_OPEN_FILE, 0, 0);
860  if (te->fd != NULL) {
861  rpmVSFlags nvsflags = (rpmVSFlags)
863  rpmVSFlags ovsflags = rpmtsSetVSFlags(ts, nvsflags);
864  rpmRC pkgrc = rpmReadPackageFile(ts, rpmteFd(te), rpmteNEVR(te), &h);
865  ovsflags = rpmtsSetVSFlags(ts, ovsflags);
866  switch (pkgrc) {
867  default:
868  (void) rpmteClose(te, ts, 1);
869  break;
870  case RPMRC_NOTTRUSTED:
871  case RPMRC_NOKEY:
872  case RPMRC_OK:
873  break;
874  }
875  }
876  return h;
877 }
878 
879 /*@-mods@*/
880 int rpmteOpen(rpmte te, rpmts ts, int reload_fi)
881 {
882  Header h = NULL;
883  uint32_t instance;
884  int rc = 0; /* assume failure */
885 
886  if (te == NULL || ts == NULL)
887  goto exit;
888 
889  instance = rpmteDBInstance(te);
890  (void) rpmteSetHeader(te, NULL);
891 
892  switch (rpmteType(te)) {
893  case TR_ADDED:
894  h = instance ? rpmteDBHeader(ts, instance) : rpmteFDHeader(ts, te);
895  break;
896  case TR_REMOVED:
897  h = rpmteDBHeader(ts, instance);
898  break;
899  }
900  if (h != NULL) {
901 #ifdef REFERENCE
902  if (reload_fi) {
903  te->fi = getFI(te, ts, h);
904  }
905 #else
906  if (reload_fi) {
907  static int scareMem = 0;
908  te->fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
909  }
910 #endif
911 
912  (void) rpmteSetHeader(te, h);
913  h = headerFree(h);
914  rc = 1;
915  }
916 
917 exit:
918  return rc;
919 }
920 /*@=mods@*/
921 
922 int rpmteClose(rpmte te, rpmts ts, int reset_fi)
923 {
924  if (te == NULL || ts == NULL)
925  return 0;
926 
927  switch (te->type) {
928  case TR_ADDED:
929  if (te->fd != NULL) {
930  void * ptr;
931  ptr = rpmtsNotify(ts, te, RPMCALLBACK_INST_CLOSE_FILE, 0, 0);
932  te->fd = NULL;
933  }
934  break;
935  case TR_REMOVED:
936  /* eventually we'll want notifications for erase open too */
937  break;
938  }
939  (void) rpmteSetHeader(te, NULL);
940  if (reset_fi)
941  (void) rpmteSetFI(te, NULL);
942  return 1;
943 }
944 
946 {
947  return (te != NULL) ? te->linkFailed : -1;
948 }
949 
951 {
952  rpmfi fi = (te ? te->fi : NULL);
953  int rc = 0;
954 
955  switch (tag) {
956  default:
957  break;
958  case RPMTAG_PRETRANS:
959  if (fi)
960  rc = (fi->pretrans || fi->pretransprog) ? 1 : 0;
961  break;
962  case RPMTAG_POSTTRANS:
963  if (fi)
964  rc = (fi->posttrans || fi->posttransprog) ? 1 : 0;
965  break;
966  }
967  return rc;
968 }
969 
970 #ifdef REFERENCE
971 int rpmteMarkFailed(rpmte te, rpmts ts)
972 {
973  rpmtsi pi = rpmtsiInit(ts);
974  int rc = 0;
975  rpmte p;
976 
977  te->failed = 1;
978  /* XXX we can do a much better here than this... */
979  while ((p = rpmtsiNext(pi, TR_REMOVED))) {
980  if (rpmteDependsOn(p) == te) {
981  p->failed = 1;
982  }
983  }
984  rpmtsiFree(pi);
985  return rc;
986 }
987 
988 rpmps rpmteProblems(rpmte te)
989 {
990  return te ? te->probs : NULL;
991 }
992 
993 rpmfs rpmteGetFileStates(rpmte te) {
994  return te->fs;
995 }
996 
997 rpmfs rpmfsNew(unsigned int fc, rpmElementType type) {
998  rpmfs fs = (rpmfs) xmalloc(sizeof(*fs));
999  fs->fc = fc;
1000  fs->replaced = NULL;
1001  fs->states = NULL;
1002  if (type == TR_ADDED) {
1003  fs->states = (sharedFileInfo) xmalloc(sizeof(*fs->states) * fs->fc);
1004  memset(fs->states, RPMFILE_STATE_NORMAL, fs->fc);
1005  }
1006  fs->actions = (rpmFIleAction *) xmalloc(fc * sizeof(*fs->actions));
1007  memset(fs->actions, FA_UNKNOWN, fc * sizeof(*fs->actions));
1008  fs->numReplaced = fs->allocatedReplaced = 0;
1009  return fs;
1010 }
1011 
1012 rpmfs rpmfsFree(rpmfs fs) {
1013  fs->replaced = _free(fs->replaced);
1014  fs->states = _free(fs->states);
1015  fs->actions = _free(fs->actions);
1016 
1017  fs = _free(fs);
1018  return fs;
1019 }
1020 
1021 rpm_count_t rpmfsFC(rpmfs fs) {
1022  return fs->fc;
1023 }
1024 
1025 void rpmfsAddReplaced(rpmfs fs, int pkgFileNum, int otherPkg, int otherFileNum)
1026 {
1027  if (!fs->replaced) {
1028  fs->replaced = (sharedFileInfo) xcalloc(3, sizeof(*fs->replaced));
1029  fs->allocatedReplaced = 3;
1030  }
1031  if (fs->numReplaced>=fs->allocatedReplaced) {
1032  fs->allocatedReplaced += (fs->allocatedReplaced>>1) + 2;
1033  fs->replaced = (sharedFileInfo) xrealloc(fs->replaced, fs->allocatedReplaced*sizeof(*fs->replaced));
1034  }
1035  fs->replaced[fs->numReplaced].pkgFileNum = pkgFileNum;
1036  fs->replaced[fs->numReplaced].otherPkg = otherPkg;
1037  fs->replaced[fs->numReplaced].otherFileNum = otherFileNum;
1038 
1039  fs->numReplaced++;
1040 }
1041 
1042 sharedFileInfo rpmfsGetReplaced(rpmfs fs)
1043 {
1044  if (fs && fs->numReplaced)
1045  return fs->replaced;
1046  else
1047  return NULL;
1048 }
1049 
1050 sharedFileInfo rpmfsNextReplaced(rpmfs fs , sharedFileInfo replaced)
1051 {
1052  if (fs && replaced) {
1053  replaced++;
1054  if (replaced - fs->replaced < fs->numReplaced)
1055  return replaced;
1056  }
1057  return NULL;
1058 }
1059 
1060 void rpmfsSetState(rpmfs fs, unsigned int ix, rpmfileState state)
1061 {
1062  assert(ix < fs->fc);
1063  fs->states[ix] = state;
1064 }
1065 
1066 rpmfileState rpmfsGetState(rpmfs fs, unsigned int ix)
1067 {
1068  assert(ix < fs->fc);
1069  if (fs->states) return fs->states[ix];
1070  return RPMFILE_STATE_MISSING;
1071 }
1072 
1073 rpm_fstate_t * rpmfsGetStates(rpmfs fs)
1074 {
1075  return fs->states;
1076 }
1077 
1078 rpmFileAction rpmfsGetAction(rpmfs fs, unsigned int ix)
1079 {
1080  rpmFileAction action;
1081  if (fs->actions != NULL && ix < fs->fc) {
1082  action = fs->actions[ix];
1083  } else {
1084  action = FA_UNKNOWN;
1085  }
1086  return action;
1087 }
1088 
1089 void rpmfsSetAction(rpmfs fs, unsigned int ix, rpmFileAction action)
1090 {
1091  if (fs->actions != NULL && ix < fs->fc) {
1092  fs->actions[ix] = action;
1093  }
1094 }
1095 #endif /* REFERENCE */