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