3 * Routines to handle file info tag sets.
8 #include "fsm.h" /* XXX newFSM and CPIO_MAP_* */
11 #include "misc.h" /* XXX stripTrailingChar */
16 /*@access transactionElement @*/
17 /*@access rpmTransactionSet @*/ /* XXX for ts->ignoreSet and ts->probs */
20 static int _fi_debug = 0;
22 TFI_t XrpmfiUnlink(TFI_t fi, const char * msg, const char * fn, unsigned ln)
24 if (fi == NULL) return NULL;
26 if (_fi_debug && msg != NULL)
27 fprintf(stderr, "--> fi %p -- %d %s at %s:%u\n", fi, fi->nrefs, msg, fn, ln);
33 TFI_t XrpmfiLink(TFI_t fi, const char * msg, const char * fn, unsigned ln)
35 if (fi == NULL) return NULL;
38 if (_fi_debug && msg != NULL)
39 fprintf(stderr, "--> fi %p ++ %d %s at %s:%u\n", fi, fi->nrefs, msg, fn, ln);
41 /*@-refcounttrans@*/ return fi; /*@=refcounttrans@*/
44 fnpyKey rpmfiGetKey(TFI_t fi)
46 return (fi != NULL ? teGetKey(fi->te) : NULL);
49 int tfiGetFC(TFI_t fi)
51 return (fi != NULL ? fi->fc : 0);
54 int tfiGetDC(TFI_t fi)
56 return (fi != NULL ? fi->dc : 0);
60 int tfiGetDI(TFI_t fi)
65 int tfiGetFX(TFI_t fi)
67 return (fi != NULL ? fi->i : -1);
70 int tfiSetFX(TFI_t fi, int fx)
74 if (fi != NULL && fx >= 0 && fx < fi->fc) {
77 fi->j = fi->dil[fi->i];
82 int tfiGetDX(TFI_t fi)
84 return (fi != NULL ? fi->j : -1);
87 int tfiSetDX(TFI_t fi, int dx)
91 if (fi != NULL && dx >= 0 && dx < fi->dc) {
98 const char * tfiGetBN(TFI_t fi)
100 const char * BN = NULL;
102 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
109 const char * tfiGetDN(TFI_t fi)
111 const char * DN = NULL;
113 if (fi != NULL && fi->j >= 0 && fi->j < fi->dc) {
120 const char * tfiGetFN(TFI_t fi)
122 const char * FN = "";
125 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
128 fi->fn = xmalloc(fi->fnlen);
131 t = stpcpy(t, fi->dnl[fi->dil[fi->i]]);
132 t = stpcpy(t, fi->bnl[fi->i]);
138 int_32 tfiGetFFlags(TFI_t fi)
142 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
143 if (fi->fflags != NULL)
144 FFlags = fi->fflags[fi->i];
149 int_32 tfiGetVFlags(TFI_t fi)
153 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
154 if (fi->vflags != NULL)
155 VFlags = fi->vflags[fi->i];
160 int_16 tfiGetFMode(TFI_t fi)
164 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
165 if (fi->fmodes != NULL)
166 fmode = fi->fmodes[fi->i];
171 rpmfileState tfiGetFState(TFI_t fi)
175 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
176 if (fi->fstates != NULL)
177 fstate = fi->fstates[fi->i];
182 const unsigned char * tfiGetMD5(TFI_t fi)
184 unsigned char * md5 = NULL;
186 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
187 if (fi->md5s != NULL)
188 md5 = fi->md5s + (16 * fi->i);
193 const char * tfiGetFLink(TFI_t fi)
195 const char * flink = NULL;
197 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
198 if (fi->flinks != NULL)
199 flink = fi->flinks[fi->i];
204 int_32 tfiGetFSize(TFI_t fi)
208 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
209 if (fi->fsizes != NULL)
210 fsize = fi->fsizes[fi->i];
215 int_16 tfiGetFRdev(TFI_t fi)
219 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
220 if (fi->frdevs != NULL)
221 frdev = fi->frdevs[fi->i];
226 int_32 tfiGetFMtime(TFI_t fi)
230 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
231 if (fi->fmtimes != NULL)
232 fmtime = fi->fmtimes[fi->i];
237 const char * tfiGetFUser(TFI_t fi)
239 const char * fuser = NULL;
241 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
242 if (fi->fuser != NULL)
243 fuser = fi->fuser[fi->i];
248 const char * tfiGetFGroup(TFI_t fi)
250 const char * fgroup = NULL;
252 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
253 if (fi->fgroup != NULL)
254 fgroup = fi->fgroup[fi->i];
259 int tfiNext(TFI_t fi)
263 if (fi != NULL && ++fi->i >= 0) {
264 if (fi->i < fi->fc) {
267 fi->j = fi->dil[fi->i];
271 /*@-modfilesystem @*/
272 if (_fi_debug < 0 && i != -1)
273 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] : ""));
274 /*@=modfilesystem @*/
281 TFI_t tfiInit(TFI_t fi, int fx)
284 if (fx >= 0 && fx < fi->fc) {
299 int tdiNext(TFI_t fi)
303 if (fi != NULL && ++fi->j >= 0) {
309 /*@-modfilesystem @*/
310 if (_fi_debug < 0 && j != -1)
311 fprintf(stderr, "*** fi %p\t%s[%d]\n", fi, (fi->Type ? fi->Type : "?Type?"), j);
312 /*@=modfilesystem @*/
319 TFI_t tdiInit(TFI_t fi, int dx)
322 if (dx >= 0 && dx < fi->fc)
334 * Identify a file type.
335 * @param ft file type
336 * @return string to identify a file type
338 static /*@observer@*/
339 const char *const ftstring (fileTypes ft)
343 case XDIR: return "directory";
344 case CDEV: return "char dev";
345 case BDEV: return "block dev";
346 case LINK: return "link";
347 case SOCK: return "sock";
348 case PIPE: return "fifo/pipe";
349 case REG: return "file";
350 default: return "unknown file type";
355 fileTypes whatis(uint_16 mode)
357 if (S_ISDIR(mode)) return XDIR;
358 if (S_ISCHR(mode)) return CDEV;
359 if (S_ISBLK(mode)) return BDEV;
360 if (S_ISLNK(mode)) return LINK;
361 if (S_ISSOCK(mode)) return SOCK;
362 if (S_ISFIFO(mode)) return PIPE;
366 #define alloca_strdup(_s) strcpy(alloca(strlen(_s)+1), (_s))
369 * Relocate files in header.
370 * @todo multilib file dispositions need to be checked.
371 * @param ts transaction set
372 * @param fi transaction element file info
373 * @param origH package header
374 * @param actions file dispositions
375 * @return header with relocated files
378 Header relocateFileList(const rpmTransactionSet ts, TFI_t fi,
379 Header origH, fileAction * actions)
380 /*@modifies ts, fi, origH, actions @*/
382 transactionElement p = fi->te;
386 HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
387 static int _printed = 0;
388 int allowBadRelocate = (ts->ignoreSet & RPMPROB_FILTER_FORCERELOCATE);
389 rpmRelocation * relocations = NULL;
391 const char ** validRelocations;
392 rpmTagType validType;
394 const char ** baseNames;
395 const char ** dirNames;
397 int_32 * newDirIndexes;
400 uint_32 * fFlags = NULL;
401 uint_16 * fModes = NULL;
407 int haveRelocatedFile = 0;
412 if (!hge(origH, RPMTAG_PREFIXES, &validType,
413 (void **) &validRelocations, &numValid))
418 while (p->relocs[numRelocations].newPath ||
419 p->relocs[numRelocations].oldPath)
423 * If no relocations are specified (usually the case), then return the
424 * original header. If there are prefixes, however, then INSTPREFIXES
425 * should be added, but, since relocateFileList() can be called more
426 * than once for the same header, don't bother if already present.
428 if (p->relocs == NULL || numRelocations == 0) {
430 if (!headerIsEntry(origH, RPMTAG_INSTPREFIXES))
431 xx = hae(origH, RPMTAG_INSTPREFIXES,
432 validType, validRelocations, numValid);
433 validRelocations = hfd(validRelocations, validType);
435 /* XXX FIXME multilib file actions need to be checked. */
436 return headerLink(origH, "relocate(return)");
439 h = headerLink(origH, "relocate(orig)");
441 relocations = alloca(sizeof(*relocations) * numRelocations);
443 /* Build sorted relocation list from raw relocations. */
444 for (i = 0; i < numRelocations; i++) {
448 * Default relocations (oldPath == NULL) are handled in the UI,
451 if (p->relocs[i].oldPath == NULL) continue; /* XXX can't happen */
453 /* FIXME: Trailing /'s will confuse us greatly. Internal ones will
454 too, but those are more trouble to fix up. :-( */
455 t = alloca_strdup(p->relocs[i].oldPath);
457 relocations[i].oldPath = (t[0] == '/' && t[1] == '\0')
459 : stripTrailingChar(t, '/');
462 /* An old path w/o a new path is valid, and indicates exclusion */
463 if (p->relocs[i].newPath) {
466 t = alloca_strdup(p->relocs[i].newPath);
468 relocations[i].newPath = (t[0] == '/' && t[1] == '\0')
470 : stripTrailingChar(t, '/');
473 /*@-nullpass@*/ /* FIX: relocations[i].oldPath == NULL */
474 /* Verify that the relocation's old path is in the header. */
475 for (j = 0; j < numValid; j++) {
476 if (!strcmp(validRelocations[j], relocations[i].oldPath))
477 /*@innerbreak@*/ break;
480 /* XXX actions check prevents problem from being appended twice. */
481 if (j == numValid && !allowBadRelocate && actions) {
482 rpmProblemSetAppend(ts->probs, RPMPROB_BADRELOCATE,
484 relocations[i].oldPath, NULL, NULL, 0);
487 strlen(relocations[i].newPath) - strlen(relocations[i].oldPath);
493 relocations[i].newPath = NULL;
497 /* stupid bubble sort, but it's probably faster here */
498 for (i = 0; i < numRelocations; i++) {
501 for (j = 1; j < numRelocations; j++) {
502 rpmRelocation tmpReloc;
503 if (relocations[j - 1].oldPath == NULL || /* XXX can't happen */
504 relocations[j ].oldPath == NULL || /* XXX can't happen */
505 strcmp(relocations[j - 1].oldPath, relocations[j].oldPath) <= 0)
506 /*@innercontinue@*/ continue;
507 /*@-usereleased@*/ /* LCL: ??? */
508 tmpReloc = relocations[j - 1];
509 relocations[j - 1] = relocations[j];
510 relocations[j] = tmpReloc;
514 if (!madeSwap) break;
519 rpmMessage(RPMMESS_DEBUG, _("========== relocations\n"));
520 for (i = 0; i < numRelocations; i++) {
521 if (relocations[i].oldPath == NULL) continue; /* XXX can't happen */
522 if (relocations[i].newPath == NULL)
523 rpmMessage(RPMMESS_DEBUG, _("%5d exclude %s\n"),
524 i, relocations[i].oldPath);
526 rpmMessage(RPMMESS_DEBUG, _("%5d relocate %s -> %s\n"),
527 i, relocations[i].oldPath, relocations[i].newPath);
531 /* Add relocation values to the header */
533 const char ** actualRelocations;
536 actualRelocations = xmalloc(numValid * sizeof(*actualRelocations));
538 for (i = 0; i < numValid; i++) {
539 for (j = 0; j < numRelocations; j++) {
540 if (relocations[j].oldPath == NULL || /* XXX can't happen */
541 strcmp(validRelocations[i], relocations[j].oldPath))
542 /*@innercontinue@*/ continue;
543 /* On install, a relocate to NULL means skip the path. */
544 if (relocations[j].newPath) {
545 actualRelocations[numActual] = relocations[j].newPath;
548 /*@innerbreak@*/ break;
550 if (j == numRelocations) {
551 actualRelocations[numActual] = validRelocations[i];
557 xx = hae(h, RPMTAG_INSTPREFIXES, RPM_STRING_ARRAY_TYPE,
558 (void **) actualRelocations, numActual);
560 actualRelocations = _free(actualRelocations);
561 validRelocations = hfd(validRelocations, validType);
564 xx = hge(h, RPMTAG_BASENAMES, NULL, (void **) &baseNames, &fileCount);
565 xx = hge(h, RPMTAG_DIRINDEXES, NULL, (void **) &dirIndexes, NULL);
566 xx = hge(h, RPMTAG_DIRNAMES, NULL, (void **) &dirNames, &dirCount);
567 xx = hge(h, RPMTAG_FILEFLAGS, NULL, (void **) &fFlags, NULL);
568 xx = hge(h, RPMTAG_FILEMODES, NULL, (void **) &fModes, NULL);
570 skipDirList = alloca(dirCount * sizeof(*skipDirList));
571 memset(skipDirList, 0, dirCount * sizeof(*skipDirList));
573 newDirIndexes = alloca(sizeof(*newDirIndexes) * fileCount);
574 memcpy(newDirIndexes, dirIndexes, sizeof(*newDirIndexes) * fileCount);
575 dirIndexes = newDirIndexes;
578 * For all relocations, we go through sorted file/relocation lists
579 * backwards so that /usr/local relocations take precedence over /usr
583 /* Relocate individual paths. */
585 for (i = fileCount - 1; i >= 0; i--) {
590 * If only adding libraries of different arch into an already
591 * installed package, skip all other files.
593 if (p->multiLib && !isFileMULTILIB((fFlags[i]))) {
595 actions[i] = FA_SKIPMULTILIB;
596 rpmMessage(RPMMESS_DEBUG, _("excluding multilib path %s%s\n"),
597 dirNames[dirIndexes[i]], baseNames[i]);
603 strlen(dirNames[dirIndexes[i]]) + strlen(baseNames[i]) + 1;
605 if (len >= fileAlloced) {
606 fileAlloced = len * 2;
607 fn = xrealloc(fn, fileAlloced);
611 fnlen = stpcpy( stpcpy(fn, dirNames[dirIndexes[i]]), baseNames[i]) - fn;
614 * See if this file path needs relocating.
617 * XXX FIXME: Would a bsearch of the (already sorted)
618 * relocation list be a good idea?
620 for (j = numRelocations - 1; j >= 0; j--) {
621 if (relocations[j].oldPath == NULL) /* XXX can't happen */
622 /*@innercontinue@*/ continue;
623 len = strcmp(relocations[j].oldPath, "/")
624 ? strlen(relocations[j].oldPath)
628 /*@innercontinue@*/ continue;
630 * Only subdirectories or complete file paths may be relocated. We
631 * don't check for '\0' as our directory names all end in '/'.
633 if (!(fn[len] == '/' || fnlen == len))
634 /*@innercontinue@*/ continue;
636 if (strncmp(relocations[j].oldPath, fn, len))
637 /*@innercontinue@*/ continue;
638 /*@innerbreak@*/ break;
642 ft = whatis(fModes[i]);
644 /* On install, a relocate to NULL means skip the path. */
645 if (relocations[j].newPath == NULL) {
647 /* Start with the parent, looking for directory to exclude. */
648 for (j = dirIndexes[i]; j < dirCount; j++) {
649 len = strlen(dirNames[j]) - 1;
650 while (len > 0 && dirNames[j][len-1] == '/') len--;
652 /*@innercontinue@*/ continue;
653 if (strncmp(fn, dirNames[j], fnlen))
654 /*@innercontinue@*/ continue;
655 /*@innerbreak@*/ break;
661 actions[i] = FA_SKIPNSTATE;
662 rpmMessage(RPMMESS_DEBUG, _("excluding %s %s\n"),
668 /* Relocation on full paths only, please. */
669 if (fnlen != len) continue;
672 rpmMessage(RPMMESS_DEBUG, _("relocating %s to %s\n"),
673 fn, relocations[j].newPath);
676 strcpy(fn, relocations[j].newPath);
677 { char * te = strrchr(fn, '/');
679 if (te > fn) te++; /* root is special */
682 te = fn + strlen(fn);
683 /*@-nullpass -nullderef@*/ /* LCL: te != NULL here. */
684 if (strcmp(baseNames[i], te)) /* basename changed too? */
685 baseNames[i] = alloca_strdup(te);
686 *te = '\0'; /* terminate new directory name */
687 /*@=nullpass =nullderef@*/
690 /* Does this directory already exist in the directory list? */
691 for (j = 0; j < dirCount; j++) {
692 if (fnlen != strlen(dirNames[j]))
693 /*@innercontinue@*/ continue;
694 if (strncmp(fn, dirNames[j], fnlen))
695 /*@innercontinue@*/ continue;
696 /*@innerbreak@*/ break;
704 /* Creating new paths is a pita */
705 if (!haveRelocatedFile) {
706 const char ** newDirList;
708 haveRelocatedFile = 1;
709 newDirList = xmalloc((dirCount + 1) * sizeof(*newDirList));
710 for (j = 0; j < dirCount; j++)
711 newDirList[j] = alloca_strdup(dirNames[j]);
712 dirNames = hfd(dirNames, RPM_STRING_ARRAY_TYPE);
713 dirNames = newDirList;
715 dirNames = xrealloc(dirNames,
716 sizeof(*dirNames) * (dirCount + 1));
719 dirNames[dirCount] = alloca_strdup(fn);
720 dirIndexes[i] = dirCount;
724 /* Finish off by relocating directories. */
725 for (i = dirCount - 1; i >= 0; i--) {
726 for (j = numRelocations - 1; j >= 0; j--) {
728 if (relocations[j].oldPath == NULL) /* XXX can't happen */
729 /*@innercontinue@*/ continue;
730 len = strcmp(relocations[j].oldPath, "/")
731 ? strlen(relocations[j].oldPath)
734 if (len && strncmp(relocations[j].oldPath, dirNames[i], len))
735 /*@innercontinue@*/ continue;
738 * Only subdirectories or complete file paths may be relocated. We
739 * don't check for '\0' as our directory names all end in '/'.
741 if (dirNames[i][len] != '/')
742 /*@innercontinue@*/ continue;
744 if (relocations[j].newPath) { /* Relocate the path */
745 const char * s = relocations[j].newPath;
746 char * t = alloca(strlen(s) + strlen(dirNames[i]) - len + 1);
748 (void) stpcpy( stpcpy(t, s) , dirNames[i] + len);
750 rpmMessage(RPMMESS_DEBUG,
751 _("relocating directory %s to %s\n"), dirNames[i], t);
758 /* Save original filenames in header and replace (relocated) filenames. */
765 xx = hge(h, RPMTAG_BASENAMES, &t, &d, &c);
766 xx = hae(h, RPMTAG_ORIGBASENAMES, t, d, c);
770 xx = hge(h, RPMTAG_DIRNAMES, &t, &d, &c);
771 xx = hae(h, RPMTAG_ORIGDIRNAMES, t, d, c);
775 xx = hge(h, RPMTAG_DIRINDEXES, &t, &d, &c);
776 xx = hae(h, RPMTAG_ORIGDIRINDEXES, t, d, c);
779 xx = hme(h, RPMTAG_BASENAMES, RPM_STRING_ARRAY_TYPE,
780 baseNames, fileCount);
781 fi->bnl = hfd(fi->bnl, RPM_STRING_ARRAY_TYPE);
782 xx = hge(h, RPMTAG_BASENAMES, NULL, (void **) &fi->bnl, &fi->fc);
784 xx = hme(h, RPMTAG_DIRNAMES, RPM_STRING_ARRAY_TYPE,
786 fi->dnl = hfd(fi->dnl, RPM_STRING_ARRAY_TYPE);
787 xx = hge(h, RPMTAG_DIRNAMES, NULL, (void **) &fi->dnl, &fi->dc);
789 xx = hme(h, RPMTAG_DIRINDEXES, RPM_INT32_TYPE,
790 dirIndexes, fileCount);
791 xx = hge(h, RPMTAG_DIRINDEXES, NULL, (void **) &fi->dil, NULL);
794 baseNames = hfd(baseNames, RPM_STRING_ARRAY_TYPE);
795 dirNames = hfd(dirNames, RPM_STRING_ARRAY_TYPE);
801 TFI_t fiFree(TFI_t fi, int freefimem)
803 HFD_t hfd = headerFreeData;
805 if (fi == NULL) return NULL;
808 return rpmfiUnlink(fi, fi->Type);
812 fprintf(stderr, "*** fi %p\t%s[%d]\n", fi, fi->Type, fi->fc);
817 fi->bnl = hfd(fi->bnl, -1);
818 fi->dnl = hfd(fi->dnl, -1);
820 fi->flinks = hfd(fi->flinks, -1);
821 fi->flangs = hfd(fi->flangs, -1);
822 fi->fmd5s = hfd(fi->fmd5s, -1);
823 fi->md5s = _free(fi->md5s);
825 fi->fuser = hfd(fi->fuser, -1);
826 fi->fuids = _free(fi->fuids);
827 fi->fgroup = hfd(fi->fgroup, -1);
828 fi->fgids = _free(fi->fgids);
830 fi->fstates = _free(fi->fstates);
833 if (!fi->keep_header && fi->h == NULL) {
834 fi->fmtimes = _free(fi->fmtimes);
835 fi->fmodes = _free(fi->fmodes);
836 fi->fflags = _free(fi->fflags);
837 fi->vflags = _free(fi->vflags);
838 fi->fsizes = _free(fi->fsizes);
839 fi->frdevs = _free(fi->frdevs);
840 fi->dil = _free(fi->dil);
846 fi->fsm = freeFSM(fi->fsm);
848 fi->fn = _free(fi->fn);
849 fi->apath = _free(fi->apath);
850 fi->fmapflags = _free(fi->fmapflags);
852 fi->obnl = hfd(fi->obnl, -1);
853 fi->odnl = hfd(fi->odnl, -1);
855 fi->actions = _free(fi->actions);
856 fi->replacedSizes = _free(fi->replacedSizes);
857 fi->replaced = _free(fi->replaced);
859 fi->h = headerFree(fi->h, fi->Type);
861 /*@-nullstate -refcounttrans -usereleased@*/
862 (void) rpmfiUnlink(fi, fi->Type);
865 memset(fi, 0, sizeof(*fi)); /* XXX trash and burn */
869 /*@=nullstate =refcounttrans =usereleased@*/
875 * Convert hex to binary nibble.
876 * @param c hex character
877 * @return binary nibble
879 static inline unsigned char nibble(char c)
882 if (c >= '0' && c <= '9')
884 if (c >= 'A' && c <= 'F')
885 return (c - 'A') + 10;
886 if (c >= 'a' && c <= 'f')
887 return (c - 'a') + 10;
891 #define _fdupe(_fi, _data) \
892 if ((_fi)->_data != NULL) \
893 (_fi)->_data = memcpy(xmalloc((_fi)->fc * sizeof(*(_fi)->_data)), \
894 (_fi)->_data, (_fi)->fc * sizeof(*(_fi)->_data))
896 TFI_t fiNew(rpmTransactionSet ts, TFI_t fi,
897 Header h, rpmTag tagN, int scareMem)
900 (scareMem ? (HGE_t) headerGetEntryMinMemory : (HGE_t) headerGetEntry);
901 HFD_t hfd = headerFreeData;
911 if (tagN == RPMTAG_BASENAMES) {
920 fi = xcalloc(1, sizeof(*fi));
921 malloced = 0; /* XXX always return with memory alloced. */
925 fi->magic = TFIMAGIC;
931 fi->hae = (HAE_t) headerAddEntry;
932 fi->hme = (HME_t) headerModifyEntry;
933 fi->hre = (HRE_t) headerRemoveEntry;
934 fi->hfd = headerFreeData;
936 fi->h = (scareMem ? headerLink(h, fi->Type) : NULL);
941 /* 0 means unknown */
942 xx = hge(h, RPMTAG_ARCHIVESIZE, NULL, (void **) &uip, NULL);
943 fi->archiveSize = (xx ? *uip : 0);
945 if (!hge(h, RPMTAG_BASENAMES, NULL, (void **) &fi->bnl, &fi->fc)) {
948 if (scareMem && fi->h)
949 fi->h = headerFree(fi->h, fi->Type);
950 fi->fsm = freeFSM(fi->fsm);
961 xx = hge(h, RPMTAG_DIRNAMES, NULL, (void **) &fi->dnl, &fi->dc);
962 xx = hge(h, RPMTAG_DIRINDEXES, NULL, (void **) &fi->dil, NULL);
963 xx = hge(h, RPMTAG_FILEMODES, NULL, (void **) &fi->fmodes, NULL);
964 xx = hge(h, RPMTAG_FILEFLAGS, NULL, (void **) &fi->fflags, NULL);
965 xx = hge(h, RPMTAG_FILEVERIFYFLAGS, NULL, (void **) &fi->vflags, NULL);
966 xx = hge(h, RPMTAG_FILESIZES, NULL, (void **) &fi->fsizes, NULL);
967 xx = hge(h, RPMTAG_FILESTATES, NULL, (void **) &fi->fstates, NULL);
968 if (xx == 0 || fi->fstates == NULL)
969 fi->fstates = xcalloc(fi->fc, sizeof(*fi->fstates));
973 fi->action = FA_UNKNOWN;
975 if (fi->actions == NULL)
976 fi->actions = xcalloc(fi->fc, sizeof(*fi->actions));
977 fi->keep_header = (scareMem ? 1 : 0);
979 /* XXX TR_REMOVED needs CPIO_MAP_{ABSOLUTE,ADDDOT} CPIO_ALL_HARDLINKS */
981 CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
983 xx = hge(h, RPMTAG_FILELINKTOS, NULL, (void **) &fi->flinks, NULL);
984 xx = hge(h, RPMTAG_FILELANGS, NULL, (void **) &fi->flangs, NULL);
986 xx = hge(h, RPMTAG_FILEMD5S, NULL, (void **) &fi->fmd5s, NULL);
987 t = xmalloc(fi->fc * 16);
989 for (i = 0; i < fi->fc; i++) {
994 if (!(fmd5 && *fmd5 != '\0')) {
999 for (j = 0; j < 16; j++, t++, fmd5 += 2)
1000 *t = (nibble(fmd5[0]) << 4) | nibble(fmd5[1]);
1002 fi->fmd5s = hfd(fi->fmd5s, -1);
1004 /* XXX TR_REMOVED doesn;t need fmtimes or frdevs */
1005 xx = hge(h, RPMTAG_FILEMTIMES, NULL, (void **) &fi->fmtimes, NULL);
1006 xx = hge(h, RPMTAG_FILERDEVS, NULL, (void **) &fi->frdevs, NULL);
1007 fi->replacedSizes = xcalloc(fi->fc, sizeof(*fi->replacedSizes));
1009 xx = hge(h, RPMTAG_FILEUSERNAME, NULL, (void **) &fi->fuser, NULL);
1011 xx = hge(h, RPMTAG_FILEGROUPNAME, NULL, (void **) &fi->fgroup, NULL);
1016 if (fi->te != NULL && fi->te->type == TR_ADDED) {
1018 fi->actions = xcalloc(fi->fc, sizeof(*fi->actions));
1019 /*@-compdef@*/ /* FIX: fi-md5s undefined */
1020 foo = relocateFileList(ts, fi, h, fi->actions);
1022 fi->h = headerFree(fi->h, "fiNew fi->h");
1023 fi->h = headerLink(foo, "fiNew fi->h = foo");
1024 foo = headerFree(foo, "fiNew foo");
1028 _fdupe(fi, fmtimes);
1035 fi->h = headerFree(fi->h, fi->Type);
1039 for (i = 0; i < fi->dc; i++) {
1040 if ((len = strlen(fi->dnl[i])) > dnlmax)
1044 for (i = 0; i < fi->fc; i++) {
1045 if ((len = strlen(fi->bnl[i])) > bnlmax)
1048 fi->fnlen = dnlmax + bnlmax + 1;
1055 /*@-modfilesystem@*/
1057 fprintf(stderr, "*** fi %p\t%s[%d]\n", fi, Type, (fi ? fi->fc : 0));
1058 /*@=modfilesystem@*/
1060 /*@-compdef -nullstate@*/ /* FIX: TFI null annotations */
1061 return rpmfiLink(fi, (fi ? fi->Type : NULL));
1062 /*@=compdef =nullstate@*/