00001
00005 #include "system.h"
00006 #include <rpmlib.h>
00007
00008 #include <rpmmacro.h>
00009
00010 #include "fsm.h"
00011 #include "psm.h"
00012
00013 #include "rpmdb.h"
00014
00015 #include "rpmds.h"
00016
00017 #define _RPMFI_INTERNAL
00018 #include "rpmfi.h"
00019
00020 #define _RPMTE_INTERNAL
00021 #include "rpmte.h"
00022
00023 #define _RPMTS_INTERNAL
00024 #include "rpmts.h"
00025
00026 #include "cpio.h"
00027 #include "fprint.h"
00028 #include "legacy.h"
00029 #include "misc.h"
00030
00031 #include "debug.h"
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00052 static int archOkay( const char * pkgArch)
00053
00054 {
00055 if (pkgArch == NULL) return 0;
00056 return (rpmMachineScore(RPM_MACHTABLE_INSTARCH, pkgArch) ? 1 : 0);
00057 }
00058
00061 static int osOkay( const char * pkgOs)
00062
00063 {
00064 if (pkgOs == NULL) return 0;
00065 return (rpmMachineScore(RPM_MACHTABLE_INSTOS, pkgOs) ? 1 : 0);
00066 }
00067
00070 static int sharedCmp(const void * one, const void * two)
00071
00072 {
00073 sharedFileInfo a = (sharedFileInfo) one;
00074 sharedFileInfo b = (sharedFileInfo) two;
00075
00076 if (a->otherPkg < b->otherPkg)
00077 return -1;
00078 else if (a->otherPkg > b->otherPkg)
00079 return 1;
00080
00081 return 0;
00082 }
00083
00086
00087 static fileAction decideFileFate(const rpmts ts,
00088 const rpmfi ofi, rpmfi nfi)
00089
00090
00091 {
00092 const char * fn = rpmfiFN(nfi);
00093 int newFlags = rpmfiFFlags(nfi);
00094 char buffer[1024];
00095 fileTypes dbWhat, newWhat, diskWhat;
00096 struct stat sb;
00097 int save = (newFlags & RPMFILE_NOREPLACE) ? FA_ALTNAME : FA_SAVE;
00098
00099 if (lstat(fn, &sb)) {
00100
00101
00102
00103
00104 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_ALLFILES)
00105 && (newFlags & RPMFILE_MISSINGOK))
00106 {
00107 rpmMessage(RPMMESS_DEBUG, _("%s skipped due to missingok flag\n"),
00108 fn);
00109 return FA_SKIP;
00110 } else {
00111 return FA_CREATE;
00112 }
00113 }
00114
00115 diskWhat = whatis((int_16)sb.st_mode);
00116 dbWhat = whatis(rpmfiFMode(ofi));
00117 newWhat = whatis(rpmfiFMode(nfi));
00118
00119
00120
00121
00122
00123 if (newWhat == XDIR)
00124 return FA_CREATE;
00125
00126 if (diskWhat != newWhat)
00127 return save;
00128 else if (newWhat != dbWhat && diskWhat != dbWhat)
00129 return save;
00130 else if (dbWhat != newWhat)
00131 return FA_CREATE;
00132 else if (dbWhat != LINK && dbWhat != REG)
00133 return FA_CREATE;
00134
00135
00136
00137
00138
00139 if (dbWhat == REG) {
00140 const unsigned char * omd5, * nmd5;
00141 if (domd5(fn, buffer, 0, NULL))
00142 return FA_CREATE;
00143 omd5 = rpmfiMD5(ofi);
00144 if (omd5 && !memcmp(omd5, buffer, 16))
00145 return FA_CREATE;
00146 nmd5 = rpmfiMD5(nfi);
00147
00148 if (omd5 && nmd5 && !memcmp(omd5, nmd5, 16))
00149 return FA_SKIP;
00150
00151 } else {
00152 const char * oFLink, * nFLink;
00153 memset(buffer, 0, sizeof(buffer));
00154 if (readlink(fn, buffer, sizeof(buffer) - 1) == -1)
00155 return FA_CREATE;
00156 oFLink = rpmfiFLink(ofi);
00157 if (oFLink && !strcmp(oFLink, buffer))
00158 return FA_CREATE;
00159 nFLink = rpmfiFLink(nfi);
00160
00161 if (oFLink && nFLink && !strcmp(oFLink, nFLink))
00162 return FA_SKIP;
00163
00164 }
00165
00166
00167
00168
00169
00170
00171
00172 return save;
00173 }
00174
00175
00178
00179 static int filecmp(rpmfi afi, rpmfi bfi)
00180
00181 {
00182 fileTypes awhat = whatis(rpmfiFMode(afi));
00183 fileTypes bwhat = whatis(rpmfiFMode(bfi));
00184
00185 if (awhat != bwhat) return 1;
00186
00187 if (awhat == LINK) {
00188 const char * alink = rpmfiFLink(afi);
00189 const char * blink = rpmfiFLink(bfi);
00190 if (alink == blink) return 0;
00191 if (alink == NULL) return 1;
00192 if (blink == NULL) return -1;
00193 return strcmp(alink, blink);
00194 } else if (awhat == REG) {
00195 const unsigned char * amd5 = rpmfiMD5(afi);
00196 const unsigned char * bmd5 = rpmfiMD5(bfi);
00197 if (amd5 == bmd5) return 0;
00198 if (amd5 == NULL) return 1;
00199 if (bmd5 == NULL) return -1;
00200 return memcmp(amd5, bmd5, 16);
00201 }
00202
00203 return 0;
00204 }
00205
00206
00209
00210
00211 static int handleInstInstalledFiles(const rpmts ts,
00212 rpmte p, rpmfi fi,
00213 sharedFileInfo shared,
00214 int sharedCount, int reportConflicts)
00215
00216
00217 {
00218 const char * altNEVR = NULL;
00219 rpmfi otherFi = NULL;
00220 int numReplaced = 0;
00221 rpmps ps;
00222 int i;
00223
00224 { rpmdbMatchIterator mi;
00225 Header h;
00226 int scareMem = 0;
00227
00228 mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES,
00229 &shared->otherPkg, sizeof(shared->otherPkg));
00230 while ((h = rpmdbNextIterator(mi)) != NULL) {
00231 altNEVR = hGetNEVR(h, NULL);
00232 otherFi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
00233 break;
00234 }
00235 mi = rpmdbFreeIterator(mi);
00236 }
00237
00238 if (otherFi == NULL)
00239 return 1;
00240
00241 fi->replaced = xcalloc(sharedCount, sizeof(*fi->replaced));
00242
00243 ps = rpmtsProblems(ts);
00244 for (i = 0; i < sharedCount; i++, shared++) {
00245 int otherFileNum, fileNum;
00246 int isCfgFile;
00247
00248 otherFileNum = shared->otherFileNum;
00249 (void) rpmfiSetFX(otherFi, otherFileNum);
00250
00251 fileNum = shared->pkgFileNum;
00252 (void) rpmfiSetFX(fi, fileNum);
00253
00254 isCfgFile = ((rpmfiFFlags(otherFi) | rpmfiFFlags(fi)) & RPMFILE_CONFIG);
00255
00256 #ifdef DYING
00257
00258 if (otherStates && otherStates[otherFileNum] != RPMFILE_STATE_NORMAL)
00259 continue;
00260 #endif
00261
00262 if (XFA_SKIPPING(fi->actions[fileNum]))
00263 continue;
00264
00265 if (filecmp(otherFi, fi)) {
00266 if (reportConflicts) {
00267 rpmpsAppend(ps, RPMPROB_FILE_CONFLICT,
00268 rpmteNEVR(p), rpmteKey(p),
00269 rpmfiDN(fi), rpmfiBN(fi),
00270 altNEVR,
00271 0);
00272 }
00273 if (!isCfgFile) {
00274
00275 if (!shared->isRemoved)
00276 fi->replaced[numReplaced++] = *shared;
00277
00278 }
00279 }
00280
00281 if (isCfgFile) {
00282 fileAction action;
00283 action = decideFileFate(ts, otherFi, fi);
00284 fi->actions[fileNum] = action;
00285 }
00286 fi->replacedSizes[fileNum] = rpmfiFSize(otherFi);
00287 }
00288 ps = rpmpsFree(ps);
00289
00290 altNEVR = _free(altNEVR);
00291 otherFi = rpmfiFree(otherFi);
00292
00293 fi->replaced = xrealloc(fi->replaced,
00294 sizeof(*fi->replaced) * (numReplaced + 1));
00295 fi->replaced[numReplaced].otherPkg = 0;
00296
00297 return 0;
00298 }
00299
00300
00303
00304 static int handleRmvdInstalledFiles(const rpmts ts, rpmfi fi,
00305 sharedFileInfo shared, int sharedCount)
00306
00307
00308 {
00309 HGE_t hge = fi->hge;
00310 Header h;
00311 const char * otherStates;
00312 int i, xx;
00313
00314 rpmdbMatchIterator mi;
00315
00316 mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES,
00317 &shared->otherPkg, sizeof(shared->otherPkg));
00318 h = rpmdbNextIterator(mi);
00319 if (h == NULL) {
00320 mi = rpmdbFreeIterator(mi);
00321 return 1;
00322 }
00323
00324 xx = hge(h, RPMTAG_FILESTATES, NULL, (void **) &otherStates, NULL);
00325
00326
00327 for (i = 0; i < sharedCount; i++, shared++) {
00328 int otherFileNum, fileNum;
00329 otherFileNum = shared->otherFileNum;
00330 fileNum = shared->pkgFileNum;
00331
00332 if (otherStates[otherFileNum] != RPMFILE_STATE_NORMAL)
00333 continue;
00334
00335 fi->actions[fileNum] = FA_SKIP;
00336 }
00337
00338
00339 mi = rpmdbFreeIterator(mi);
00340
00341 return 0;
00342 }
00343
00344 #define ISROOT(_d) (((_d)[0] == '/' && (_d)[1] == '\0') ? "" : (_d))
00345
00346
00347 int _fps_debug = 0;
00348
00349 static int fpsCompare (const void * one, const void * two)
00350
00351 {
00352 const struct fingerPrint_s * a = (const struct fingerPrint_s *)one;
00353 const struct fingerPrint_s * b = (const struct fingerPrint_s *)two;
00354 int adnlen = strlen(a->entry->dirName);
00355 int asnlen = (a->subDir ? strlen(a->subDir) : 0);
00356 int abnlen = strlen(a->baseName);
00357 int bdnlen = strlen(b->entry->dirName);
00358 int bsnlen = (b->subDir ? strlen(b->subDir) : 0);
00359 int bbnlen = strlen(b->baseName);
00360 char * afn, * bfn, * t;
00361 int rc = 0;
00362
00363 if (adnlen == 1 && asnlen != 0) adnlen = 0;
00364 if (bdnlen == 1 && bsnlen != 0) bdnlen = 0;
00365
00366
00367 afn = t = alloca(adnlen+asnlen+abnlen+2);
00368 if (adnlen) t = stpcpy(t, a->entry->dirName);
00369 *t++ = '/';
00370 if (a->subDir && asnlen) t = stpcpy(t, a->subDir);
00371 if (abnlen) t = stpcpy(t, a->baseName);
00372 if (afn[0] == '/' && afn[1] == '/') afn++;
00373
00374 bfn = t = alloca(bdnlen+bsnlen+bbnlen+2);
00375 if (bdnlen) t = stpcpy(t, b->entry->dirName);
00376 *t++ = '/';
00377 if (b->subDir && bsnlen) t = stpcpy(t, b->subDir);
00378 if (bbnlen) t = stpcpy(t, b->baseName);
00379 if (bfn[0] == '/' && bfn[1] == '/') bfn++;
00380
00381
00382 rc = strcmp(afn, bfn);
00383
00384 if (_fps_debug)
00385 fprintf(stderr, "\trc(%d) = strcmp(\"%s\", \"%s\")\n", rc, afn, bfn);
00386
00387
00388
00389 if (_fps_debug)
00390 fprintf(stderr, "\t%s/%s%s\trc %d\n",
00391 ISROOT(b->entry->dirName),
00392 (b->subDir ? b->subDir : ""),
00393 b->baseName,
00394 rc
00395 );
00396
00397
00398 return rc;
00399 }
00400
00401
00402 static int _linear_fps_search = 0;
00403
00404 static int findFps(const struct fingerPrint_s * fiFps,
00405 const struct fingerPrint_s * otherFps,
00406 int otherFc)
00407
00408 {
00409 int otherFileNum;
00410
00411
00412 if (_fps_debug)
00413 fprintf(stderr, "==> %s/%s%s\n",
00414 ISROOT(fiFps->entry->dirName),
00415 (fiFps->subDir ? fiFps->subDir : ""),
00416 fiFps->baseName);
00417
00418
00419 if (_linear_fps_search) {
00420
00421 linear:
00422 for (otherFileNum = 0; otherFileNum < otherFc; otherFileNum++, otherFps++) {
00423
00424
00425 if (_fps_debug)
00426 fprintf(stderr, "\t%4d %s/%s%s\n", otherFileNum,
00427 ISROOT(otherFps->entry->dirName),
00428 (otherFps->subDir ? otherFps->subDir : ""),
00429 otherFps->baseName);
00430
00431
00432
00433 if (fiFps == otherFps)
00434 break;
00435
00436
00437
00438 if (FP_EQUAL((*fiFps), (*otherFps)))
00439 break;
00440
00441 }
00442
00443 if (otherFileNum == otherFc) {
00444
00445 if (_fps_debug)
00446 fprintf(stderr, "*** FP_EQUAL NULL %s/%s%s\n",
00447 ISROOT(fiFps->entry->dirName),
00448 (fiFps->subDir ? fiFps->subDir : ""),
00449 fiFps->baseName);
00450
00451 }
00452
00453 return otherFileNum;
00454
00455 } else {
00456
00457 const struct fingerPrint_s * bingoFps;
00458
00459
00460 bingoFps = bsearch(fiFps, otherFps, otherFc, sizeof(*otherFps), fpsCompare);
00461
00462 if (bingoFps == NULL) {
00463
00464 if (_fps_debug)
00465 fprintf(stderr, "*** bingoFps NULL %s/%s%s\n",
00466 ISROOT(fiFps->entry->dirName),
00467 (fiFps->subDir ? fiFps->subDir : ""),
00468 fiFps->baseName);
00469
00470 goto linear;
00471 }
00472
00473
00474
00475 if (!(fiFps == bingoFps || FP_EQUAL((*fiFps), (*bingoFps)))) {
00476
00477 if (_fps_debug)
00478 fprintf(stderr, "*** BAD %s/%s%s\n",
00479 ISROOT(bingoFps->entry->dirName),
00480 (bingoFps->subDir ? bingoFps->subDir : ""),
00481 bingoFps->baseName);
00482
00483 goto linear;
00484 }
00485
00486 otherFileNum = (bingoFps != NULL ? (bingoFps - otherFps) : 0);
00487
00488 }
00489
00490 return otherFileNum;
00491 }
00492
00496
00497 static void handleOverlappedFiles(const rpmts ts,
00498 const rpmte p, rpmfi fi)
00499
00500
00501 {
00502 uint_32 fixupSize = 0;
00503 rpmps ps;
00504 const char * fn;
00505 int i, j;
00506
00507 ps = rpmtsProblems(ts);
00508 fi = rpmfiInit(fi, 0);
00509 if (fi != NULL)
00510 while ((i = rpmfiNext(fi)) >= 0) {
00511 struct fingerPrint_s * fiFps;
00512 int otherPkgNum, otherFileNum;
00513 rpmfi otherFi;
00514 int_32 FFlags;
00515 int_16 FMode;
00516 const rpmfi * recs;
00517 int numRecs;
00518
00519 if (XFA_SKIPPING(fi->actions[i]))
00520 continue;
00521
00522 fn = rpmfiFN(fi);
00523 fiFps = fi->fps + i;
00524 FFlags = rpmfiFFlags(fi);
00525 FMode = rpmfiFMode(fi);
00526
00527 fixupSize = 0;
00528
00529
00530
00531
00532
00533
00534
00535 (void) htGetEntry(ts->ht, fiFps,
00536 (const void ***) &recs, &numRecs, NULL);
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 for (j = 0; j < numRecs && recs[j] != fi; j++)
00561 {};
00562
00563
00564 otherFileNum = -1;
00565 otherFi = NULL;
00566 for (otherPkgNum = j - 1; otherPkgNum >= 0; otherPkgNum--) {
00567 struct fingerPrint_s * otherFps;
00568 int otherFc;
00569
00570 otherFi = recs[otherPkgNum];
00571
00572
00573 if (rpmteType(p) == TR_ADDED && rpmteType(otherFi->te) != TR_ADDED)
00574 continue;
00575
00576 otherFps = otherFi->fps;
00577 otherFc = rpmfiFC(otherFi);
00578
00579 otherFileNum = findFps(fiFps, otherFps, otherFc);
00580 (void) rpmfiSetFX(otherFi, otherFileNum);
00581
00582
00583 if (otherFi->actions[otherFileNum] != FA_UNKNOWN)
00584 break;
00585 }
00586
00587
00588 switch (rpmteType(p)) {
00589 case TR_ADDED:
00590 { struct stat sb;
00591 if (otherPkgNum < 0) {
00592
00593 if (fi->actions[i] != FA_UNKNOWN)
00594 break;
00595 if ((FFlags & RPMFILE_CONFIG) && !lstat(fn, &sb)) {
00596
00597 fi->actions[i] = (FFlags & RPMFILE_NOREPLACE)
00598 ? FA_ALTNAME : FA_BACKUP;
00599 } else {
00600 fi->actions[i] = FA_CREATE;
00601 }
00602 break;
00603 }
00604
00605 assert(otherFi != NULL);
00606
00607 if ((rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACENEWFILES)
00608 && filecmp(otherFi, fi))
00609 {
00610 rpmpsAppend(ps, RPMPROB_NEW_FILE_CONFLICT,
00611 rpmteNEVR(p), rpmteKey(p),
00612 fn, NULL,
00613 rpmteNEVR(otherFi->te),
00614 0);
00615 }
00616
00617
00618 fixupSize = rpmfiFSize(otherFi);
00619
00620 if ((FFlags & RPMFILE_CONFIG) && !lstat(fn, &sb)) {
00621
00622 fi->actions[i] = (FFlags & RPMFILE_NOREPLACE)
00623 ? FA_ALTNAME : FA_SKIP;
00624 } else {
00625 fi->actions[i] = FA_CREATE;
00626 }
00627 } break;
00628
00629 case TR_REMOVED:
00630 if (otherPkgNum >= 0) {
00631 assert(otherFi != NULL);
00632
00633 if (otherFi->actions[otherFileNum] != FA_ERASE) {
00634
00635 fi->actions[i] = FA_SKIP;
00636 break;
00637 }
00638
00639 otherFi->actions[otherFileNum] = FA_SKIP;
00640 }
00641 if (XFA_SKIPPING(fi->actions[i]))
00642 break;
00643 if (rpmfiFState(fi) != RPMFILE_STATE_NORMAL)
00644 break;
00645 if (!(S_ISREG(FMode) && (FFlags & RPMFILE_CONFIG))) {
00646 fi->actions[i] = FA_ERASE;
00647 break;
00648 }
00649
00650
00651 { char md5sum[50];
00652 const unsigned char * MD5 = rpmfiMD5(fi);
00653 if (!domd5(fn, md5sum, 0, NULL) && memcmp(MD5, md5sum, 16)) {
00654 fi->actions[i] = FA_BACKUP;
00655 break;
00656 }
00657 }
00658 fi->actions[i] = FA_ERASE;
00659 break;
00660 }
00661
00662
00663
00664 rpmtsUpdateDSI(ts, fiFps->entry->dev,
00665 rpmfiFSize(fi), fi->replacedSizes[i], fixupSize, fi->actions[i]);
00666
00667 }
00668 ps = rpmpsFree(ps);
00669 }
00670
00678 static int ensureOlder(rpmts ts,
00679 const rpmte p, const Header h)
00680
00681 {
00682 int_32 reqFlags = (RPMSENSE_LESS | RPMSENSE_EQUAL);
00683 const char * reqEVR;
00684 rpmds req;
00685 char * t;
00686 int nb;
00687 int rc;
00688
00689 if (p == NULL || h == NULL)
00690 return 1;
00691
00692
00693 nb = strlen(rpmteNEVR(p)) + (rpmteE(p) != NULL ? strlen(rpmteE(p)) : 0) + 1;
00694 t = alloca(nb);
00695 *t = '\0';
00696 reqEVR = t;
00697 if (rpmteE(p) != NULL) t = stpcpy( stpcpy(t, rpmteE(p)), ":");
00698 if (rpmteV(p) != NULL) t = stpcpy(t, rpmteV(p));
00699 *t++ = '-';
00700 if (rpmteR(p) != NULL) t = stpcpy(t, rpmteR(p));
00701
00702
00703 req = rpmdsSingle(RPMTAG_REQUIRENAME, rpmteN(p), reqEVR, reqFlags);
00704 rc = rpmdsNVRMatchesDep(h, req, _rpmds_nopromote);
00705 req = rpmdsFree(req);
00706
00707 if (rc == 0) {
00708 rpmps ps = rpmtsProblems(ts);
00709 const char * altNEVR = hGetNEVR(h, NULL);
00710 rpmpsAppend(ps, RPMPROB_OLDPACKAGE,
00711 rpmteNEVR(p), rpmteKey(p),
00712 NULL, NULL,
00713 altNEVR,
00714 0);
00715 altNEVR = _free(altNEVR);
00716 ps = rpmpsFree(ps);
00717 rc = 1;
00718 } else
00719 rc = 0;
00720
00721 return rc;
00722 }
00723
00726
00727
00728 static void skipFiles(const rpmts ts, rpmfi fi)
00729
00730
00731 {
00732 int noDocs = (rpmtsFlags(ts) & RPMTRANS_FLAG_NODOCS);
00733 char ** netsharedPaths = NULL;
00734 const char ** languages;
00735 const char * dn, * bn;
00736 int dnlen, bnlen, ix;
00737 const char * s;
00738 int * drc;
00739 char * dff;
00740 int dc;
00741 int i, j;
00742
00743 if (!noDocs)
00744 noDocs = rpmExpandNumeric("%{_excludedocs}");
00745
00746 { const char *tmpPath = rpmExpand("%{_netsharedpath}", NULL);
00747
00748 if (tmpPath && *tmpPath != '%')
00749 netsharedPaths = splitString(tmpPath, strlen(tmpPath), ':');
00750
00751 tmpPath = _free(tmpPath);
00752 }
00753
00754 s = rpmExpand("%{_install_langs}", NULL);
00755
00756 if (!(s && *s != '%'))
00757 s = _free(s);
00758 if (s) {
00759 languages = (const char **) splitString(s, strlen(s), ':');
00760 s = _free(s);
00761 } else
00762 languages = NULL;
00763
00764
00765
00766 dc = rpmfiDC(fi);
00767 drc = alloca(dc * sizeof(*drc));
00768 memset(drc, 0, dc * sizeof(*drc));
00769 dff = alloca(dc * sizeof(*dff));
00770 memset(dff, 0, dc * sizeof(*dff));
00771
00772 fi = rpmfiInit(fi, 0);
00773 if (fi != NULL)
00774 while ((i = rpmfiNext(fi)) >= 0)
00775 {
00776 char **nsp;
00777
00778 bn = rpmfiBN(fi);
00779 bnlen = strlen(bn);
00780 ix = rpmfiDX(fi);
00781 dn = rpmfiDN(fi);
00782 dnlen = strlen(dn);
00783 if (dn == NULL)
00784 continue;
00785
00786 drc[ix]++;
00787
00788
00789 if (XFA_SKIPPING(fi->actions[i])) {
00790 drc[ix]--;
00791 continue;
00792 }
00793
00794
00795
00796
00797
00798
00799 for (nsp = netsharedPaths; nsp && *nsp; nsp++) {
00800 int len;
00801
00802 len = strlen(*nsp);
00803 if (dnlen >= len) {
00804 if (strncmp(dn, *nsp, len))
00805 continue;
00806
00807 if (!(dn[len] == '/' || dn[len] == '\0'))
00808 continue;
00809 } else {
00810 if (len < (dnlen + bnlen))
00811 continue;
00812 if (strncmp(dn, *nsp, dnlen))
00813 continue;
00814 if (strncmp(bn, (*nsp) + dnlen, bnlen))
00815 continue;
00816 len = dnlen + bnlen;
00817
00818 if (!((*nsp)[len] == '/' || (*nsp)[len] == '\0'))
00819 continue;
00820 }
00821
00822 break;
00823 }
00824
00825 if (nsp && *nsp) {
00826 drc[ix]--; dff[ix] = 1;
00827 fi->actions[i] = FA_SKIPNETSHARED;
00828 continue;
00829 }
00830
00831
00832
00833
00834 if (fi->flangs && languages && *fi->flangs[i]) {
00835 const char **lang, *l, *le;
00836 for (lang = languages; *lang != NULL; lang++) {
00837 if (!strcmp(*lang, "all"))
00838 break;
00839 for (l = fi->flangs[i]; *l != '\0'; l = le) {
00840 for (le = l; *le != '\0' && *le != '|'; le++)
00841 {};
00842 if ((le-l) > 0 && !strncmp(*lang, l, (le-l)))
00843 break;
00844 if (*le == '|') le++;
00845 }
00846 if (*l != '\0')
00847 break;
00848 }
00849 if (*lang == NULL) {
00850 drc[ix]--; dff[ix] = 1;
00851 fi->actions[i] = FA_SKIPNSTATE;
00852 continue;
00853 }
00854 }
00855
00856
00857
00858
00859 if (noDocs && (rpmfiFFlags(fi) & RPMFILE_DOC)) {
00860 drc[ix]--; dff[ix] = 1;
00861 fi->actions[i] = FA_SKIPNSTATE;
00862 continue;
00863 }
00864 }
00865
00866
00867 #ifndef NOTYET
00868 if (fi != NULL)
00869 for (j = 0; j < dc; j++)
00870 #else
00871 if ((fi = rpmfiInitD(fi)) != NULL)
00872 while (j = rpmfiNextD(fi) >= 0)
00873 #endif
00874 {
00875
00876 if (drc[j]) continue;
00877 if (!dff[j]) continue;
00878
00879
00880 dn = fi->dnl[j]; dnlen = strlen(dn) - 1;
00881 bn = dn + dnlen; bnlen = 0;
00882 while (bn > dn && bn[-1] != '/') {
00883 bnlen++;
00884 dnlen--;
00885 bn--;
00886 }
00887
00888
00889 fi = rpmfiInit(fi, 0);
00890 if (fi != NULL)
00891 while ((i = rpmfiNext(fi)) >= 0) {
00892 const char * fdn, * fbn;
00893 int_16 fFMode;
00894
00895 if (XFA_SKIPPING(fi->actions[i]))
00896 continue;
00897
00898 fFMode = rpmfiFMode(fi);
00899
00900 if (whatis(fFMode) != XDIR)
00901 continue;
00902 fdn = rpmfiDN(fi);
00903 if (strlen(fdn) != dnlen)
00904 continue;
00905 if (strncmp(fdn, dn, dnlen))
00906 continue;
00907 fbn = rpmfiBN(fi);
00908 if (strlen(fbn) != bnlen)
00909 continue;
00910 if (strncmp(fbn, bn, bnlen))
00911 continue;
00912 rpmMessage(RPMMESS_DEBUG, _("excluding directory %s\n"), dn);
00913 fi->actions[i] = FA_SKIPNSTATE;
00914 break;
00915 }
00916 }
00917
00918 if (netsharedPaths) freeSplitString(netsharedPaths);
00919 #ifdef DYING
00920 fi->flangs = _free(fi->flangs);
00921 #endif
00922 if (languages) freeSplitString((char **)languages);
00923 }
00924
00925
00926
00933 static
00934 rpmfi rpmtsiFi(const rpmtsi tsi)
00935
00936 {
00937 rpmfi fi = NULL;
00938
00939 if (tsi != NULL && tsi->ocsave != -1) {
00940
00941 rpmte te = rpmtsElement(tsi->ts, tsi->ocsave);
00942
00943 if (te != NULL && (fi = te->fi) != NULL)
00944 fi->te = te;
00945
00946
00947 }
00948
00949 return fi;
00950
00951 }
00952
00953 #define NOTIFY(_ts, _al) if ((_ts)->notify) (void) (_ts)->notify _al
00954
00955 int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
00956 {
00957 int i, j;
00958 int ourrc = 0;
00959 int totalFileCount = 0;
00960 rpmfi fi;
00961 sharedFileInfo shared, sharedList;
00962 int numShared;
00963 int nexti;
00964 alKey lastFailKey;
00965 fingerPrintCache fpc;
00966 rpmps ps;
00967 rpmpsm psm;
00968 rpmtsi pi; rpmte p;
00969 rpmtsi qi; rpmte q;
00970 int numAdded;
00971 int numRemoved;
00972 int xx;
00973
00974
00975
00976 if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOSCRIPTS)
00977 (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers));
00978 if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERS)
00979 (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransTriggers));
00980
00981
00982 if (rpmtsFlags(ts) & (RPMTRANS_FLAG_JUSTDB | RPMTRANS_FLAG_MULTILIB))
00983 (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers));
00984
00985 ts->probs = rpmpsFree(ts->probs);
00986 ts->probs = rpmpsCreate();
00987
00988
00989 { int dbmode = (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)
00990 ? O_RDONLY : (O_RDWR|O_CREAT);
00991
00992
00993 if (rpmtsOpenDB(ts, dbmode))
00994 return -1;
00995 }
00996
00997 ts->ignoreSet = ignoreSet;
00998 { const char * currDir = currentDirectory();
00999 rpmtsSetCurrDir(ts, currDir);
01000 currDir = _free(currDir);
01001 }
01002
01003 (void) rpmtsSetChrootDone(ts, 0);
01004
01005 { int_32 tid = (int_32) time(NULL);
01006 (void) rpmtsSetTid(ts, tid);
01007 }
01008
01009
01010 xx = rpmtsInitDSI(ts);
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021 rpmMessage(RPMMESS_DEBUG, _("sanity checking %d elments\n"), rpmtsNElements(ts));
01022 ps = rpmtsProblems(ts);
01023
01024 pi = rpmtsiInit(ts);
01025 while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
01026 rpmdbMatchIterator mi;
01027 int fc;
01028
01029 if ((fi = rpmtsiFi(pi)) == NULL)
01030 continue;
01031 fc = rpmfiFC(fi);
01032
01033 if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_IGNOREARCH))
01034 if (!archOkay(rpmteA(p)))
01035 rpmpsAppend(ps, RPMPROB_BADARCH,
01036 rpmteNEVR(p), rpmteKey(p),
01037 rpmteA(p), NULL,
01038 NULL, 0);
01039
01040 if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_IGNOREOS))
01041 if (!osOkay(rpmteO(p)))
01042 rpmpsAppend(ps, RPMPROB_BADOS,
01043 rpmteNEVR(p), rpmteKey(p),
01044 rpmteO(p), NULL,
01045 NULL, 0);
01046
01047 if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_OLDPACKAGE)) {
01048 Header h;
01049 mi = rpmtsInitIterator(ts, RPMTAG_NAME, rpmteN(p), 0);
01050 while ((h = rpmdbNextIterator(mi)) != NULL)
01051 xx = ensureOlder(ts, p, h);
01052 mi = rpmdbFreeIterator(mi);
01053 }
01054
01055
01056 if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEPKG) && !rpmteMultiLib(p)) {
01057 mi = rpmtsInitIterator(ts, RPMTAG_NAME, rpmteN(p), 0);
01058 xx = rpmdbSetIteratorRE(mi, RPMTAG_EPOCH, RPMMIRE_DEFAULT,
01059 rpmteE(p));
01060 xx = rpmdbSetIteratorRE(mi, RPMTAG_VERSION, RPMMIRE_DEFAULT,
01061 rpmteV(p));
01062 xx = rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, RPMMIRE_DEFAULT,
01063 rpmteR(p));
01064
01065 while (rpmdbNextIterator(mi) != NULL) {
01066 rpmpsAppend(ps, RPMPROB_PKG_INSTALLED,
01067 rpmteNEVR(p), rpmteKey(p),
01068 NULL, NULL,
01069 NULL, 0);
01070 break;
01071 }
01072 mi = rpmdbFreeIterator(mi);
01073 }
01074
01075
01076 totalFileCount += fc;
01077
01078 }
01079 pi = rpmtsiFree(pi);
01080 ps = rpmpsFree(ps);
01081
01082
01083 pi = rpmtsiInit(ts);
01084 while ((p = rpmtsiNext(pi, TR_REMOVED)) != NULL) {
01085 int fc;
01086
01087 if ((fi = rpmtsiFi(pi)) == NULL)
01088 continue;
01089 fc = rpmfiFC(fi);
01090
01091 totalFileCount += fc;
01092 }
01093 pi = rpmtsiFree(pi);
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104 rpmMessage(RPMMESS_DEBUG, _("computing %d file fingerprints\n"), totalFileCount);
01105 numAdded = numRemoved = 0;
01106 pi = rpmtsiInit(ts);
01107 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01108 int fc;
01109
01110 if ((fi = rpmtsiFi(pi)) == NULL)
01111 continue;
01112 fc = rpmfiFC(fi);
01113
01114
01115 switch (rpmteType(p)) {
01116 case TR_ADDED:
01117 numAdded++;
01118 fi->record = 0;
01119
01120 if (fc > 0)
01121 skipFiles(ts, fi);
01122 break;
01123 case TR_REMOVED:
01124 numRemoved++;
01125 fi->record = rpmteDBOffset(p);
01126 break;
01127 }
01128
01129
01130 fi->fps = (fc > 0 ? xmalloc(fc * sizeof(*fi->fps)) : NULL);
01131 }
01132 pi = rpmtsiFree(pi);
01133
01134 if (!rpmtsChrootDone(ts)) {
01135 const char * rootDir = rpmtsRootDir(ts);
01136 xx = chdir("/");
01137
01138 if (rootDir != NULL)
01139 xx = chroot(rootDir);
01140
01141 (void) rpmtsSetChrootDone(ts, 1);
01142 }
01143
01144 ts->ht = htCreate(totalFileCount * 2, 0, 0, fpHashFunction, fpEqual);
01145 fpc = fpCacheCreate(totalFileCount);
01146
01147
01148
01149
01150 pi = rpmtsiInit(ts);
01151 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01152 int fc;
01153
01154 (void) rpmdbCheckSignals();
01155
01156 if ((fi = rpmtsiFi(pi)) == NULL)
01157 continue;
01158 fc = rpmfiFC(fi);
01159
01160 fpLookupList(fpc, fi->dnl, fi->bnl, fi->dil, fc, fi->fps);
01161
01162 fi = rpmfiInit(fi, 0);
01163 if (fi != NULL)
01164 while ((i = rpmfiNext(fi)) >= 0) {
01165 if (XFA_SKIPPING(fi->actions[i]))
01166 continue;
01167
01168 htAddEntry(ts->ht, fi->fps + i, (void *) fi);
01169
01170 }
01171
01172 }
01173 pi = rpmtsiFree(pi);
01174
01175 NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_START, 6, ts->orderCount,
01176 NULL, ts->notifyData));
01177
01178
01179
01180
01181 rpmMessage(RPMMESS_DEBUG, _("computing file dispositions\n"));
01182 ps = rpmtsProblems(ts);
01183 pi = rpmtsiInit(ts);
01184 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01185 dbiIndexSet * matches;
01186 int knownBad;
01187 int fc;
01188
01189 (void) rpmdbCheckSignals();
01190
01191 if ((fi = rpmtsiFi(pi)) == NULL)
01192 continue;
01193 fc = rpmfiFC(fi);
01194
01195 NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_PROGRESS, rpmtsiOc(pi),
01196 ts->orderCount, NULL, ts->notifyData));
01197
01198 if (fc == 0) continue;
01199
01200
01201 matches = xcalloc(fc, sizeof(*matches));
01202 if (rpmdbFindFpList(rpmtsGetRdb(ts), fi->fps, matches, fc)) {
01203 ps = rpmpsFree(ps);
01204 return 1;
01205 }
01206
01207 numShared = 0;
01208 fi = rpmfiInit(fi, 0);
01209 while ((i = rpmfiNext(fi)) >= 0)
01210 numShared += dbiIndexSetCount(matches[i]);
01211
01212
01213 shared = sharedList = xcalloc((numShared + 1), sizeof(*sharedList));
01214
01215 fi = rpmfiInit(fi, 0);
01216 while ((i = rpmfiNext(fi)) >= 0) {
01217
01218
01219
01220
01221 for (j = 0; j < dbiIndexSetCount(matches[i]); j++) {
01222 int ro;
01223 ro = dbiIndexRecordOffset(matches[i], j);
01224 knownBad = 0;
01225 qi = rpmtsiInit(ts);
01226 while ((q = rpmtsiNext(qi, TR_REMOVED)) != NULL) {
01227 if (ro == knownBad)
01228 break;
01229 if (rpmteDBOffset(q) == ro)
01230 knownBad = ro;
01231 }
01232 qi = rpmtsiFree(qi);
01233
01234 shared->pkgFileNum = i;
01235 shared->otherPkg = dbiIndexRecordOffset(matches[i], j);
01236 shared->otherFileNum = dbiIndexRecordFileNumber(matches[i], j);
01237 shared->isRemoved = (knownBad == ro);
01238 shared++;
01239 }
01240 matches[i] = dbiFreeIndexSet(matches[i]);
01241 }
01242 numShared = shared - sharedList;
01243 shared->otherPkg = -1;
01244 matches = _free(matches);
01245
01246
01247 qsort(sharedList, numShared, sizeof(*shared), sharedCmp);
01248
01249
01250
01251 for (i = 0; i < numShared; i = nexti) {
01252 int beingRemoved;
01253
01254 shared = sharedList + i;
01255
01256
01257 for (nexti = i + 1; nexti < numShared; nexti++) {
01258 if (sharedList[nexti].otherPkg != shared->otherPkg)
01259 break;
01260 }
01261
01262
01263 beingRemoved = 0;
01264 if (ts->removedPackages != NULL)
01265 for (j = 0; j < ts->numRemovedPackages; j++) {
01266 if (ts->removedPackages[j] != shared->otherPkg)
01267 continue;
01268 beingRemoved = 1;
01269 break;
01270 }
01271
01272
01273 switch (rpmteType(p)) {
01274 case TR_ADDED:
01275 xx = handleInstInstalledFiles(ts, p, fi, shared, nexti - i,
01276 !(beingRemoved || (rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEOLDFILES)));
01277 break;
01278 case TR_REMOVED:
01279 if (!beingRemoved)
01280 xx = handleRmvdInstalledFiles(ts, fi, shared, nexti - i);
01281 break;
01282 }
01283 }
01284
01285
01286 free(sharedList);
01287
01288
01289 handleOverlappedFiles(ts, p, fi);
01290
01291
01292 switch (rpmteType(p)) {
01293 case TR_ADDED:
01294 rpmtsCheckDSIProblems(ts, p);
01295 break;
01296 case TR_REMOVED:
01297 break;
01298 }
01299 }
01300 pi = rpmtsiFree(pi);
01301 ps = rpmpsFree(ps);
01302
01303 if (rpmtsChrootDone(ts)) {
01304 const char * currDir = rpmtsCurrDir(ts);
01305
01306 xx = chroot(".");
01307
01308 (void) rpmtsSetChrootDone(ts, 0);
01309 if (currDir != NULL)
01310 xx = chdir(currDir);
01311 }
01312
01313 NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_STOP, 6, ts->orderCount,
01314 NULL, ts->notifyData));
01315
01316
01317
01318
01319 pi = rpmtsiInit(ts);
01320 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01321 if ((fi = rpmtsiFi(pi)) == NULL)
01322 continue;
01323 if (rpmfiFC(fi) == 0)
01324 continue;
01325 fi->fps = _free(fi->fps);
01326 }
01327 pi = rpmtsiFree(pi);
01328
01329 fpc = fpCacheFree(fpc);
01330 ts->ht = htFree(ts->ht);
01331
01332
01333
01334
01335 if ((rpmtsFlags(ts) & RPMTRANS_FLAG_BUILD_PROBS)
01336 || (ts->probs->numProblems &&
01337 (okProbs != NULL || rpmpsTrim(ts->probs, okProbs)))
01338 )
01339 {
01340 return ts->orderCount;
01341 }
01342
01343
01344
01345
01346 if (rpmtsFlags(ts) & (RPMTRANS_FLAG_DIRSTASH | RPMTRANS_FLAG_REPACKAGE)) {
01347 int progress;
01348 progress = 0;
01349 pi = rpmtsiInit(ts);
01350 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01351
01352 (void) rpmdbCheckSignals();
01353
01354 if ((fi = rpmtsiFi(pi)) == NULL)
01355 continue;
01356 switch (rpmteType(p)) {
01357 case TR_ADDED:
01358 break;
01359 case TR_REMOVED:
01360 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_REPACKAGE))
01361 break;
01362 if (!progress)
01363 NOTIFY(ts, (NULL, RPMCALLBACK_REPACKAGE_START,
01364 7, numRemoved, NULL, ts->notifyData));
01365
01366 NOTIFY(ts, (NULL, RPMCALLBACK_REPACKAGE_PROGRESS, progress,
01367 numRemoved, NULL, ts->notifyData));
01368 progress++;
01369
01370
01371 fi->mapflags |= CPIO_MAP_ABSOLUTE;
01372 fi->mapflags |= CPIO_MAP_ADDDOT;
01373 fi->mapflags |= CPIO_ALL_HARDLINKS;
01374 psm = rpmpsmNew(ts, p, fi);
01375 xx = rpmpsmStage(psm, PSM_PKGSAVE);
01376 psm = rpmpsmFree(psm);
01377 fi->mapflags &= ~CPIO_MAP_ABSOLUTE;
01378 fi->mapflags &= ~CPIO_MAP_ADDDOT;
01379 fi->mapflags &= ~CPIO_ALL_HARDLINKS;
01380
01381 break;
01382 }
01383 }
01384 pi = rpmtsiFree(pi);
01385 if (progress) {
01386 NOTIFY(ts, (NULL, RPMCALLBACK_REPACKAGE_STOP, 7, numRemoved,
01387 NULL, ts->notifyData));
01388 }
01389 }
01390
01391
01392
01393
01394 lastFailKey = (alKey)-2;
01395 pi = rpmtsiInit(ts);
01396
01397 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01398 alKey pkgKey;
01399 int gotfd;
01400
01401 (void) rpmdbCheckSignals();
01402
01403 gotfd = 0;
01404 if ((fi = rpmtsiFi(pi)) == NULL)
01405 continue;
01406
01407 psm = rpmpsmNew(ts, p, fi);
01408 psm->unorderedSuccessor =
01409 (rpmtsiOc(pi) >= rpmtsUnorderedSuccessors(ts, -1) ? 1 : 0);
01410
01411 switch (rpmteType(p)) {
01412 case TR_ADDED:
01413
01414 pkgKey = rpmteAddedKey(p);
01415
01416 rpmMessage(RPMMESS_DEBUG, "========== +++ %s\n", rpmteNEVR(p));
01417 p->h = NULL;
01418
01419 {
01420
01421 p->fd = ts->notify(p->h, RPMCALLBACK_INST_OPEN_FILE, 0, 0,
01422 rpmteKey(p), ts->notifyData);
01423
01424 if (rpmteFd(p) != NULL) {
01425 rpmVSFlags ovsflags = rpmtsVSFlags(ts);
01426 rpmVSFlags vsflags = ovsflags | RPMVSF_NEEDPAYLOAD;
01427 rpmRC rpmrc;
01428
01429 ovsflags = rpmtsSetVSFlags(ts, vsflags);
01430 rpmrc = rpmReadPackageFile(ts, rpmteFd(p),
01431 rpmteNEVR(p), &p->h);
01432 vsflags = rpmtsSetVSFlags(ts, ovsflags);
01433
01434 switch (rpmrc) {
01435 default:
01436
01437 p->fd = ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE,
01438 0, 0,
01439 rpmteKey(p), ts->notifyData);
01440
01441 p->fd = NULL;
01442 ourrc++;
01443 break;
01444 case RPMRC_NOTTRUSTED:
01445 case RPMRC_NOKEY:
01446 case RPMRC_OK:
01447 break;
01448 }
01449 if (rpmteFd(p) != NULL) gotfd = 1;
01450 }
01451 }
01452
01453
01454 if (rpmteFd(p) != NULL) {
01455
01456
01457
01458
01459 psm->fi = rpmfiFree(psm->fi);
01460 {
01461 char * fstates = fi->fstates;
01462 fileAction * actions = fi->actions;
01463
01464 fi->fstates = NULL;
01465 fi->actions = NULL;
01466 fi = rpmfiFree(fi);
01467 fi = rpmfiNew(ts, p->h, RPMTAG_BASENAMES, 1);
01468 if (fi != NULL) {
01469 fi->te = p;
01470 fi->fstates = _free(fi->fstates);
01471 fi->fstates = fstates;
01472 fi->actions = _free(fi->actions);
01473 fi->actions = actions;
01474 p->fi = fi;
01475 }
01476 }
01477 psm->fi = rpmfiLink(p->fi, NULL);
01478
01479 if (rpmteMultiLib(p))
01480 (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_MULTILIB));
01481 else
01482 (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) & ~RPMTRANS_FLAG_MULTILIB));
01483
01484
01485 if (rpmpsmStage(psm, PSM_PKGINSTALL)) {
01486 ourrc++;
01487 lastFailKey = pkgKey;
01488 }
01489
01490 } else {
01491 ourrc++;
01492 lastFailKey = pkgKey;
01493 }
01494
01495 if (gotfd) {
01496
01497 (void) ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE, 0, 0,
01498 rpmteKey(p), ts->notifyData);
01499
01500
01501 p->fd = NULL;
01502
01503 }
01504
01505 p->h = headerFree(p->h);
01506
01507 break;
01508 case TR_REMOVED:
01509 rpmMessage(RPMMESS_DEBUG, "========== --- %s\n", rpmteNEVR(p));
01510
01511
01512
01513
01514 if (rpmteDependsOnKey(p) != lastFailKey) {
01515 if (rpmpsmStage(psm, PSM_PKGERASE))
01516 ourrc++;
01517 }
01518 break;
01519 }
01520 xx = rpmdbSync(rpmtsGetRdb(ts));
01521
01522
01523 psm = rpmpsmFree(psm);
01524
01525
01526
01527 p->fi = rpmfiFree(p->fi);
01528
01529
01530 }
01531
01532 pi = rpmtsiFree(pi);
01533
01534
01535 if (ourrc)
01536 return -1;
01537 else
01538 return 0;
01539
01540 }