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