00001
00006 #include "system.h"
00007
00008 #include <rpmio_internal.h>
00009 #include <rpmlib.h>
00010
00011 #include "cpio.h"
00012 #include "fsm.h"
00013
00014 #include "rpmds.h"
00015
00016 #include "legacy.h"
00017
00018 #define _RPMFI_INTERNAL
00019 #include "rpmfi.h"
00020
00021 #include "rpmsx.h"
00022
00023 #define _RPMTE_INTERNAL
00024 #include "rpmte.h"
00025 #include "rpmts.h"
00026
00027 #include "misc.h"
00028 #include "rpmmacro.h"
00029
00030 #include "debug.h"
00031
00032
00033
00034
00035 int _rpmfi_debug = 0;
00036
00037 rpmfi XrpmfiUnlink(rpmfi fi, const char * msg, const char * fn, unsigned ln)
00038 {
00039 if (fi == NULL) return NULL;
00040
00041 if (_rpmfi_debug && msg != NULL)
00042 fprintf(stderr, "--> fi %p -- %d %s at %s:%u\n", fi, fi->nrefs, msg, fn, ln);
00043
00044 fi->nrefs--;
00045 return NULL;
00046 }
00047
00048 rpmfi XrpmfiLink(rpmfi fi, const char * msg, const char * fn, unsigned ln)
00049 {
00050 if (fi == NULL) return NULL;
00051 fi->nrefs++;
00052
00053 if (_rpmfi_debug && msg != NULL)
00054 fprintf(stderr, "--> fi %p ++ %d %s at %s:%u\n", fi, fi->nrefs, msg, fn, ln);
00055
00056 return fi;
00057 }
00058
00059 int rpmfiFC(rpmfi fi)
00060 {
00061 return (fi != NULL ? fi->fc : 0);
00062 }
00063
00064 int rpmfiDC(rpmfi fi)
00065 {
00066 return (fi != NULL ? fi->dc : 0);
00067 }
00068
00069 #ifdef NOTYET
00070 int rpmfiDI(rpmfi fi)
00071 {
00072 }
00073 #endif
00074
00075 int rpmfiFX(rpmfi fi)
00076 {
00077 return (fi != NULL ? fi->i : -1);
00078 }
00079
00080 int rpmfiSetFX(rpmfi fi, int fx)
00081 {
00082 int i = -1;
00083
00084 if (fi != NULL && fx >= 0 && fx < fi->fc) {
00085 i = fi->i;
00086 fi->i = fx;
00087
00088 fi->j = fi->dil[fi->i];
00089
00090 }
00091 return i;
00092 }
00093
00094 int rpmfiDX(rpmfi fi)
00095 {
00096 return (fi != NULL ? fi->j : -1);
00097 }
00098
00099 int rpmfiSetDX(rpmfi fi, int dx)
00100 {
00101 int j = -1;
00102
00103 if (fi != NULL && dx >= 0 && dx < fi->dc) {
00104 j = fi->j;
00105 fi->j = dx;
00106 }
00107 return j;
00108 }
00109
00110 const char * rpmfiBN(rpmfi fi)
00111 {
00112 const char * BN = NULL;
00113
00114 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
00115
00116 if (fi->bnl != NULL)
00117 BN = fi->bnl[fi->i];
00118
00119 }
00120 return BN;
00121 }
00122
00123 const char * rpmfiDN(rpmfi fi)
00124 {
00125 const char * DN = NULL;
00126
00127 if (fi != NULL && fi->j >= 0 && fi->j < fi->dc) {
00128
00129 if (fi->dnl != NULL)
00130 DN = fi->dnl[fi->j];
00131
00132 }
00133 return DN;
00134 }
00135
00136 const char * rpmfiFN(rpmfi fi)
00137 {
00138 const char * FN = "";
00139
00140
00141 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
00142 char * t;
00143 if (fi->fn == NULL)
00144 fi->fn = xmalloc(fi->fnlen);
00145 FN = t = fi->fn;
00146
00147 *t = '\0';
00148 t = stpcpy(t, fi->dnl[fi->dil[fi->i]]);
00149 t = stpcpy(t, fi->bnl[fi->i]);
00150
00151 }
00152
00153 return FN;
00154 }
00155
00156 int_32 rpmfiFFlags(rpmfi fi)
00157 {
00158 int_32 FFlags = 0;
00159
00160 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
00161
00162 if (fi->fflags != NULL)
00163 FFlags = fi->fflags[fi->i];
00164
00165 }
00166 return FFlags;
00167 }
00168
00169 int_32 rpmfiVFlags(rpmfi fi)
00170 {
00171 int_32 VFlags = 0;
00172
00173 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
00174
00175 if (fi->vflags != NULL)
00176 VFlags = fi->vflags[fi->i];
00177
00178 }
00179 return VFlags;
00180 }
00181
00182 int_16 rpmfiFMode(rpmfi fi)
00183 {
00184 int_16 fmode = 0;
00185
00186 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
00187
00188 if (fi->fmodes != NULL)
00189 fmode = fi->fmodes[fi->i];
00190
00191 }
00192 return fmode;
00193 }
00194
00195 rpmfileState rpmfiFState(rpmfi fi)
00196 {
00197 rpmfileState fstate = RPMFILE_STATE_MISSING;
00198
00199 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
00200
00201 if (fi->fstates != NULL)
00202 fstate = fi->fstates[fi->i];
00203
00204 }
00205 return fstate;
00206 }
00207
00208 const unsigned char * rpmfiMD5(rpmfi fi)
00209 {
00210 unsigned char * MD5 = NULL;
00211
00212 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
00213
00214 if (fi->md5s != NULL)
00215 MD5 = fi->md5s + (16 * fi->i);
00216
00217 }
00218 return MD5;
00219 }
00220
00221 const char * rpmfiFLink(rpmfi fi)
00222 {
00223 const char * flink = NULL;
00224
00225 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
00226
00227 if (fi->flinks != NULL)
00228 flink = fi->flinks[fi->i];
00229
00230 }
00231 return flink;
00232 }
00233
00234 int_32 rpmfiFSize(rpmfi fi)
00235 {
00236 int_32 fsize = 0;
00237
00238 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
00239
00240 if (fi->fsizes != NULL)
00241 fsize = fi->fsizes[fi->i];
00242
00243 }
00244 return fsize;
00245 }
00246
00247 int_16 rpmfiFRdev(rpmfi fi)
00248 {
00249 int_16 frdev = 0;
00250
00251 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
00252
00253 if (fi->frdevs != NULL)
00254 frdev = fi->frdevs[fi->i];
00255
00256 }
00257 return frdev;
00258 }
00259
00260 int_32 rpmfiFInode(rpmfi fi)
00261 {
00262 int_32 finode = 0;
00263
00264 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
00265
00266 if (fi->finodes != NULL)
00267 finode = fi->finodes[fi->i];
00268
00269 }
00270 return finode;
00271 }
00272
00273 uint_32 rpmfiColor(rpmfi fi)
00274 {
00275 uint_32 color = 0;
00276
00277 if (fi != NULL)
00278
00279 color = fi->color & 0xf;
00280 return color;
00281 }
00282
00283 uint_32 rpmfiFColor(rpmfi fi)
00284 {
00285 uint_32 fcolor = 0;
00286
00287 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
00288
00289 if (fi->fcolors != NULL)
00290
00291 fcolor = (fi->fcolors[fi->i] & 0x0f);
00292
00293 }
00294 return fcolor;
00295 }
00296
00297 const char * rpmfiFClass(rpmfi fi)
00298 {
00299 const char * fclass = NULL;
00300 int cdictx;
00301
00302 if (fi != NULL && fi->fcdictx != NULL && fi->i >= 0 && fi->i < fi->fc) {
00303
00304 cdictx = fi->fcdictx[fi->i];
00305 if (fi->cdict != NULL && cdictx >= 0 && cdictx < fi->ncdict)
00306 fclass = fi->cdict[cdictx];
00307
00308 }
00309 return fclass;
00310 }
00311
00312 const char * rpmfiFContext(rpmfi fi)
00313 {
00314 const char * fcontext = NULL;
00315
00316 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
00317
00318 if (fi->fcontexts != NULL)
00319 fcontext = fi->fcontexts[fi->i];
00320
00321 }
00322 return fcontext;
00323 }
00324
00325 int_32 rpmfiFDepends(rpmfi fi, const int_32 ** fddictp)
00326 {
00327 int fddictx = -1;
00328 int fddictn = 0;
00329 const int_32 * fddict = NULL;
00330
00331 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
00332
00333 if (fi->fddictn != NULL)
00334 fddictn = fi->fddictn[fi->i];
00335 if (fddictn > 0 && fi->fddictx != NULL)
00336 fddictx = fi->fddictx[fi->i];
00337 if (fi->ddict != NULL && fddictx >= 0 && (fddictx+fddictn) <= fi->nddict)
00338 fddict = fi->ddict + fddictx;
00339
00340 }
00341
00342 if (fddictp)
00343 *fddictp = fddict;
00344
00345 return fddictn;
00346 }
00347
00348 int_32 rpmfiFNlink(rpmfi fi)
00349 {
00350 int_32 nlink = 0;
00351
00352 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
00353
00354
00355 if (fi->finodes && fi->frdevs) {
00356 int_32 finode = fi->finodes[fi->i];
00357 int_16 frdev = fi->frdevs[fi->i];
00358 int j;
00359
00360 for (j = 0; j < fi->fc; j++) {
00361 if (fi->frdevs[j] == frdev && fi->finodes[j] == finode)
00362 nlink++;
00363 }
00364 }
00365
00366 }
00367 return nlink;
00368 }
00369
00370 int_32 rpmfiFMtime(rpmfi fi)
00371 {
00372 int_32 fmtime = 0;
00373
00374 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
00375
00376 if (fi->fmtimes != NULL)
00377 fmtime = fi->fmtimes[fi->i];
00378
00379 }
00380 return fmtime;
00381 }
00382
00383 const char * rpmfiFUser(rpmfi fi)
00384 {
00385 const char * fuser = NULL;
00386
00387
00388 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
00389
00390 if (fi->fuser != NULL)
00391 fuser = fi->fuser[fi->i];
00392
00393 }
00394 return fuser;
00395 }
00396
00397 const char * rpmfiFGroup(rpmfi fi)
00398 {
00399 const char * fgroup = NULL;
00400
00401
00402 if (fi != NULL && fi->i >= 0 && fi->i < fi->fc) {
00403
00404 if (fi->fgroup != NULL)
00405 fgroup = fi->fgroup[fi->i];
00406
00407 }
00408 return fgroup;
00409 }
00410
00411 int rpmfiNext(rpmfi fi)
00412 {
00413 int i = -1;
00414
00415 if (fi != NULL && ++fi->i >= 0) {
00416 if (fi->i < fi->fc) {
00417 i = fi->i;
00418
00419 if (fi->dil != NULL)
00420 fi->j = fi->dil[fi->i];
00421
00422 } else
00423 fi->i = -1;
00424
00425
00426 if (_rpmfi_debug < 0 && i != -1)
00427 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] : ""));
00428
00429
00430 }
00431
00432 return i;
00433 }
00434
00435 rpmfi rpmfiInit(rpmfi fi, int fx)
00436 {
00437 if (fi != NULL) {
00438 if (fx >= 0 && fx < fi->fc) {
00439 fi->i = fx - 1;
00440 fi->j = -1;
00441 }
00442 }
00443
00444
00445 return fi;
00446
00447 }
00448
00449 int rpmfiNextD(rpmfi fi)
00450 {
00451 int j = -1;
00452
00453 if (fi != NULL && ++fi->j >= 0) {
00454 if (fi->j < fi->dc)
00455 j = fi->j;
00456 else
00457 fi->j = -1;
00458
00459
00460 if (_rpmfi_debug < 0 && j != -1)
00461 fprintf(stderr, "*** fi %p\t%s[%d]\n", fi, (fi->Type ? fi->Type : "?Type?"), j);
00462
00463
00464 }
00465
00466 return j;
00467 }
00468
00469 rpmfi rpmfiInitD(rpmfi fi, int dx)
00470 {
00471 if (fi != NULL) {
00472 if (dx >= 0 && dx < fi->fc)
00473 fi->j = dx - 1;
00474 else
00475 fi = NULL;
00476 }
00477
00478
00479 return fi;
00480
00481 }
00482
00488 static
00489 const char *const ftstring (fileTypes ft)
00490
00491 {
00492 switch (ft) {
00493 case XDIR: return "directory";
00494 case CDEV: return "char dev";
00495 case BDEV: return "block dev";
00496 case LINK: return "link";
00497 case SOCK: return "sock";
00498 case PIPE: return "fifo/pipe";
00499 case REG: return "file";
00500 default: return "unknown file type";
00501 }
00502
00503 }
00504
00505 fileTypes whatis(uint_16 mode)
00506 {
00507 if (S_ISDIR(mode)) return XDIR;
00508 if (S_ISCHR(mode)) return CDEV;
00509 if (S_ISBLK(mode)) return BDEV;
00510 if (S_ISLNK(mode)) return LINK;
00511
00512 if (S_ISSOCK(mode)) return SOCK;
00513
00514 if (S_ISFIFO(mode)) return PIPE;
00515 return REG;
00516 }
00517
00518
00519 int rpmfiCompare(const rpmfi afi, const rpmfi bfi)
00520
00521 {
00522 fileTypes awhat = whatis(rpmfiFMode(afi));
00523 fileTypes bwhat = whatis(rpmfiFMode(bfi));
00524
00525 if (awhat != bwhat) return 1;
00526
00527 if (awhat == LINK) {
00528 const char * alink = rpmfiFLink(afi);
00529 const char * blink = rpmfiFLink(bfi);
00530 if (alink == blink) return 0;
00531 if (alink == NULL) return 1;
00532 if (blink == NULL) return -1;
00533 return strcmp(alink, blink);
00534 } else if (awhat == REG) {
00535 const unsigned char * amd5 = rpmfiMD5(afi);
00536 const unsigned char * bmd5 = rpmfiMD5(bfi);
00537 if (amd5 == bmd5) return 0;
00538 if (amd5 == NULL) return 1;
00539 if (bmd5 == NULL) return -1;
00540 return memcmp(amd5, bmd5, 16);
00541 }
00542
00543 return 0;
00544 }
00545
00546
00547
00548 fileAction rpmfiDecideFate(const rpmfi ofi, rpmfi nfi, int skipMissing)
00549 {
00550 const char * fn = rpmfiFN(nfi);
00551 int newFlags = rpmfiFFlags(nfi);
00552 char buffer[1024];
00553 fileTypes dbWhat, newWhat, diskWhat;
00554 struct stat sb;
00555 int save = (newFlags & RPMFILE_NOREPLACE) ? FA_ALTNAME : FA_SAVE;
00556
00557 if (lstat(fn, &sb)) {
00558
00559
00560
00561
00562 if (skipMissing && (newFlags & RPMFILE_MISSINGOK)) {
00563 rpmMessage(RPMMESS_DEBUG, _("%s skipped due to missingok flag\n"),
00564 fn);
00565 return FA_SKIP;
00566 } else {
00567 return FA_CREATE;
00568 }
00569 }
00570
00571 diskWhat = whatis((int_16)sb.st_mode);
00572 dbWhat = whatis(rpmfiFMode(ofi));
00573 newWhat = whatis(rpmfiFMode(nfi));
00574
00575
00576
00577
00578
00579 if (newWhat == XDIR)
00580 return FA_CREATE;
00581
00582 if (diskWhat != newWhat)
00583 return save;
00584 else if (newWhat != dbWhat && diskWhat != dbWhat)
00585 return save;
00586 else if (dbWhat != newWhat)
00587 return FA_CREATE;
00588 else if (dbWhat != LINK && dbWhat != REG)
00589 return FA_CREATE;
00590
00591
00592
00593
00594
00595 memset(buffer, 0, sizeof(buffer));
00596 if (dbWhat == REG) {
00597 const unsigned char * omd5, * nmd5;
00598
00599 if (strcmp(fn, "/var/log/lastlog"))
00600 if (domd5(fn, buffer, 0, NULL))
00601 return FA_CREATE;
00602 omd5 = rpmfiMD5(ofi);
00603 if (omd5 && !memcmp(omd5, buffer, 16))
00604 return FA_CREATE;
00605 nmd5 = rpmfiMD5(nfi);
00606
00607 if (omd5 && nmd5 && !memcmp(omd5, nmd5, 16))
00608 return FA_SKIP;
00609
00610 } else {
00611 const char * oFLink, * nFLink;
00612 if (readlink(fn, buffer, sizeof(buffer) - 1) == -1)
00613 return FA_CREATE;
00614 oFLink = rpmfiFLink(ofi);
00615 if (oFLink && !strcmp(oFLink, buffer))
00616 return FA_CREATE;
00617 nFLink = rpmfiFLink(nfi);
00618
00619 if (oFLink && nFLink && !strcmp(oFLink, nFLink))
00620 return FA_SKIP;
00621
00622 }
00623
00624
00625
00626
00627
00628
00629
00630 return save;
00631 }
00632
00633
00634
00635 const char *const rpmfiTypeString(rpmfi fi)
00636 {
00637 switch(rpmteType(fi->te)) {
00638 case TR_ADDED: return " install";
00639 case TR_REMOVED: return " erase";
00640 default: return "???";
00641 }
00642
00643 }
00644
00645 #define alloca_strdup(_s) strcpy(alloca(strlen(_s)+1), (_s))
00646
00656
00657 static
00658 Header relocateFileList(const rpmts ts, rpmfi fi,
00659 Header origH, fileAction * actions)
00660
00661
00662 {
00663 rpmte p = rpmtsRelocateElement(ts);
00664 HGE_t hge = fi->hge;
00665 HAE_t hae = fi->hae;
00666 HME_t hme = fi->hme;
00667 HFD_t hfd = (fi->hfd ? fi->hfd : headerFreeData);
00668 static int _printed = 0;
00669 int allowBadRelocate = (rpmtsFilterFlags(ts) & RPMPROB_FILTER_FORCERELOCATE);
00670 rpmRelocation * relocations = NULL;
00671 int numRelocations;
00672 const char ** validRelocations;
00673 rpmTagType validType;
00674 int numValid;
00675 const char ** baseNames;
00676 const char ** dirNames;
00677 int_32 * dirIndexes;
00678 int_32 * newDirIndexes;
00679 int_32 fileCount;
00680 int_32 dirCount;
00681 uint_32 mydColor = rpmExpandNumeric("%{?_autorelocate_dcolor}");
00682 uint_32 * fFlags = NULL;
00683 uint_32 * fColors = NULL;
00684 uint_32 * dColors = NULL;
00685 uint_16 * fModes = NULL;
00686 Header h;
00687 int nrelocated = 0;
00688 int fileAlloced = 0;
00689 char * fn = NULL;
00690 int haveRelocatedFile = 0;
00691 int reldel = 0;
00692 int len;
00693 int i, j, xx;
00694
00695 if (!hge(origH, RPMTAG_PREFIXES, &validType,
00696 (void **) &validRelocations, &numValid))
00697 numValid = 0;
00698
00699 assert(p != NULL);
00700 numRelocations = 0;
00701 if (p->relocs)
00702 while (p->relocs[numRelocations].newPath ||
00703 p->relocs[numRelocations].oldPath)
00704 numRelocations++;
00705
00706
00707
00708
00709
00710
00711
00712 if (p->relocs == NULL || numRelocations == 0) {
00713 if (numValid) {
00714 if (!headerIsEntry(origH, RPMTAG_INSTPREFIXES))
00715 xx = hae(origH, RPMTAG_INSTPREFIXES,
00716 validType, validRelocations, numValid);
00717 validRelocations = hfd(validRelocations, validType);
00718 }
00719
00720 return headerLink(origH);
00721 }
00722
00723 h = headerLink(origH);
00724
00725 relocations = alloca(sizeof(*relocations) * numRelocations);
00726
00727
00728 for (i = 0; i < numRelocations; i++) {
00729 char * t;
00730
00731
00732
00733
00734
00735 if (p->relocs[i].oldPath == NULL) continue;
00736
00737
00738
00739 t = alloca_strdup(p->relocs[i].oldPath);
00740
00741 relocations[i].oldPath = (t[0] == '/' && t[1] == '\0')
00742 ? t
00743 : stripTrailingChar(t, '/');
00744
00745
00746
00747 if (p->relocs[i].newPath) {
00748 int del;
00749
00750 t = alloca_strdup(p->relocs[i].newPath);
00751
00752 relocations[i].newPath = (t[0] == '/' && t[1] == '\0')
00753 ? t
00754 : stripTrailingChar(t, '/');
00755
00756
00757
00758
00759 for (j = 0; j < numValid; j++) {
00760 if (!strcmp(validRelocations[j], relocations[i].oldPath))
00761 break;
00762 }
00763
00764
00765 if (j == numValid && !allowBadRelocate && actions) {
00766 rpmps ps = rpmtsProblems(ts);
00767 rpmpsAppend(ps, RPMPROB_BADRELOCATE,
00768 rpmteNEVR(p), rpmteKey(p),
00769 relocations[i].oldPath, NULL, NULL, 0);
00770 ps = rpmpsFree(ps);
00771 }
00772 del =
00773 strlen(relocations[i].newPath) - strlen(relocations[i].oldPath);
00774
00775
00776 if (del > reldel)
00777 reldel = del;
00778 } else {
00779 relocations[i].newPath = NULL;
00780 }
00781 }
00782
00783
00784 for (i = 0; i < numRelocations; i++) {
00785 int madeSwap;
00786 madeSwap = 0;
00787 for (j = 1; j < numRelocations; j++) {
00788 rpmRelocation tmpReloc;
00789 if (relocations[j - 1].oldPath == NULL ||
00790 relocations[j ].oldPath == NULL ||
00791 strcmp(relocations[j - 1].oldPath, relocations[j].oldPath) <= 0)
00792 continue;
00793
00794 tmpReloc = relocations[j - 1];
00795 relocations[j - 1] = relocations[j];
00796 relocations[j] = tmpReloc;
00797
00798 madeSwap = 1;
00799 }
00800 if (!madeSwap) break;
00801 }
00802
00803 if (!_printed) {
00804 _printed = 1;
00805 rpmMessage(RPMMESS_DEBUG, _("========== relocations\n"));
00806 for (i = 0; i < numRelocations; i++) {
00807 if (relocations[i].oldPath == NULL) continue;
00808 if (relocations[i].newPath == NULL)
00809 rpmMessage(RPMMESS_DEBUG, _("%5d exclude %s\n"),
00810 i, relocations[i].oldPath);
00811 else
00812 rpmMessage(RPMMESS_DEBUG, _("%5d relocate %s -> %s\n"),
00813 i, relocations[i].oldPath, relocations[i].newPath);
00814 }
00815 }
00816
00817
00818 if (numValid) {
00819 const char ** actualRelocations;
00820 int numActual;
00821
00822 actualRelocations = xmalloc(numValid * sizeof(*actualRelocations));
00823 numActual = 0;
00824 for (i = 0; i < numValid; i++) {
00825 for (j = 0; j < numRelocations; j++) {
00826 if (relocations[j].oldPath == NULL ||
00827 strcmp(validRelocations[i], relocations[j].oldPath))
00828 continue;
00829
00830 if (relocations[j].newPath) {
00831 actualRelocations[numActual] = relocations[j].newPath;
00832 numActual++;
00833 }
00834 break;
00835 }
00836 if (j == numRelocations) {
00837 actualRelocations[numActual] = validRelocations[i];
00838 numActual++;
00839 }
00840 }
00841
00842 if (numActual)
00843 xx = hae(h, RPMTAG_INSTPREFIXES, RPM_STRING_ARRAY_TYPE,
00844 (void **) actualRelocations, numActual);
00845
00846 actualRelocations = _free(actualRelocations);
00847 validRelocations = hfd(validRelocations, validType);
00848 }
00849
00850 xx = hge(h, RPMTAG_BASENAMES, NULL, (void **) &baseNames, &fileCount);
00851 xx = hge(h, RPMTAG_DIRINDEXES, NULL, (void **) &dirIndexes, NULL);
00852 xx = hge(h, RPMTAG_DIRNAMES, NULL, (void **) &dirNames, &dirCount);
00853 xx = hge(h, RPMTAG_FILEFLAGS, NULL, (void **) &fFlags, NULL);
00854 xx = hge(h, RPMTAG_FILECOLORS, NULL, (void **) &fColors, NULL);
00855 xx = hge(h, RPMTAG_FILEMODES, NULL, (void **) &fModes, NULL);
00856
00857 dColors = alloca(dirCount * sizeof(*dColors));
00858 memset(dColors, 0, dirCount * sizeof(*dColors));
00859
00860 newDirIndexes = alloca(sizeof(*newDirIndexes) * fileCount);
00861 memcpy(newDirIndexes, dirIndexes, sizeof(*newDirIndexes) * fileCount);
00862 dirIndexes = newDirIndexes;
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872 for (i = fileCount - 1; i >= 0; i--) {
00873 fileTypes ft;
00874 int fnlen;
00875
00876 len = reldel +
00877 strlen(dirNames[dirIndexes[i]]) + strlen(baseNames[i]) + 1;
00878
00879 if (len >= fileAlloced) {
00880 fileAlloced = len * 2;
00881 fn = xrealloc(fn, fileAlloced);
00882 }
00883
00884
00885 assert(fn != NULL);
00886 *fn = '\0';
00887 fnlen = stpcpy( stpcpy(fn, dirNames[dirIndexes[i]]), baseNames[i]) - fn;
00888
00889 if (fColors != NULL) {
00890
00891 for (j = 0; j < dirCount; j++) {
00892 if (strcmp(dirNames[dirIndexes[i]], dirNames[j])) continue;
00893 dColors[j] |= fColors[i];
00894 }
00895 }
00896
00897
00898
00899
00900
00901
00902
00903
00904 for (j = numRelocations - 1; j >= 0; j--) {
00905 if (relocations[j].oldPath == NULL)
00906 continue;
00907 len = strcmp(relocations[j].oldPath, "/")
00908 ? strlen(relocations[j].oldPath)
00909 : 0;
00910
00911 if (fnlen < len)
00912 continue;
00913
00914
00915
00916
00917 if (!(fn[len] == '/' || fnlen == len))
00918 continue;
00919
00920 if (strncmp(relocations[j].oldPath, fn, len))
00921 continue;
00922 break;
00923 }
00924 if (j < 0) continue;
00925
00926
00927 ft = whatis(fModes[i]);
00928
00929
00930
00931 if (relocations[j].newPath == NULL) {
00932 if (ft == XDIR) {
00933
00934 for (j = dirIndexes[i]; j < dirCount; j++) {
00935 len = strlen(dirNames[j]) - 1;
00936 while (len > 0 && dirNames[j][len-1] == '/') len--;
00937 if (fnlen != len)
00938 continue;
00939 if (strncmp(fn, dirNames[j], fnlen))
00940 continue;
00941 break;
00942 }
00943 }
00944 if (actions) {
00945 actions[i] = FA_SKIPNSTATE;
00946 rpmMessage(RPMMESS_DEBUG, _("excluding %s %s\n"),
00947 ftstring(ft), fn);
00948 }
00949 continue;
00950 }
00951
00952
00953 if (fnlen != len) continue;
00954
00955 if (actions)
00956 rpmMessage(RPMMESS_DEBUG, _("relocating %s to %s\n"),
00957 fn, relocations[j].newPath);
00958 nrelocated++;
00959
00960 strcpy(fn, relocations[j].newPath);
00961 { char * te = strrchr(fn, '/');
00962 if (te) {
00963 if (te > fn) te++;
00964 fnlen = te - fn;
00965 } else
00966 te = fn + strlen(fn);
00967
00968 if (strcmp(baseNames[i], te))
00969 baseNames[i] = alloca_strdup(te);
00970 *te = '\0';
00971
00972 }
00973
00974
00975 for (j = 0; j < dirCount; j++) {
00976 if (fnlen != strlen(dirNames[j]))
00977 continue;
00978 if (strncmp(fn, dirNames[j], fnlen))
00979 continue;
00980 break;
00981 }
00982
00983 if (j < dirCount) {
00984 dirIndexes[i] = j;
00985 continue;
00986 }
00987
00988
00989 if (!haveRelocatedFile) {
00990 const char ** newDirList;
00991
00992 haveRelocatedFile = 1;
00993 newDirList = xmalloc((dirCount + 1) * sizeof(*newDirList));
00994 for (j = 0; j < dirCount; j++)
00995 newDirList[j] = alloca_strdup(dirNames[j]);
00996 dirNames = hfd(dirNames, RPM_STRING_ARRAY_TYPE);
00997 dirNames = newDirList;
00998 } else {
00999 dirNames = xrealloc(dirNames,
01000 sizeof(*dirNames) * (dirCount + 1));
01001 }
01002
01003 dirNames[dirCount] = alloca_strdup(fn);
01004 dirIndexes[i] = dirCount;
01005 dirCount++;
01006 }
01007
01008
01009 for (i = dirCount - 1; i >= 0; i--) {
01010 for (j = numRelocations - 1; j >= 0; j--) {
01011
01012
01013 if (j == p->autorelocatex
01014 && (dColors[i] == 0 || !(dColors[i] & mydColor)))
01015 continue;
01016
01017 if (relocations[j].oldPath == NULL)
01018 continue;
01019 len = strcmp(relocations[j].oldPath, "/")
01020 ? strlen(relocations[j].oldPath)
01021 : 0;
01022
01023 if (len && strncmp(relocations[j].oldPath, dirNames[i], len))
01024 continue;
01025
01026
01027
01028
01029
01030 if (dirNames[i][len] != '/')
01031 continue;
01032
01033 if (relocations[j].newPath) {
01034 const char * s = relocations[j].newPath;
01035 char * t = alloca(strlen(s) + strlen(dirNames[i]) - len + 1);
01036 size_t slen;
01037
01038 (void) stpcpy( stpcpy(t, s) , dirNames[i] + len);
01039
01040
01041 (void) rpmCleanPath(t);
01042 slen = strlen(t);
01043 t[slen] = '/';
01044 t[slen+1] = '\0';
01045
01046 if (actions)
01047 rpmMessage(RPMMESS_DEBUG,
01048 _("relocating directory %s to %s\n"), dirNames[i], t);
01049 dirNames[i] = t;
01050 nrelocated++;
01051 }
01052 }
01053 }
01054
01055
01056 if (nrelocated) {
01057 int c;
01058 void * d;
01059 rpmTagType t;
01060
01061 d = NULL;
01062 xx = hge(h, RPMTAG_BASENAMES, &t, &d, &c);
01063 xx = hae(h, RPMTAG_ORIGBASENAMES, t, d, c);
01064 d = hfd(d, t);
01065
01066 d = NULL;
01067 xx = hge(h, RPMTAG_DIRNAMES, &t, &d, &c);
01068 xx = hae(h, RPMTAG_ORIGDIRNAMES, t, d, c);
01069 d = hfd(d, t);
01070
01071 d = NULL;
01072 xx = hge(h, RPMTAG_DIRINDEXES, &t, &d, &c);
01073 xx = hae(h, RPMTAG_ORIGDIRINDEXES, t, d, c);
01074 d = hfd(d, t);
01075
01076 xx = hme(h, RPMTAG_BASENAMES, RPM_STRING_ARRAY_TYPE,
01077 baseNames, fileCount);
01078 fi->bnl = hfd(fi->bnl, RPM_STRING_ARRAY_TYPE);
01079 xx = hge(h, RPMTAG_BASENAMES, NULL, (void **) &fi->bnl, &fi->fc);
01080
01081 xx = hme(h, RPMTAG_DIRNAMES, RPM_STRING_ARRAY_TYPE,
01082 dirNames, dirCount);
01083 fi->dnl = hfd(fi->dnl, RPM_STRING_ARRAY_TYPE);
01084 xx = hge(h, RPMTAG_DIRNAMES, NULL, (void **) &fi->dnl, &fi->dc);
01085
01086 xx = hme(h, RPMTAG_DIRINDEXES, RPM_INT32_TYPE,
01087 dirIndexes, fileCount);
01088 xx = hge(h, RPMTAG_DIRINDEXES, NULL, (void **) &fi->dil, NULL);
01089 }
01090
01091 baseNames = hfd(baseNames, RPM_STRING_ARRAY_TYPE);
01092 dirNames = hfd(dirNames, RPM_STRING_ARRAY_TYPE);
01093
01094 fn = _free(fn);
01095
01096
01097 return h;
01098 }
01099
01100
01101 rpmfi rpmfiFree(rpmfi fi)
01102 {
01103 HFD_t hfd = headerFreeData;
01104
01105 if (fi == NULL) return NULL;
01106
01107 if (fi->nrefs > 1)
01108 return rpmfiUnlink(fi, fi->Type);
01109
01110
01111 if (_rpmfi_debug < 0)
01112 fprintf(stderr, "*** fi %p\t%s[%d]\n", fi, fi->Type, fi->fc);
01113
01114
01115
01116 fi->pretrans = _free(fi->pretrans);
01117 fi->pretransprog = _free(fi->pretransprog);
01118 fi->posttrans = _free(fi->posttrans);
01119 fi->posttransprog = _free(fi->posttransprog);
01120
01121
01122 if (fi->fc > 0) {
01123 fi->bnl = hfd(fi->bnl, -1);
01124 fi->dnl = hfd(fi->dnl, -1);
01125
01126 fi->flinks = hfd(fi->flinks, -1);
01127 fi->flangs = hfd(fi->flangs, -1);
01128 fi->fmd5s = hfd(fi->fmd5s, -1);
01129 fi->md5s = _free(fi->md5s);
01130
01131 fi->cdict = hfd(fi->cdict, -1);
01132
01133 fi->fuser = hfd(fi->fuser, -1);
01134 fi->fgroup = hfd(fi->fgroup, -1);
01135
01136 fi->fstates = _free(fi->fstates);
01137
01138
01139 if (!fi->keep_header && fi->h == NULL) {
01140 fi->fmtimes = _free(fi->fmtimes);
01141 fi->fmodes = _free(fi->fmodes);
01142 fi->fflags = _free(fi->fflags);
01143 fi->vflags = _free(fi->vflags);
01144 fi->fsizes = _free(fi->fsizes);
01145 fi->frdevs = _free(fi->frdevs);
01146 fi->finodes = _free(fi->finodes);
01147 fi->dil = _free(fi->dil);
01148
01149 fi->fcolors = _free(fi->fcolors);
01150 fi->fcdictx = _free(fi->fcdictx);
01151 fi->ddict = _free(fi->ddict);
01152 fi->fddictx = _free(fi->fddictx);
01153 fi->fddictn = _free(fi->fddictn);
01154
01155 }
01156
01157 }
01158
01159
01160 fi->fsm = freeFSM(fi->fsm);
01161
01162 fi->fn = _free(fi->fn);
01163 fi->apath = _free(fi->apath);
01164 fi->fmapflags = _free(fi->fmapflags);
01165
01166 fi->obnl = hfd(fi->obnl, -1);
01167 fi->odnl = hfd(fi->odnl, -1);
01168
01169 fi->fcontexts = hfd(fi->fcontexts, -1);
01170
01171 fi->actions = _free(fi->actions);
01172 fi->replacedSizes = _free(fi->replacedSizes);
01173 fi->replaced = _free(fi->replaced);
01174
01175 fi->h = headerFree(fi->h);
01176
01177
01178 (void) rpmfiUnlink(fi, fi->Type);
01179 memset(fi, 0, sizeof(*fi));
01180 fi = _free(fi);
01181
01182
01183 return NULL;
01184 }
01185
01191 static inline unsigned char nibble(char c)
01192
01193 {
01194 if (c >= '0' && c <= '9')
01195 return (c - '0');
01196 if (c >= 'A' && c <= 'F')
01197 return (c - 'A') + 10;
01198 if (c >= 'a' && c <= 'f')
01199 return (c - 'a') + 10;
01200 return 0;
01201 }
01202
01203 #define _fdupe(_fi, _data) \
01204 if ((_fi)->_data != NULL) \
01205 (_fi)->_data = memcpy(xmalloc((_fi)->fc * sizeof(*(_fi)->_data)), \
01206 (_fi)->_data, (_fi)->fc * sizeof(*(_fi)->_data))
01207
01208
01209 #define _fdupestring(_h, _tag, _data) \
01210 if (hge((_h), (_tag), NULL, (void **) &(_data), NULL)) \
01211 _data = xstrdup(_data)
01212
01213 rpmfi rpmfiNew(const rpmts ts, Header h, rpmTag tagN, int scareMem)
01214 {
01215 HGE_t hge =
01216 (scareMem ? (HGE_t) headerGetEntryMinMemory : (HGE_t) headerGetEntry);
01217 HFD_t hfd = headerFreeData;
01218 rpmte p;
01219 rpmfi fi = NULL;
01220 const char * Type;
01221 uint_32 * uip;
01222 int dnlmax, bnlmax;
01223 unsigned char * t;
01224 int len;
01225 int xx;
01226 int i;
01227
01228 if (tagN == RPMTAG_BASENAMES) {
01229 Type = "Files";
01230 } else {
01231 Type = "?Type?";
01232 goto exit;
01233 }
01234
01235 fi = xcalloc(1, sizeof(*fi));
01236 if (fi == NULL)
01237 goto exit;
01238
01239 fi->magic = RPMFIMAGIC;
01240 fi->Type = Type;
01241 fi->i = -1;
01242 fi->tagN = tagN;
01243
01244 fi->hge = hge;
01245 fi->hae = (HAE_t) headerAddEntry;
01246 fi->hme = (HME_t) headerModifyEntry;
01247 fi->hre = (HRE_t) headerRemoveEntry;
01248 fi->hfd = headerFreeData;
01249
01250 fi->h = (scareMem ? headerLink(h) : NULL);
01251
01252 if (fi->fsm == NULL)
01253 fi->fsm = newFSM();
01254
01255
01256 xx = hge(h, RPMTAG_ARCHIVESIZE, NULL, (void **) &uip, NULL);
01257 fi->archivePos = 0;
01258 fi->archiveSize = (xx ? *uip : 0);
01259
01260
01261 _fdupestring(h, RPMTAG_PRETRANS, fi->pretrans);
01262 _fdupestring(h, RPMTAG_PRETRANSPROG, fi->pretransprog);
01263 _fdupestring(h, RPMTAG_POSTTRANS, fi->posttrans);
01264 _fdupestring(h, RPMTAG_POSTTRANSPROG, fi->posttransprog);
01265
01266 if (!hge(h, RPMTAG_BASENAMES, NULL, (void **) &fi->bnl, &fi->fc)) {
01267 fi->fc = 0;
01268 fi->dc = 0;
01269 goto exit;
01270 }
01271 xx = hge(h, RPMTAG_DIRNAMES, NULL, (void **) &fi->dnl, &fi->dc);
01272 xx = hge(h, RPMTAG_DIRINDEXES, NULL, (void **) &fi->dil, NULL);
01273 xx = hge(h, RPMTAG_FILEMODES, NULL, (void **) &fi->fmodes, NULL);
01274 xx = hge(h, RPMTAG_FILEFLAGS, NULL, (void **) &fi->fflags, NULL);
01275 xx = hge(h, RPMTAG_FILEVERIFYFLAGS, NULL, (void **) &fi->vflags, NULL);
01276 xx = hge(h, RPMTAG_FILESIZES, NULL, (void **) &fi->fsizes, NULL);
01277
01278 xx = hge(h, RPMTAG_FILECOLORS, NULL, (void **) &fi->fcolors, NULL);
01279 fi->color = 0;
01280 if (fi->fcolors != NULL)
01281 for (i = 0; i < fi->fc; i++)
01282 fi->color |= fi->fcolors[i];
01283 xx = hge(h, RPMTAG_CLASSDICT, NULL, (void **) &fi->cdict, &fi->ncdict);
01284 xx = hge(h, RPMTAG_FILECLASS, NULL, (void **) &fi->fcdictx, NULL);
01285
01286 xx = hge(h, RPMTAG_DEPENDSDICT, NULL, (void **) &fi->ddict, &fi->nddict);
01287 xx = hge(h, RPMTAG_FILEDEPENDSX, NULL, (void **) &fi->fddictx, NULL);
01288 xx = hge(h, RPMTAG_FILEDEPENDSN, NULL, (void **) &fi->fddictn, NULL);
01289
01290 xx = hge(h, RPMTAG_FILESTATES, NULL, (void **) &fi->fstates, NULL);
01291 if (xx == 0 || fi->fstates == NULL)
01292 fi->fstates = xcalloc(fi->fc, sizeof(*fi->fstates));
01293 else
01294 _fdupe(fi, fstates);
01295
01296 fi->action = FA_UNKNOWN;
01297 fi->flags = 0;
01298
01299 if (fi->actions == NULL)
01300 fi->actions = xcalloc(fi->fc, sizeof(*fi->actions));
01301
01302 fi->keep_header = (scareMem ? 1 : 0);
01303
01304
01305 fi->mapflags =
01306 CPIO_MAP_PATH | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
01307
01308 xx = hge(h, RPMTAG_FILELINKTOS, NULL, (void **) &fi->flinks, NULL);
01309 xx = hge(h, RPMTAG_FILELANGS, NULL, (void **) &fi->flangs, NULL);
01310
01311 fi->fmd5s = NULL;
01312 xx = hge(h, RPMTAG_FILEMD5S, NULL, (void **) &fi->fmd5s, NULL);
01313
01314 fi->md5s = NULL;
01315 if (fi->fmd5s) {
01316 t = xmalloc(fi->fc * 16);
01317 fi->md5s = t;
01318 for (i = 0; i < fi->fc; i++) {
01319 const char * fmd5;
01320 int j;
01321
01322 fmd5 = fi->fmd5s[i];
01323 if (!(fmd5 && *fmd5 != '\0')) {
01324 memset(t, 0, 16);
01325 t += 16;
01326 continue;
01327 }
01328 for (j = 0; j < 16; j++, t++, fmd5 += 2)
01329 *t = (nibble(fmd5[0]) << 4) | nibble(fmd5[1]);
01330 }
01331 fi->fmd5s = hfd(fi->fmd5s, -1);
01332 }
01333
01334
01335 xx = hge(h, RPMTAG_FILEMTIMES, NULL, (void **) &fi->fmtimes, NULL);
01336 xx = hge(h, RPMTAG_FILERDEVS, NULL, (void **) &fi->frdevs, NULL);
01337 xx = hge(h, RPMTAG_FILEINODES, NULL, (void **) &fi->finodes, NULL);
01338 xx = hge(h, RPMTAG_FILECONTEXTS, NULL, (void **) &fi->fcontexts, NULL);
01339
01340 fi->replacedSizes = xcalloc(fi->fc, sizeof(*fi->replacedSizes));
01341
01342 xx = hge(h, RPMTAG_FILEUSERNAME, NULL, (void **) &fi->fuser, NULL);
01343 xx = hge(h, RPMTAG_FILEGROUPNAME, NULL, (void **) &fi->fgroup, NULL);
01344
01345 if (ts != NULL)
01346 if (fi != NULL)
01347 if ((p = rpmtsRelocateElement(ts)) != NULL && rpmteType(p) == TR_ADDED
01348 && !headerIsEntry(h, RPMTAG_SOURCEPACKAGE)
01349 && !headerIsEntry(h, RPMTAG_ORIGBASENAMES))
01350 {
01351 const char * fmt = rpmGetPath("%{?_autorelocate_path}", NULL);
01352 const char * errstr;
01353 char * newPath;
01354 Header foo;
01355
01356
01357 newPath = headerSprintf(h, fmt, rpmTagTable, rpmHeaderFormats, &errstr);
01358 fmt = _free(fmt);
01359
01360 #if __ia64__
01361
01362 if (newPath != NULL && *newPath != '\0'
01363 && strlen(newPath) >= (sizeof("/emul/i386")-1)
01364 && newPath[0] == '/' && newPath[1] == 'e' && newPath[2] == 'm'
01365 && newPath[3] == 'u' && newPath[4] == 'l' && newPath[5] == '/'
01366 && newPath[6] == 'i' && newPath[8] == '8' && newPath[9] == '6')
01367 {
01368 newPath[7] = 'a';
01369 newPath[8] = '3';
01370 newPath[9] = '2';
01371 }
01372 #endif
01373
01374
01375 i = p->nrelocs;
01376 if (newPath != NULL && *newPath != '\0' && p->relocs != NULL)
01377 for (i = 0; i < p->nrelocs; i++) {
01378
01379 if (strcmp(p->relocs[i].oldPath, "/"))
01380 continue;
01381 if (strcmp(p->relocs[i].newPath, newPath))
01382 continue;
01383
01384 break;
01385 }
01386
01387
01388 if (newPath != NULL && *newPath != '\0' && i == p->nrelocs
01389 && p->archScore == 0)
01390 {
01391
01392 p->relocs =
01393 xrealloc(p->relocs, (p->nrelocs + 2) * sizeof(*p->relocs));
01394 p->relocs[p->nrelocs].oldPath = xstrdup("/");
01395 p->relocs[p->nrelocs].newPath = xstrdup(newPath);
01396 p->autorelocatex = p->nrelocs;
01397 p->nrelocs++;
01398 p->relocs[p->nrelocs].oldPath = NULL;
01399 p->relocs[p->nrelocs].newPath = NULL;
01400 }
01401 newPath = _free(newPath);
01402
01403
01404 if (fi->actions == NULL)
01405 fi->actions = xcalloc(fi->fc, sizeof(*fi->actions));
01406
01407 foo = relocateFileList(ts, fi, h, fi->actions);
01408
01409 fi->h = headerFree(fi->h);
01410 fi->h = headerLink(foo);
01411 foo = headerFree(foo);
01412 }
01413
01414 if (!scareMem) {
01415 _fdupe(fi, fmtimes);
01416 _fdupe(fi, frdevs);
01417 _fdupe(fi, finodes);
01418 _fdupe(fi, fsizes);
01419 _fdupe(fi, fflags);
01420 _fdupe(fi, vflags);
01421 _fdupe(fi, fmodes);
01422 _fdupe(fi, dil);
01423
01424 _fdupe(fi, fcolors);
01425 _fdupe(fi, fcdictx);
01426
01427 if (fi->ddict != NULL)
01428 fi->ddict = memcpy(xmalloc(fi->nddict * sizeof(*fi->ddict)),
01429 fi->ddict, fi->nddict * sizeof(*fi->ddict));
01430
01431 _fdupe(fi, fddictx);
01432 _fdupe(fi, fddictn);
01433
01434 fi->h = headerFree(fi->h);
01435 }
01436
01437 dnlmax = -1;
01438 for (i = 0; i < fi->dc; i++) {
01439 if ((len = strlen(fi->dnl[i])) > dnlmax)
01440 dnlmax = len;
01441 }
01442 bnlmax = -1;
01443 for (i = 0; i < fi->fc; i++) {
01444 if ((len = strlen(fi->bnl[i])) > bnlmax)
01445 bnlmax = len;
01446 }
01447 fi->fnlen = dnlmax + bnlmax + 1;
01448 fi->fn = NULL;
01449
01450 fi->dperms = 0755;
01451 fi->fperms = 0644;
01452
01453 exit:
01454
01455 if (_rpmfi_debug < 0)
01456 fprintf(stderr, "*** fi %p\t%s[%d]\n", fi, Type, (fi ? fi->fc : 0));
01457
01458
01459
01460 return rpmfiLink(fi, (fi ? fi->Type : NULL));
01461
01462 }
01463
01464 void rpmfiBuildFClasses(Header h,
01465 const char *** fclassp, int * fcp)
01466 {
01467 int scareMem = 0;
01468 rpmfi fi = rpmfiNew(NULL, h, RPMTAG_BASENAMES, scareMem);
01469 const char * FClass;
01470 const char ** av;
01471 int ac;
01472 size_t nb;
01473 char * t;
01474
01475 if ((ac = rpmfiFC(fi)) <= 0) {
01476 av = NULL;
01477 ac = 0;
01478 goto exit;
01479 }
01480
01481
01482 nb = (ac + 1) * sizeof(*av);
01483 fi = rpmfiInit(fi, 0);
01484 if (fi != NULL)
01485 while (rpmfiNext(fi) >= 0) {
01486 FClass = rpmfiFClass(fi);
01487 if (FClass && *FClass != '\0')
01488 nb += strlen(FClass);
01489 nb += 1;
01490 }
01491
01492
01493 av = xmalloc(nb);
01494 t = ((char *) av) + ((ac + 1) * sizeof(*av));
01495 ac = 0;
01496 fi = rpmfiInit(fi, 0);
01497 if (fi != NULL)
01498 while (rpmfiNext(fi) >= 0) {
01499 FClass = rpmfiFClass(fi);
01500 av[ac++] = t;
01501 if (FClass && *FClass != '\0')
01502 t = stpcpy(t, FClass);
01503 *t++ = '\0';
01504 }
01505 av[ac] = NULL;
01506
01507
01508 exit:
01509 fi = rpmfiFree(fi);
01510
01511 if (fclassp)
01512 *fclassp = av;
01513 else
01514 av = _free(av);
01515
01516 if (fcp) *fcp = ac;
01517 }
01518
01519 void rpmfiBuildFContexts(Header h,
01520 const char *** fcontextp, int * fcp)
01521 {
01522 int scareMem = 0;
01523 rpmfi fi = rpmfiNew(NULL, h, RPMTAG_BASENAMES, scareMem);
01524 const char * fcontext;
01525 const char ** av;
01526 int ac;
01527 size_t nb;
01528 char * t;
01529
01530 if ((ac = rpmfiFC(fi)) <= 0) {
01531 av = NULL;
01532 ac = 0;
01533 goto exit;
01534 }
01535
01536
01537 nb = (ac + 1) * sizeof(*av);
01538 fi = rpmfiInit(fi, 0);
01539 if (fi != NULL)
01540 while (rpmfiNext(fi) >= 0) {
01541 fcontext = rpmfiFContext(fi);
01542 if (fcontext && *fcontext != '\0')
01543 nb += strlen(fcontext);
01544 nb += 1;
01545 }
01546
01547
01548 av = xmalloc(nb);
01549 t = ((char *) av) + ((ac + 1) * sizeof(*av));
01550 ac = 0;
01551 fi = rpmfiInit(fi, 0);
01552 if (fi != NULL)
01553 while (rpmfiNext(fi) >= 0) {
01554 fcontext = rpmfiFContext(fi);
01555 av[ac++] = t;
01556 if (fcontext && *fcontext != '\0')
01557 t = stpcpy(t, fcontext);
01558 *t++ = '\0';
01559 }
01560 av[ac] = NULL;
01561
01562
01563 exit:
01564 fi = rpmfiFree(fi);
01565
01566 if (fcontextp)
01567 *fcontextp = av;
01568 else
01569 av = _free(av);
01570
01571 if (fcp) *fcp = ac;
01572 }
01573
01574 void rpmfiBuildFSContexts(Header h,
01575 const char *** fcontextp, int * fcp)
01576 {
01577 int scareMem = 0;
01578 rpmfi fi = rpmfiNew(NULL, h, RPMTAG_BASENAMES, scareMem);
01579 const char ** av;
01580 int ac;
01581 size_t nb;
01582 char * t;
01583 char * fctxt = NULL;
01584 size_t fctxtlen = 0;
01585 int * fcnb;
01586
01587 if ((ac = rpmfiFC(fi)) <= 0) {
01588 av = NULL;
01589 ac = 0;
01590 goto exit;
01591 }
01592
01593
01594 nb = ac * sizeof(*fcnb);
01595 fcnb = memset(alloca(nb), 0, nb);
01596 ac = 0;
01597 fi = rpmfiInit(fi, 0);
01598 if (fi != NULL)
01599 while (rpmfiNext(fi) >= 0) {
01600 const char * fn = rpmfiFN(fi);
01601 security_context_t scon;
01602
01603 fcnb[ac] = lgetfilecon(fn, &scon);
01604
01605 if (fcnb[ac] > 0) {
01606 fctxt = xrealloc(fctxt, fctxtlen + fcnb[ac]);
01607 memcpy(fctxt+fctxtlen, scon, fcnb[ac]);
01608 fctxtlen += fcnb[ac];
01609 freecon(scon);
01610 }
01611
01612 ac++;
01613 }
01614
01615
01616 nb = (ac + 1) * sizeof(*av) + fctxtlen;
01617 av = xmalloc(nb);
01618 t = ((char *) av) + ((ac + 1) * sizeof(*av));
01619 if (fctxt != NULL && fctxtlen > 0)
01620 (void) memcpy(t, fctxt, fctxtlen);
01621 ac = 0;
01622 fi = rpmfiInit(fi, 0);
01623 if (fi != NULL)
01624 while (rpmfiNext(fi) >= 0) {
01625 av[ac] = "";
01626 if (fcnb[ac] > 0) {
01627 av[ac] = t;
01628 t += fcnb[ac];
01629 }
01630 ac++;
01631 }
01632 av[ac] = NULL;
01633
01634 exit:
01635 fi = rpmfiFree(fi);
01636
01637 if (fcontextp)
01638 *fcontextp = av;
01639 else
01640 av = _free(av);
01641
01642 if (fcp) *fcp = ac;
01643 }
01644
01645 void rpmfiBuildREContexts(Header h,
01646 const char *** fcontextp, int * fcp)
01647 {
01648 int scareMem = 0;
01649 rpmfi fi = rpmfiNew(NULL, h, RPMTAG_BASENAMES, scareMem);
01650 rpmsx sx = NULL;
01651 const char ** av = NULL;
01652 int ac;
01653 size_t nb;
01654 char * t;
01655 char * fctxt = NULL;
01656 size_t fctxtlen = 0;
01657 int * fcnb;
01658
01659 if ((ac = rpmfiFC(fi)) <= 0) {
01660 ac = 0;
01661 goto exit;
01662 }
01663
01664
01665 sx = rpmsxNew(NULL);
01666
01667
01668 nb = ac * sizeof(*fcnb);
01669 fcnb = memset(alloca(nb), 0, nb);
01670 ac = 0;
01671 fi = rpmfiInit(fi, 0);
01672 if (fi != NULL)
01673 while (rpmfiNext(fi) >= 0) {
01674 const char * fn = rpmfiFN(fi);
01675 mode_t fmode = rpmfiFMode(fi);
01676 const char * scon;
01677
01678 scon = rpmsxFContext(sx, fn, fmode);
01679 if (scon != NULL) {
01680 fcnb[ac] = strlen(scon) + 1;
01681
01682 if (fcnb[ac] > 0) {
01683 fctxt = xrealloc(fctxt, fctxtlen + fcnb[ac]);
01684 memcpy(fctxt+fctxtlen, scon, fcnb[ac]);
01685 fctxtlen += fcnb[ac];
01686 }
01687
01688 }
01689 ac++;
01690 }
01691
01692
01693 nb = (ac + 1) * sizeof(*av) + fctxtlen;
01694 av = xmalloc(nb);
01695 t = ((char *) av) + ((ac + 1) * sizeof(*av));
01696 (void) memcpy(t, fctxt, fctxtlen);
01697 ac = 0;
01698 fi = rpmfiInit(fi, 0);
01699 if (fi != NULL)
01700 while (rpmfiNext(fi) >= 0) {
01701 av[ac] = "";
01702 if (fcnb[ac] > 0) {
01703 av[ac] = t;
01704 t += fcnb[ac];
01705 }
01706 ac++;
01707 }
01708 av[ac] = NULL;
01709
01710 exit:
01711 fi = rpmfiFree(fi);
01712 sx = rpmsxFree(sx);
01713
01714 if (fcontextp)
01715 *fcontextp = av;
01716 else
01717 av = _free(av);
01718
01719 if (fcp) *fcp = ac;
01720 }
01721
01722 void rpmfiBuildFDeps(Header h, rpmTag tagN,
01723 const char *** fdepsp, int * fcp)
01724 {
01725 int scareMem = 0;
01726 rpmfi fi = rpmfiNew(NULL, h, RPMTAG_BASENAMES, scareMem);
01727 rpmds ds = NULL;
01728 const char ** av;
01729 int ac;
01730 size_t nb;
01731 char * t;
01732 char deptype = 'R';
01733 char mydt;
01734 const char * DNEVR;
01735 const int_32 * ddict;
01736 unsigned ix;
01737 int ndx;
01738
01739 if ((ac = rpmfiFC(fi)) <= 0) {
01740 av = NULL;
01741 ac = 0;
01742 goto exit;
01743 }
01744
01745 if (tagN == RPMTAG_PROVIDENAME)
01746 deptype = 'P';
01747 else if (tagN == RPMTAG_REQUIRENAME)
01748 deptype = 'R';
01749
01750 ds = rpmdsNew(h, tagN, scareMem);
01751
01752
01753 nb = (ac + 1) * sizeof(*av);
01754 fi = rpmfiInit(fi, 0);
01755 if (fi != NULL)
01756 while (rpmfiNext(fi) >= 0) {
01757 ddict = NULL;
01758 ndx = rpmfiFDepends(fi, &ddict);
01759 if (ddict != NULL)
01760 while (ndx-- > 0) {
01761 ix = *ddict++;
01762 mydt = ((ix >> 24) & 0xff);
01763 if (mydt != deptype)
01764 continue;
01765 ix &= 0x00ffffff;
01766 (void) rpmdsSetIx(ds, ix-1);
01767 if (rpmdsNext(ds) < 0)
01768 continue;
01769 DNEVR = rpmdsDNEVR(ds);
01770 if (DNEVR != NULL)
01771 nb += strlen(DNEVR+2) + 1;
01772 }
01773 nb += 1;
01774 }
01775
01776
01777 av = xmalloc(nb);
01778 t = ((char *) av) + ((ac + 1) * sizeof(*av));
01779 ac = 0;
01780
01781 fi = rpmfiInit(fi, 0);
01782 if (fi != NULL)
01783 while (rpmfiNext(fi) >= 0) {
01784 av[ac++] = t;
01785 ddict = NULL;
01786 ndx = rpmfiFDepends(fi, &ddict);
01787 if (ddict != NULL)
01788 while (ndx-- > 0) {
01789 ix = *ddict++;
01790 mydt = ((ix >> 24) & 0xff);
01791 if (mydt != deptype)
01792 continue;
01793 ix &= 0x00ffffff;
01794 (void) rpmdsSetIx(ds, ix-1);
01795 if (rpmdsNext(ds) < 0)
01796 continue;
01797 DNEVR = rpmdsDNEVR(ds);
01798 if (DNEVR != NULL) {
01799 t = stpcpy(t, DNEVR+2);
01800 *t++ = ' ';
01801 *t = '\0';
01802 }
01803 }
01804 *t++ = '\0';
01805 }
01806
01807 av[ac] = NULL;
01808
01809 exit:
01810 fi = rpmfiFree(fi);
01811 ds = rpmdsFree(ds);
01812
01813 if (fdepsp)
01814 *fdepsp = av;
01815 else
01816 av = _free(av);
01817
01818 if (fcp) *fcp = ac;
01819 }