rpm  4.5
rpmte.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 #include <rpmlib.h>
7 
8 #include "psm.h"
9 
10 #include "rpmds.h"
11 #include "rpmfi.h"
12 
13 #define _RPMTE_INTERNAL
14 #include "rpmte.h"
15 #include "rpmts.h"
16 
17 #include "debug.h"
18 
19 /*@unchecked@*/
20 int _rpmte_debug = 0;
21 
22 /*@access alKey @*/
23 /*@access rpmtsi @*/
24 
26 {
27  te->PRCO = rpmdsFreePRCO(te->PRCO);
28 }
29 
34 static void delTE(rpmte p)
35  /*@globals fileSystem @*/
36  /*@modifies p, fileSystem @*/
37 {
38  rpmRelocation r;
39 
40  if (p->relocs) {
41  for (r = p->relocs; (r->oldPath || r->newPath); r++) {
42  r->oldPath = _free(r->oldPath);
43  r->newPath = _free(r->newPath);
44  }
45  p->relocs = _free(p->relocs);
46  }
47 
48  rpmteCleanDS(p);
49 
50  p->fi = rpmfiFree(p->fi);
51 
52  if (p->fd != NULL)
53  p->fd = fdFree(p->fd, "delTE");
54 
55  p->os = _free(p->os);
56  p->arch = _free(p->arch);
57  p->epoch = _free(p->epoch);
58  p->name = _free(p->name);
59  p->NEVR = _free(p->NEVR);
60  p->NEVRA = _free(p->NEVRA);
61  p->pkgid = _free(p->pkgid);
62  p->hdrid = _free(p->hdrid);
63 
64  p->flink.NEVRA = argvFree(p->flink.NEVRA);
65  p->flink.Pkgid = argvFree(p->flink.Pkgid);
66  p->flink.Hdrid = argvFree(p->flink.Hdrid);
67  p->blink.NEVRA = argvFree(p->blink.NEVRA);
68  p->blink.Pkgid = argvFree(p->blink.Pkgid);
69  p->blink.Hdrid = argvFree(p->blink.Hdrid);
70 
71  p->h = headerFree(p->h);
72 
73 /*@-boundswrite@*/
74  memset(p, 0, sizeof(*p)); /* XXX trash and burn */
75 /*@=boundswrite@*/
76  /*@-nullstate@*/ /* FIX: p->{NEVR,name} annotations */
77  return;
78  /*@=nullstate@*/
79 }
80 
89 /*@-bounds@*/
90 static void addTE(rpmts ts, rpmte p, Header h,
91  /*@dependent@*/ /*@null@*/ fnpyKey key,
92  /*@null@*/ rpmRelocation relocs)
93  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
94  /*@modifies ts, p, h,
95  rpmGlobalMacroContext, fileSystem, internalState @*/
96 {
97  int scareMem = 0;
99  rpmte savep;
100  int_32 * ep, pkgidcnt;
101  const char * hdrid, * arch, * os;
102  const unsigned char * pkgid;
103  char * t;
104  size_t nb;
105  int xx;
106 
107  p->NEVR = hGetNEVR(h, NULL);
108  p->name = xstrdup(p->NEVR);
109  if ((p->release = strrchr(p->name, '-')) != NULL)
110  *p->release++ = '\0';
111  if ((p->version = strrchr(p->name, '-')) != NULL)
112  *p->version++ = '\0';
113 
114  p->db_instance = 0;
115 
116  hdrid = NULL;
117  xx = hge(h, RPMTAG_HDRID, NULL, &hdrid, NULL);
118  if (hdrid != NULL)
119  p->hdrid = xstrdup(hdrid);
120  else
121  p->hdrid = NULL;
122 
123  pkgid = NULL;
124  xx = hge(h, RPMTAG_PKGID, NULL, &pkgid, &pkgidcnt);
125  if (pkgid != NULL) {
126  static const char hex[] = "0123456789abcdef";
127  int i;
128 
129  p->pkgid = t = xmalloc((2*pkgidcnt) + 1);
130  for (i = 0 ; i < pkgidcnt; i++) {
131  *t++ = hex[ (unsigned)((pkgid[i] >> 4) & 0x0f) ];
132  *t++ = hex[ (unsigned)((pkgid[i] ) & 0x0f) ];
133  }
134  *t = '\0';
135 #ifdef NOTYET /* XXX MinMemory. */
136  pkgid = headerFreeData(pkgid, RPM_BIN_TYPE);
137 #endif
138  } else
139  p->pkgid = NULL;
140 
141  arch = NULL;
142  xx = hge(h, RPMTAG_ARCH, NULL, &arch, NULL);
143  p->arch = (arch != NULL ? xstrdup(arch) : NULL);
144  os = NULL;
145  xx = hge(h, RPMTAG_OS, NULL, &os, NULL);
146  p->os = (os != NULL ? xstrdup(os) : NULL);
147 
148  p->isSource = (headerIsEntry(h, RPMTAG_SOURCERPM) == 0);
149 
150  nb = strlen(p->NEVR) + 1;
151  if (p->arch == NULL)
152  nb += sizeof("pubkey");
153  else if (p->isSource)
154  nb += sizeof("src");
155  else
156  nb += strlen(p->arch) + 1;
157  t = xmalloc(nb);
158  p->NEVRA = t;
159  *t = '\0';
160  t = stpcpy(t, p->NEVR);
161  if (p->arch == NULL)
162  t = stpcpy( t, ".pubkey");
163  else if (p->isSource)
164  t = stpcpy( t, ".src");
165  else
166  t = stpcpy( stpcpy( t, "."), p->arch);
167 
168  ep = NULL;
169  xx = hge(h, RPMTAG_EPOCH, NULL, &ep, NULL);
170 /*@-branchstate@*/
171  if (ep) {
172  p->epoch = xmalloc(20);
173  sprintf(p->epoch, "%d", *ep);
174  } else
175  p->epoch = NULL;
176 /*@=branchstate@*/
177 
178  p->installed = 0;
179 
180  p->nrelocs = 0;
181  p->relocs = NULL;
182  if (relocs != NULL) {
183  rpmRelocation r;
184  int i;
185 
186  for (r = relocs; r->oldPath || r->newPath; r++)
187  p->nrelocs++;
188  p->relocs = xmalloc((p->nrelocs + 1) * sizeof(*p->relocs));
189 
190  for (i = 0, r = relocs; r->oldPath || r->newPath; i++, r++) {
191  p->relocs[i].oldPath = r->oldPath ? xstrdup(r->oldPath) : NULL;
192  p->relocs[i].newPath = r->newPath ? xstrdup(r->newPath) : NULL;
193  }
194  p->relocs[i].oldPath = NULL;
195  p->relocs[i].newPath = NULL;
196  }
197  p->autorelocatex = -1;
198 
199  p->key = key;
200  p->fd = NULL;
201 
202  p->pkgFileSize = 0;
203 
204  p->PRCO = rpmdsNewPRCO(h);
205 
206  savep = rpmtsSetRelocateElement(ts, p);
207  p->fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
208  (void) rpmtsSetRelocateElement(ts, savep);
209 
212 /*@-compdef@*/
213  return;
214 /*@=compdef@*/
215 }
216 /*@=bounds@*/
217 
219 {
220  if (te != NULL) {
221  delTE(te);
222  memset(te, 0, sizeof(*te)); /* XXX trash and burn */
223  te = _free(te);
224  }
225  return NULL;
226 }
227 
229  rpmElementType type,
230  fnpyKey key,
231  rpmRelocation relocs,
232  int dboffset,
233  alKey pkgKey)
234 {
235  rpmte p = xcalloc(1, sizeof(*p));
236  int_32 * ep;
237  int xx;
238 
239  p->type = type;
240 
241  addTE(ts, p, h, key, relocs);
242  switch (type) {
243  case TR_ADDED:
244  p->u.addedKey = pkgKey;
245  ep = NULL;
246  xx = headerGetEntry(h, RPMTAG_SIGSIZE, NULL, &ep, NULL);
247  /* XXX 256 is only an estimate of signature header. */
248  if (ep != NULL)
249  p->pkgFileSize += 96 + 256 + *ep;
250  break;
251  case TR_REMOVED:
252  p->u.addedKey = pkgKey;
253  p->u.removed.dboffset = dboffset;
254  break;
255  }
256  return p;
257 }
258 
259 /* Get the DB Instance value */
260 unsigned int rpmteDBInstance(rpmte te)
261 {
262  return (te != NULL ? te->db_instance : 0);
263 }
264 
265 /* Set the DB Instance value */
266 void rpmteSetDBInstance(rpmte te, unsigned int instance)
267 {
268  if (te != NULL)
269  te->db_instance = instance;
270 }
271 
273 {
274  return (te != NULL && te->h != NULL ? headerLink(te->h) : NULL);
275 }
276 
278 {
279  if (te != NULL) {
280  te->h = headerFree(te->h);
281  if (h != NULL)
282  te->h = headerLink(h);
283  }
284  return NULL;
285 }
286 
288 {
289  return (te != NULL ? te->type : -1);
290 }
291 
292 const char * rpmteN(rpmte te)
293 {
294  return (te != NULL ? te->name : NULL);
295 }
296 
297 const char * rpmteE(rpmte te)
298 {
299  return (te != NULL ? te->epoch : NULL);
300 }
301 
302 const char * rpmteV(rpmte te)
303 {
304  return (te != NULL ? te->version : NULL);
305 }
306 
307 const char * rpmteR(rpmte te)
308 {
309  return (te != NULL ? te->release : NULL);
310 }
311 
312 const char * rpmteA(rpmte te)
313 {
314  return (te != NULL ? te->arch : NULL);
315 }
316 
317 const char * rpmteO(rpmte te)
318 {
319  return (te != NULL ? te->os : NULL);
320 }
321 
323 {
324  return (te != NULL ? te->isSource : 0);
325 }
326 
328 {
329  return (te != NULL ? te->color : 0);
330 }
331 
333 {
334  int ocolor = 0;
335  if (te != NULL) {
336  ocolor = te->color;
337  te->color = color;
338  }
339  return ocolor;
340 }
341 
343 {
344  return (te != NULL ? te->pkgFileSize : 0);
345 }
346 
348 {
349  return (te != NULL ? te->depth : 0);
350 }
351 
352 int rpmteSetDepth(rpmte te, int ndepth)
353 {
354  int odepth = 0;
355  if (te != NULL) {
356  odepth = te->depth;
357  te->depth = ndepth;
358  }
359  return odepth;
360 }
361 
363 {
364  return (te != NULL ? te->depth : 0);
365 }
366 
367 int rpmteSetBreadth(rpmte te, int nbreadth)
368 {
369  int obreadth = 0;
370  if (te != NULL) {
371  obreadth = te->breadth;
372  te->breadth = nbreadth;
373  }
374  return obreadth;
375 }
376 
378 {
379  return (te != NULL ? te->npreds : 0);
380 }
381 
382 int rpmteSetNpreds(rpmte te, int npreds)
383 {
384  int opreds = 0;
385  if (te != NULL) {
386  opreds = te->npreds;
387  te->npreds = npreds;
388  }
389  return opreds;
390 }
391 
393 {
394  return (te != NULL ? te->tree : 0);
395 }
396 
397 int rpmteSetTree(rpmte te, int ntree)
398 {
399  int otree = 0;
400  if (te != NULL) {
401  otree = te->tree;
402  te->tree = ntree;
403  }
404  return otree;
405 }
406 
408 {
409  return (te != NULL ? te->parent : NULL);
410 }
411 
413 {
414  rpmte opte = NULL;
415 /*@-branchstate@*/
416  if (te != NULL) {
417  opte = te->parent;
418  /*@-assignexpose -temptrans@*/
419  te->parent = pte;
420  /*@=assignexpose =temptrans@*/
421  }
422 /*@=branchstate@*/
423  return opte;
424 }
425 
427 {
428  return (te != NULL ? te->degree : 0);
429 }
430 
431 int rpmteSetDegree(rpmte te, int ndegree)
432 {
433  int odegree = 0;
434  if (te != NULL) {
435  odegree = te->degree;
436  te->degree = ndegree;
437  }
438  return odegree;
439 }
440 
442 {
443  /*@-compdef -retalias -retexpose -usereleased @*/
444  return te->tsi;
445  /*@=compdef =retalias =retexpose =usereleased @*/
446 }
447 
449 {
450  if (te != NULL && rpmteTSI(te) != NULL) {
451  tsortInfo tsi;
452 
453  /* Clean up tsort remnants (if any). */
454  while ((tsi = rpmteTSI(te)->tsi_next) != NULL) {
455  rpmteTSI(te)->tsi_next = tsi->tsi_next;
456  tsi->tsi_next = NULL;
457  tsi = _free(tsi);
458  }
459  te->tsi = _free(te->tsi);
460  }
461  /*@-nullstate@*/ /* FIX: te->tsi is NULL */
462  return;
463  /*@=nullstate@*/
464 }
465 
467 {
468  if (te != NULL) {
469  rpmteFreeTSI(te);
470  te->tsi = xcalloc(1, sizeof(*te->tsi));
471  }
472 }
473 
475 {
476  return (te != NULL ? te->u.addedKey : RPMAL_NOMATCH);
477 }
478 
480 {
481  alKey opkgKey = RPMAL_NOMATCH;
482  if (te != NULL) {
483  opkgKey = te->u.addedKey;
484  te->u.addedKey = npkgKey;
485  }
486  return opkgKey;
487 }
488 
489 
491 {
492  return (te != NULL ? te->u.removed.dboffset : 0);
493 }
494 
495 const char * rpmteNEVR(rpmte te)
496 {
497  return (te != NULL ? te->NEVR : NULL);
498 }
499 
500 const char * rpmteNEVRA(rpmte te)
501 {
502  return (te != NULL ? te->NEVRA : NULL);
503 }
504 
505 const char * rpmtePkgid(rpmte te)
506 {
507  return (te != NULL ? te->pkgid : NULL);
508 }
509 
510 const char * rpmteHdrid(rpmte te)
511 {
512  return (te != NULL ? te->hdrid : NULL);
513 }
514 
516 {
517  /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
518  return (te != NULL ? te->fd : NULL);
519  /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
520 }
521 
523 {
524  return (te != NULL ? te->key : NULL);
525 }
526 
528 {
529  return (te != NULL ? rpmdsFromPRCO(te->PRCO, tag) : NULL);
530 }
531 
533 {
534  /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
535  if (te == NULL)
536  return NULL;
537 
538  if (tag == RPMTAG_BASENAMES)
539  return te->fi;
540  else
541  return NULL;
542  /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
543 }
544 
545 void rpmteColorDS(rpmte te, rpmTag tag)
546 {
547  rpmfi fi = rpmteFI(te, RPMTAG_BASENAMES);
548  rpmds ds = rpmteDS(te, tag);
549  char deptype = 'R';
550  char mydt;
551  const uint_32 * ddict;
552  int_32 * colors;
553  int_32 * refs;
554  int_32 val;
555  int Count;
556  size_t nb;
557  unsigned ix;
558  int ndx, i;
559 
560  if (!(te && (Count = rpmdsCount(ds)) > 0 && rpmfiFC(fi) > 0))
561  return;
562 
563  switch (tag) {
564  default:
565  return;
566  /*@notreached@*/ break;
567  case RPMTAG_PROVIDENAME:
568  deptype = 'P';
569  break;
570  case RPMTAG_REQUIRENAME:
571  deptype = 'R';
572  break;
573  }
574 
575  nb = Count * sizeof(*colors);
576  colors = memset(alloca(nb), 0, nb);
577  nb = Count * sizeof(*refs);
578  refs = memset(alloca(nb), -1, nb);
579 
580  /* Calculate dependency color and reference count. */
581  fi = rpmfiInit(fi, 0);
582  if (fi != NULL)
583  while (rpmfiNext(fi) >= 0) {
584  val = rpmfiFColor(fi);
585  ddict = NULL;
586  ndx = rpmfiFDepends(fi, &ddict);
587  if (ddict != NULL)
588  while (ndx-- > 0) {
589  ix = *ddict++;
590  mydt = ((ix >> 24) & 0xff);
591  if (mydt != deptype)
592  /*@innercontinue@*/ continue;
593  ix &= 0x00ffffff;
594 assert (ix < Count);
595  colors[ix] |= val;
596  refs[ix]++;
597  }
598  }
599 
600  /* Set color/refs values in dependency set. */
601  ds = rpmdsInit(ds);
602  while ((i = rpmdsNext(ds)) >= 0) {
603  val = colors[i];
604  te->color |= val;
605  (void) rpmdsSetColor(ds, val);
606  val = refs[i];
607  if (val >= 0)
608  val++;
609  (void) rpmdsSetRefs(ds, val);
610  }
611 }
612 
613 /*@unchecked@*/
614 static int __mydebug = 0;
615 
616 int rpmteChain(rpmte p, rpmte q, Header oh, const char * msg)
617 {
619  const char * blinkNEVRA = NULL;
620  const char * blinkPkgid = NULL;
621  const char * blinkHdrid = NULL;
622  const unsigned char * pkgid;
623  int_32 pkgidcnt;
624  int xx;
625 
626 /*@-branchstate@*/
627  if (msg == NULL)
628  msg = "";
629 /*@=branchstate@*/
630  blinkNEVRA = hGetNEVRA(oh, NULL);
631 
632  /*
633  * Convert binary pkgid to a string.
634  * XXX Yum's borken conception of a "header" doesn't have signature
635  * tags appended.
636  */
637  pkgid = NULL;
638  pkgidcnt = 0;
639  xx = hge(oh, RPMTAG_PKGID, NULL, &pkgid, &pkgidcnt);
640  if (pkgid != NULL) {
641  static const char hex[] = "0123456789abcdef";
642  char * t;
643  int i;
644 
645  blinkPkgid = t = xmalloc((2*pkgidcnt) + 1);
646  for (i = 0 ; i < pkgidcnt; i++) {
647  *t++ = hex[ ((pkgid[i] >> 4) & 0x0f) ];
648  *t++ = hex[ ((pkgid[i] ) & 0x0f) ];
649  }
650  *t = '\0';
651 #if NOTYET /* XXX MinMemory. */
652  pkgid = headerFreeData(pkgid, RPM_BIN_TYPE);
653 #endif
654  } else
655  blinkPkgid = NULL;
656 
657  blinkHdrid = NULL;
658  xx = hge(oh, RPMTAG_HDRID, NULL, &blinkHdrid, NULL);
659 
660 /*@-modfilesys@*/
661 if (__mydebug)
662 fprintf(stderr, "%s argvAdd(&q->flink.NEVRA, \"%s\")\n", msg, p->NEVRA);
663  xx = argvAdd(&q->flink.NEVRA, p->NEVRA);
664 if (__mydebug)
665 fprintf(stderr, "%s argvAdd(&p->blink.NEVRA, \"%s\")\n", msg, blinkNEVRA);
666  xx = argvAdd(&p->blink.NEVRA, blinkNEVRA);
667 if (__mydebug)
668 fprintf(stderr, "%s argvAdd(&q->flink.Pkgid, \"%s\")\n", msg, p->pkgid);
669  if (p->pkgid != NULL)
670  xx = argvAdd(&q->flink.Pkgid, p->pkgid);
671 if (__mydebug)
672 fprintf(stderr, "%s argvAdd(&p->blink.Pkgid, \"%s\")\n", msg, blinkPkgid);
673  if (blinkPkgid != NULL)
674  xx = argvAdd(&p->blink.Pkgid, blinkPkgid);
675 if (__mydebug)
676 fprintf(stderr, "%s argvAdd(&q->flink.Hdrid, \"%s\")\n", msg, p->hdrid);
677  if (p->hdrid != NULL)
678  xx = argvAdd(&q->flink.Hdrid, p->hdrid);
679 if (__mydebug)
680 fprintf(stderr, "%s argvAdd(&p->blink.Hdrid, \"%s\")\n", msg, blinkHdrid);
681  if (blinkHdrid != NULL)
682  xx = argvAdd(&p->blink.Hdrid, blinkHdrid);
683 /*@=modfilesys@*/
684 
685  blinkNEVRA = _free(blinkNEVRA);
686  blinkPkgid = _free(blinkPkgid);
687 #ifdef NOTYET /* XXX MinMemory. */
688  blinkHdrid = _free(blinkHdrid);
689 #endif
690 
691  return 0;
692 }
693 
694 int rpmtsiOc(rpmtsi tsi)
695 {
696  return tsi->ocsave;
697 }
698 
699 rpmtsi XrpmtsiFree(/*@only@*//*@null@*/ rpmtsi tsi,
700  const char * fn, unsigned int ln)
701 {
702  /* XXX watchout: a funky recursion segfaults here iff nrefs is wrong. */
703 /*@-internalglobs@*/
704  if (tsi)
705  tsi->ts = rpmtsFree(tsi->ts);
706 /*@=internalglobs@*/
707 
708 /*@-modfilesys@*/
709 if (_rpmte_debug)
710 fprintf(stderr, "*** tsi %p -- %s:%d\n", tsi, fn, ln);
711 /*@=modfilesys@*/
712  return _free(tsi);
713 }
714 
715 rpmtsi XrpmtsiInit(rpmts ts, const char * fn, unsigned int ln)
716 {
717  rpmtsi tsi = NULL;
718 
719  tsi = xcalloc(1, sizeof(*tsi));
720  tsi->ts = rpmtsLink(ts, "rpmtsi");
721  tsi->reverse = 0;
722  tsi->oc = (tsi->reverse ? (rpmtsNElements(ts) - 1) : 0);
723  tsi->ocsave = tsi->oc;
724 /*@-modfilesys@*/
725 if (_rpmte_debug)
726 fprintf(stderr, "*** tsi %p ++ %s:%d\n", tsi, fn, ln);
727 /*@=modfilesys@*/
728  return tsi;
729 }
730 
736 static /*@null@*/ /*@dependent@*/
738  /*@modifies tsi @*/
739 {
740  rpmte te = NULL;
741  int oc = -1;
742 
743  if (tsi == NULL || tsi->ts == NULL || rpmtsNElements(tsi->ts) <= 0)
744  return te;
745 
746  if (tsi->reverse) {
747  if (tsi->oc >= 0) oc = tsi->oc--;
748  } else {
749  if (tsi->oc < rpmtsNElements(tsi->ts)) oc = tsi->oc++;
750  }
751  tsi->ocsave = oc;
752 /*@-branchstate@*/
753  if (oc != -1)
754  te = rpmtsElement(tsi->ts, oc);
755 /*@=branchstate@*/
756  return te;
757 }
758 
760 {
761  rpmte te;
762 
763  while ((te = rpmtsiNextElement(tsi)) != NULL) {
764  if (type == 0 || (te->type & type) != 0)
765  break;
766  }
767  return te;
768 }