00001
00005 #include "system.h"
00006 #include "rpmcli.h"
00007 #include <rpmlib.h>
00008
00009 #include <rpmmacro.h>
00010
00011 #include "fsm.h"
00012 #include "psm.h"
00013
00014 #define _RPMDB_INTERNAL
00015 #include "rpmdb.h"
00016
00017 #include "rpmds.h"
00018
00019 #include "rpmlock.h"
00020
00021 #define _RPMFI_INTERNAL
00022 #include "rpmfi.h"
00023
00024 #define _RPMTE_INTERNAL
00025 #include "rpmte.h"
00026
00027 #define _RPMTS_INTERNAL
00028 #include "rpmts.h"
00029
00030 #include "cpio.h"
00031 #include "fprint.h"
00032 #include "legacy.h"
00033 #include "misc.h"
00034
00035 #include "debug.h"
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 extern void * rpmShowProgress( const void * arg,
00061 const rpmCallbackType what,
00062 const unsigned long long amount,
00063 const unsigned long long total,
00064 fnpyKey key,
00065 void * data)
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
00094
00095 static int handleInstInstalledFiles(const rpmts ts,
00096 rpmte p, rpmfi fi,
00097 sharedFileInfo shared,
00098 int sharedCount, int reportConflicts)
00099
00100
00101 {
00102 uint_32 tscolor = rpmtsColor(ts);
00103 uint_32 prefcolor = rpmtsPrefColor(ts);
00104 uint_32 otecolor, tecolor;
00105 uint_32 oFColor, FColor;
00106 uint_32 oFFlags, FFlags;
00107 const char * altNEVRA = NULL;
00108 rpmfi otherFi = NULL;
00109 int numReplaced = 0;
00110 rpmps ps;
00111 int i;
00112
00113 { rpmdbMatchIterator mi;
00114 Header h;
00115 int scareMem = 0;
00116
00117 mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES,
00118 &shared->otherPkg, sizeof(shared->otherPkg));
00119 while ((h = rpmdbNextIterator(mi)) != NULL) {
00120 altNEVRA = hGetNEVRA(h, NULL);
00121 otherFi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
00122 break;
00123 }
00124 mi = rpmdbFreeIterator(mi);
00125 }
00126
00127
00128 tecolor = rpmteColor(p);
00129 tecolor &= tscolor;
00130
00131
00132 otecolor = 0;
00133 otherFi = rpmfiInit(otherFi, 0);
00134 if (otherFi != NULL)
00135 while (rpmfiNext(otherFi) >= 0)
00136 otecolor |= rpmfiFColor(otherFi);
00137 otecolor &= tscolor;
00138
00139 if (otherFi == NULL)
00140 return 1;
00141
00142 fi->replaced = xcalloc(sharedCount, sizeof(*fi->replaced));
00143
00144 ps = rpmtsProblems(ts);
00145 for (i = 0; i < sharedCount; i++, shared++) {
00146 int otherFileNum, fileNum;
00147
00148 otherFileNum = shared->otherFileNum;
00149 (void) rpmfiSetFX(otherFi, otherFileNum);
00150 oFFlags = rpmfiFFlags(otherFi);
00151 oFColor = rpmfiFColor(otherFi);
00152 oFColor &= tscolor;
00153
00154 fileNum = shared->pkgFileNum;
00155 (void) rpmfiSetFX(fi, fileNum);
00156 FFlags = rpmfiFFlags(fi);
00157 FColor = rpmfiFColor(fi);
00158 FColor &= tscolor;
00159
00160 #ifdef DYING
00161
00162 if (otherStates && otherStates[otherFileNum] != RPMFILE_STATE_NORMAL)
00163 continue;
00164 #endif
00165
00166 if (XFA_SKIPPING(fi->actions[fileNum]))
00167 continue;
00168
00169
00170 if (!(fi->mapflags & CPIO_SBIT_CHECK)) {
00171 int_16 omode = rpmfiFMode(otherFi);
00172 if (S_ISREG(omode) && (omode & 06000) != 0)
00173 fi->mapflags |= CPIO_SBIT_CHECK;
00174 }
00175
00176 if (((FFlags | oFFlags) & RPMFILE_GHOST))
00177 continue;
00178
00179 if (rpmfiCompare(otherFi, fi)) {
00180 int rConflicts;
00181
00182 rConflicts = reportConflicts;
00183
00184 if (tscolor != 0 && FColor != 0 && FColor != oFColor)
00185 {
00186 if (oFColor & prefcolor) {
00187 fi->actions[fileNum] = FA_SKIPCOLOR;
00188 rConflicts = 0;
00189 } else
00190 if (FColor & prefcolor) {
00191 fi->actions[fileNum] = FA_CREATE;
00192 rConflicts = 0;
00193 }
00194 }
00195
00196 if (rConflicts) {
00197 rpmpsAppend(ps, RPMPROB_FILE_CONFLICT,
00198 rpmteNEVRA(p), rpmteKey(p),
00199 rpmfiDN(fi), rpmfiBN(fi),
00200 altNEVRA,
00201 0);
00202 }
00203
00204
00205 if ( !(((FFlags | oFFlags) & RPMFILE_CONFIG) || XFA_SKIPPING(fi->actions[fileNum])) ) {
00206
00207 if (!shared->isRemoved)
00208 fi->replaced[numReplaced++] = *shared;
00209
00210 }
00211 }
00212
00213
00214 if (((FFlags | oFFlags) & RPMFILE_CONFIG)) {
00215 int skipMissing =
00216 ((rpmtsFlags(ts) & RPMTRANS_FLAG_ALLFILES) ? 0 : 1);
00217 fileAction action = rpmfiDecideFate(otherFi, fi, skipMissing);
00218 fi->actions[fileNum] = action;
00219 }
00220 fi->replacedSizes[fileNum] = rpmfiFSize(otherFi);
00221 }
00222 ps = rpmpsFree(ps);
00223
00224 altNEVRA = _free(altNEVRA);
00225 otherFi = rpmfiFree(otherFi);
00226
00227 fi->replaced = xrealloc(fi->replaced,
00228 sizeof(*fi->replaced) * (numReplaced + 1));
00229 fi->replaced[numReplaced].otherPkg = 0;
00230
00231 return 0;
00232 }
00233
00234
00237
00238 static int handleRmvdInstalledFiles(const rpmts ts, rpmfi fi,
00239 sharedFileInfo shared, int sharedCount)
00240
00241
00242 {
00243 HGE_t hge = fi->hge;
00244 Header h;
00245 const char * otherStates;
00246 int i, xx;
00247
00248 rpmdbMatchIterator mi;
00249
00250 mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES,
00251 &shared->otherPkg, sizeof(shared->otherPkg));
00252 h = rpmdbNextIterator(mi);
00253 if (h == NULL) {
00254 mi = rpmdbFreeIterator(mi);
00255 return 1;
00256 }
00257
00258 xx = hge(h, RPMTAG_FILESTATES, NULL, &otherStates, NULL);
00259
00260
00261
00262 if (otherStates != NULL)
00263 for (i = 0; i < sharedCount; i++, shared++) {
00264 int otherFileNum, fileNum;
00265 otherFileNum = shared->otherFileNum;
00266 fileNum = shared->pkgFileNum;
00267
00268 if (otherStates[otherFileNum] != RPMFILE_STATE_NORMAL)
00269 continue;
00270
00271 fi->actions[fileNum] = FA_SKIP;
00272 }
00273
00274
00275 mi = rpmdbFreeIterator(mi);
00276
00277 return 0;
00278 }
00279
00280 #define ISROOT(_d) (((_d)[0] == '/' && (_d)[1] == '\0') ? "" : (_d))
00281
00282
00283 int _fps_debug = 0;
00284
00285 static int fpsCompare (const void * one, const void * two)
00286
00287 {
00288 const struct fingerPrint_s * a = (const struct fingerPrint_s *)one;
00289 const struct fingerPrint_s * b = (const struct fingerPrint_s *)two;
00290 int adnlen = strlen(a->entry->dirName);
00291 int asnlen = (a->subDir ? strlen(a->subDir) : 0);
00292 int abnlen = strlen(a->baseName);
00293 int bdnlen = strlen(b->entry->dirName);
00294 int bsnlen = (b->subDir ? strlen(b->subDir) : 0);
00295 int bbnlen = strlen(b->baseName);
00296 char * afn, * bfn, * t;
00297 int rc = 0;
00298
00299 if (adnlen == 1 && asnlen != 0) adnlen = 0;
00300 if (bdnlen == 1 && bsnlen != 0) bdnlen = 0;
00301
00302
00303 afn = t = alloca(adnlen+asnlen+abnlen+2);
00304 if (adnlen) t = stpcpy(t, a->entry->dirName);
00305 *t++ = '/';
00306 if (a->subDir && asnlen) t = stpcpy(t, a->subDir);
00307 if (abnlen) t = stpcpy(t, a->baseName);
00308 if (afn[0] == '/' && afn[1] == '/') afn++;
00309
00310 bfn = t = alloca(bdnlen+bsnlen+bbnlen+2);
00311 if (bdnlen) t = stpcpy(t, b->entry->dirName);
00312 *t++ = '/';
00313 if (b->subDir && bsnlen) t = stpcpy(t, b->subDir);
00314 if (bbnlen) t = stpcpy(t, b->baseName);
00315 if (bfn[0] == '/' && bfn[1] == '/') bfn++;
00316
00317
00318 rc = strcmp(afn, bfn);
00319
00320 return rc;
00321 }
00322
00323
00324 static int _linear_fps_search = 0;
00325
00326 static int findFps(const struct fingerPrint_s * fiFps,
00327 const struct fingerPrint_s * otherFps,
00328 int otherFc)
00329
00330 {
00331 int otherFileNum;
00332
00333 if (_linear_fps_search) {
00334
00335 linear:
00336 for (otherFileNum = 0; otherFileNum < otherFc; otherFileNum++, otherFps++) {
00337
00338
00339 if (fiFps == otherFps)
00340 break;
00341
00342
00343
00344 if (FP_EQUAL((*fiFps), (*otherFps)))
00345 break;
00346
00347 }
00348
00349 return otherFileNum;
00350
00351 } else {
00352
00353 const struct fingerPrint_s * bingoFps;
00354
00355
00356 bingoFps = bsearch(fiFps, otherFps, otherFc, sizeof(*otherFps), fpsCompare);
00357
00358 if (bingoFps == NULL)
00359 goto linear;
00360
00361
00362 if (!(fiFps == bingoFps || FP_EQUAL((*fiFps), (*bingoFps))))
00363 goto linear;
00364
00365 otherFileNum = (bingoFps != NULL ? (bingoFps - otherFps) : 0);
00366
00367 }
00368
00369 return otherFileNum;
00370 }
00371
00375
00376 static void handleOverlappedFiles(const rpmts ts,
00377 const rpmte p, rpmfi fi)
00378
00379
00380 {
00381 uint_32 fixupSize = 0;
00382 rpmps ps;
00383 const char * fn;
00384 int i, j;
00385
00386 ps = rpmtsProblems(ts);
00387 fi = rpmfiInit(fi, 0);
00388 if (fi != NULL)
00389 while ((i = rpmfiNext(fi)) >= 0) {
00390 uint_32 tscolor = rpmtsColor(ts);
00391 uint_32 prefcolor = rpmtsPrefColor(ts);
00392 uint_32 oFColor, FColor;
00393 struct fingerPrint_s * fiFps;
00394 int otherPkgNum, otherFileNum;
00395 rpmfi otherFi;
00396 int_32 FFlags;
00397 int_16 FMode;
00398 const rpmfi * recs;
00399 int numRecs;
00400
00401 if (XFA_SKIPPING(fi->actions[i]))
00402 continue;
00403
00404 fn = rpmfiFN(fi);
00405 fiFps = fi->fps + i;
00406 FFlags = rpmfiFFlags(fi);
00407 FMode = rpmfiFMode(fi);
00408 FColor = rpmfiFColor(fi);
00409 FColor &= tscolor;
00410
00411 fixupSize = 0;
00412
00413
00414
00415
00416
00417
00418
00419 (void) htGetEntry(ts->ht, fiFps,
00420 (const void ***) &recs, &numRecs, NULL);
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 for (j = 0; j < numRecs && recs[j] != fi; j++)
00445 {};
00446
00447
00448 otherFileNum = -1;
00449 otherFi = NULL;
00450 for (otherPkgNum = j - 1; otherPkgNum >= 0; otherPkgNum--) {
00451 struct fingerPrint_s * otherFps;
00452 int otherFc;
00453
00454 otherFi = recs[otherPkgNum];
00455
00456
00457 if (rpmteType(p) == TR_ADDED && rpmteType(otherFi->te) != TR_ADDED)
00458 continue;
00459
00460 otherFps = otherFi->fps;
00461 otherFc = rpmfiFC(otherFi);
00462
00463 otherFileNum = findFps(fiFps, otherFps, otherFc);
00464 (void) rpmfiSetFX(otherFi, otherFileNum);
00465
00466
00467 if (otherFi->actions[otherFileNum] != FA_UNKNOWN)
00468 break;
00469 }
00470
00471 oFColor = rpmfiFColor(otherFi);
00472 oFColor &= tscolor;
00473
00474
00475 switch (rpmteType(p)) {
00476 case TR_ADDED:
00477 { int reportConflicts =
00478 !(rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACENEWFILES);
00479 int done = 0;
00480
00481 if (otherPkgNum < 0) {
00482
00483 if (fi->actions[i] != FA_UNKNOWN)
00484 break;
00485 if ((FFlags & RPMFILE_CONFIG) && (FFlags & RPMFILE_EXISTS)) {
00486
00487 fi->actions[i] = (FFlags & RPMFILE_NOREPLACE)
00488 ? FA_ALTNAME : FA_BACKUP;
00489 } else {
00490 fi->actions[i] = FA_CREATE;
00491 }
00492 break;
00493 }
00494
00495 assert(otherFi != NULL);
00496
00497 if (rpmfiCompare(otherFi, fi)) {
00498 int rConflicts;
00499
00500 rConflicts = reportConflicts;
00501
00502 if (tscolor != 0) {
00503 if (FColor & prefcolor) {
00504
00505 if (!XFA_SKIPPING(fi->actions[i])) {
00506
00507 if (strcmp(fn, "/usr/sbin/libgcc_post_upgrade")
00508 && strcmp(fn, "/usr/sbin/glibc_post_upgrade"))
00509 otherFi->actions[otherFileNum] = FA_SKIPCOLOR;
00510 }
00511 fi->actions[i] = FA_CREATE;
00512 rConflicts = 0;
00513 } else
00514 if (oFColor & prefcolor) {
00515
00516 if (XFA_SKIPPING(fi->actions[i]))
00517 otherFi->actions[otherFileNum] = FA_CREATE;
00518 fi->actions[i] = FA_SKIPCOLOR;
00519 rConflicts = 0;
00520 } else
00521 if (FColor == 0 && oFColor == 0) {
00522
00523 otherFi->actions[otherFileNum] = FA_CREATE;
00524 fi->actions[i] = FA_CREATE;
00525 rConflicts = 0;
00526 }
00527 done = 1;
00528 }
00529
00530 if (rConflicts) {
00531 rpmpsAppend(ps, RPMPROB_NEW_FILE_CONFLICT,
00532 rpmteNEVR(p), rpmteKey(p),
00533 fn, NULL,
00534 rpmteNEVR(otherFi->te),
00535 0);
00536 }
00537 }
00538
00539
00540 fixupSize = rpmfiFSize(otherFi);
00541
00542 if ((FFlags & RPMFILE_CONFIG) && (FFlags & RPMFILE_EXISTS)) {
00543
00544 fi->actions[i] = (FFlags & RPMFILE_NOREPLACE)
00545 ? FA_ALTNAME : FA_SKIP;
00546 } else {
00547 if (!done)
00548 fi->actions[i] = FA_CREATE;
00549 }
00550 } break;
00551
00552 case TR_REMOVED:
00553 if (otherPkgNum >= 0) {
00554 assert(otherFi != NULL);
00555
00556 if (otherFi->actions[otherFileNum] != FA_ERASE) {
00557
00558 fi->actions[i] = FA_SKIP;
00559 break;
00560 }
00561
00562 otherFi->actions[otherFileNum] = FA_SKIP;
00563 }
00564 if (XFA_SKIPPING(fi->actions[i]))
00565 break;
00566 if (rpmfiFState(fi) != RPMFILE_STATE_NORMAL)
00567 break;
00568
00569
00570 fi->actions[i] = FA_ERASE;
00571 if (!(S_ISREG(FMode) && (FFlags & RPMFILE_CONFIG)))
00572 break;
00573
00574
00575 if (!(FFlags & RPMFILE_SPARSE))
00576 { int dalgo = 0;
00577 size_t dlen = 0;
00578 const unsigned char * digest = rpmfiDigest(fi, &dalgo, &dlen);
00579 unsigned char * fdigest;
00580 assert(digest != NULL);
00581
00582 fdigest = xcalloc(1, dlen);
00583
00584 if (!dodigest(dalgo, fn, fdigest, 0, NULL)
00585 && memcmp(digest, fdigest, dlen))
00586 fi->actions[i] = FA_BACKUP;
00587 fdigest = _free(fdigest);
00588 }
00589 break;
00590 }
00591
00592
00593
00594 rpmtsUpdateDSI(ts, fiFps->entry->dev, rpmfiFSize(fi),
00595 fi->replacedSizes[i], fixupSize, fi->actions[i]);
00596
00597 }
00598 ps = rpmpsFree(ps);
00599 }
00600
00608
00609 static int ensureOlder(rpmts ts,
00610 const rpmte p, const Header h)
00611
00612 {
00613 int_32 reqFlags = (RPMSENSE_LESS | RPMSENSE_EQUAL);
00614 const char * reqEVR;
00615 rpmds req;
00616 char * t;
00617 int nb;
00618 int rc;
00619
00620 if (p == NULL || h == NULL)
00621 return 1;
00622
00623
00624 nb = strlen(rpmteNEVR(p)) + (rpmteE(p) != NULL ? strlen(rpmteE(p)) : 0) + 1;
00625 t = alloca(nb);
00626 *t = '\0';
00627 reqEVR = t;
00628 if (rpmteE(p) != NULL) t = stpcpy( stpcpy(t, rpmteE(p)), ":");
00629 if (rpmteV(p) != NULL) t = stpcpy(t, rpmteV(p));
00630 *t++ = '-';
00631 if (rpmteR(p) != NULL) t = stpcpy(t, rpmteR(p));
00632
00633
00634 req = rpmdsSingle(RPMTAG_REQUIRENAME, rpmteN(p), reqEVR, reqFlags);
00635 rc = rpmdsNVRMatchesDep(h, req, _rpmds_nopromote);
00636 req = rpmdsFree(req);
00637
00638 if (rc == 0) {
00639 rpmps ps = rpmtsProblems(ts);
00640 const char * altNEVR = hGetNEVR(h, NULL);
00641 rpmpsAppend(ps, RPMPROB_OLDPACKAGE,
00642 rpmteNEVR(p), rpmteKey(p),
00643 NULL, NULL,
00644 altNEVR,
00645 0);
00646 altNEVR = _free(altNEVR);
00647 ps = rpmpsFree(ps);
00648 rc = 1;
00649 } else
00650 rc = 0;
00651
00652 return rc;
00653 }
00654
00655
00661
00662
00663
00664 static void skipFiles(const rpmts ts, rpmfi fi)
00665
00666
00667 {
00668 uint_32 tscolor = rpmtsColor(ts);
00669 uint_32 FColor;
00670 int noConfigs = (rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONFIGS);
00671 int noDocs = (rpmtsFlags(ts) & RPMTRANS_FLAG_NODOCS);
00672 char ** netsharedPaths = NULL;
00673 const char ** languages;
00674 const char * dn, * bn;
00675 int dnlen, bnlen, ix;
00676 const char * s;
00677 int * drc;
00678 char * dff;
00679 int dc;
00680 int i, j;
00681
00682 if (!noDocs)
00683 noDocs = rpmExpandNumeric("%{_excludedocs}");
00684
00685 { const char *tmpPath = rpmExpand("%{_netsharedpath}", NULL);
00686
00687 if (tmpPath && *tmpPath != '%')
00688 netsharedPaths = splitString(tmpPath, strlen(tmpPath), ':');
00689
00690 tmpPath = _free(tmpPath);
00691 }
00692
00693 s = rpmExpand("%{_install_langs}", NULL);
00694
00695 if (!(s && *s != '%'))
00696 s = _free(s);
00697 if (s) {
00698 languages = (const char **) splitString(s, strlen(s), ':');
00699 s = _free(s);
00700 } else
00701 languages = NULL;
00702
00703
00704
00705 dc = rpmfiDC(fi);
00706 drc = alloca(dc * sizeof(*drc));
00707 memset(drc, 0, dc * sizeof(*drc));
00708 dff = alloca(dc * sizeof(*dff));
00709 memset(dff, 0, dc * sizeof(*dff));
00710
00711 fi = rpmfiInit(fi, 0);
00712 if (fi != NULL)
00713 while ((i = rpmfiNext(fi)) >= 0)
00714 {
00715 char ** nsp;
00716
00717 bn = rpmfiBN(fi);
00718 bnlen = strlen(bn);
00719 ix = rpmfiDX(fi);
00720 dn = rpmfiDN(fi);
00721 if (dn == NULL)
00722 continue;
00723 dnlen = strlen(dn);
00724
00725 drc[ix]++;
00726
00727
00728 if (XFA_SKIPPING(fi->actions[i])) {
00729 drc[ix]--; dff[ix] = 1;
00730 continue;
00731 }
00732
00733
00734 FColor = rpmfiFColor(fi);
00735 if (tscolor && FColor && !(tscolor & FColor)) {
00736 drc[ix]--; dff[ix] = 1;
00737 fi->actions[i] = FA_SKIPCOLOR;
00738 continue;
00739 }
00740
00741
00742
00743
00744
00745
00746 for (nsp = netsharedPaths; nsp && *nsp; nsp++) {
00747 int len;
00748
00749 len = strlen(*nsp);
00750 if (dnlen >= len) {
00751 if (strncmp(dn, *nsp, len))
00752 continue;
00753
00754 if (!(dn[len] == '/' || dn[len] == '\0'))
00755 continue;
00756 } else {
00757 if (len < (dnlen + bnlen))
00758 continue;
00759 if (strncmp(dn, *nsp, dnlen))
00760 continue;
00761
00762 if ((s = strchr((*nsp) + dnlen, '/')) != NULL && s[1] != '\0')
00763 continue;
00764 if (strncmp(bn, (*nsp) + dnlen, bnlen))
00765 continue;
00766 len = dnlen + bnlen;
00767
00768 if (!((*nsp)[len] == '/' || (*nsp)[len] == '\0'))
00769 continue;
00770 }
00771
00772 break;
00773 }
00774
00775 if (nsp && *nsp) {
00776 drc[ix]--; dff[ix] = 1;
00777 fi->actions[i] = FA_SKIPNETSHARED;
00778 continue;
00779 }
00780
00781
00782
00783
00784 if (languages != NULL && fi->flangs != NULL && *fi->flangs[i]) {
00785 const char **lang, *l, *le;
00786 for (lang = languages; *lang != NULL; lang++) {
00787 if (!strcmp(*lang, "all"))
00788 break;
00789 for (l = fi->flangs[i]; *l != '\0'; l = le) {
00790 for (le = l; *le != '\0' && *le != '|'; le++)
00791 {};
00792 if ((le-l) > 0 && !strncmp(*lang, l, (le-l)))
00793 break;
00794 if (*le == '|') le++;
00795 }
00796 if (*l != '\0')
00797 break;
00798 }
00799 if (*lang == NULL) {
00800 drc[ix]--; dff[ix] = 1;
00801 fi->actions[i] = FA_SKIPNSTATE;
00802 continue;
00803 }
00804 }
00805
00806
00807
00808
00809 if (noConfigs && (rpmfiFFlags(fi) & RPMFILE_CONFIG)) {
00810 drc[ix]--; dff[ix] = 1;
00811 fi->actions[i] = FA_SKIPNSTATE;
00812 continue;
00813 }
00814
00815
00816
00817
00818 if (noDocs && (rpmfiFFlags(fi) & RPMFILE_DOC)) {
00819 drc[ix]--; dff[ix] = 1;
00820 fi->actions[i] = FA_SKIPNSTATE;
00821 continue;
00822 }
00823 }
00824
00825
00826 #ifndef NOTYET
00827 if (fi != NULL)
00828 for (j = 0; j < dc; j++)
00829 #else
00830 if ((fi = rpmfiInitD(fi)) != NULL)
00831 while (j = rpmfiNextD(fi) >= 0)
00832 #endif
00833 {
00834
00835 if (drc[j]) continue;
00836 if (!dff[j]) continue;
00837
00838
00839 dn = fi->dnl[j]; dnlen = strlen(dn) - 1;
00840 bn = dn + dnlen; bnlen = 0;
00841 while (bn > dn && bn[-1] != '/') {
00842 bnlen++;
00843 dnlen--;
00844 bn--;
00845 }
00846
00847
00848 fi = rpmfiInit(fi, 0);
00849 if (fi != NULL)
00850 while ((i = rpmfiNext(fi)) >= 0) {
00851 const char * fdn, * fbn;
00852 int_16 fFMode;
00853
00854 if (XFA_SKIPPING(fi->actions[i]))
00855 continue;
00856
00857 fFMode = rpmfiFMode(fi);
00858
00859 if (whatis(fFMode) != XDIR)
00860 continue;
00861 fdn = rpmfiDN(fi);
00862 if (strlen(fdn) != dnlen)
00863 continue;
00864 if (strncmp(fdn, dn, dnlen))
00865 continue;
00866 fbn = rpmfiBN(fi);
00867 if (strlen(fbn) != bnlen)
00868 continue;
00869 if (strncmp(fbn, bn, bnlen))
00870 continue;
00871 rpmMessage(RPMMESS_DEBUG, D_("excluding directory %s\n"), dn);
00872 fi->actions[i] = FA_SKIPNSTATE;
00873 break;
00874 }
00875 }
00876
00877
00878 if (netsharedPaths) freeSplitString(netsharedPaths);
00879 if (languages) freeSplitString((char **)languages);
00880
00881 }
00882
00883
00884
00885
00892 static
00893 rpmfi rpmtsiFi(const rpmtsi tsi)
00894
00895 {
00896 rpmfi fi = NULL;
00897
00898 if (tsi != NULL && tsi->ocsave != -1) {
00899
00900 rpmte te = rpmtsElement(tsi->ts, tsi->ocsave);
00901
00902 if (te != NULL && (fi = te->fi) != NULL)
00903 fi->te = te;
00904
00905
00906 }
00907
00908 return fi;
00909
00910 }
00911
00918
00919 static rpmRC _processFailedPackage(rpmts ts, rpmte p)
00920
00921
00922 {
00923 int rc = RPMRC_OK;
00924
00925
00926
00927 if (p != NULL && rpmteType(p) == TR_ADDED && !p->installed) {
00928
00929 rpmpsm psm = rpmpsmNew(ts, p, p->fi);
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939 assert(psm != NULL);
00940 psm->stepName = "failed";
00941 rc = rpmpsmStage(psm, PSM_RPMDB_ADD);
00942 psm = rpmpsmFree(psm);
00943 }
00944 return rc;
00945 }
00946
00947
00948
00949 rpmRC rpmtsRollback(rpmts rbts, rpmprobFilterFlags ignoreSet, int running, rpmte rbte)
00950
00951
00952 {
00953 const char * semfn = NULL;
00954 rpmRC rc = 0;
00955 uint_32 arbgoal = rpmtsARBGoal(rbts);
00956 QVA_t ia = memset(alloca(sizeof(*ia)), 0, sizeof(*ia));
00957 time_t ttid;
00958 int xx;
00959
00960
00961 if ((rpmtsType(rbts) & RPMTRANS_TYPE_ROLLBACK) ||
00962 (rpmtsType(rbts) & RPMTRANS_TYPE_AUTOROLLBACK))
00963 return RPMRC_OK;
00964
00965 if (arbgoal == 0xffffffff)
00966 arbgoal = rpmtsGetTid(rbts);
00967
00968
00969 if (!running && arbgoal == 0xffffffff)
00970 return RPMRC_OK;
00971
00972
00973
00974
00975
00976
00977 { rpmtsi tsi;
00978 rpmte te;
00979
00980
00981 rpmtsOpenDB(rbts, O_RDWR);
00982
00983 tsi = rpmtsiInit(rbts);
00984 while((te = rpmtsiNext(tsi, TR_REMOVED)) != NULL) {
00985 if(!te->u.removed.dboffset)
00986 continue;
00987 rc = rpmdbRemove(rpmtsGetRdb(rbts),
00988 rpmtsGetTid(rbts),
00989 te->u.removed.dboffset, NULL, NULL);
00990 if (rc != RPMRC_OK) {
00991 rpmMessage(RPMMESS_ERROR, _("rpmdb erase failed. NEVRA: %s\n"),
00992 rpmteNEVRA(te));
00993 break;
00994 }
00995 }
00996 tsi = rpmtsiFree(tsi);
00997 if (rc != RPMRC_OK)
00998 goto cleanup;
00999 }
01000
01001
01002 rc = _processFailedPackage(rbts, rbte);
01003 if (rc != RPMRC_OK)
01004 goto cleanup;
01005
01006 rpmtsEmpty(rbts);
01007
01008 ttid = (time_t)arbgoal;
01009 rpmMessage(RPMMESS_NORMAL, _("Rollback to %-24.24s (0x%08x)\n"),
01010 ctime(&ttid), arbgoal);
01011
01012
01013
01014
01015
01016 {
01017 rpmVSFlags vsflags = rpmExpandNumeric("%{?_vsflags_erase}");
01018 vsflags |= _RPMVSF_NODIGESTS;
01019 vsflags |= _RPMVSF_NOSIGNATURES;
01020 vsflags |= RPMVSF_NOHDRCHK;
01021 vsflags |= RPMVSF_NEEDPAYLOAD;
01022 xx = rpmtsSetVSFlags(rbts, vsflags);
01023 }
01024
01025
01026 {
01027 rpmtransFlags tsFlags = rpmtsFlags(rbts);
01028 tsFlags &= ~RPMTRANS_FLAG_DIRSTASH;
01029 tsFlags &= ~RPMTRANS_FLAG_REPACKAGE;
01030 tsFlags |= RPMTRANS_FLAG_NOFDIGESTS;
01031 tsFlags = rpmtsSetFlags(rbts, tsFlags);
01032 }
01033
01034
01035 ia->rbtid = arbgoal;
01036
01037 ia->transFlags = rpmtsFlags(rbts);
01038 ia->depFlags = rpmtsDFlags(rbts);
01039
01040 ia->probFilter = ignoreSet;
01041
01042 ia->installInterfaceFlags = INSTALL_UPGRADE | INSTALL_HASH ;
01043
01044
01045 ia->no_rollback_links = 1;
01046
01047
01048 semfn = rpmExpand("%{?semaphore_backout}", NULL);
01049 if (semfn && *semfn) {
01050 FD_t fd = Fopen(semfn, "w.fdio");
01051 if (fd)
01052 xx = Fclose(fd);
01053 }
01054
01055
01056 rc = rpmRollback(rbts, ia, NULL);
01057
01058
01059 cleanup:
01060
01061 if (semfn && *semfn)
01062 xx = Unlink(semfn);
01063 semfn = _free(semfn);
01064
01065 return rc;
01066 }
01067
01068
01075 static int cmpArgvStr( const char ** AV, const char * B)
01076
01077 {
01078 const char ** a;
01079
01080 if (AV != NULL && B != NULL)
01081 for (a = AV; *a != NULL; a++) {
01082 if (**a && *B && !strcmp(*a, B))
01083 return 1;
01084 }
01085 return 0;
01086 }
01087
01088
01095 static int markLinkedFailed(rpmts ts, rpmte p)
01096
01097
01098 {
01099 rpmtsi qi; rpmte q;
01100 int bingo;
01101
01102 p->linkFailed = 1;
01103
01104 qi = rpmtsiInit(ts);
01105 while ((q = rpmtsiNext(qi, TR_REMOVED)) != NULL) {
01106
01107 if (q->done)
01108 continue;
01109
01110
01111
01112
01113
01114 bingo = cmpArgvStr(q->flink.Hdrid, p->hdrid);
01115 if (!bingo)
01116 bingo = cmpArgvStr(q->flink.Pkgid, p->pkgid);
01117 if (!bingo)
01118 bingo = cmpArgvStr(q->flink.NEVRA, p->NEVRA);
01119
01120 if (!bingo)
01121 continue;
01122
01123 q->linkFailed = p->linkFailed;
01124 }
01125 qi = rpmtsiFree(qi);
01126
01127 return 0;
01128 }
01129
01130 #define NOTIFY(_ts, _al) if ((_ts)->notify) (void) (_ts)->notify _al
01131
01132 int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
01133 {
01134 uint_32 tscolor = rpmtsColor(ts);
01135 int i, j;
01136 int ourrc = 0;
01137 int totalFileCount = 0;
01138 rpmfi fi;
01139 sharedFileInfo shared, sharedList;
01140 int numShared;
01141 int nexti;
01142 fingerPrintCache fpc;
01143 rpmps ps;
01144 rpmpsm psm;
01145 rpmtsi pi; rpmte p;
01146 rpmtsi qi; rpmte q;
01147 int numAdded;
01148 int numRemoved;
01149 int rollbackFailures = 0;
01150 void * lock = NULL;
01151 int xx;
01152
01153
01154 if (rpmtsNElements(ts) <= 0) {
01155 rpmMessage(RPMMESS_ERROR,
01156 _("Invalid number of transaction elements.\n"));
01157 return -1;
01158 }
01159
01160 rollbackFailures = rpmExpandNumeric("%{?_rollback_transaction_on_failure}");
01161
01162 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_REPACKAGE))
01163 rollbackFailures = 0;
01164
01165 if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)
01166 rollbackFailures = 0;
01167
01168 if (rpmtsType(ts) & (RPMTRANS_TYPE_ROLLBACK | RPMTRANS_TYPE_AUTOROLLBACK))
01169 rollbackFailures = 0;
01170
01171
01172
01173
01174
01175
01176 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST))
01177 lock = rpmtsAcquireLock(ts);
01178
01179
01180
01181 if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOSCRIPTS)
01182 (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers));
01183
01184 if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERS)
01185 (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransTriggers));
01186
01187
01188 if (rpmtsFlags(ts) & RPMTRANS_FLAG_JUSTDB)
01189 (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers));
01190
01191 ts->probs = rpmpsFree(ts->probs);
01192 ts->probs = rpmpsCreate();
01193
01194
01195 { int dbmode = (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)
01196 ? O_RDONLY : (O_RDWR|O_CREAT);
01197
01198
01199 if (rpmtsOpenDB(ts, dbmode)) {
01200 lock = rpmtsFreeLock(lock);
01201 return -1;
01202 }
01203 }
01204
01205 ts->ignoreSet = ignoreSet;
01206 { const char * currDir = currentDirectory();
01207 rpmtsSetCurrDir(ts, currDir);
01208 currDir = _free(currDir);
01209 }
01210
01211 (void) rpmtsSetChrootDone(ts, 0);
01212
01213
01214 { int_32 tid = (int_32) time(NULL);
01215 (void) rpmtsSetTid(ts, tid);
01216 }
01217
01218
01219 xx = rpmtsInitDSI(ts);
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229 rpmMessage(RPMMESS_DEBUG, D_("sanity checking %d elements\n"), rpmtsNElements(ts));
01230 ps = rpmtsProblems(ts);
01231
01232 pi = rpmtsiInit(ts);
01233
01234 while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
01235 rpmdbMatchIterator mi;
01236 int fc;
01237
01238 if ((fi = rpmtsiFi(pi)) == NULL)
01239 continue;
01240 fc = rpmfiFC(fi);
01241
01242 if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_OLDPACKAGE)) {
01243 Header h;
01244 mi = rpmtsInitIterator(ts, RPMTAG_NAME, rpmteN(p), 0);
01245 while ((h = rpmdbNextIterator(mi)) != NULL)
01246 xx = ensureOlder(ts, p, h);
01247 mi = rpmdbFreeIterator(mi);
01248 }
01249
01250 if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEPKG)) {
01251 mi = rpmtsInitIterator(ts, RPMTAG_NAME, rpmteN(p), 0);
01252 xx = rpmdbSetIteratorRE(mi, RPMTAG_EPOCH, RPMMIRE_STRCMP,
01253 rpmteE(p));
01254 xx = rpmdbSetIteratorRE(mi, RPMTAG_VERSION, RPMMIRE_STRCMP,
01255 rpmteV(p));
01256 xx = rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, RPMMIRE_STRCMP,
01257 rpmteR(p));
01258 if (tscolor) {
01259 xx = rpmdbSetIteratorRE(mi, RPMTAG_ARCH, RPMMIRE_STRCMP,
01260 rpmteA(p));
01261 xx = rpmdbSetIteratorRE(mi, RPMTAG_OS, RPMMIRE_STRCMP,
01262 rpmteO(p));
01263 }
01264
01265 while (rpmdbNextIterator(mi) != NULL) {
01266 rpmpsAppend(ps, RPMPROB_PKG_INSTALLED,
01267 rpmteNEVR(p), rpmteKey(p),
01268 NULL, NULL,
01269 NULL, 0);
01270 break;
01271 }
01272 mi = rpmdbFreeIterator(mi);
01273 }
01274
01275
01276 totalFileCount += fc;
01277
01278 }
01279 pi = rpmtsiFree(pi);
01280 ps = rpmpsFree(ps);
01281
01282
01283 pi = rpmtsiInit(ts);
01284 while ((p = rpmtsiNext(pi, TR_REMOVED)) != NULL) {
01285 int fc;
01286
01287 if ((fi = rpmtsiFi(pi)) == NULL)
01288 continue;
01289 fc = rpmfiFC(fi);
01290
01291 totalFileCount += fc;
01292 }
01293 pi = rpmtsiFree(pi);
01294
01295
01296
01297
01298 if (!((rpmtsFlags(ts) & (RPMTRANS_FLAG_BUILD_PROBS|RPMTRANS_FLAG_TEST))
01299 || (rpmpsNumProblems(ts->probs) &&
01300 (okProbs == NULL || rpmpsTrim(ts->probs, okProbs)))))
01301 {
01302 rpmMessage(RPMMESS_DEBUG, D_("running pre-transaction scripts\n"));
01303 pi = rpmtsiInit(ts);
01304 while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
01305 if ((fi = rpmtsiFi(pi)) == NULL)
01306 continue;
01307
01308
01309 if (fi->pretrans == NULL)
01310 continue;
01311
01312 p->fd = ts->notify(p->h, RPMCALLBACK_INST_OPEN_FILE, 0, 0,
01313 rpmteKey(p), ts->notifyData);
01314 p->h = NULL;
01315 if (rpmteFd(p) != NULL) {
01316 rpmVSFlags ovsflags = rpmtsVSFlags(ts);
01317 rpmVSFlags vsflags = ovsflags | RPMVSF_NEEDPAYLOAD;
01318 rpmRC rpmrc;
01319 ovsflags = rpmtsSetVSFlags(ts, vsflags);
01320 rpmrc = rpmReadPackageFile(ts, rpmteFd(p),
01321 rpmteNEVR(p), &p->h);
01322 vsflags = rpmtsSetVSFlags(ts, ovsflags);
01323 switch (rpmrc) {
01324 default:
01325
01326 p->fd = ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE,
01327 0, 0,
01328 rpmteKey(p), ts->notifyData);
01329
01330 p->fd = NULL;
01331 break;
01332 case RPMRC_NOTTRUSTED:
01333 case RPMRC_NOKEY:
01334 case RPMRC_OK:
01335 break;
01336 }
01337 }
01338
01339
01340 if (rpmteFd(p) != NULL) {
01341 fi = rpmfiNew(ts, p->h, RPMTAG_BASENAMES, 1);
01342 if (fi != NULL) {
01343 fi->te = p;
01344 p->fi = fi;
01345 }
01346
01347 psm = rpmpsmNew(ts, p, p->fi);
01348
01349 assert(psm != NULL);
01350 psm->stepName = "pretrans";
01351 psm->scriptTag = RPMTAG_PRETRANS;
01352 psm->progTag = RPMTAG_PRETRANSPROG;
01353 xx = rpmpsmStage(psm, PSM_SCRIPT);
01354 psm = rpmpsmFree(psm);
01355
01356
01357 (void) ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE, 0, 0,
01358 rpmteKey(p), ts->notifyData);
01359
01360 p->fd = NULL;
01361 p->h = headerFree(p->h);
01362 }
01363
01364 }
01365 pi = rpmtsiFree(pi);
01366 }
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377 rpmMessage(RPMMESS_DEBUG, D_("computing %d file fingerprints\n"), totalFileCount);
01378
01379 numAdded = numRemoved = 0;
01380 pi = rpmtsiInit(ts);
01381 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01382 int fc;
01383
01384 if ((fi = rpmtsiFi(pi)) == NULL)
01385 continue;
01386 fc = rpmfiFC(fi);
01387
01388
01389 switch (rpmteType(p)) {
01390 case TR_ADDED:
01391 numAdded++;
01392 fi->record = 0;
01393
01394 if (fc > 0)
01395 skipFiles(ts, fi);
01396 break;
01397 case TR_REMOVED:
01398 numRemoved++;
01399 fi->record = rpmteDBOffset(p);
01400 break;
01401 }
01402
01403
01404 fi->fps = (fc > 0 ? xmalloc(fc * sizeof(*fi->fps)) : NULL);
01405 }
01406 pi = rpmtsiFree(pi);
01407
01408 if (!rpmtsChrootDone(ts)) {
01409 const char * rootDir = rpmtsRootDir(ts);
01410 static int openall_before_chroot = -1;
01411
01412 if (openall_before_chroot < 0)
01413 openall_before_chroot = rpmExpandNumeric("%{?_openall_before_chroot}");
01414
01415 xx = Chdir("/");
01416
01417 if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/') {
01418 if (openall_before_chroot)
01419 xx = rpmdbOpenAll(rpmtsGetRdb(ts));
01420 xx = Chroot(rootDir);
01421 }
01422
01423 (void) rpmtsSetChrootDone(ts, 1);
01424 }
01425
01426 ts->ht = htCreate(totalFileCount * 2, 0, 0, fpHashFunction, fpEqual);
01427 fpc = fpCacheCreate(totalFileCount);
01428
01429
01430
01431
01432 pi = rpmtsiInit(ts);
01433 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01434 int fc;
01435
01436 (void) rpmdbCheckSignals();
01437
01438 if ((fi = rpmtsiFi(pi)) == NULL)
01439 continue;
01440 fc = rpmfiFC(fi);
01441
01442 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
01443 fpLookupList(fpc, fi->dnl, fi->bnl, fi->dil, fc, fi->fps);
01444
01445 fi = rpmfiInit(fi, 0);
01446 if (fi != NULL)
01447 while ((i = rpmfiNext(fi)) >= 0) {
01448 if (XFA_SKIPPING(fi->actions[i]))
01449 continue;
01450
01451 htAddEntry(ts->ht, fi->fps + i, (void *) fi);
01452
01453 }
01454
01455 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), fc);
01456
01457 }
01458 pi = rpmtsiFree(pi);
01459
01460 NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_START, 6, ts->orderCount,
01461 NULL, ts->notifyData));
01462
01463
01464
01465
01466 rpmMessage(RPMMESS_DEBUG, D_("computing file dispositions\n"));
01467 ps = rpmtsProblems(ts);
01468 pi = rpmtsiInit(ts);
01469
01470 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01471 dbiIndexSet * matches;
01472 unsigned int exclude;
01473 int knownBad;
01474 int fc;
01475
01476 (void) rpmdbCheckSignals();
01477
01478 if ((fi = rpmtsiFi(pi)) == NULL)
01479 continue;
01480 fc = rpmfiFC(fi);
01481
01482 NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_PROGRESS, rpmtsiOc(pi),
01483 ts->orderCount, NULL, ts->notifyData));
01484
01485 if (fc == 0) continue;
01486
01487 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
01488
01489 matches = xcalloc(fc, sizeof(*matches));
01490 exclude = (rpmteType(p) == TR_REMOVED ? fi->record : 0);
01491 if (rpmdbFindFpList(rpmtsGetRdb(ts), fi->fps, matches, fc, exclude)) {
01492 ps = rpmpsFree(ps);
01493 lock = rpmtsFreeLock(lock);
01494 return 1;
01495 }
01496
01497 numShared = 0;
01498 fi = rpmfiInit(fi, 0);
01499 while ((i = rpmfiNext(fi)) >= 0) {
01500 struct stat sb, *st = &sb;
01501 uint_32 FFlags = rpmfiFFlags(fi);
01502 numShared += dbiIndexSetCount(matches[i]);
01503 if (!(FFlags & RPMFILE_CONFIG))
01504 continue;
01505 if (!Lstat(rpmfiFN(fi), st)) {
01506 FFlags |= RPMFILE_EXISTS;
01507 if ((512 * st->st_blocks) < st->st_size)
01508 FFlags |= RPMFILE_SPARSE;
01509 (void) rpmfiSetFFlags(fi, FFlags);
01510 }
01511 }
01512
01513
01514 shared = sharedList = xcalloc((numShared + 1), sizeof(*sharedList));
01515
01516 fi = rpmfiInit(fi, 0);
01517 while ((i = rpmfiNext(fi)) >= 0) {
01518
01519
01520
01521
01522 for (j = 0; j < dbiIndexSetCount(matches[i]); j++) {
01523 int ro;
01524 ro = dbiIndexRecordOffset(matches[i], j);
01525 knownBad = 0;
01526 qi = rpmtsiInit(ts);
01527 while ((q = rpmtsiNext(qi, TR_REMOVED)) != NULL) {
01528 if (ro == knownBad)
01529 break;
01530 if (rpmteDBOffset(q) == ro)
01531 knownBad = ro;
01532 }
01533 qi = rpmtsiFree(qi);
01534
01535 shared->pkgFileNum = i;
01536 shared->otherPkg = dbiIndexRecordOffset(matches[i], j);
01537 shared->otherFileNum = dbiIndexRecordFileNumber(matches[i], j);
01538 shared->isRemoved = (knownBad == ro);
01539 shared++;
01540 }
01541 matches[i] = dbiFreeIndexSet(matches[i]);
01542 }
01543 numShared = shared - sharedList;
01544 shared->otherPkg = -1;
01545 matches = _free(matches);
01546
01547
01548 qsort(sharedList, numShared, sizeof(*shared), sharedCmp);
01549
01550
01551
01552
01553 for (i = 0; i < numShared; i = nexti) {
01554 int beingRemoved;
01555
01556 shared = sharedList + i;
01557
01558
01559 for (nexti = i + 1; nexti < numShared; nexti++) {
01560 if (sharedList[nexti].otherPkg != shared->otherPkg)
01561 break;
01562 }
01563
01564
01565 beingRemoved = 0;
01566 if (ts->removedPackages != NULL)
01567 for (j = 0; j < ts->numRemovedPackages; j++) {
01568 if (ts->removedPackages[j] != shared->otherPkg)
01569 continue;
01570 beingRemoved = 1;
01571 break;
01572 }
01573
01574
01575 switch (rpmteType(p)) {
01576 case TR_ADDED:
01577 xx = handleInstInstalledFiles(ts, p, fi, shared, nexti - i,
01578 !(beingRemoved || (rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEOLDFILES)));
01579 break;
01580 case TR_REMOVED:
01581 if (!beingRemoved)
01582 xx = handleRmvdInstalledFiles(ts, fi, shared, nexti - i);
01583 break;
01584 }
01585 }
01586
01587
01588
01589 free(sharedList);
01590
01591
01592
01593 handleOverlappedFiles(ts, p, fi);
01594
01595
01596
01597 switch (rpmteType(p)) {
01598 case TR_ADDED:
01599 rpmtsCheckDSIProblems(ts, p);
01600 break;
01601 case TR_REMOVED:
01602 break;
01603 }
01604 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), fc);
01605 }
01606
01607 pi = rpmtsiFree(pi);
01608 ps = rpmpsFree(ps);
01609
01610 if (rpmtsChrootDone(ts)) {
01611 const char * rootDir = rpmtsRootDir(ts);
01612 const char * currDir = rpmtsCurrDir(ts);
01613
01614 if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/')
01615 xx = Chroot(".");
01616
01617 (void) rpmtsSetChrootDone(ts, 0);
01618 if (currDir != NULL)
01619 xx = Chdir(currDir);
01620 }
01621
01622 NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_STOP, 6, ts->orderCount,
01623 NULL, ts->notifyData));
01624
01625
01626
01627
01628 pi = rpmtsiInit(ts);
01629 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01630 if ((fi = rpmtsiFi(pi)) == NULL)
01631 continue;
01632 if (rpmfiFC(fi) == 0)
01633 continue;
01634 fi->fps = _free(fi->fps);
01635 }
01636 pi = rpmtsiFree(pi);
01637
01638 fpc = fpCacheFree(fpc);
01639 ts->ht = htFree(ts->ht);
01640
01641
01642
01643
01644 if ((rpmtsFlags(ts) & RPMTRANS_FLAG_BUILD_PROBS)
01645 || (rpmpsNumProblems(ts->probs) &&
01646 (okProbs == NULL || rpmpsTrim(ts->probs, okProbs)))
01647 )
01648 {
01649 lock = rpmtsFreeLock(lock);
01650 return ts->orderCount;
01651 }
01652
01653
01654
01655
01656 if (rpmtsFlags(ts) & (RPMTRANS_FLAG_DIRSTASH | RPMTRANS_FLAG_REPACKAGE)) {
01657 int progress;
01658
01659 progress = 0;
01660 pi = rpmtsiInit(ts);
01661 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01662
01663 (void) rpmdbCheckSignals();
01664
01665 if ((fi = rpmtsiFi(pi)) == NULL)
01666 continue;
01667 switch (rpmteType(p)) {
01668 case TR_ADDED:
01669 break;
01670 case TR_REMOVED:
01671 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_REPACKAGE))
01672 break;
01673 if (!progress)
01674 NOTIFY(ts, (NULL, RPMCALLBACK_REPACKAGE_START,
01675 7, numRemoved, NULL, ts->notifyData));
01676
01677 NOTIFY(ts, (NULL, RPMCALLBACK_REPACKAGE_PROGRESS, progress,
01678 numRemoved, NULL, ts->notifyData));
01679 progress++;
01680
01681 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_REPACKAGE), 0);
01682
01683
01684 fi->mapflags |= CPIO_MAP_ABSOLUTE;
01685 fi->mapflags |= CPIO_MAP_ADDDOT;
01686 fi->mapflags |= CPIO_ALL_HARDLINKS;
01687 psm = rpmpsmNew(ts, p, fi);
01688 assert(psm != NULL);
01689 xx = rpmpsmStage(psm, PSM_PKGSAVE);
01690 psm = rpmpsmFree(psm);
01691 fi->mapflags &= ~CPIO_MAP_ABSOLUTE;
01692 fi->mapflags &= ~CPIO_MAP_ADDDOT;
01693 fi->mapflags &= ~CPIO_ALL_HARDLINKS;
01694
01695 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_REPACKAGE), 0);
01696
01697 break;
01698 }
01699 }
01700 pi = rpmtsiFree(pi);
01701 if (progress) {
01702 NOTIFY(ts, (NULL, RPMCALLBACK_REPACKAGE_STOP, 7, numRemoved,
01703 NULL, ts->notifyData));
01704 }
01705 }
01706
01707
01708
01709
01710
01711 pi = rpmtsiInit(ts);
01712
01713 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01714 alKey pkgKey;
01715 int gotfd;
01716
01717 (void) rpmdbCheckSignals();
01718
01719 gotfd = 0;
01720 if ((fi = rpmtsiFi(pi)) == NULL)
01721 continue;
01722
01723 psm = rpmpsmNew(ts, p, fi);
01724 assert(psm != NULL);
01725 psm->unorderedSuccessor =
01726 (rpmtsiOc(pi) >= rpmtsUnorderedSuccessors(ts, -1) ? 1 : 0);
01727
01728 switch (rpmteType(p)) {
01729 case TR_ADDED:
01730 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_INSTALL), 0);
01731
01732 pkgKey = rpmteAddedKey(p);
01733
01734 rpmMessage(RPMMESS_DEBUG, "========== +++ %s %s-%s 0x%x\n",
01735 rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));
01736
01737 p->h = NULL;
01738
01739 {
01740
01741 p->fd = ts->notify(p->h, RPMCALLBACK_INST_OPEN_FILE, 0, 0,
01742 rpmteKey(p), ts->notifyData);
01743
01744 if (rpmteFd(p) != NULL) {
01745 rpmVSFlags ovsflags = rpmtsVSFlags(ts);
01746 rpmVSFlags vsflags = ovsflags | RPMVSF_NEEDPAYLOAD;
01747 rpmRC rpmrc;
01748
01749 ovsflags = rpmtsSetVSFlags(ts, vsflags);
01750 rpmrc = rpmReadPackageFile(ts, rpmteFd(p),
01751 rpmteNEVR(p), &p->h);
01752 vsflags = rpmtsSetVSFlags(ts, ovsflags);
01753
01754 switch (rpmrc) {
01755 default:
01756
01757 p->fd = ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE,
01758 0, 0,
01759 rpmteKey(p), ts->notifyData);
01760
01761 p->fd = NULL;
01762 ourrc++;
01763 break;
01764 case RPMRC_NOTTRUSTED:
01765 case RPMRC_NOKEY:
01766 case RPMRC_OK:
01767 break;
01768 }
01769 if (rpmteFd(p) != NULL) gotfd = 1;
01770 } else {
01771 ourrc++;
01772 xx = markLinkedFailed(ts, p);
01773 }
01774 }
01775
01776
01777 if (rpmteFd(p) != NULL) {
01778
01779
01780
01781
01782 psm->fi = rpmfiFree(psm->fi);
01783 {
01784 char * fstates = fi->fstates;
01785 fileAction * actions = fi->actions;
01786 int mapflags = fi->mapflags;
01787 rpmte savep;
01788 int scareMem = 1;
01789
01790 fi->fstates = NULL;
01791 fi->actions = NULL;
01792
01793 fi = rpmfiFree(fi);
01794
01795
01796 savep = rpmtsSetRelocateElement(ts, p);
01797 fi = rpmfiNew(ts, p->h, RPMTAG_BASENAMES, scareMem);
01798 (void) rpmtsSetRelocateElement(ts, savep);
01799
01800 if (fi != NULL) {
01801 fi->te = p;
01802 fi->fstates = _free(fi->fstates);
01803 fi->fstates = fstates;
01804 fi->actions = _free(fi->actions);
01805 fi->actions = actions;
01806 if (mapflags & CPIO_SBIT_CHECK)
01807 fi->mapflags |= CPIO_SBIT_CHECK;
01808 p->fi = fi;
01809 }
01810 }
01811 psm->fi = rpmfiLink(p->fi, NULL);
01812
01813 if ((xx = rpmpsmStage(psm, PSM_PKGINSTALL)) != 0) {
01814 ourrc++;
01815 xx = markLinkedFailed(ts, p);
01816 } else
01817 p->done = 1;
01818
01819 } else {
01820 ourrc++;
01821 }
01822
01823 if (gotfd) {
01824
01825 (void) ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE, 0, 0,
01826 rpmteKey(p), ts->notifyData);
01827
01828
01829 p->fd = NULL;
01830
01831 }
01832
01833 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_INSTALL), 0);
01834
01835 break;
01836
01837 case TR_REMOVED:
01838 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_ERASE), 0);
01839
01840 rpmMessage(RPMMESS_DEBUG, "========== --- %s %s-%s 0x%x\n",
01841 rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));
01842
01843
01844 if (p->linkFailed == 0) {
01845 if ((xx != rpmpsmStage(psm, PSM_PKGERASE)) != 0) {
01846 ourrc++;
01847 } else
01848 p->done = 1;
01849 } else
01850 ourrc++;
01851
01852 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_ERASE), 0);
01853
01854 break;
01855 }
01856
01857
01858
01859
01860 if (rpmteType(p) == TR_ADDED)
01861 p->h = headerFree(p->h);
01862
01863 xx = rpmdbSync(rpmtsGetRdb(ts));
01864
01865
01866 psm = rpmpsmFree(psm);
01867
01868
01869
01870
01871
01872 if (ourrc && rollbackFailures) {
01873 xx = rpmtsRollback(ts, ignoreSet, 1, p);
01874 break;
01875 }
01876 }
01877
01878
01879 pi = rpmtsiFree(pi);
01880
01881 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) {
01882 rpmMessage(RPMMESS_DEBUG, D_("running post-transaction scripts\n"));
01883 pi = rpmtsiInit(ts);
01884 while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
01885 int haspostscript;
01886
01887 if ((fi = rpmtsiFi(pi)) == NULL)
01888 continue;
01889
01890 haspostscript = (fi->posttrans != NULL ? 1 : 0);
01891 p->fi = rpmfiFree(p->fi);
01892
01893
01894 if (!haspostscript)
01895 continue;
01896
01897 p->fd = ts->notify(p->h, RPMCALLBACK_INST_OPEN_FILE, 0, 0,
01898 rpmteKey(p), ts->notifyData);
01899 p->h = NULL;
01900 if (rpmteFd(p) != NULL) {
01901 rpmVSFlags ovsflags = rpmtsVSFlags(ts);
01902 rpmVSFlags vsflags = ovsflags | RPMVSF_NEEDPAYLOAD;
01903 rpmRC rpmrc;
01904 ovsflags = rpmtsSetVSFlags(ts, vsflags);
01905 rpmrc = rpmReadPackageFile(ts, rpmteFd(p),
01906 rpmteNEVR(p), &p->h);
01907 vsflags = rpmtsSetVSFlags(ts, ovsflags);
01908 switch (rpmrc) {
01909 default:
01910 p->fd = ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE,
01911 0, 0, rpmteKey(p), ts->notifyData);
01912 p->fd = NULL;
01913 break;
01914 case RPMRC_NOTTRUSTED:
01915 case RPMRC_NOKEY:
01916 case RPMRC_OK:
01917 break;
01918 }
01919 }
01920
01921
01922 if (rpmteFd(p) != NULL) {
01923 p->fi = rpmfiNew(ts, p->h, RPMTAG_BASENAMES, 1);
01924 if (p->fi != NULL)
01925 p->fi->te = p;
01926
01927 psm = rpmpsmNew(ts, p, p->fi);
01928
01929 assert(psm != NULL);
01930 psm->stepName = "posttrans";
01931 psm->scriptTag = RPMTAG_POSTTRANS;
01932 psm->progTag = RPMTAG_POSTTRANSPROG;
01933 xx = rpmpsmStage(psm, PSM_SCRIPT);
01934 psm = rpmpsmFree(psm);
01935
01936
01937 (void) ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE, 0, 0,
01938 rpmteKey(p), ts->notifyData);
01939
01940 p->fd = NULL;
01941 p->fi = rpmfiFree(p->fi);
01942 p->h = headerFree(p->h);
01943 }
01944
01945 }
01946 pi = rpmtsiFree(pi);
01947 }
01948
01949 lock = rpmtsFreeLock(lock);
01950
01951
01952 if (ourrc)
01953 return -1;
01954 else
01955 return 0;
01956
01957 }