rpm  5.4.14
rpmfi.c
Go to the documentation of this file.
1 
6 #include "system.h"
7 
8 #include <rpmiotypes.h> /* XXX fnpyKey */
9 #include <rpmio.h>
10 #include <rpmlog.h>
11 #include <rpmbf.h>
12 #include <rpmurl.h> /* XXX urlGetPath */
13 #define _RPMDIR_INTERNAL
14 #include <rpmdir.h>
15 #include <rpmmacro.h> /* XXX rpmCleanPath */
16 #include <ugid.h>
17 
18 #define _RPMAV_INTERNAL /* XXX avOpendir */
19 #include <rpmdav.h>
20 
21 #include <rpmtypes.h>
22 #include <rpmtag.h>
23 
24 #define _FPRINT_INTERNAL
25 #include "fprint.h"
26 
27 #define _IOSM_INTERNAL
28 #define _RPMFI_INTERNAL
29 #include "fsm.h" /* XXX newFSM() */
30 #include "legacy.h" /* XXX dodigest */
31 
32 #include "rpmds.h"
33 
34 #define _RPMTE_INTERNAL /* relocations */
35 #include "rpmte.h"
36 #include "rpmts.h"
37 
38 #include <rpmcli.h> /* XXX rpmHeaderFormats */
39 
40 #include "debug.h"
41 
42 /*@access IOSM_t @*/ /* XXX cast */
43 
44 /*@access rpmte @*/
45 /*@access rpmts @*/ /* XXX cast */
46 
47 /*@access FSM_t @*/ /* XXX fsm->repackaged */
48 /*@access DIR @*/
49 
50 #ifdef __cplusplus
51 GENfree(int *)
52 GENpair(rpmuint16_t *)
53 GENpair(rpmuint32_t *)
54 GENfree(rpmRelocation)
55 #endif /* __cplusplus */
56 
60 /*@only@*/ /*@null@*/
61  const char * oldPath;
62 /*@only@*/ /*@null@*/
63  const char * newPath;
64 };
65 
66 /*@unchecked@*/
67 int _rpmfi_debug = 0;
68 
75 static /*@only@*/
76 char * stripTrailingChar(/*@only@*/ char * s, char c)
77  /*@modifies *s */
78 {
79  char * t;
80 /*@-boundswrite@*/
81  for (t = s + strlen(s) - 1; *t == c && t >= s; t--)
82  *t = '\0';
83 /*@=boundswrite@*/
84  return s;
85 }
86 
88 {
89  return (fi != NULL ? fi->fc : 0);
90 }
91 
93 {
94  return (fi != NULL ? fi->dc : 0);
95 }
96 
97 #ifdef NOTYET
98 int rpmfiDI(rpmfi fi)
99 {
100 }
101 #endif
102 
104 {
105  return (fi != NULL ? fi->i : -1);
106 }
107 
108 int rpmfiSetFX(rpmfi fi, int fx)
109 {
110  int i = -1;
111 
112  if (fi != NULL && fx >= 0 && fx < (int)fi->fc) {
113  i = fi->i;
114  fi->i = fx;
115  fi->j = fi->dil[fi->i];
116  }
117  return i;
118 }
119 
121 {
122  return (fi != NULL ? fi->j : -1);
123 }
124 
125 int rpmfiSetDX(rpmfi fi, int dx)
126 {
127  int j = -1;
128 
129  if (fi != NULL && dx >= 0 && dx < (int)fi->dc) {
130  j = fi->j;
131  fi->j = dx;
132  }
133  return j;
134 }
135 
137 {
138  return (fi != NULL ? fi->isSource : 0);
139 }
140 
141 const char * rpmfiBN(rpmfi fi)
142 {
143  const char * BN = NULL;
144 
145  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
146  if (fi->bnl != NULL)
147  BN = fi->bnl[fi->i];
148  }
149  return BN;
150 }
151 
152 const char * rpmfiDN(rpmfi fi)
153 {
154  const char * DN = NULL;
155 
156  if (fi != NULL && fi->j >= 0 && fi->j < (int)fi->dc) {
157  if (fi->dnl != NULL)
158  DN = fi->dnl[fi->j];
159  }
160  return DN;
161 }
162 
163 const char * rpmfiFN(rpmfi fi)
164 {
165  const char * FN = "";
166 
167  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
168  const char *dn;
169  char * t;
170  if (fi->fn == NULL)
171  fi->fn = (char *) xmalloc(fi->fnlen + 1);
172  FN = t = fi->fn;
173  (void) urlPath(fi->dnl[fi->dil[fi->i]], &dn);
174  *t = '\0';
175  t = stpcpy(t, dn);
176  t = stpcpy(t, fi->bnl[fi->i]);
177  }
178  return FN;
179 }
180 
182 {
183  void * _fnbf = NULL;
184  if (fi != NULL) {
185  if (fi->_fnbf == NULL) {
186  char * fn = (char *) alloca(fi->fnlen + 1);
187  static double e = 1.0e-4;
188  size_t n = (fi->fc > 10 ? fi->fc : 10);
189  size_t m = 0;
190  size_t k = 0;
191  rpmbf bf;
192  int i;
193 
194  rpmbfParams(n, e, &m, &k);
195  bf = rpmbfNew(m, k, 0);
196  for (i = 0; i < (int)fi->fc; i++) {
197  const char * dn;
198  int xx;
199  dn = NULL;
200  (void) urlPath(fi->dnl[fi->dil[i]], &dn);
201  dn = stpcpy(stpcpy(fn, dn), fi->bnl[i]);
202  xx = rpmbfAdd(bf, fn, (size_t)(dn - fn));
203 assert(xx == 0);
204  }
205  fi->_fnbf = bf;
206  }
207  _fnbf = fi->_fnbf;
208  }
209  return _fnbf;
210 }
211 
213 {
214  return (fi ? fi->fnlen : 0);
215 }
216 
218 {
219  rpmuint32_t FFlags = 0;
220 
221  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
222  if (fi->fflags != NULL)
223  FFlags = fi->fflags[fi->i];
224  }
225  return FFlags;
226 }
227 
229 {
230  rpmuint32_t oFFlags = 0;
231 
232  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
233  if (fi->fflags != NULL && fi->h == NULL) {
234  oFFlags = fi->fflags[fi->i];
235  *((rpmuint32_t *)(fi->fflags + fi->i)) = FFlags;
236  }
237  }
238  return oFFlags;
239 }
240 
242 {
243  rpmuint32_t VFlags = 0;
244 
245  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
246  if (fi->vflags != NULL)
247  VFlags = fi->vflags[fi->i];
248  }
249  return VFlags;
250 }
251 
253 {
254  rpmuint32_t oVFlags = 0;
255 
256  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
257  if (fi->vflags != NULL && fi->h == NULL) {
258  oVFlags = fi->vflags[fi->i];
259  *((rpmuint32_t *)(fi->vflags + fi->i)) = VFlags;
260  }
261  }
262  return oVFlags;
263 }
264 
266 {
267  rpmuint16_t fmode = 0;
268 
269  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
270  if (fi->fmodes != NULL)
271  fmode = fi->fmodes[fi->i];
272  }
273  return fmode;
274 }
275 
277 {
279 
280  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
281  if (fi->fstates != NULL)
282  fstate = (rpmfileState) fi->fstates[fi->i];
283  }
284  return fstate;
285 }
286 
288 {
289  rpmuint32_t ofstate = 0;
290 
291  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
292  if (fi->fstates != NULL) {
293  ofstate = fi->fstates[fi->i];
294  fi->fstates[fi->i] = fstate;
295  }
296  }
297  return (rpmfileState) ofstate;
298 }
299 
300 const unsigned char * rpmfiDigest(rpmfi fi, int * algop, size_t * lenp)
301 {
302  unsigned char * digest = NULL;
303 
304  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
305  if (fi->digests != NULL) {
306  digest = fi->digests + (fi->digestlen * fi->i);
307  if (algop != NULL)
308  *algop = (fi->fdigestalgos
309  ? fi->fdigestalgos[fi->i] : fi->digestalgo);
310  if (lenp != NULL)
311  *lenp = fi->digestlen;
312  }
313  }
314  return digest;
315 }
316 
317 const char * rpmfiFLink(rpmfi fi)
318 {
319  const char * flink = NULL;
320 
321  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
322  if (fi->flinks != NULL)
323  flink = fi->flinks[fi->i];
324  }
325  return flink;
326 }
327 
329 {
330  rpmuint32_t fsize = 0;
331 
332  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
333  if (fi->fsizes != NULL)
334  fsize = fi->fsizes[fi->i];
335  }
336  return fsize;
337 }
338 
340 {
341  rpmuint16_t frdev = 0;
342 
343  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
344  if (fi->frdevs != NULL)
345  frdev = fi->frdevs[fi->i];
346  }
347  return frdev;
348 }
349 
351 {
352  rpmuint32_t finode = 0;
353 
354  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
355  if (fi->finodes != NULL)
356  finode = fi->finodes[fi->i];
357  }
358  return finode;
359 }
360 
362 {
363  rpmuint32_t color = 0;
364 
365  if (fi != NULL)
366  /* XXX ignore all but lsnibble for now. */
367  color = fi->color & 0xf;
368  return color;
369 }
370 
372 {
373  rpmuint32_t fcolor = 0;
374 
375  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
376  if (fi->fcolors != NULL)
377  /* XXX ignore all but lsnibble for now. */
378  fcolor = (fi->fcolors[fi->i] & 0x0f);
379  }
380  return fcolor;
381 }
382 
383 const char * rpmfiFClass(rpmfi fi)
384 {
385  const char * fclass = NULL;
386 
387  if (fi != NULL && fi->fcdictx != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
388  int cdictx = fi->fcdictx[fi->i];
389  if (fi->cdict != NULL && cdictx >= 0 && cdictx < (int)fi->ncdict)
390  fclass = fi->cdict[cdictx];
391  }
392  return fclass;
393 }
394 
395 const char * rpmfiFContext(rpmfi fi)
396 {
397  const char * fcontext = NULL;
398 
399  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
400  if (fi->fcontexts != NULL)
401  fcontext = fi->fcontexts[fi->i];
402  }
403  return fcontext;
404 }
405 
407 {
408  int fddictx = -1;
409  int fddictn = 0;
410  const rpmuint32_t * fddict = NULL;
411 
412  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
413  if (fi->fddictn != NULL)
414  fddictn = fi->fddictn[fi->i];
415  if (fddictn > 0 && fi->fddictx != NULL)
416  fddictx = fi->fddictx[fi->i];
417  if (fi->ddict != NULL && fddictx >= 0 && (fddictx+fddictn) <= (int)fi->nddict)
418  fddict = fi->ddict + fddictx;
419  }
420 /*@-dependenttrans -onlytrans @*/
421  if (fddictp)
422  *fddictp = fddict;
423 /*@=dependenttrans =onlytrans @*/
424  return fddictn;
425 }
426 
428 {
429  rpmuint32_t nlink = 0;
430 
431  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
432  /* XXX rpm-2.3.12 has not RPMTAG_FILEINODES */
433  if (fi->finodes && fi->frdevs) {
434  rpmuint32_t finode = fi->finodes[fi->i];
435  rpmuint16_t frdev = fi->frdevs[fi->i];
436  int j;
437 
438  for (j = 0; j < (int)fi->fc; j++) {
439  if (fi->frdevs[j] == frdev && fi->finodes[j] == finode)
440  nlink++;
441  }
442  }
443  }
444  return nlink;
445 }
446 
448 {
449  rpmuint32_t fmtime = 0;
450 
451  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
452  if (fi->fmtimes != NULL)
453  fmtime = fi->fmtimes[fi->i];
454  }
455  return fmtime;
456 }
457 
458 const char * rpmfiFUser(rpmfi fi)
459 {
460  const char * fuser = NULL;
461 
462  /* XXX add support for ancient RPMTAG_FILEUIDS? */
463  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
464  if (fi->fuser != NULL)
465  fuser = fi->fuser[fi->i];
466  }
467  return fuser;
468 }
469 
470 const char * rpmfiFGroup(rpmfi fi)
471 {
472  const char * fgroup = NULL;
473 
474  /* XXX add support for ancient RPMTAG_FILEGIDS? */
475  if (fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
476  if (fi->fgroup != NULL)
477  fgroup = fi->fgroup[fi->i];
478  }
479  return fgroup;
480 }
481 
482 void * rpmfiBloomFN(const rpmfi fi)
483 {
484 /*@-assignexpose -retexpose @*/
485  return (fi != NULL ? fi->_fnbf : NULL);
486 /*@=assignexpose =retexpose @*/
487 }
488 
489 void * rpmfiExclude(const rpmfi fi)
490 {
491  return (fi != NULL ? fi->exclude : NULL);
492 }
493 
495 {
496  return (fi != NULL ? fi->nexclude : 0);
497 }
498 
499 void * rpmfiInclude(const rpmfi fi)
500 {
501  return (fi != NULL ? fi->include : NULL);
502 }
503 
505 {
506  return (fi != NULL ? fi->ninclude : 0);
507 }
508 
510 {
511  struct fingerPrint_s * fps = NULL;
512  if (fi != NULL && fi->fps != NULL && ix >= 0 && ix < (int)fi->fc) {
513  fps = fi->fps + ix;
514  }
515  return fps;
516 }
517 
519 {
520  if (fi->fc > 0 && fi->fps == NULL) {
521  fi->fps = (struct fingerPrint_s *) xcalloc(fi->fc, sizeof(*fi->fps));
522  }
523  fpLookupList(fpc, fi->dnl, fi->bnl, fi->dil, fi->fc, fi->fps);
524 }
525 
527 {
528  int i = -1;
529 
530  if (fi != NULL && ++fi->i >= 0) {
531  if (fi->i < (int)fi->fc) {
532  i = fi->i;
533  if (fi->dil != NULL)
534  fi->j = fi->dil[fi->i];
535  } else
536  fi->i = -1;
537 
538 /*@-modfilesys @*/
539 if (_rpmfi_debug < 0 && i != -1)
540 fprintf(stderr, "*** fi %p\t%s[%d] %s%s\n", fi, (fi->Type ? fi->Type : "?Type?"), i, (i >= 0 ? fi->dnl[fi->j] : ""), (i >= 0 ? fi->bnl[fi->i] : ""));
541 /*@=modfilesys @*/
542 
543  }
544 
545  return i;
546 }
547 
549 {
550  if (fi != NULL) {
551  if (fx >= 0 && fx < (int)fi->fc) {
552  fi->i = fx - 1;
553  fi->j = -1;
554  }
555  }
556 
557  /*@-refcounttrans@*/
558  return fi;
559  /*@=refcounttrans@*/
560 }
561 
563 {
564  int j = -1;
565 
566  if (fi != NULL && ++fi->j >= 0) {
567  if (fi->j < (int)fi->dc)
568  j = fi->j;
569  else
570  fi->j = -1;
571 
572 /*@-modfilesys @*/
573 if (_rpmfi_debug < 0 && j != -1)
574 fprintf(stderr, "*** fi %p\t%s[%d]\n", fi, (fi->Type ? fi->Type : "?Type?"), j);
575 /*@=modfilesys @*/
576 
577  }
578 
579  return j;
580 }
581 
583 {
584  if (fi != NULL) {
585  if (dx >= 0 && dx < (int)fi->fc)
586  fi->j = dx - 1;
587  else
588  fi = NULL;
589  }
590 
591  /*@-refcounttrans@*/
592  return fi;
593  /*@=refcounttrans@*/
594 }
595 
601 static /*@observer@*/
602 const char * rpmfiFtstring (rpmFileTypes ft)
603  /*@*/
604 {
605  switch (ft) {
606  case XDIR: return "directory";
607  case CDEV: return "char dev";
608  case BDEV: return "block dev";
609  case LINK: return "link";
610  case SOCK: return "sock";
611  case PIPE: return "fifo/pipe";
612  case REG: return "file";
613  default: return "unknown file type";
614  }
615  /*@notreached@*/
616 }
617 
624  /*@*/
625 {
626  if (S_ISDIR(mode)) return XDIR;
627  if (S_ISCHR(mode)) return CDEV;
628  if (S_ISBLK(mode)) return BDEV;
629  if (S_ISLNK(mode)) return LINK;
630 /*@-unrecog@*/
631  if (S_ISSOCK(mode)) return SOCK;
632 /*@=unrecog@*/
633  if (S_ISFIFO(mode)) return PIPE;
634  return REG;
635 }
636 
637 int rpmfiCompare(const rpmfi afi, const rpmfi bfi)
638  /*@*/
639 {
640  rpmFileTypes awhat = rpmfiWhatis(rpmfiFMode(afi));
641  rpmFileTypes bwhat = rpmfiWhatis(rpmfiFMode(bfi));
642 
643  if (awhat != bwhat) return 1;
644 
645  if (awhat == LINK) {
646  const char * alink = rpmfiFLink(afi);
647  const char * blink = rpmfiFLink(bfi);
648  if (alink == blink) return 0;
649  if (alink == NULL) return 1;
650  if (blink == NULL) return -1;
651  return strcmp(alink, blink);
652  } else if (awhat == REG) {
653  int aalgo = 0;
654  size_t alen = 0;
655  const unsigned char * adigest = rpmfiDigest(afi, &aalgo, &alen);
656  int balgo = 0;
657  size_t blen = 0;
658  const unsigned char * bdigest = rpmfiDigest(bfi, &balgo, &blen);
659  /* XXX W2DO? changing file digest algo may break rpmfiCompare. */
660  if (!(aalgo == balgo && alen == blen))
661  return -1;
662  if (adigest == bdigest) return 0;
663  if (adigest == NULL) return 1;
664  if (bdigest == NULL) return -1;
665  return memcmp(adigest, bdigest, alen);
666  }
667 
668  return 0;
669 }
670 
671 int rpmfiDecideFate(const rpmfi ofi, rpmfi nfi, int skipMissing)
672 {
673  const char * fn = rpmfiFN(nfi);
674  int newFlags = rpmfiFFlags(nfi);
675  char buffer[1024+1];
676  rpmFileTypes dbWhat, newWhat, diskWhat;
677  struct stat sb;
678  int save = (newFlags & RPMFILE_NOREPLACE) ? FA_ALTNAME : FA_SAVE;
679 
680  if (Lstat(fn, &sb)) {
681  /*
682  * The file doesn't exist on the disk. Create it unless the new
683  * package has marked it as missingok, or allfiles is requested.
684  */
685  if (skipMissing && (newFlags & RPMFILE_MISSINGOK)) {
686  rpmlog(RPMLOG_DEBUG, D_("%s skipped due to missingok flag\n"),
687  fn);
688  return FA_SKIP;
689  } else {
690  return FA_CREATE;
691  }
692  }
693 
694  diskWhat = rpmfiWhatis((rpmuint16_t)sb.st_mode);
695  dbWhat = rpmfiWhatis(rpmfiFMode(ofi));
696  newWhat = rpmfiWhatis(rpmfiFMode(nfi));
697 
698  /*
699  * RPM >= 2.3.10 shouldn't create config directories -- we'll ignore
700  * them in older packages as well.
701  */
702  if (newWhat == XDIR)
703  return FA_CREATE;
704 
705  if (diskWhat != newWhat && dbWhat != REG && dbWhat != LINK)
706  return save;
707  else if (newWhat != dbWhat && diskWhat != dbWhat)
708  return save;
709  else if (dbWhat != newWhat)
710  return FA_CREATE;
711  else if (dbWhat != LINK && dbWhat != REG)
712  return FA_CREATE;
713 
714  /*
715  * This order matters - we'd prefer to CREATE the file if at all
716  * possible in case something else (like the timestamp) has changed.
717  */
718  memset(buffer, 0, sizeof(buffer));
719  if (dbWhat == REG) {
720  int oalgo = 0;
721  size_t olen = 0;
722  const unsigned char * odigest;
723  int nalgo = 0;
724  size_t nlen = 0;
725  const unsigned char * ndigest;
726  odigest = rpmfiDigest(ofi, &oalgo, &olen);
727  if (diskWhat == REG) {
728  if (!(newFlags & RPMFILE_SPARSE))
729  if (dodigest(oalgo, fn, (unsigned char *)buffer, 0, NULL))
730  return FA_CREATE; /* assume file has been removed */
731  if (odigest && !memcmp(odigest, buffer, olen))
732  return FA_CREATE; /* unmodified config file, replace. */
733  }
734  ndigest = rpmfiDigest(nfi, &nalgo, &nlen);
735 /*@-nullpass@*/
736  if (odigest && ndigest && oalgo == nalgo && olen == nlen
737  && !memcmp(odigest, ndigest, nlen))
738  return FA_SKIP; /* identical file, don't bother. */
739 /*@=nullpass@*/
740  } else /* dbWhat == LINK */ {
741  const char * oFLink, * nFLink;
742  oFLink = rpmfiFLink(ofi);
743  if (diskWhat == LINK) {
744  if (Readlink(fn, buffer, sizeof(buffer) - 1) == -1)
745  return FA_CREATE; /* assume file has been removed */
746  buffer[sizeof(buffer)-1] = '\0';
747  if (oFLink && !strcmp(oFLink, buffer))
748  return FA_CREATE; /* unmodified config file, replace. */
749  }
750  nFLink = rpmfiFLink(nfi);
751 /*@-nullpass@*/
752  if (oFLink && nFLink && !strcmp(oFLink, nFLink))
753  return FA_SKIP; /* identical file, don't bother. */
754 /*@=nullpass@*/
755  }
756 
757  /*
758  * The config file on the disk has been modified, but
759  * the ones in the two packages are different. It would
760  * be nice if RPM was smart enough to at least try and
761  * merge the difference ala CVS, but...
762  */
763  return save;
764 }
765 
766 /*@observer@*/
767 const char * rpmfiTypeString(rpmfi fi)
768 {
769  switch(rpmteType((rpmte)fi->te)) {
770  case TR_ADDED: return " install";
771  case TR_REMOVED: return " erase";
772  default: return "???";
773  }
774  /*@noteached@*/
775 }
776 
777 #define alloca_strdup(_s) strcpy((char *)alloca(strlen(_s)+1), (_s))
778 
788 static
790  Header origH, iosmFileAction * actions)
791  /*@globals rpmGlobalMacroContext, h_errno,
792  internalState @*/
793  /*@modifies ts, fi, origH, actions, rpmGlobalMacroContext,
794  internalState @*/
795 {
796  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
798  static int _printed = 0;
799  int allowBadRelocate = (rpmtsFilterFlags(ts) & RPMPROB_FILTER_FORCERELOCATE);
801  int numRelocations;
802  const char ** validRelocations;
803  rpmTagType validType;
804  int numValid;
805  const char ** baseNames;
806  const char ** dirNames;
807  rpmuint32_t * dirIndexes;
808  rpmuint32_t fileCount;
809  rpmuint32_t dirCount;
810  rpmuint32_t mydColor = rpmExpandNumeric("%{?_autorelocate_dcolor}");
811  rpmuint32_t * fFlags = NULL;
812  rpmuint32_t * fColors = NULL;
813  rpmuint32_t * dColors = NULL;
814  rpmuint16_t * fModes = NULL;
815  Header h;
816  int nrelocated = 0;
817  size_t fileAlloced = 0;
818  char * fn = NULL;
819  int haveRelocatedFile = 0;
820  int reldel = 0;
821  size_t len;
822  int i, j;
823  int xx;
824 
825  he->tag = RPMTAG_PREFIXES;
826  xx = headerGet(origH, he, 0);
827  validType = he->t;
828  validRelocations = he->p.argv;
829  numValid = he->c;
830  if (!xx)
831  numValid = 0;
832 
833 assert(p != NULL);
834  numRelocations = 0;
835  if (p->relocs)
836  while (p->relocs[numRelocations].newPath ||
837  p->relocs[numRelocations].oldPath)
838  numRelocations++;
839 
840  /*
841  * If no relocations are specified (usually the case), then return the
842  * original header. If there are prefixes, however, then INSTPREFIXES
843  * should be added, but, since relocateFileList() can be called more
844  * than once for the same header, don't bother if already present.
845  */
846  if (p->relocs == NULL || numRelocations == 0) {
847  if (numValid) {
848  if (!headerIsEntry(origH, RPMTAG_INSTPREFIXES)) {
849  he->tag = RPMTAG_INSTPREFIXES;
850  he->t = validType;
851  he->p.argv = validRelocations;
852  he->c = numValid;
853  xx = headerPut(origH, he, 0);
854  }
855  validRelocations = _free(validRelocations);
856  }
857  /* XXX FIXME multilib file actions need to be checked. */
858 /*@-castexpose@*/
859  return headerLink(origH);
860 /*@=castexpose@*/
861  }
862 
863 /*@-castexpose@*/
864  h = headerLink(origH);
865 /*@=castexpose@*/
866 
867  relocations = (rpmRelocation) alloca(sizeof(*relocations) * numRelocations);
868 
869  /* Build sorted relocation list from raw relocations. */
870  for (i = 0; i < numRelocations; i++) {
871  char * t;
872 
873  /*
874  * Default relocations (oldPath == NULL) are handled in the UI,
875  * not rpmlib.
876  */
877  if (p->relocs[i].oldPath == NULL) continue; /* XXX can't happen */
878 
879  /* FIXME: Trailing /'s will confuse us greatly. Internal ones will
880  too, but those are more trouble to fix up. :-( */
881  t = alloca_strdup(p->relocs[i].oldPath);
882  relocations[i].oldPath = (t[0] == '/' && t[1] == '\0')
883  ? t
884  : stripTrailingChar(t, '/');
885 
886  /* An old path w/o a new path is valid, and indicates exclusion */
887  if (p->relocs[i].newPath) {
888  int del;
889 
890  t = alloca_strdup(p->relocs[i].newPath);
891  relocations[i].newPath = (t[0] == '/' && t[1] == '\0')
892  ? t
893  : stripTrailingChar(t, '/');
894 
895  /*@-nullpass@*/ /* FIX: relocations[i].oldPath == NULL */
896  /* Verify that the relocation's old path is in the header. */
897  for (j = 0; j < numValid; j++) {
898  if (!strcmp(validRelocations[j], relocations[i].oldPath))
899  /*@innerbreak@*/ break;
900  }
901 
902  /* XXX actions check prevents problem from being appended twice. */
903  if (j == numValid && !allowBadRelocate && actions) {
904  rpmps ps = rpmtsProblems(ts);
906  rpmteNEVR(p), rpmteKey(p),
907  relocations[i].oldPath, NULL, NULL, 0);
908  ps = rpmpsFree(ps);
909  }
910  del =
911  (int)strlen(relocations[i].newPath) - (int)strlen(relocations[i].oldPath);
912  /*@=nullpass@*/
913 
914  if (del > reldel)
915  reldel = del;
916  } else {
917  relocations[i].newPath = NULL;
918  }
919  }
920 
921  /* stupid bubble sort, but it's probably faster here */
922  for (i = 0; i < numRelocations; i++) {
923  int madeSwap;
924  madeSwap = 0;
925  for (j = 1; j < numRelocations; j++) {
926  struct rpmRelocation_s tmpReloc;
927  if (relocations[j - 1].oldPath == NULL || /* XXX can't happen */
928  relocations[j ].oldPath == NULL || /* XXX can't happen */
929  strcmp(relocations[j - 1].oldPath, relocations[j].oldPath) <= 0)
930  /*@innercontinue@*/ continue;
931  /*@-usereleased@*/ /* LCL: ??? */
932  tmpReloc = relocations[j - 1];
933  relocations[j - 1] = relocations[j];
934  relocations[j] = tmpReloc;
935  /*@=usereleased@*/
936  madeSwap = 1;
937  }
938  if (!madeSwap) break;
939  }
940 
941  if (!_printed) {
942  _printed = 1;
943  rpmlog(RPMLOG_DEBUG, D_("========== relocations\n"));
944  for (i = 0; i < numRelocations; i++) {
945  if (relocations[i].oldPath == NULL) continue; /* XXX can't happen */
946  if (relocations[i].newPath == NULL)
947  rpmlog(RPMLOG_DEBUG, D_("%5d exclude %s\n"),
948  i, relocations[i].oldPath);
949  else
950  rpmlog(RPMLOG_DEBUG, D_("%5d relocate %s -> %s\n"),
951  i, relocations[i].oldPath, relocations[i].newPath);
952  }
953  }
954 
955  /* Add relocation values to the header */
956  if (numValid) {
957  const char ** actualRelocations;
958  int numActual;
959 
960  actualRelocations = (const char **) xmalloc(numValid * sizeof(*actualRelocations));
961  numActual = 0;
962  for (i = 0; i < numValid; i++) {
963  for (j = 0; j < numRelocations; j++) {
964  if (relocations[j].oldPath == NULL || /* XXX can't happen */
965  strcmp(validRelocations[i], relocations[j].oldPath))
966  /*@innercontinue@*/ continue;
967  /* On install, a relocate to NULL means skip the path. */
968  if (relocations[j].newPath) {
969  actualRelocations[numActual] = relocations[j].newPath;
970  numActual++;
971  }
972  /*@innerbreak@*/ break;
973  }
974  if (j == numRelocations) {
975  actualRelocations[numActual] = validRelocations[i];
976  numActual++;
977  }
978  }
979 
980  if (numActual) {
981  he->tag = RPMTAG_INSTPREFIXES;
982  he->t = RPM_STRING_ARRAY_TYPE;
983  he->p.argv = actualRelocations;
984  he->c = numActual;
985  xx = headerPut(h, he, 0);
986  }
987 
988  actualRelocations = _free(actualRelocations);
989  validRelocations = _free(validRelocations);
990  }
991 
992  he->tag = RPMTAG_BASENAMES;
993  xx = headerGet(h, he, 0);
994  baseNames = he->p.argv;
995  fileCount = he->c;
996  he->tag = RPMTAG_DIRINDEXES;
997  xx = headerGet(h, he, 0);
998  dirIndexes = he->p.ui32p;
999  he->tag = RPMTAG_DIRNAMES;
1000  xx = headerGet(h, he, 0);
1001  dirNames = he->p.argv;
1002  dirCount = he->c;
1003  he->tag = RPMTAG_FILEFLAGS;
1004  xx = headerGet(h, he, 0);
1005  fFlags = he->p.ui32p;
1006  he->tag = RPMTAG_FILECOLORS;
1007  xx = headerGet(h, he, 0);
1008  fColors = he->p.ui32p;
1009  he->tag = RPMTAG_FILEMODES;
1010  xx = headerGet(h, he, 0);
1011  fModes = he->p.ui16p;
1012 
1013  dColors = (rpmuint32_t *) alloca(dirCount * sizeof(*dColors));
1014  memset(dColors, 0, dirCount * sizeof(*dColors));
1015 
1016  /*
1017  * For all relocations, we go through sorted file/relocation lists
1018  * backwards so that /usr/local relocations take precedence over /usr
1019  * ones.
1020  */
1021 
1022  /* Relocate individual paths. */
1023 
1024  for (i = fileCount - 1; i >= 0; i--) {
1025  rpmFileTypes ft;
1026  size_t fnlen;
1027 
1028  len = reldel +
1029  strlen(dirNames[dirIndexes[i]]) + strlen(baseNames[i]) + 1;
1030  if (len >= fileAlloced) {
1031  fileAlloced = len * 2;
1032  fn = (char *) xrealloc(fn, fileAlloced);
1033  }
1034 
1035 assert(fn != NULL); /* XXX can't happen */
1036  *fn = '\0';
1037  fnlen = stpcpy( stpcpy(fn, dirNames[dirIndexes[i]]), baseNames[i]) - fn;
1038 
1039 if (fColors != NULL) {
1040 /* XXX pkgs may not have unique dirNames, so color all dirNames that match. */
1041 for (j = 0; j < (int)dirCount; j++) {
1042 if (strcmp(dirNames[dirIndexes[i]], dirNames[j])) /*@innercontinue@*/ continue;
1043 dColors[j] |= fColors[i];
1044 }
1045 }
1046 
1047  /*
1048  * See if this file path needs relocating.
1049  */
1050  /*
1051  * XXX FIXME: Would a bsearch of the (already sorted)
1052  * relocation list be a good idea?
1053  */
1054  for (j = numRelocations - 1; j >= 0; j--) {
1055  if (relocations[j].oldPath == NULL) /* XXX can't happen */
1056  /*@innercontinue@*/ continue;
1057  len = strcmp(relocations[j].oldPath, "/")
1058  ? strlen(relocations[j].oldPath)
1059  : 0;
1060 
1061  if (fnlen < len)
1062  /*@innercontinue@*/ continue;
1063  /*
1064  * Only subdirectories or complete file paths may be relocated. We
1065  * don't check for '\0' as our directory names all end in '/'.
1066  */
1067  if (!(fn[len] == '/' || fnlen == len))
1068  /*@innercontinue@*/ continue;
1069 
1070  if (strncmp(relocations[j].oldPath, fn, len))
1071  /*@innercontinue@*/ continue;
1072  /*@innerbreak@*/ break;
1073  }
1074  if (j < 0) continue;
1075 
1076 /*@-nullderef@*/ /* FIX: fModes may be NULL */
1077  ft = rpmfiWhatis(fModes[i]);
1078 /*@=nullderef@*/
1079 
1080  /* On install, a relocate to NULL means skip the path. */
1081  if (relocations[j].newPath == NULL) {
1082  if (ft == XDIR) {
1083  /* Start with the parent, looking for directory to exclude. */
1084  for (j = dirIndexes[i]; j < (int)dirCount; j++) {
1085  len = strlen(dirNames[j]) - 1;
1086  while (len > 0 && dirNames[j][len-1] == '/') len--;
1087  if (fnlen != len)
1088  /*@innercontinue@*/ continue;
1089  if (strncmp(fn, dirNames[j], fnlen))
1090  /*@innercontinue@*/ continue;
1091  /*@innerbreak@*/ break;
1092  }
1093  }
1094  if (actions) {
1095  actions[i] = FA_SKIPNSTATE;
1096  rpmlog(RPMLOG_DEBUG, D_("excluding %s %s\n"),
1097  rpmfiFtstring(ft), fn);
1098  }
1099  continue;
1100  }
1101 
1102  /* Relocation on full paths only, please. */
1103  if (fnlen != len) continue;
1104 
1105  if (actions)
1106  rpmlog(RPMLOG_DEBUG, D_("relocating %s to %s\n"),
1107  fn, relocations[j].newPath);
1108  nrelocated++;
1109 
1110  strcpy(fn, relocations[j].newPath);
1111  { char * te = strrchr(fn, '/');
1112  if (te) {
1113  if (te > fn) te++; /* root is special */
1114  fnlen = te - fn;
1115  } else
1116  te = fn + strlen(fn);
1117  /*@-nullpass -nullderef@*/ /* LCL: te != NULL here. */
1118  if (strcmp(baseNames[i], te)) /* basename changed too? */
1119  baseNames[i] = alloca_strdup(te);
1120  *te = '\0'; /* terminate new directory name */
1121  /*@=nullpass =nullderef@*/
1122  }
1123 
1124  /* Does this directory already exist in the directory list? */
1125  for (j = 0; j < (int)dirCount; j++) {
1126  if (fnlen != strlen(dirNames[j]))
1127  /*@innercontinue@*/ continue;
1128  if (strncmp(fn, dirNames[j], fnlen))
1129  /*@innercontinue@*/ continue;
1130  /*@innerbreak@*/ break;
1131  }
1132 
1133  if (j < (int)dirCount) {
1134  dirIndexes[i] = j;
1135  continue;
1136  }
1137 
1138  /* Creating new paths is a pita */
1139  if (!haveRelocatedFile) {
1140  const char ** newDirList;
1141 
1142  haveRelocatedFile = 1;
1143  newDirList = (const char **) xmalloc((dirCount + 1) * sizeof(*newDirList));
1144  for (j = 0; j < (int)dirCount; j++)
1145  newDirList[j] = alloca_strdup(dirNames[j]);
1146  dirNames = _free(dirNames);
1147  dirNames = newDirList;
1148  } else {
1149  dirNames = (const char **) xrealloc(dirNames,
1150  sizeof(*dirNames) * (dirCount + 1));
1151  }
1152 
1153  dirNames[dirCount] = alloca_strdup(fn);
1154  dirIndexes[i] = dirCount;
1155  dirCount++;
1156  }
1157 
1158  /* Finish off by relocating directories. */
1159  for (i = dirCount - 1; i >= 0; i--) {
1160  for (j = numRelocations - 1; j >= 0; j--) {
1161 
1162  /* XXX Don't autorelocate uncolored directories. */
1163  if (j == p->autorelocatex
1164  && (dColors[i] == 0 || !(dColors[i] & mydColor)))
1165  /*@innercontinue@*/ continue;
1166 
1167  if (relocations[j].oldPath == NULL) /* XXX can't happen */
1168  /*@innercontinue@*/ continue;
1169  len = strcmp(relocations[j].oldPath, "/")
1170  ? strlen(relocations[j].oldPath)
1171  : 0;
1172 
1173  if (len && strncmp(relocations[j].oldPath, dirNames[i], len))
1174  /*@innercontinue@*/ continue;
1175 
1176  /*
1177  * Only subdirectories or complete file paths may be relocated. We
1178  * don't check for '\0' as our directory names all end in '/'.
1179  */
1180  if (dirNames[i][len] != '/')
1181  /*@innercontinue@*/ continue;
1182 
1183  if (relocations[j].newPath) { /* Relocate the path */
1184  const char * s = relocations[j].newPath;
1185  size_t slen = strlen(s) + strlen(dirNames[i]) - len;
1186  char * t = (char *) alloca(slen + 1);
1187 
1188  (void) stpcpy( stpcpy(t, s) , dirNames[i] + len);
1189 
1190  /* Unfortunately rpmCleanPath strips the trailing slash.. */
1191  (void) rpmCleanPath(t);
1192  slen = strlen(t);
1193  t[slen] = '/';
1194  t[slen+1] = '\0';
1195 
1196  if (actions)
1198  D_("relocating directory %s to %s\n"), dirNames[i], t);
1199  dirNames[i] = t;
1200  nrelocated++;
1201  }
1202  }
1203  }
1204 
1205  /* Save original filenames in header and replace (relocated) filenames. */
1206  if (nrelocated) {
1207  he->tag = RPMTAG_BASENAMES;
1208  xx = headerGet(h, he, 0);
1209  he->tag = RPMTAG_ORIGBASENAMES;
1210  xx = headerPut(h, he, 0);
1211  he->p.ptr = _free(he->p.ptr);
1212 
1213  he->tag = RPMTAG_DIRNAMES;
1214  xx = headerGet(h, he, 0);
1215  he->tag = RPMTAG_ORIGDIRNAMES;
1216  xx = headerPut(h, he, 0);
1217  he->p.ptr = _free(he->p.ptr);
1218 
1219  he->tag = RPMTAG_DIRINDEXES;
1220  xx = headerGet(h, he, 0);
1221  he->tag = RPMTAG_ORIGDIRINDEXES;
1222  xx = headerPut(h, he, 0);
1223  he->p.ptr = _free(he->p.ptr);
1224 
1225  he->tag = RPMTAG_BASENAMES;
1226  he->t = RPM_STRING_ARRAY_TYPE;
1227  he->p.argv = baseNames;
1228  he->c = fileCount;
1229  xx = headerMod(h, he, 0);
1230  fi->bnl = _free(fi->bnl);
1231  xx = headerGet(h, he, 0);
1232 /*@-dependenttrans@*/
1233  fi->bnl = he->p.argv;
1234 /*@=dependenttrans@*/
1235  fi->fc = he->c;
1236 
1237  he->tag = RPMTAG_DIRNAMES;
1238  he->t = RPM_STRING_ARRAY_TYPE;
1239  he->p.argv = dirNames;
1240  he->c = dirCount;
1241  xx = headerMod(h, he, 0);
1242  fi->dnl = _free(fi->dnl);
1243  xx = headerGet(h, he, 0);
1244  fi->dnl = he->p.argv;
1245  fi->dc = he->c;
1246 
1247  he->tag = RPMTAG_DIRINDEXES;
1248  he->t = RPM_UINT32_TYPE;
1249  he->p.ui32p = dirIndexes;
1250  he->c = fileCount;
1251  xx = headerMod(h, he, 0);
1252  fi->dil = _free(fi->dil);
1253  xx = headerGet(h, he, 0);
1254 /*@-dependenttrans@*/
1255  fi->dil = he->p.ui32p;
1256 /*@=dependenttrans@*/
1257  }
1258 
1259  baseNames = _free(baseNames);
1260  dirIndexes = _free(dirIndexes);
1261  dirNames = _free(dirNames);
1262  fFlags = _free(fFlags);
1263  fColors = _free(fColors);
1264  fModes = _free(fModes);
1265 
1266 /*@-dependenttrans@*/
1267  fn = _free(fn);
1268 /*@=dependenttrans@*/
1269 
1270 /*@-retalias@*/
1271  return h;
1272 /*@=retalias@*/
1273 }
1274 
1276 {
1277  if (fi->h != NULL)
1278  (void)headerFree(fi->h);
1279  fi->h = NULL;
1280 /*@-assignexpose -castexpose @*/
1281  if (h != NULL)
1282  fi->h = headerLink(h);
1283 /*@=assignexpose =castexpose @*/
1284  return 0;
1285 }
1286 
1287 static void rpmfiFini(void * _fi)
1288  /*@modifies *_fi @*/
1289 {
1290  rpmfi fi = (rpmfi) _fi;
1291 
1292  /* Free pre- and post-transaction script and interpreter strings. */
1293  fi->pretrans = _free(fi->pretrans);
1294  fi->pretransprog = _free(fi->pretransprog);
1295  fi->posttrans = _free(fi->posttrans);
1296  fi->posttransprog = _free(fi->posttransprog);
1297  fi->verifyscript = _free(fi->verifyscript);
1298  fi->verifyscriptprog = _free(fi->verifyscriptprog);
1299 
1300  if (fi->fc > 0) {
1301  fi->bnl = _free(fi->bnl);
1302  fi->dnl = _free(fi->dnl);
1303 
1304  fi->flinks = _free(fi->flinks);
1305  fi->flangs = _free(fi->flangs);
1306  fi->fdigests = _free(fi->fdigests);
1307  fi->digests = _free(fi->digests);
1308 
1309  fi->cdict = _free(fi->cdict);
1310 
1311  fi->fuser = _free(fi->fuser);
1312  fi->fgroup = _free(fi->fgroup);
1313 
1314  fi->fstates = _free(fi->fstates);
1315 
1316  fi->fmtimes = _free(fi->fmtimes);
1317  fi->fmodes = _free(fi->fmodes);
1318  fi->fflags = _free(fi->fflags);
1319  fi->vflags = _free(fi->vflags);
1320  fi->fsizes = _free(fi->fsizes);
1321  fi->frdevs = _free(fi->frdevs);
1322  fi->finodes = _free(fi->finodes);
1323  fi->dil = _free(fi->dil);
1324 
1325  fi->fcolors = _free(fi->fcolors);
1326  fi->fcdictx = _free(fi->fcdictx);
1327  fi->ddict = _free(fi->ddict);
1328  fi->fddictx = _free(fi->fddictx);
1329  fi->fddictn = _free(fi->fddictn);
1330  }
1331 
1332 /*@-globs@*/ /* Avoid rpmGlobalMacroContext */
1333  fi->fsm = freeFSM((IOSM_t)fi->fsm);
1334 /*@=globs@*/
1335 
1336  fi->_fnbf = rpmbfFree((rpmbf)fi->_fnbf);
1337  fi->exclude = (miRE) mireFreeAll(fi->exclude, fi->nexclude);
1338  fi->include = (miRE) mireFreeAll(fi->include, fi->ninclude);
1339 
1340  fi->fn = _free(fi->fn);
1341  fi->apath = _free(fi->apath);
1342  fi->fmapflags = _free(fi->fmapflags);
1343 
1344  fi->obnl = _free(fi->obnl);
1345  fi->odnl = _free(fi->odnl);
1346 
1347  fi->fcontexts = _free(fi->fcontexts);
1348 
1349  fi->actions = _free(fi->actions);
1350  fi->replacedSizes = _free(fi->replacedSizes);
1351 
1352  (void)headerFree(fi->h);
1353  fi->h = NULL;
1354 }
1355 
1356 /*@unchecked@*/ /*@only@*/ /*@null@*/
1358 
1359 static rpmfi rpmfiGetPool(/*@null@*/ rpmioPool pool)
1360  /*@globals _rpmfiPool, fileSystem, internalState @*/
1361  /*@modifies pool, _rpmfiPool, fileSystem, internalState @*/
1362 {
1363  rpmfi fi;
1364 
1365  if (_rpmfiPool == NULL) {
1366  _rpmfiPool = rpmioNewPool("fi", sizeof(*fi), -1, _rpmfi_debug,
1367  NULL, NULL, rpmfiFini);
1368  pool = _rpmfiPool;
1369  }
1370  fi = (rpmfi) rpmioGetPool(pool, sizeof(*fi));
1371  memset(((char *)fi)+sizeof(fi->_item), 0, sizeof(*fi)-sizeof(fi->_item));
1372  return fi;
1373 }
1374 
1380 static inline unsigned char nibble(char c)
1381  /*@*/
1382 {
1383  if (c >= '0' && c <= '9')
1384  return (c - '0');
1385  if (c >= 'A' && c <= 'F')
1386  return (c - 'A') + 10;
1387  if (c >= 'a' && c <= 'f')
1388  return (c - 'a') + 10;
1389  return 0;
1390 }
1391 
1392 #define _fdupestring(_h, _tag, _data) \
1393  he->tag = _tag; \
1394  xx = headerGet((_h), he, 0); \
1395  _data = he->p.str;
1396 
1397 #define _fdupedata(_h, _tag, _cast, _data) \
1398  he->tag = _tag; \
1399  xx = headerGet((_h), he, 0); \
1400  _data = (_cast) he->p.ptr;
1401 
1402 /*@-strictusereleased@*/
1403 rpmfi rpmfiNew(const void * _ts, Header h, rpmTag tagN, int flags)
1404 {
1405 /*@-castexpose@*/
1406  const rpmts ts = (const rpmts) _ts;
1407 /*@=castexpose@*/
1408  int scareMem = (flags & 0x1);
1409  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
1410  rpmte p;
1411  rpmfi fi = NULL;
1412  const char * Type;
1413  unsigned char * t;
1414  pgpHashAlgo dalgo;
1415  int xx;
1416  int i;
1417 
1418 assert(scareMem == 0); /* XXX always allocate memory */
1419  if (tagN == RPMTAG_BASENAMES) {
1420  Type = "Files";
1421  } else {
1422  Type = "?Type?";
1423  goto exit;
1424  }
1425 
1426  fi = rpmfiGetPool(_rpmfiPool);
1427  if (fi == NULL) /* XXX can't happen */
1428  goto exit;
1429 
1430  fi->magic = RPMFIMAGIC;
1431  fi->Type = Type;
1432  fi->i = -1;
1433  fi->tagN = tagN;
1434 
1435  fi->h = NULL;
1436  fi->isSource =
1437  (headerIsEntry(h, RPMTAG_SOURCERPM) == 0 &&
1438  headerIsEntry(h, RPMTAG_RPMVERSION) != 0 &&
1439  headerIsEntry(h, RPMTAG_ARCH) != 0);
1440 
1441  if (fi->fsm == NULL)
1442  fi->fsm = newFSM();
1443 
1444  ((FSM_t)fi->fsm)->repackaged = (headerIsEntry(h, RPMTAG_REMOVETID) ? 1 : 0);
1445 
1446  /* 0 means unknown */
1447  he->tag = RPMTAG_ARCHIVESIZE;
1448  xx = headerGet(h, he, 0);
1449  fi->archivePos = 0;
1450  fi->archiveSize = (xx && he->p.ui32p ? he->p.ui32p[0] : 0);
1451  he->p.ptr = _free(he->p.ptr);
1452 
1453  /* Extract pre- and post-transaction script and interpreter strings. */
1454  _fdupestring(h, RPMTAG_PRETRANS, fi->pretrans);
1455  _fdupestring(h, RPMTAG_PRETRANSPROG, fi->pretransprog);
1456  _fdupestring(h, RPMTAG_POSTTRANS, fi->posttrans);
1457  _fdupestring(h, RPMTAG_POSTTRANSPROG, fi->posttransprog);
1458  _fdupestring(h, RPMTAG_VERIFYSCRIPT, fi->verifyscript);
1459  _fdupestring(h, RPMTAG_VERIFYSCRIPTPROG, fi->verifyscriptprog);
1460 
1461  he->tag = RPMTAG_BASENAMES;
1462  xx = headerGet(h, he, 0);
1463  /* XXX 3.0.x SRPM's can be used, relative fn's at RPMTAG_OLDFILENAMES. */
1464  if (xx == 0 && fi->isSource) {
1465  he->tag = RPMTAG_OLDFILENAMES;
1466  xx = headerGet(h, he, 0);
1467  }
1468  fi->bnl = he->p.argv;
1469  fi->fc = he->c;
1470  if (!xx) {
1471  fi->fc = 0;
1472  fi->dc = 0;
1473  goto exit;
1474  }
1475  _fdupedata(h, RPMTAG_DIRNAMES, const char **, fi->dnl);
1476  fi->dc = he->c;
1477  /* XXX 3.0.x SRPM's can be used, relative fn's at RPMTAG_OLDFILENAMES. */
1478  if (fi->dc == 0 && fi->isSource) {
1479  fi->dc = 1;
1480  fi->dnl = (const char **) xcalloc(3, sizeof(*fi->dnl));
1481  fi->dnl[0] = (const char *)&fi->dnl[2];
1482  fi->dil = (rpmuint32_t *) xcalloc(fi->fc, sizeof(*fi->dil));
1483  } else {
1484  _fdupedata(h, RPMTAG_DIRINDEXES, rpmuint32_t *, fi->dil);
1485  }
1486  _fdupedata(h, RPMTAG_FILEMODES, rpmuint16_t *, fi->fmodes);
1487  _fdupedata(h, RPMTAG_FILEFLAGS, rpmuint32_t *, fi->fflags);
1488  _fdupedata(h, RPMTAG_FILEVERIFYFLAGS, rpmuint32_t *, fi->vflags);
1489  _fdupedata(h, RPMTAG_FILESIZES, rpmuint32_t *, fi->fsizes);
1490 
1491  _fdupedata(h, RPMTAG_FILECOLORS, rpmuint32_t *, fi->fcolors);
1492  fi->color = 0;
1493  if (fi->fcolors != NULL)
1494  for (i = 0; i < (int)fi->fc; i++)
1495  fi->color |= fi->fcolors[i];
1496  _fdupedata(h, RPMTAG_CLASSDICT, const char **, fi->cdict);
1497  fi->ncdict = he->c;
1498  _fdupedata(h, RPMTAG_FILECLASS, rpmuint32_t *, fi->fcdictx);
1499 
1500  _fdupedata(h, RPMTAG_DEPENDSDICT, rpmuint32_t *, fi->ddict);
1501  fi->nddict = he->c;
1502  _fdupedata(h, RPMTAG_FILEDEPENDSX, rpmuint32_t *, fi->fddictx);
1503  _fdupedata(h, RPMTAG_FILEDEPENDSN, rpmuint32_t *, fi->fddictn);
1504 
1505  _fdupedata(h, RPMTAG_FILESTATES, rpmuint8_t *, fi->fstates);
1506  if (xx == 0 || fi->fstates == NULL)
1507  fi->fstates = (rpmuint8_t *) xcalloc(fi->fc, sizeof(*fi->fstates));
1508 
1509  fi->action = FA_UNKNOWN;
1510  fi->flags = 0;
1511 
1512 if (fi->actions == NULL)
1513  fi->actions = (int *) xcalloc(fi->fc, sizeof(*fi->actions));
1514 
1515  /* XXX TR_REMOVED needs IOSM_MAP_{ABSOLUTE,ADDDOT} IOSM_ALL_HARDLINKS */
1516  fi->mapflags =
1518 
1519  _fdupedata(h, RPMTAG_FILELINKTOS, const char **, fi->flinks);
1520  _fdupedata(h, RPMTAG_FILELANGS, const char **, fi->flangs);
1521 
1522  dalgo = PGPHASHALGO_ERROR;
1523  fi->fdigestalgos = NULL;
1524  _fdupedata(h, RPMTAG_FILEDIGESTALGOS, rpmuint32_t *, fi->fdigestalgos);
1525  if (fi->fdigestalgos) {
1526  /* XXX Insure that all algorithms are either 0 or constant. */
1527  for (i = 0; i < (int)fi->fc; i++) {
1528  if (fi->fdigestalgos[i] == 0)
1529  continue;
1530  if (dalgo == PGPHASHALGO_ERROR)
1531  dalgo = (pgpHashAlgo) (fi->fdigestalgos[i] & 0xff);
1532  else
1533 assert(dalgo == (pgpHashAlgo)fi->fdigestalgos[i]);
1534  }
1535  fi->fdigestalgos = _free(fi->fdigestalgos);
1536  } else {
1537  he->tag = RPMTAG_FILEDIGESTALGO;
1538  xx = headerGet(h, he, 0);
1539  if (xx)
1540  dalgo = (pgpHashAlgo) he->p.ui32p[0];
1541  he->p.ptr = _free(he->p.ptr);
1542  }
1543 
1544  switch (dalgo) {
1545  default: dalgo = PGPHASHALGO_MD5; fi->digestlen = 128/8; break;
1546  case PGPHASHALGO_MD2: fi->digestlen = 128/8; break;
1547  case PGPHASHALGO_MD5: fi->digestlen = 128/8; break;
1548  case PGPHASHALGO_SHA1: fi->digestlen = 160/8; break;
1549  case PGPHASHALGO_RIPEMD128: fi->digestlen = 128/8; break;
1550  case PGPHASHALGO_RIPEMD160: fi->digestlen = 160/8; break;
1551  case PGPHASHALGO_RIPEMD256: fi->digestlen = 256/8; break;
1552  case PGPHASHALGO_RIPEMD320: fi->digestlen = 320/8; break;
1553  case PGPHASHALGO_SHA224: fi->digestlen = 224/8; break;
1554  case PGPHASHALGO_SHA256: fi->digestlen = 256/8; break;
1555  case PGPHASHALGO_SHA384: fi->digestlen = 384/8; break;
1556  case PGPHASHALGO_SHA512: fi->digestlen = 512/8; break;
1557  case PGPHASHALGO_CRC32: fi->digestlen = 32/8; break;
1558  }
1559  fi->digestalgo = dalgo;
1560 
1561  fi->digests = NULL;
1562  _fdupedata(h, RPMTAG_FILEDIGESTS, const char **, fi->fdigests);
1563  if (fi->fdigests) {
1564  t = (unsigned char *) xmalloc(fi->fc * fi->digestlen);
1565  fi->digests = t;
1566  for (i = 0; i < (int)fi->fc; i++) {
1567  const char * fdigests;
1568  int j;
1569 
1570  fdigests = fi->fdigests[i];
1571  if (!(fdigests && *fdigests != '\0')) {
1572  memset(t, 0, fi->digestlen);
1573  t += fi->digestlen;
1574  continue;
1575  }
1576  for (j = 0; j < (int)fi->digestlen; j++, t++, fdigests += 2)
1577  *t = (nibble(fdigests[0]) << 4) | nibble(fdigests[1]);
1578  }
1579  fi->fdigests = _free(fi->fdigests);
1580  }
1581 
1582  /* XXX TR_REMOVED doesn't need fmtimes, frdevs, finodes, or fcontexts */
1583  _fdupedata(h, RPMTAG_FILEMTIMES, rpmuint32_t *, fi->fmtimes);
1584  _fdupedata(h, RPMTAG_FILERDEVS, rpmuint16_t *, fi->frdevs);
1585  _fdupedata(h, RPMTAG_FILEINODES, rpmuint32_t *, fi->finodes);
1586  _fdupedata(h, RPMTAG_FILECONTEXTS, const char **, fi->fcontexts);
1587 
1588  fi->replacedSizes = (rpmuint32_t *) xcalloc(fi->fc, sizeof(*fi->replacedSizes));
1589 
1590  _fdupedata(h, RPMTAG_FILEUSERNAME, const char **, fi->fuser);
1591  _fdupedata(h, RPMTAG_FILEGROUPNAME, const char **, fi->fgroup);
1592 
1593  if (ts != NULL)
1594  if (fi != NULL)
1595  if ((p = rpmtsRelocateElement(ts)) != NULL && rpmteType(p) == TR_ADDED
1598  {
1599  const char * fmt = rpmGetPath("%{?_autorelocate_path}", NULL);
1600  const char * errstr;
1601  char * newPath;
1602  Header foo;
1603 
1604  /* XXX error handling. */
1605  newPath = headerSprintf(h, fmt, NULL, rpmHeaderFormats, &errstr);
1606  fmt = _free(fmt);
1607 
1608  /* XXX Make sure autoreloc is not already specified. */
1609  i = p->nrelocs;
1610  if (newPath != NULL && *newPath != '\0' && p->relocs != NULL)
1611  for (i = 0; i < p->nrelocs; i++) {
1612 /*@-nullpass@*/ /* XXX {old,new}Path might be NULL */
1613  if (strcmp(p->relocs[i].oldPath, "/"))
1614  continue;
1615  if (strcmp(p->relocs[i].newPath, newPath))
1616  continue;
1617 /*@=nullpass@*/
1618  break;
1619  }
1620 
1621  /* XXX test for incompatible arch triggering autorelocation is dumb. */
1622  /* XXX DIEDIEDIE: used to test '... && p->archScore == 0' */
1623  if (newPath != NULL && *newPath != '\0' && i == p->nrelocs) {
1624 
1625  p->relocs =
1626  (rpmRelocation) xrealloc(p->relocs, (p->nrelocs + 2) * sizeof(*p->relocs));
1627  p->relocs[p->nrelocs].oldPath = xstrdup("/");
1628  p->relocs[p->nrelocs].newPath = xstrdup(newPath);
1629  p->autorelocatex = p->nrelocs;
1630  p->nrelocs++;
1631  p->relocs[p->nrelocs].oldPath = NULL;
1632  p->relocs[p->nrelocs].newPath = NULL;
1633  }
1634  newPath = _free(newPath);
1635 
1636 /* XXX DYING */
1637 if (fi->actions == NULL)
1638  fi->actions = (int *) xcalloc(fi->fc, sizeof(*fi->actions));
1639  /*@-compdef@*/ /* FIX: fi->digests undefined */
1640  foo = relocateFileList(ts, fi, h, (iosmFileAction *) fi->actions);
1641  /*@=compdef@*/
1642  (void)headerFree(fi->h);
1643  fi->h = NULL;
1644  fi->h = headerLink(foo);
1645  (void)headerFree(foo);
1646  foo = NULL;
1647  }
1648 
1649  if (fi->isSource && fi->dc == 1 && *fi->dnl[0] == '\0') {
1650  const char ** av = (const char **) xcalloc(4+1, sizeof(*av));
1651  char * te;
1652  size_t nb;
1653 
1654  xx = headerMacrosLoad(h);
1655  av[0] = rpmGenPath(rpmtsRootDir(ts), "%{_sourcedir}", "");
1656  av[1] = rpmGenPath(rpmtsRootDir(ts), "%{_specdir}", "");
1657  av[2] = rpmGenPath(rpmtsRootDir(ts), "%{_patchdir}", "");
1658  av[3] = rpmGenPath(rpmtsRootDir(ts), "%{_icondir}", "");
1659  av[4] = NULL;
1660  xx = headerMacrosUnload(h);
1661 
1662  /* Hack up a header RPM_STRING_ARRAY_TYPE array. */
1663  fi->dnl = _free(fi->dnl);
1664  fi->dc = 4;
1665  nb = fi->dc * sizeof(*av);
1666  for (i = 0; i < (int)fi->dc; i++)
1667  nb += strlen(av[i]) + sizeof("/");
1668 
1669  fi->dnl = (const char **) xmalloc(nb);
1670  te = (char *) (&fi->dnl[fi->dc]);
1671  *te = '\0';
1672  for (i = 0; i < (int)fi->dc; i++) {
1673  fi->dnl[i] = te;
1674  te = stpcpy( stpcpy(te, av[i]), "/");
1675  *te++ = '\0';
1676  }
1677  av = argvFree(av);
1678 
1679  /* Map basenames to appropriate directories. */
1680  for (i = 0; i < (int)fi->fc; i++) {
1681  if (fi->fflags[i] & RPMFILE_SOURCE)
1682  fi->dil[i] = 0;
1683  else if (fi->fflags[i] & RPMFILE_SPECFILE)
1684  fi->dil[i] = 1;
1685  else if (fi->fflags[i] & RPMFILE_PATCH)
1686  fi->dil[i] = 2;
1687  else if (fi->fflags[i] & RPMFILE_ICON)
1688  fi->dil[i] = 3;
1689  else {
1690  const char * b = fi->bnl[i];
1691  const char * be = b + strlen(b) - sizeof(".spec") - 1;
1692 
1693  fi->dil[i] = (be > b && !strcmp(be, ".spec") ? 1 : 0);
1694  }
1695  }
1696  }
1697 
1698  if (!scareMem)
1699  (void)headerFree(fi->h);
1700  fi->h = NULL;
1701 
1702  fi->fn = NULL;
1703  fi->fnlen = 0;
1704  for (i = 0; i < (int)fi->fc; i++) {
1705  size_t fnlen = strlen(fi->dnl[fi->dil[i]]) + strlen(fi->bnl[i]);
1706  fnlen++; /* XXX guarantee space for pesky trailing '/' */
1707  if (fnlen > fi->fnlen)
1708  fi->fnlen = fnlen;
1709  }
1710 
1711  fi->dperms = 0755;
1712  fi->fperms = 0644;
1713 
1714 exit:
1715 /*@-modfilesys@*/
1716 if (_rpmfi_debug < 0)
1717 fprintf(stderr, "*** fi %p\t%s[%d]\n", fi, Type, (fi ? fi->fc : 0));
1718 /*@=modfilesys@*/
1719 
1720  /*@-compdef -nullstate@*/ /* FIX: rpmfi null annotations */
1721  return rpmfiLink(fi, (fi ? fi->Type : NULL));
1722  /*@=compdef =nullstate@*/
1723 }
1724 /*@=strictusereleased@*/
1725 
1726 int rpmfiAddRelocation(rpmRelocation * relp, int * nrelp,
1727  const char * oldPath, const char * newPath)
1728 {
1729 /*@-unqualifiedtrans@*/
1730  *relp = (rpmRelocation) xrealloc(*relp, sizeof(**relp) * ((*nrelp) + 1));
1731 /*@=unqualifiedtrans@*/
1732  (*relp)[*nrelp].oldPath = (oldPath ? xstrdup(oldPath) : NULL);
1733  (*relp)[*nrelp].newPath = (newPath ? xstrdup(newPath) : NULL);
1734  (*nrelp)++;
1735  return 0;
1736 }
1737 
1739 {
1740  if (relocs) {
1741  rpmRelocation r;
1742  for (r = relocs; (r->oldPath || r->newPath); r++) {
1743  r->oldPath = _free(r->oldPath);
1744  r->newPath = _free(r->newPath);
1745  }
1746  relocs = _free(relocs);
1747  }
1748  return NULL;
1749 }
1750 
1752 {
1753  rpmRelocation newr = NULL;
1754  int nrelocs = 0;
1755 
1756  if (relocs) {
1757  rpmRelocation r;
1758  int i;
1759 
1760  for (r = relocs; r->oldPath || r->newPath; r++)
1761  nrelocs++;
1762  newr = (rpmRelocation) xmalloc((nrelocs + 1) * sizeof(*relocs));
1763 
1764  for (i = 0, r = relocs; r->oldPath || r->newPath; i++, r++) {
1765  newr[i].oldPath = r->oldPath ? xstrdup(r->oldPath) : NULL;
1766  newr[i].newPath = r->newPath ? xstrdup(r->newPath) : NULL;
1767  }
1768  newr[i].oldPath = NULL;
1769  newr[i].newPath = NULL;
1770  }
1771  if (nrelocsp)
1772  *nrelocsp = nrelocs;
1773  return newr;
1774 }
1775 
1776 int rpmfiFStat(rpmfi fi, struct stat * st)
1777 {
1778  int rc = -1;
1779 
1780  if (st != NULL && fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc) {
1781  memset(st, 0, sizeof(*st));
1782  st->st_dev =
1783  st->st_rdev = fi->frdevs[fi->i];
1784  st->st_ino = fi->finodes[fi->i];
1785  st->st_mode = fi->fmodes[fi->i];
1786  st->st_nlink = rpmfiFNlink(fi) + (int)S_ISDIR(st->st_mode);
1787  if (unameToUid(fi->fuser[fi->i], &st->st_uid) == -1)
1788  st->st_uid = 0; /* XXX */
1789  if (gnameToGid(fi->fgroup[fi->i], &st->st_gid) == -1)
1790  st->st_gid = 0; /* XXX */
1791  st->st_size = fi->fsizes[fi->i];
1792  st->st_blksize = 4 * 1024; /* XXX */
1793  st->st_blocks = (st->st_size + (st->st_blksize - 1)) / st->st_blksize;
1794  st->st_atime =
1795  st->st_ctime =
1796  st->st_mtime = fi->fmtimes[fi->i];
1797  rc = 0;
1798  }
1799 
1800  return rc;
1801 }
1802 
1803 int rpmfiStat(rpmfi fi, const char * path, struct stat * st)
1804 {
1805  size_t pathlen = strlen(path);
1806  int rc = -1;
1807  int i;
1808 
1809  while (pathlen > 0 && path[pathlen-1] == '/')
1810  pathlen--;
1811 
1812  /* If not actively iterating, initialize. */
1813  if (!(fi != NULL && fi->i >= 0 && fi->i < (int)fi->fc))
1814  fi = rpmfiInit(fi, 0);
1815 
1816  while ((i = rpmfiNext(fi)) >= 0) {
1817  const char * fn = rpmfiFN(fi);
1818  size_t fnlen = strlen(fn);
1819 
1820  if (pathlen != fnlen || strncmp(path, fn, fnlen))
1821  continue;
1822  rc = rpmfiFStat(fi, st);
1823  break;
1824  }
1825 
1826 /*@-modfilesys@*/
1827 if (_rpmfi_debug)
1828 fprintf(stderr, "*** rpmfiStat(%p, %s, %p) rc %d\n", fi, path, st, rc);
1829 /*@=modfilesys@*/
1830 
1831  return rc;
1832 }
1833 
1834 void * rpmfiOpendir(rpmfi fi, const char * name)
1835 {
1836  const char * dn = name;
1837  size_t dnlen = strlen(dn);
1838  const char ** fnames = NULL;
1839  rpmuint16_t * fmodes = NULL;
1840  DIR * dir;
1841  int xx;
1842  int i, j;
1843 
1844  j = 0;
1845  fmodes = (rpmuint16_t *) xcalloc(fi->fc, sizeof(*fmodes));
1846 
1847  /* XXX todo full iteration is pig slow, fi->dil can be used for speedup. */
1848  fi = rpmfiInit(fi, 0);
1849  while ((i = rpmfiNext(fi)) >= 0) {
1850  const char * fn = rpmfiFN(fi);
1851  size_t fnlen = strlen(fn);
1852 
1853  if (fnlen <= dnlen)
1854  continue;
1855  if (strncmp(dn, fn, dnlen) || fn[dnlen] != '/')
1856  continue;
1857 
1858  /* XXX todo basename, or orphandir/.../basname, needs to be used. */
1859  /* Trim the directory part of the name. */
1860  xx = argvAdd(&fnames, fn + dnlen + 1);
1861  fmodes[j++] = fi->fmodes[i];
1862  }
1863 
1864  /* Add "." & ".." to the argv array. */
1865  dir = (DIR *) avOpendir(name, fnames, fmodes);
1866 
1867  fnames = argvFree(fnames);
1868  fmodes = _free(fmodes);
1869 
1870 /*@-modfilesys +voidabstract @*/
1871 if (_rpmfi_debug)
1872 fprintf(stderr, "*** rpmfiOpendir(%p, %s) dir %p\n", fi, name, dir);
1873 /*@=modfilesys =voidabstract @*/
1874 
1875  return (void *)dir;
1876 }
1877 
1879  /*@out@*/ const char *** fclassp, /*@out@*/ rpmuint32_t * fcp)
1880 {
1881  int scareMem = 0;
1882  rpmfi fi = rpmfiNew(NULL, h, RPMTAG_BASENAMES, scareMem);
1883  const char * FClass;
1884  const char ** av;
1885  int ac;
1886  size_t nb;
1887  char * t;
1888 
1889  if ((ac = rpmfiFC(fi)) <= 0) {
1890  av = NULL;
1891  ac = 0;
1892  goto exit;
1893  }
1894 
1895  /* Compute size of file class argv array blob. */
1896  nb = (ac + 1) * sizeof(*av);
1897  fi = rpmfiInit(fi, 0);
1898  if (fi != NULL)
1899  while (rpmfiNext(fi) >= 0) {
1900  FClass = rpmfiFClass(fi);
1901  if (FClass && *FClass != '\0')
1902  nb += strlen(FClass);
1903  nb += 1;
1904  }
1905 
1906  /* Create and load file class argv array. */
1907  av = (const char **) xmalloc(nb);
1908  t = ((char *) av) + ((ac + 1) * sizeof(*av));
1909  ac = 0;
1910  fi = rpmfiInit(fi, 0);
1911  if (fi != NULL)
1912  while (rpmfiNext(fi) >= 0) {
1913  FClass = rpmfiFClass(fi);
1914  av[ac++] = t;
1915  if (FClass && *FClass != '\0')
1916  t = stpcpy(t, FClass);
1917  *t++ = '\0';
1918  }
1919  av[ac] = NULL; /* XXX tag arrays are not NULL terminated. */
1920 
1921 exit:
1922  fi = rpmfiFree(fi);
1923  if (fclassp)
1924  *fclassp = av;
1925  else
1926  av = _free(av);
1927  if (fcp) *fcp = ac;
1928 }
1929 
1930 #ifdef DYING
1931 void rpmfiBuildFContexts(Header h,
1932  /*@out@*/ const char *** fcontextp, /*@out@*/ rpmuint32_t * fcp)
1933 {
1934  int scareMem = 0;
1935  rpmfi fi = rpmfiNew(NULL, h, RPMTAG_BASENAMES, scareMem);
1936  const char * fcontext;
1937  const char ** av;
1938  int ac;
1939  size_t nb;
1940  char * t;
1941 
1942  if ((ac = rpmfiFC(fi)) <= 0) {
1943  av = NULL;
1944  ac = 0;
1945  goto exit;
1946  }
1947 
1948  /* Compute size of argv array blob. */
1949  nb = (ac + 1) * sizeof(*av);
1950  fi = rpmfiInit(fi, 0);
1951  if (fi != NULL)
1952  while (rpmfiNext(fi) >= 0) {
1953  fcontext = rpmfiFContext(fi);
1954  if (fcontext && *fcontext != '\0')
1955  nb += strlen(fcontext);
1956  nb += 1;
1957  }
1958 
1959  /* Create and load argv array. */
1960  av = (const char **) xmalloc(nb);
1961  t = ((char *) av) + ((ac + 1) * sizeof(*av));
1962  ac = 0;
1963  fi = rpmfiInit(fi, 0);
1964  if (fi != NULL)
1965  while (rpmfiNext(fi) >= 0) {
1966  fcontext = rpmfiFContext(fi);
1967  av[ac++] = t;
1968  if (fcontext && *fcontext != '\0')
1969  t = stpcpy(t, fcontext);
1970  *t++ = '\0';
1971  }
1972  av[ac] = NULL; /* XXX tag arrays are not NULL terminated. */
1973 
1974 exit:
1975  fi = rpmfiFree(fi);
1976  if (fcontextp)
1977  *fcontextp = av;
1978  else
1979  av = _free(av);
1980  if (fcp) *fcp = ac;
1981 }
1982 
1983 void rpmfiBuildFSContexts(Header h,
1984  /*@out@*/ const char *** fcontextp, /*@out@*/ rpmuint32_t * fcp)
1985 {
1986  int scareMem = 0;
1987  rpmfi fi = rpmfiNew(NULL, h, RPMTAG_BASENAMES, scareMem);
1988  const char ** av;
1989  int ac;
1990  size_t nb;
1991  char * t;
1992  char * fctxt = NULL;
1993  size_t fctxtlen = 0;
1994  int * fcnb;
1995 
1996  if ((ac = rpmfiFC(fi)) <= 0) {
1997  av = NULL;
1998  ac = 0;
1999  goto exit;
2000  }
2001 
2002  /* Compute size of argv array blob, concatenating file contexts. */
2003  nb = ac * sizeof(*fcnb);
2004  fcnb = memset(alloca(nb), 0, nb);
2005  ac = 0;
2006  fi = rpmfiInit(fi, 0);
2007  if (fi != NULL)
2008  while (rpmfiNext(fi) >= 0) {
2009  const char *fn;
2010  security_context_t scon = NULL;
2011 
2012  fn = rpmfiFN(fi);
2013  fcnb[ac] = lgetfilecon(fn, &scon);
2014  if (fcnb[ac] > 0) {
2015  fctxt = (char *) xrealloc(fctxt, fctxtlen + fcnb[ac]);
2016  memcpy(fctxt+fctxtlen, scon, fcnb[ac]);
2017  fctxtlen += fcnb[ac];
2018  freecon(scon);
2019  }
2020  ac++;
2021  }
2022 
2023  /* Create and load argv array from concatenated file contexts. */
2024  nb = (ac + 1) * sizeof(*av) + fctxtlen;
2025  av = (const char **) xmalloc(nb);
2026  t = ((char *) av) + ((ac + 1) * sizeof(*av));
2027  if (fctxt != NULL && fctxtlen > 0)
2028  (void) memcpy(t, fctxt, fctxtlen);
2029  ac = 0;
2030  fi = rpmfiInit(fi, 0);
2031  if (fi != NULL)
2032  while (rpmfiNext(fi) >= 0) {
2033  av[ac] = "";
2034  if (fcnb[ac] > 0) {
2035  av[ac] = t;
2036  t += fcnb[ac];
2037  }
2038  ac++;
2039  }
2040  av[ac] = NULL; /* XXX tag arrays are not NULL terminated. */
2041 
2042 exit:
2043  fi = rpmfiFree(fi);
2044  if (fcontextp)
2045  *fcontextp = av;
2046  else
2047  av = _free(av);
2048  if (fcp) *fcp = ac;
2049 }
2050 
2051 void rpmfiBuildREContexts(Header h,
2052  /*@out@*/ const char *** fcontextp, /*@out@*/ rpmuint32_t * fcp)
2053 {
2054  int scareMem = 0;
2055  rpmfi fi = rpmfiNew(NULL, h, RPMTAG_BASENAMES, scareMem);
2056  const char ** av = NULL;
2057  int ac;
2058  size_t nb;
2059  char * t;
2060  char * fctxt = NULL;
2061  size_t fctxtlen = 0;
2062  int * fcnb;
2063 
2064  if ((ac = rpmfiFC(fi)) <= 0) {
2065  ac = 0;
2066  goto exit;
2067  }
2068 
2069  /* Read security context patterns. */
2070  { const char *fn = rpmGetPath("%{?__file_context_path}", NULL);
2071 /*@-moduncon -noeffectuncon @*/
2072  if (fn != NULL && *fn != '\0')
2073  (void)matchpathcon_init(fn);
2074 /*@=moduncon =noeffectuncon @*/
2075  fn = _free(fn);
2076  }
2077 
2078  /* Compute size of argv array blob, concatenating file contexts. */
2079  nb = ac * sizeof(*fcnb);
2080  fcnb = memset(alloca(nb), 0, nb);
2081  ac = 0;
2082  fi = rpmfiInit(fi, 0);
2083  if (fi != NULL)
2084  while (rpmfiNext(fi) >= 0) {
2085  const char *fn;
2086  mode_t fmode;
2087  security_context_t scon;
2088 
2089  fn = rpmfiFN(fi);
2090  fmode = rpmfiFMode(fi);
2091  scon = NULL;
2092 /*@-moduncon@*/
2093  if (matchpathcon(fn, fmode, &scon) == 0 && scon != NULL) {
2094  fcnb[ac] = strlen(scon) + 1;
2095  if (fcnb[ac] > 0) {
2096  fctxt = (char *) xrealloc(fctxt, fctxtlen + fcnb[ac]);
2097  memcpy(fctxt+fctxtlen, scon, fcnb[ac]);
2098  fctxtlen += fcnb[ac];
2099  }
2100  freecon(scon);
2101  }
2102 /*@=moduncon@*/
2103  ac++;
2104  }
2105 
2106  /* Create and load argv array from concatenated file contexts. */
2107  nb = (ac + 1) * sizeof(*av) + fctxtlen;
2108  av = (const char **) xmalloc(nb);
2109  t = ((char *) av) + ((ac + 1) * sizeof(*av));
2110  (void) memcpy(t, fctxt, fctxtlen);
2111  ac = 0;
2112  fi = rpmfiInit(fi, 0);
2113  if (fi != NULL)
2114  while (rpmfiNext(fi) >= 0) {
2115  av[ac] = "";
2116  if (fcnb[ac] > 0) {
2117  av[ac] = t;
2118  t += fcnb[ac];
2119  }
2120  ac++;
2121  }
2122  av[ac] = NULL; /* XXX tag arrays are not NULL terminated. */
2123 
2124 exit:
2125 /*@-moduncon -noeffectuncon @*/
2126  matchpathcon_fini();
2127 /*@=moduncon =noeffectuncon @*/
2128  fi = rpmfiFree(fi);
2129  if (fcontextp)
2130  *fcontextp = av;
2131  else
2132  av = _free(av);
2133  if (fcp) *fcp = ac;
2134 }
2135 #endif
2136 
2138  /*@out@*/ const char *** fdepsp, /*@out@*/ rpmuint32_t * fcp)
2139 {
2140  int scareMem = 0;
2141  rpmfi fi = rpmfiNew(NULL, h, RPMTAG_BASENAMES, scareMem);
2142  rpmds ds = NULL;
2143  const char ** av;
2144  int ac;
2145  size_t nb;
2146  char * t;
2147  char deptype = 'R';
2148  char mydt;
2149  const char * DNEVR;
2150  const rpmuint32_t * ddict;
2151  unsigned ix;
2152  int ndx;
2153 
2154  if ((ac = rpmfiFC(fi)) <= 0) {
2155  av = NULL;
2156  ac = 0;
2157  goto exit;
2158  }
2159 
2160  if (tagN == RPMTAG_PROVIDENAME)
2161  deptype = 'P';
2162  else if (tagN == RPMTAG_REQUIRENAME)
2163  deptype = 'R';
2164 
2165  ds = rpmdsNew(h, tagN, scareMem);
2166 
2167  /* Compute size of file depends argv array blob. */
2168  nb = (ac + 1) * sizeof(*av);
2169  fi = rpmfiInit(fi, 0);
2170  if (fi != NULL)
2171  while (rpmfiNext(fi) >= 0) {
2172  ddict = NULL;
2173  ndx = rpmfiFDepends(fi, &ddict);
2174  if (ddict != NULL)
2175  while (ndx-- > 0) {
2176  ix = *ddict++;
2177  mydt = ((ix >> 24) & 0xff);
2178  if (mydt != deptype)
2179  /*@innercontinue@*/ continue;
2180  ix &= 0x00ffffff;
2181  (void) rpmdsSetIx(ds, ix-1);
2182  if (rpmdsNext(ds) < 0)
2183  /*@innercontinue@*/ continue;
2184  DNEVR = rpmdsDNEVR(ds);
2185  if (DNEVR != NULL)
2186  nb += strlen(DNEVR+2) + 1;
2187  }
2188  nb += 1;
2189  }
2190 
2191  /* Create and load file depends argv array. */
2192  av = (const char **) xmalloc(nb);
2193  t = ((char *) av) + ((ac + 1) * sizeof(*av));
2194  ac = 0;
2195  fi = rpmfiInit(fi, 0);
2196  if (fi != NULL)
2197  while (rpmfiNext(fi) >= 0) {
2198  av[ac++] = t;
2199  ddict = NULL;
2200  ndx = rpmfiFDepends(fi, &ddict);
2201  if (ddict != NULL)
2202  while (ndx-- > 0) {
2203  ix = *ddict++;
2204  mydt = ((ix >> 24) & 0xff);
2205  if (mydt != deptype)
2206  /*@innercontinue@*/ continue;
2207  ix &= 0x00ffffff;
2208  (void) rpmdsSetIx(ds, ix-1);
2209  if (rpmdsNext(ds) < 0)
2210  /*@innercontinue@*/ continue;
2211  DNEVR = rpmdsDNEVR(ds);
2212  if (DNEVR != NULL) {
2213  t = stpcpy(t, DNEVR+2);
2214  *t++ = ' ';
2215  *t = '\0';
2216  }
2217  }
2218  *t++ = '\0';
2219  }
2220  av[ac] = NULL; /* XXX tag arrays are not NULL terminated. */
2221 
2222 exit:
2223  fi = rpmfiFree(fi);
2224  (void)rpmdsFree(ds);
2225  ds = NULL;
2226  if (fdepsp)
2227  *fdepsp = av;
2228  else
2229  av = _free(av);
2230  if (fcp) *fcp = ac;
2231 }
int rpmdsNext(rpmds ds)
Return next dependency set iterator index.
Definition: rpmds.c:912
rpmuint32_t rpmfiFFlags(rpmfi fi)
Return current file flags from file info set.
Definition: rpmfi.c:217
int headerMacrosUnload(Header h)
Define per-header macros.
Definition: hdrNVR.c:111
void * rpmfiInclude(const rpmfi fi)
Return file info include patterns.
Definition: rpmfi.c:499
rpmTagType t
Definition: rpmtag.h:502
Definition: iosm.h:34
int xx
Definition: spec.c:744
rpmTag tag
Definition: rpmtag.h:501
iter fi
Definition: fsm.c:170
rpmprobFilterFlags rpmtsFilterFlags(rpmts ts)
Get problem ignore bit mask, i.e.
Definition: rpmts.c:1327
const char ** argv
Definition: rpmtag.h:75
int rpmfiSetHeader(rpmfi fi, Header h)
Link a header to a file info set.
Definition: rpmfi.c:1275
rpmfileState rpmfiSetFState(rpmfi fi, rpmfileState fstate)
Set current file state in file info set.
Definition: rpmfi.c:287
#define headerFree(_h)
Definition: rpmtag.h:870
int rpmfiDX(rpmfi fi)
Return current directory index from file info set.
Definition: rpmfi.c:120
rpmlog(RPMLOG_ERR,"%s\n", buf)
struct rpmte_s * rpmte
An element of a transaction set, i.e.
Definition: rpmtypes.h:38
rpmuint32_t rpmfiVFlags(rpmfi fi)
Return current file verify flags from file info set.
Definition: rpmfi.c:241
void rpmfiFpLookup(rpmfi fi, fingerPrintCache fpc)
Definition: rpmfi.c:518
ia relocations
Definition: rpmts-py.c:805
void * mireFreeAll(miRE mire, int nmire)
Destroy compiled patterns.
Definition: mire.c:96
rpmuint32_t rpmfiSetFFlags(rpmfi fi, rpmuint32_t FFlags)
Set current file flags in file info set.
Definition: rpmfi.c:228
rpmuint32_t rpmfiFDepends(rpmfi fi, const rpmuint32_t **fddictp)
Return current file depends dictionary from file info set.
Definition: rpmfi.c:406
Definition: rpmfi.h:28
void rpmpsAppend(rpmps ps, rpmProblemType type, const char *pkgNEVR, fnpyKey key, const char *dn, const char *bn, const char *altNEVR, rpmuint64_t ulong1)
Append a problem to current set of problems.
Definition: rpmps.c:123
struct iosm_s * FSM_t
File state machine data.
Definition: fsm.h:14
enum iosmFileAction_e iosmFileAction
File disposition(s) during package install/erase processing.
static const char * rpmfiFtstring(rpmFileTypes ft)
Identify a file type.
Definition: rpmfi.c:602
rpmuint32_t rpmfiFNlink(rpmfi fi)
Return (calculated) current file nlink count from file info set.
Definition: rpmfi.c:427
Structures used for an &quot;rpmte&quot; transaction element.
char * xstrdup(const char *str)
Definition: rpmmalloc.c:321
char * rpmCleanPath(char *path)
Canonicalize file path.
Definition: macro.c:3279
rpmuint32_t * ui32p
Definition: rpmtag.h:70
int headerMod(Header h, HE_t he, unsigned int flags)
Modify tag container in header.
Definition: header.c:2318
char * rpmGetPath(const char *path,...)
Return (malloc&#39;ed) expanded, canonicalized, file path.
Definition: macro.c:3371
* lenp
Definition: header.c:1796
static char *size_t nb
fgets(3) analogue that reads \ continuations.
Definition: macro.c:409
struct rpmts_s * rpmts
The RPM Transaction Set.
Definition: rpmtypes.h:14
int rc
Definition: poptALL.c:670
The Header data structure.
headerSprintfExtension rpmHeaderFormats
Table of query format extensions.
Definition: formats.c:305
rpmuint16_t * ui16p
Definition: rpmtag.h:69
Definition: rpmfi.h:27
int rpmfiSetFX(rpmfi fi, int fx)
Set current file index in file info set.
Definition: rpmfi.c:108
size_t rpmfiFNMaxLen(rpmfi fi)
Return maximum file name length from file info set.
Definition: rpmfi.c:212
void * rpmfiFNBF(rpmfi fi)
Return FN Bloom filter from file info set.
Definition: rpmfi.c:181
fts m
Definition: rpmmtree.c:3827
static rpmfi rpmfiGetPool(rpmioPool pool)
Definition: rpmfi.c:1359
#define S_ISLNK(mode)
Definition: system.h:651
rpmuint16_t rpmfiFRdev(rpmfi fi)
Return current file rdev from file info set.
Definition: rpmfi.c:339
enum rpmTag_e rpmTag
Definition: rpmtag.h:468
rpmfi rpmfiFree(rpmfi fi)
Destroy a file info set.
const char * rpmfiFN(rpmfi fi)
Return current file name from file info set.
Definition: rpmfi.c:163
unsigned short rpmuint16_t
Definition: rpmiotypes.h:27
int rpmfiNInclude(const rpmfi fi)
Return no.
Definition: rpmfi.c:504
int rpmfiDecideFate(const rpmfi ofi, rpmfi nfi, int skipMissing)
Return file disposition.
Definition: rpmfi.c:671
int dodigest(int dalgo, const char *fn, unsigned char *digest, unsigned dflags, size_t *fsizep)
Return digest and size of a file.
Definition: legacy.c:178
const char * rpmfiFUser(rpmfi fi)
Return current file owner from file info set.
Definition: rpmfi.c:458
struct rpmps_s * rpmps
Transaction problems found while processing a transaction set/.
Definition: rpmps.h:25
struct rpmRelocation_s * rpmRelocation
Definition: rpmtypes.h:57
const char * rpmfiFGroup(rpmfi fi)
Return current file group from file info set.
Definition: rpmfi.c:470
rpmfi rpmfiNew(const void *_ts, Header h, rpmTag tagN, int flags)
Create and load a file info set.
Definition: rpmfi.c:1403
rpmds rpmdsNew(Header h, rpmTag tagN, int flags)
Create and load a dependency set.
Definition: rpmds.c:238
Header headerLink(Header h)
Reference a header instance.
int ac
Definition: rpmgrep.c:1431
#define S_ISSOCK(mode)
Definition: system.h:655
Header h
Definition: spec.c:739
rpmuint32_t rpmfiFColor(rpmfi fi)
Return current file color bits from file info set.
Definition: rpmfi.c:371
const char * rpmfiBN(rpmfi fi)
Return current base name from file info set.
Definition: rpmfi.c:141
repo _ts
Definition: rpmrepo.c:164
int rpmfiFC(rpmfi fi)
Return file count from file info set.
Definition: rpmfi.c:87
rpmuint32_t rpmfiFSize(rpmfi fi)
Return current file size from file info set.
Definition: rpmfi.c:328
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
Definition: rpmiotypes.h:26
static PyObject *char * mode
Definition: rpmfd-py.c:115
struct fingerPrint_s * rpmfiFpsIndex(rpmfi fi, int ix)
Definition: rpmfi.c:509
#define RPMFILE_STATE_MISSING
Definition: rpmfi.h:46
rpmuint32_t rpmfiSetVFlags(rpmfi fi, rpmuint32_t VFlags)
Set current file verify flags in file info set.
Definition: rpmfi.c:252
char * alloca()
const char * rpmfiTypeString(rpmfi fi)
Return formatted string representation of package disposition.
Definition: rpmfi.c:767
Yet Another syslog(3) API clone.
int rpmfiNextD(rpmfi fi)
Return next directory iterator index.
Definition: rpmfi.c:562
goto exit
Definition: db3.c:1903
memset(_r, 0, sizeof(*_r))
unsigned int rpmuint32_t
Definition: rpmiotypes.h:28
void * xcalloc(size_t nmemb, size_t size)
Definition: rpmmalloc.c:300
assert(key->size==sizeof(hdrNum))
void * ptr
Definition: rpmtag.h:67
const char * rpmfiDN(rpmfi fi)
Return current directory name from file info set.
Definition: rpmfi.c:152
int ix
Definition: rpmps-py.c:174
char * p
Definition: macro.c:413
char * headerSprintf(Header h, const char *fmt, headerTagTableEntry tags, headerSprintfExtension exts, errmsg_t *errmsg)
Return formatted output string from header tags.
Definition: hdrfmt.c:6748
int rpmdsSetIx(rpmds ds, int ix)
Set dependency set index.
Definition: rpmds.c:646
rpmioItem rpmioGetPool(rpmioPool pool, size_t size)
Get unused item from pool, or alloc a new item.
Definition: rpmmalloc.c:220
int headerIsEntry(Header h, rpmTag tag)
Check if tag is in header.
Definition: header.c:1438
fprintf(stderr,"--> %s(%p,%p,%p) sig %p sigp %p\n", __FUNCTION__, dig, t, rsactx, sig, sigp)
int gnameToGid(const char *thisGname, gid_t *gid)
Definition: ugid.c:71
enum rpmTagType_e rpmTagType
Definition: rpmtag.h:47
enum pgpHashAlgo_e pgpHashAlgo
9.4.
Definition: rpmfi.h:30
rpmte rpmtsRelocateElement(rpmts ts)
Get current relocate transaction element.
Definition: rpmts.c:1392
rpmuint16_t rpmfiFMode(rpmfi fi)
Return current file mode from file info set.
Definition: rpmfi.c:265
int Lstat(const char *path, struct stat *st)
lstat(2) clone.
Definition: rpmrpc.c:1401
rpmTagData p
Definition: rpmtag.h:504
ARGV_t argvFree(ARGV_t argv)
Destroy an argv array.
Definition: argv.c:44
struct miRE_s * miRE
Definition: mire.h:60
int rpmfiAddRelocation(rpmRelocation *relp, int *nrelp, const char *oldPath, const char *newPath)
Add relocation element to array.
Definition: rpmfi.c:1726
static Header relocateFileList(const rpmts ts, rpmfi fi, Header origH, iosmFileAction *actions)
Relocate files in header.
Definition: rpmfi.c:789
int headerMacrosLoad(Header h)
Define per-header macros.
Definition: hdrNVR.c:36
struct _HE_s * HE_t
Destroy an extension cache.
Definition: rpmtag.h:59
Structure(s) used for dependency tag sets.
int headerGet(Header h, HE_t he, unsigned int flags)
Retrieve extension or tag value from a header.
Definition: header.c:2230
void fpLookupList(fingerPrintCache cache, const char **dirNames, const char **baseNames, const rpmuint32_t *dirIndexes, rpmuint32_t fileCount, fingerPrint *fpList)
Return finger prints of an array of file paths.
Definition: fprint.c:230
int rpmfiIsSource(rpmfi fi)
Return source rpm marker from file info set.
Definition: rpmfi.c:136
void * rpmfiBloomFN(const rpmfi fi)
Return file path Bloom filter.
Definition: rpmfi.c:482
int headerPut(Header h, HE_t he, unsigned int flags)
Add or append tag container to header.
Definition: header.c:2293
const char * rpmGenPath(const char *urlroot, const char *urlmdir, const char *urlfile)
Merge 3 args into path, any or all of which may be a url.
Definition: macro.c:3417
const char * newPath
Definition: rpmfi.c:63
int argvAdd(ARGV_t *argvp, ARGstr_t val)
Add a string to an argv array.
Definition: argv.c:199
const char * rpmtsRootDir(rpmts ts)
Get transaction rootDir, i.e.
Definition: rpmts.c:901
rpmTagCount c
Definition: rpmtag.h:505
rpmuint32_t rpmfiFMtime(rpmfi fi)
Return current file modify time from file info set.
Definition: rpmfi.c:447
Identify a file name path by a unique &quot;finger print&quot;.
rpmRelocation rpmfiFreeRelocations(rpmRelocation relocs)
Free relocation array.
Definition: rpmfi.c:1738
spectags st
Definition: spec.c:741
int j
Definition: spec.c:743
char * n
Definition: macro.c:744
enum rpmFileTypes_e rpmFileTypes
File types.
static char * stripTrailingChar(char *s, char c)
Remove occurrences of trailing character from string.
Definition: rpmfi.c:76
struct rpmds_s * rpmds
Dependency tag sets from a header, so that a header can be discarded early.
Definition: rpmtypes.h:28
Definition: rpmte.h:37
Associates a trailing sub-directory and final base name with an existing directory finger print...
Definition: fprint.h:50
int rpmfiNext(rpmfi fi)
Return next file iterator index.
Definition: rpmfi.c:526
rpmps rpmpsFree(rpmps ps)
Destroy a problem set.
rpmds rpmdsFree(rpmds ds)
Destroy a dependency set.
static const char *char c
Return text between pl and matching pr characters.
Definition: macro.c:470
int Readlink(const char *path, char *buf, size_t bufsiz)
readlink(2) clone.
Definition: rpmrpc.c:2154
int rpmfiDC(rpmfi fi)
Return directory count from file info set.
Definition: rpmfi.c:92
void * rpmfiOpendir(rpmfi fi, const char *name)
Return directory stream onto file info set.
Definition: rpmfi.c:1834
Definition: rpmtag.h:500
rpmfi rpmfiInit(rpmfi fi, int fx)
Initialize file iterator index.
Definition: rpmfi.c:548
#define _fdupestring(_h, _tag, _data)
Definition: rpmfi.c:1392
enum rpmfileState_e rpmfileState
File States (when installed).
const char * rpmfiFClass(rpmfi fi)
Return current file class from file info set.
Definition: rpmfi.c:383
return strcmp(ame->name, bme->name)
int rpmfiNExclude(const rpmfi fi)
Return no.
Definition: rpmfi.c:494
const char * s
Definition: poptALL.c:734
char * t
Definition: rpmds.c:2716
urltype urlPath(const char *url, const char **pathp)
Return path component of URL.
Definition: url.c:430
rpmfi rpmfiLink(rpmfi fi, const char *msg)
Reference a file info set instance.
rpmioPool _rpmfiPool
Definition: poptALL.c:575
const char * rpmfiFLink(rpmfi fi)
Return current file linkto (i.e.
Definition: rpmfi.c:317
Definition: iosm.h:29
Definition: rpmfi.h:31
char * path
Definition: poptALL.c:744
rpmioPool rpmioNewPool(const char *name, size_t size, int limit, int flags, char *(*dbg)(void *item), void(*init)(void *item), void(*fini)(void *item))
Create a memory pool.
Definition: rpmmalloc.c:109
void rpmfiBuildFDeps(Header h, rpmTag tagN, const char ***fdepsp, rpmuint32_t *fcp)
Retrieve per-file dependencies from header.
Definition: rpmfi.c:2137
struct fprintCache_s * fingerPrintCache
Definition: fprint.h:13
char * be
Definition: macro.c:746
char * stpcpy(char *dest, const char *src)
Definition: rpmfi.h:32
if(__progname==NULL)
Definition: poptALL.c:683
te
Definition: macro.c:552
void * rpmfiExclude(const rpmfi fi)
Return file info exclude patterns.
Definition: rpmfi.c:489
IOSM_t newFSM(void)
Create file state machine instance.
Definition: fsm.c:551
ps
Definition: rpmts-py.c:548
Structures and prototypes used for an &quot;rpmts&quot; transaction set.
int flags
Definition: fnmatch.c:282
rpmfileState rpmfiFState(rpmfi fi)
Return current file state from file info set.
Definition: rpmfi.c:276
const char * rpmdsDNEVR(const rpmds ds)
Return current formatted dependency string.
Definition: rpmds.c:657
#define _fi(_a)
Definition: psm.h:30
File state machine to handle a payload within an rpm package.
rpmuint32_t rpmfiColor(rpmfi fi)
Return union of all file color bits from file info set.
Definition: rpmfi.c:361
rpmfi rpmfiInitD(rpmfi fi, int dx)
Initialize directory iterator index.
Definition: rpmfi.c:582
rpmElementType rpmteType(rpmte te)
Retrieve type of transaction element.
Definition: rpmte.c:311
rpmRelocation rpmfiDupeRelocations(rpmRelocation relocs, int *nrelocsp)
Duplicate a relocation array.
Definition: rpmfi.c:1751
#define _fdupedata(_h, _tag, _cast, _data)
Definition: rpmfi.c:1397
const unsigned char * rpmfiDigest(rpmfi fi, int *algop, size_t *lenp)
Return current file (binary) digest from file info set.
Definition: rpmfi.c:300
Definition: rpmfi.h:29
IOSM_t freeFSM(IOSM_t fsm)
Destroy file state machine instance.
Definition: fsm.c:557
return NULL
Definition: poptALL.c:613
#define alloca_strdup(_s)
Definition: rpmfi.c:777
int rpmfiCompare(const rpmfi afi, const rpmfi bfi)
Return file info comparison.
Definition: rpmfi.c:637
static rpmFileTypes rpmfiWhatis(rpmuint16_t mode)
Return file type from mode_t.
Definition: rpmfi.c:623
static void
Print copy of spec file, filling in Group/Description/Summary from specspo.
Definition: spec.c:737
void rpmfiBuildFClasses(Header h, const char ***fclassp, rpmuint32_t *fcp)
Retrieve file classes from header.
Definition: rpmfi.c:1878
k
Definition: rpmmtree.c:394
static const char * name
const char * rpmteNEVR(rpmte te)
Retrieve name-version-release string from transaction element.
Definition: rpmte.c:536
char * b
Definition: macro.c:746
int
Save source and expand field into target.
Definition: rpmds.c:2709
struct rpmfi_s * rpmfi
File info tag sets from a header, so that a header can be discarded early.
Definition: rpmfi.h:83
#define xmalloc
Definition: system.h:32
static unsigned char nibble(char c)
Convert hex to binary nibble.
Definition: rpmfi.c:1380
fnpyKey rpmteKey(rpmte te)
Retrieve key from transaction element.
Definition: rpmte.c:568
rpmuint32_t rpmfiFInode(rpmfi fi)
Return current file inode from file info set.
Definition: rpmfi.c:350
int rpmfiStat(rpmfi fi, const char *path, struct stat *st)
Return lstat(2) data of path from file info set.
Definition: rpmfi.c:1803
int unameToUid(const char *thisUname, uid_t *uid)
Definition: ugid.c:16
const char * rpmfiFContext(rpmfi fi)
Return current file security context from file info set.
Definition: rpmfi.c:395
#define D_(Text)
Definition: system.h:526
Definition: rpmfi.h:33
int rpmfiFStat(rpmfi fi, struct stat *st)
Return current stat(2) data from file info set.
Definition: rpmfi.c:1776
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:647
int _rpmfi_debug
Definition: rpmfi.c:67
int i
Definition: spec.c:743
const char * oldPath
Definition: rpmfi.c:61
int rpmfiFX(rpmfi fi)
Return current file index from file info set.
Definition: rpmfi.c:103
int rpmExpandNumeric(const char *arg)
Return macro expansion as a numeric value.
Definition: macro.c:3252
const char ** av
Definition: rpmts-py.c:788
#define xrealloc
Definition: system.h:35
File name and stat information.
Definition: iosm.h:218
size_t fn
Definition: macro.c:1698
static void rpmfiFini(void *_fi)
Definition: rpmfi.c:1287
int rpmfiSetDX(rpmfi fi, int dx)
Set current directory index in file info set.
Definition: rpmfi.c:125
int len
Definition: rpmdb-py.c:119
static PyObject *rpmds ds
Definition: rpmte-py.c:283
rpmps rpmtsProblems(rpmts ts)
Return current transaction set problems.
Definition: rpmts.c:582
const unsigned char * digest
Definition: rpmfi-py.c:247
Definition: iosm.h:33