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