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