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, (void **) &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 if (languages) freeSplitString((char **)languages);
00899
00900 }
00901
00902
00903
00904
00911 static
00912 rpmfi rpmtsiFi(const rpmtsi tsi)
00913
00914 {
00915 rpmfi fi = NULL;
00916
00917 if (tsi != NULL && tsi->ocsave != -1) {
00918
00919 rpmte te = rpmtsElement(tsi->ts, tsi->ocsave);
00920
00921 if (te != NULL && (fi = te->fi) != NULL)
00922 fi->te = te;
00923
00924
00925 }
00926
00927 return fi;
00928
00929 }
00930
00937
00938 static rpmRC _processFailedPackage(rpmts ts, rpmte p)
00939
00940
00941 {
00942 int rc = RPMRC_OK;
00943
00944
00945
00946 if (p != NULL && rpmteType(p) == TR_ADDED && !p->installed) {
00947
00948 rpmpsm psm = rpmpsmNew(ts, p, p->fi);
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958 assert(psm != NULL);
00959 psm->stepName = "failed";
00960 rc = rpmpsmStage(psm, PSM_RPMDB_ADD);
00961 psm = rpmpsmFree(psm);
00962 }
00963 return rc;
00964 }
00965
00966
00967
00968 rpmRC rpmtsRollback(rpmts rbts, rpmprobFilterFlags ignoreSet, int running, rpmte rbte)
00969
00970
00971 {
00972 const char * semfn = NULL;
00973 rpmRC rc = 0;
00974 uint_32 arbgoal = rpmtsARBGoal(rbts);
00975 QVA_t ia = memset(alloca(sizeof(*ia)), 0, sizeof(*ia));
00976 time_t ttid;
00977 int xx;
00978
00979
00980 if ((rpmtsType(rbts) & RPMTRANS_TYPE_ROLLBACK) ||
00981 (rpmtsType(rbts) & RPMTRANS_TYPE_AUTOROLLBACK))
00982 return RPMRC_OK;
00983
00984 if (arbgoal == 0xffffffff)
00985 arbgoal = rpmtsGetTid(rbts);
00986
00987
00988 if (!running && arbgoal == 0xffffffff)
00989 return RPMRC_OK;
00990
00991
00992
00993
00994
00995
00996 { rpmtsi tsi;
00997 rpmte te;
00998
00999
01000 rpmtsOpenDB(rbts, O_RDWR);
01001
01002 tsi = rpmtsiInit(rbts);
01003 while((te = rpmtsiNext(tsi, TR_REMOVED)) != NULL) {
01004 if(!te->u.removed.dboffset)
01005 continue;
01006 rc = rpmdbRemove(rpmtsGetRdb(rbts),
01007 rpmtsGetTid(rbts),
01008 te->u.removed.dboffset, NULL, NULL);
01009 if (rc != RPMRC_OK) {
01010 rpmMessage(RPMMESS_ERROR, _("rpmdb erase failed. NEVRA: %s\n"),
01011 rpmteNEVRA(te));
01012 break;
01013 }
01014 }
01015 tsi = rpmtsiFree(tsi);
01016 if (rc != RPMRC_OK)
01017 goto cleanup;
01018 }
01019
01020
01021 rc = _processFailedPackage(rbts, rbte);
01022 if (rc != RPMRC_OK)
01023 goto cleanup;
01024
01025 rpmtsEmpty(rbts);
01026
01027 ttid = (time_t)arbgoal;
01028 rpmMessage(RPMMESS_NORMAL, _("Rollback to %-24.24s (0x%08x)\n"),
01029 ctime(&ttid), arbgoal);
01030
01031
01032
01033
01034
01035 {
01036 rpmVSFlags vsflags = rpmExpandNumeric("%{?_vsflags_erase}");
01037 vsflags |= _RPMVSF_NODIGESTS;
01038 vsflags |= _RPMVSF_NOSIGNATURES;
01039 vsflags |= RPMVSF_NOHDRCHK;
01040 vsflags |= RPMVSF_NEEDPAYLOAD;
01041 xx = rpmtsSetVSFlags(rbts, vsflags);
01042 }
01043
01044
01045 {
01046 rpmtransFlags tsFlags = rpmtsFlags(rbts);
01047 tsFlags &= ~RPMTRANS_FLAG_DIRSTASH;
01048 tsFlags &= ~RPMTRANS_FLAG_REPACKAGE;
01049 tsFlags |= RPMTRANS_FLAG_NOFDIGESTS;
01050 tsFlags = rpmtsSetFlags(rbts, tsFlags);
01051 }
01052
01053
01054 ia->rbtid = arbgoal;
01055
01056 ia->transFlags = rpmtsFlags(rbts);
01057 ia->depFlags = rpmtsDFlags(rbts);
01058
01059 ia->probFilter = ignoreSet;
01060
01061 ia->installInterfaceFlags = INSTALL_UPGRADE | INSTALL_HASH ;
01062
01063
01064 ia->no_rollback_links = 1;
01065
01066
01067 semfn = rpmExpand("%{?semaphore_backout}", NULL);
01068 if (semfn && *semfn) {
01069 FD_t fd = Fopen(semfn, "w.fdio");
01070 if (fd)
01071 xx = Fclose(fd);
01072 }
01073
01074
01075 rc = rpmRollback(rbts, ia, NULL);
01076
01077
01078 cleanup:
01079
01080 if (semfn && *semfn)
01081 xx = Unlink(semfn);
01082 semfn = _free(semfn);
01083
01084 return rc;
01085 }
01086
01087
01094 static int cmpArgvStr( const char ** AV, const char * B)
01095
01096 {
01097 const char ** a;
01098
01099 if (AV != NULL && B != NULL)
01100 for (a = AV; *a != NULL; a++) {
01101 if (**a && *B && !strcmp(*a, B))
01102 return 1;
01103 }
01104 return 0;
01105 }
01106
01107
01114 static int markLinkedFailed(rpmts ts, rpmte p)
01115
01116
01117 {
01118 rpmtsi qi; rpmte q;
01119 int bingo;
01120
01121 p->linkFailed = 1;
01122
01123 qi = rpmtsiInit(ts);
01124 while ((q = rpmtsiNext(qi, TR_REMOVED)) != NULL) {
01125
01126 if (q->done)
01127 continue;
01128
01129
01130
01131
01132
01133 bingo = cmpArgvStr(q->flink.Hdrid, p->hdrid);
01134 if (!bingo)
01135 bingo = cmpArgvStr(q->flink.Pkgid, p->pkgid);
01136 if (!bingo)
01137 bingo = cmpArgvStr(q->flink.NEVRA, p->NEVRA);
01138
01139 if (!bingo)
01140 continue;
01141
01142 q->linkFailed = p->linkFailed;
01143 }
01144 qi = rpmtsiFree(qi);
01145
01146 return 0;
01147 }
01148
01149 #define NOTIFY(_ts, _al) if ((_ts)->notify) (void) (_ts)->notify _al
01150
01151 int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
01152 {
01153 uint_32 tscolor = rpmtsColor(ts);
01154 int i, j;
01155 int ourrc = 0;
01156 int totalFileCount = 0;
01157 rpmfi fi;
01158 sharedFileInfo shared, sharedList;
01159 int numShared;
01160 int nexti;
01161 fingerPrintCache fpc;
01162 rpmps ps;
01163 rpmpsm psm;
01164 rpmtsi pi; rpmte p;
01165 rpmtsi qi; rpmte q;
01166 int numAdded;
01167 int numRemoved;
01168 int rollbackFailures = 0;
01169 void * lock = NULL;
01170 int xx;
01171
01172
01173 if (rpmtsNElements(ts) <= 0) {
01174 rpmMessage(RPMMESS_ERROR,
01175 _("Invalid number of transaction elements.\n"));
01176 return -1;
01177 }
01178
01179 rollbackFailures = rpmExpandNumeric("%{?_rollback_transaction_on_failure}");
01180
01181 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_REPACKAGE))
01182 rollbackFailures = 0;
01183
01184 if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)
01185 rollbackFailures = 0;
01186
01187 if (rpmtsType(ts) & (RPMTRANS_TYPE_ROLLBACK | RPMTRANS_TYPE_AUTOROLLBACK))
01188 rollbackFailures = 0;
01189
01190
01191
01192
01193
01194
01195 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST))
01196 lock = rpmtsAcquireLock(ts);
01197
01198
01199
01200 if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOSCRIPTS)
01201 (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers));
01202
01203 if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERS)
01204 (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransTriggers));
01205
01206
01207 if (rpmtsFlags(ts) & RPMTRANS_FLAG_JUSTDB)
01208 (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers));
01209
01210 ts->probs = rpmpsFree(ts->probs);
01211 ts->probs = rpmpsCreate();
01212
01213
01214 { int dbmode = (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)
01215 ? O_RDONLY : (O_RDWR|O_CREAT);
01216
01217
01218 if (rpmtsOpenDB(ts, dbmode)) {
01219 lock = rpmtsFreeLock(lock);
01220 return -1;
01221 }
01222 }
01223
01224 ts->ignoreSet = ignoreSet;
01225 { const char * currDir = currentDirectory();
01226 rpmtsSetCurrDir(ts, currDir);
01227 currDir = _free(currDir);
01228 }
01229
01230 (void) rpmtsSetChrootDone(ts, 0);
01231
01232
01233 { int_32 tid = (int_32) time(NULL);
01234 (void) rpmtsSetTid(ts, tid);
01235 }
01236
01237
01238 xx = rpmtsInitDSI(ts);
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248 rpmMessage(RPMMESS_DEBUG, _("sanity checking %d elements\n"), rpmtsNElements(ts));
01249 ps = rpmtsProblems(ts);
01250
01251 pi = rpmtsiInit(ts);
01252
01253 while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
01254 rpmdbMatchIterator mi;
01255 int fc;
01256
01257 if ((fi = rpmtsiFi(pi)) == NULL)
01258 continue;
01259 fc = rpmfiFC(fi);
01260
01261 if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_OLDPACKAGE)) {
01262 Header h;
01263 mi = rpmtsInitIterator(ts, RPMTAG_NAME, rpmteN(p), 0);
01264 while ((h = rpmdbNextIterator(mi)) != NULL)
01265 xx = ensureOlder(ts, p, h);
01266 mi = rpmdbFreeIterator(mi);
01267 }
01268
01269 if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEPKG)) {
01270 mi = rpmtsInitIterator(ts, RPMTAG_NAME, rpmteN(p), 0);
01271 xx = rpmdbSetIteratorRE(mi, RPMTAG_EPOCH, RPMMIRE_STRCMP,
01272 rpmteE(p));
01273 xx = rpmdbSetIteratorRE(mi, RPMTAG_VERSION, RPMMIRE_STRCMP,
01274 rpmteV(p));
01275 xx = rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, RPMMIRE_STRCMP,
01276 rpmteR(p));
01277 if (tscolor) {
01278 xx = rpmdbSetIteratorRE(mi, RPMTAG_ARCH, RPMMIRE_STRCMP,
01279 rpmteA(p));
01280 xx = rpmdbSetIteratorRE(mi, RPMTAG_OS, RPMMIRE_STRCMP,
01281 rpmteO(p));
01282 }
01283
01284 while (rpmdbNextIterator(mi) != NULL) {
01285 rpmpsAppend(ps, RPMPROB_PKG_INSTALLED,
01286 rpmteNEVR(p), rpmteKey(p),
01287 NULL, NULL,
01288 NULL, 0);
01289 break;
01290 }
01291 mi = rpmdbFreeIterator(mi);
01292 }
01293
01294
01295 totalFileCount += fc;
01296
01297 }
01298 pi = rpmtsiFree(pi);
01299 ps = rpmpsFree(ps);
01300
01301
01302 pi = rpmtsiInit(ts);
01303 while ((p = rpmtsiNext(pi, TR_REMOVED)) != NULL) {
01304 int fc;
01305
01306 if ((fi = rpmtsiFi(pi)) == NULL)
01307 continue;
01308 fc = rpmfiFC(fi);
01309
01310 totalFileCount += fc;
01311 }
01312 pi = rpmtsiFree(pi);
01313
01314
01315
01316
01317 if (!((rpmtsFlags(ts) & (RPMTRANS_FLAG_BUILD_PROBS|RPMTRANS_FLAG_TEST))
01318 || (rpmpsNumProblems(ts->probs) &&
01319 (okProbs == NULL || rpmpsTrim(ts->probs, okProbs)))))
01320 {
01321 rpmMessage(RPMMESS_DEBUG, _("running pre-transaction scripts\n"));
01322 pi = rpmtsiInit(ts);
01323 while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
01324 if ((fi = rpmtsiFi(pi)) == NULL)
01325 continue;
01326
01327
01328 if (fi->pretrans == NULL)
01329 continue;
01330
01331 p->fd = ts->notify(p->h, RPMCALLBACK_INST_OPEN_FILE, 0, 0,
01332 rpmteKey(p), ts->notifyData);
01333 p->h = NULL;
01334 if (rpmteFd(p) != NULL) {
01335 rpmVSFlags ovsflags = rpmtsVSFlags(ts);
01336 rpmVSFlags vsflags = ovsflags | RPMVSF_NEEDPAYLOAD;
01337 rpmRC rpmrc;
01338 ovsflags = rpmtsSetVSFlags(ts, vsflags);
01339 rpmrc = rpmReadPackageFile(ts, rpmteFd(p),
01340 rpmteNEVR(p), &p->h);
01341 vsflags = rpmtsSetVSFlags(ts, ovsflags);
01342 switch (rpmrc) {
01343 default:
01344
01345 p->fd = ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE,
01346 0, 0,
01347 rpmteKey(p), ts->notifyData);
01348
01349 p->fd = NULL;
01350 break;
01351 case RPMRC_NOTTRUSTED:
01352 case RPMRC_NOKEY:
01353 case RPMRC_OK:
01354 break;
01355 }
01356 }
01357
01358
01359 if (rpmteFd(p) != NULL) {
01360 fi = rpmfiNew(ts, p->h, RPMTAG_BASENAMES, 1);
01361 if (fi != NULL) {
01362 fi->te = p;
01363 p->fi = fi;
01364 }
01365
01366 psm = rpmpsmNew(ts, p, p->fi);
01367
01368 assert(psm != NULL);
01369 psm->stepName = "pretrans";
01370 psm->scriptTag = RPMTAG_PRETRANS;
01371 psm->progTag = RPMTAG_PRETRANSPROG;
01372 xx = rpmpsmStage(psm, PSM_SCRIPT);
01373 psm = rpmpsmFree(psm);
01374
01375
01376 (void) ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE, 0, 0,
01377 rpmteKey(p), ts->notifyData);
01378
01379 p->fd = NULL;
01380 p->h = headerFree(p->h);
01381 }
01382
01383 }
01384 pi = rpmtsiFree(pi);
01385 }
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396 rpmMessage(RPMMESS_DEBUG, _("computing %d file fingerprints\n"), totalFileCount);
01397
01398 numAdded = numRemoved = 0;
01399 pi = rpmtsiInit(ts);
01400 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01401 int fc;
01402
01403 if ((fi = rpmtsiFi(pi)) == NULL)
01404 continue;
01405 fc = rpmfiFC(fi);
01406
01407
01408 switch (rpmteType(p)) {
01409 case TR_ADDED:
01410 numAdded++;
01411 fi->record = 0;
01412
01413 if (fc > 0)
01414 skipFiles(ts, fi);
01415 break;
01416 case TR_REMOVED:
01417 numRemoved++;
01418 fi->record = rpmteDBOffset(p);
01419 break;
01420 }
01421
01422
01423 fi->fps = (fc > 0 ? xmalloc(fc * sizeof(*fi->fps)) : NULL);
01424 }
01425 pi = rpmtsiFree(pi);
01426
01427 if (!rpmtsChrootDone(ts)) {
01428 const char * rootDir = rpmtsRootDir(ts);
01429 static int openall_before_chroot = -1;
01430
01431 if (openall_before_chroot < 0)
01432 openall_before_chroot = rpmExpandNumeric("%{?_openall_before_chroot}");
01433
01434 xx = Chdir("/");
01435
01436 if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/') {
01437 if (openall_before_chroot)
01438 xx = rpmdbOpenAll(rpmtsGetRdb(ts));
01439 xx = Chroot(rootDir);
01440 }
01441
01442 (void) rpmtsSetChrootDone(ts, 1);
01443 }
01444
01445 ts->ht = htCreate(totalFileCount * 2, 0, 0, fpHashFunction, fpEqual);
01446 fpc = fpCacheCreate(totalFileCount);
01447
01448
01449
01450
01451 pi = rpmtsiInit(ts);
01452 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01453 int fc;
01454
01455 (void) rpmdbCheckSignals();
01456
01457 if ((fi = rpmtsiFi(pi)) == NULL)
01458 continue;
01459 fc = rpmfiFC(fi);
01460
01461 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
01462 fpLookupList(fpc, fi->dnl, fi->bnl, fi->dil, fc, fi->fps);
01463
01464 fi = rpmfiInit(fi, 0);
01465 if (fi != NULL)
01466 while ((i = rpmfiNext(fi)) >= 0) {
01467 if (XFA_SKIPPING(fi->actions[i]))
01468 continue;
01469
01470 htAddEntry(ts->ht, fi->fps + i, (void *) fi);
01471
01472 }
01473
01474 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), fc);
01475
01476 }
01477 pi = rpmtsiFree(pi);
01478
01479 NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_START, 6, ts->orderCount,
01480 NULL, ts->notifyData));
01481
01482
01483
01484
01485 rpmMessage(RPMMESS_DEBUG, _("computing file dispositions\n"));
01486 ps = rpmtsProblems(ts);
01487 pi = rpmtsiInit(ts);
01488
01489 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01490 dbiIndexSet * matches;
01491 unsigned int exclude;
01492 int knownBad;
01493 int fc;
01494
01495 (void) rpmdbCheckSignals();
01496
01497 if ((fi = rpmtsiFi(pi)) == NULL)
01498 continue;
01499 fc = rpmfiFC(fi);
01500
01501 NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_PROGRESS, rpmtsiOc(pi),
01502 ts->orderCount, NULL, ts->notifyData));
01503
01504 if (fc == 0) continue;
01505
01506 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
01507
01508 matches = xcalloc(fc, sizeof(*matches));
01509 exclude = (rpmteType(p) == TR_REMOVED ? fi->record : 0);
01510 if (rpmdbFindFpList(rpmtsGetRdb(ts), fi->fps, matches, fc, exclude)) {
01511 ps = rpmpsFree(ps);
01512 lock = rpmtsFreeLock(lock);
01513 return 1;
01514 }
01515
01516 numShared = 0;
01517 fi = rpmfiInit(fi, 0);
01518 while ((i = rpmfiNext(fi)) >= 0)
01519 numShared += dbiIndexSetCount(matches[i]);
01520
01521
01522 shared = sharedList = xcalloc((numShared + 1), sizeof(*sharedList));
01523
01524 fi = rpmfiInit(fi, 0);
01525 while ((i = rpmfiNext(fi)) >= 0) {
01526
01527
01528
01529
01530 for (j = 0; j < dbiIndexSetCount(matches[i]); j++) {
01531 int ro;
01532 ro = dbiIndexRecordOffset(matches[i], j);
01533 knownBad = 0;
01534 qi = rpmtsiInit(ts);
01535 while ((q = rpmtsiNext(qi, TR_REMOVED)) != NULL) {
01536 if (ro == knownBad)
01537 break;
01538 if (rpmteDBOffset(q) == ro)
01539 knownBad = ro;
01540 }
01541 qi = rpmtsiFree(qi);
01542
01543 shared->pkgFileNum = i;
01544 shared->otherPkg = dbiIndexRecordOffset(matches[i], j);
01545 shared->otherFileNum = dbiIndexRecordFileNumber(matches[i], j);
01546 shared->isRemoved = (knownBad == ro);
01547 shared++;
01548 }
01549 matches[i] = dbiFreeIndexSet(matches[i]);
01550 }
01551 numShared = shared - sharedList;
01552 shared->otherPkg = -1;
01553 matches = _free(matches);
01554
01555
01556 qsort(sharedList, numShared, sizeof(*shared), sharedCmp);
01557
01558
01559
01560
01561 for (i = 0; i < numShared; i = nexti) {
01562 int beingRemoved;
01563
01564 shared = sharedList + i;
01565
01566
01567 for (nexti = i + 1; nexti < numShared; nexti++) {
01568 if (sharedList[nexti].otherPkg != shared->otherPkg)
01569 break;
01570 }
01571
01572
01573 beingRemoved = 0;
01574 if (ts->removedPackages != NULL)
01575 for (j = 0; j < ts->numRemovedPackages; j++) {
01576 if (ts->removedPackages[j] != shared->otherPkg)
01577 continue;
01578 beingRemoved = 1;
01579 break;
01580 }
01581
01582
01583 switch (rpmteType(p)) {
01584 case TR_ADDED:
01585 xx = handleInstInstalledFiles(ts, p, fi, shared, nexti - i,
01586 !(beingRemoved || (rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEOLDFILES)));
01587 break;
01588 case TR_REMOVED:
01589 if (!beingRemoved)
01590 xx = handleRmvdInstalledFiles(ts, fi, shared, nexti - i);
01591 break;
01592 }
01593 }
01594
01595
01596
01597 free(sharedList);
01598
01599
01600
01601 handleOverlappedFiles(ts, p, fi);
01602
01603
01604
01605 switch (rpmteType(p)) {
01606 case TR_ADDED:
01607 rpmtsCheckDSIProblems(ts, p);
01608 break;
01609 case TR_REMOVED:
01610 break;
01611 }
01612 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), fc);
01613 }
01614
01615 pi = rpmtsiFree(pi);
01616 ps = rpmpsFree(ps);
01617
01618 if (rpmtsChrootDone(ts)) {
01619 const char * rootDir = rpmtsRootDir(ts);
01620 const char * currDir = rpmtsCurrDir(ts);
01621
01622 if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/')
01623 xx = Chroot(".");
01624
01625 (void) rpmtsSetChrootDone(ts, 0);
01626 if (currDir != NULL)
01627 xx = Chdir(currDir);
01628 }
01629
01630 NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_STOP, 6, ts->orderCount,
01631 NULL, ts->notifyData));
01632
01633
01634
01635
01636 pi = rpmtsiInit(ts);
01637 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01638 if ((fi = rpmtsiFi(pi)) == NULL)
01639 continue;
01640 if (rpmfiFC(fi) == 0)
01641 continue;
01642 fi->fps = _free(fi->fps);
01643 }
01644 pi = rpmtsiFree(pi);
01645
01646 fpc = fpCacheFree(fpc);
01647 ts->ht = htFree(ts->ht);
01648
01649
01650
01651
01652 if ((rpmtsFlags(ts) & RPMTRANS_FLAG_BUILD_PROBS)
01653 || (rpmpsNumProblems(ts->probs) &&
01654 (okProbs == NULL || rpmpsTrim(ts->probs, okProbs)))
01655 )
01656 {
01657 lock = rpmtsFreeLock(lock);
01658 return ts->orderCount;
01659 }
01660
01661
01662
01663
01664 if (rpmtsFlags(ts) & (RPMTRANS_FLAG_DIRSTASH | RPMTRANS_FLAG_REPACKAGE)) {
01665 int progress;
01666
01667 progress = 0;
01668 pi = rpmtsiInit(ts);
01669 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01670
01671 (void) rpmdbCheckSignals();
01672
01673 if ((fi = rpmtsiFi(pi)) == NULL)
01674 continue;
01675 switch (rpmteType(p)) {
01676 case TR_ADDED:
01677 break;
01678 case TR_REMOVED:
01679 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_REPACKAGE))
01680 break;
01681 if (!progress)
01682 NOTIFY(ts, (NULL, RPMCALLBACK_REPACKAGE_START,
01683 7, numRemoved, NULL, ts->notifyData));
01684
01685 NOTIFY(ts, (NULL, RPMCALLBACK_REPACKAGE_PROGRESS, progress,
01686 numRemoved, NULL, ts->notifyData));
01687 progress++;
01688
01689 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_REPACKAGE), 0);
01690
01691
01692 fi->mapflags |= CPIO_MAP_ABSOLUTE;
01693 fi->mapflags |= CPIO_MAP_ADDDOT;
01694 fi->mapflags |= CPIO_ALL_HARDLINKS;
01695 psm = rpmpsmNew(ts, p, fi);
01696 assert(psm != NULL);
01697 xx = rpmpsmStage(psm, PSM_PKGSAVE);
01698 psm = rpmpsmFree(psm);
01699 fi->mapflags &= ~CPIO_MAP_ABSOLUTE;
01700 fi->mapflags &= ~CPIO_MAP_ADDDOT;
01701 fi->mapflags &= ~CPIO_ALL_HARDLINKS;
01702
01703 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_REPACKAGE), 0);
01704
01705 break;
01706 }
01707 }
01708 pi = rpmtsiFree(pi);
01709 if (progress) {
01710 NOTIFY(ts, (NULL, RPMCALLBACK_REPACKAGE_STOP, 7, numRemoved,
01711 NULL, ts->notifyData));
01712 }
01713 }
01714
01715
01716
01717
01718
01719 pi = rpmtsiInit(ts);
01720
01721 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01722 alKey pkgKey;
01723 int gotfd;
01724
01725 (void) rpmdbCheckSignals();
01726
01727 gotfd = 0;
01728 if ((fi = rpmtsiFi(pi)) == NULL)
01729 continue;
01730
01731 psm = rpmpsmNew(ts, p, fi);
01732 assert(psm != NULL);
01733 psm->unorderedSuccessor =
01734 (rpmtsiOc(pi) >= rpmtsUnorderedSuccessors(ts, -1) ? 1 : 0);
01735
01736 switch (rpmteType(p)) {
01737 case TR_ADDED:
01738 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_INSTALL), 0);
01739
01740 pkgKey = rpmteAddedKey(p);
01741
01742 rpmMessage(RPMMESS_DEBUG, "========== +++ %s %s-%s 0x%x\n",
01743 rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));
01744
01745 p->h = NULL;
01746
01747 {
01748
01749 p->fd = ts->notify(p->h, RPMCALLBACK_INST_OPEN_FILE, 0, 0,
01750 rpmteKey(p), ts->notifyData);
01751
01752 if (rpmteFd(p) != NULL) {
01753 rpmVSFlags ovsflags = rpmtsVSFlags(ts);
01754 rpmVSFlags vsflags = ovsflags | RPMVSF_NEEDPAYLOAD;
01755 rpmRC rpmrc;
01756
01757 ovsflags = rpmtsSetVSFlags(ts, vsflags);
01758 rpmrc = rpmReadPackageFile(ts, rpmteFd(p),
01759 rpmteNEVR(p), &p->h);
01760 vsflags = rpmtsSetVSFlags(ts, ovsflags);
01761
01762 switch (rpmrc) {
01763 default:
01764
01765 p->fd = ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE,
01766 0, 0,
01767 rpmteKey(p), ts->notifyData);
01768
01769 p->fd = NULL;
01770 ourrc++;
01771 break;
01772 case RPMRC_NOTTRUSTED:
01773 case RPMRC_NOKEY:
01774 case RPMRC_OK:
01775 break;
01776 }
01777 if (rpmteFd(p) != NULL) gotfd = 1;
01778 }
01779 }
01780
01781
01782 if (rpmteFd(p) != NULL) {
01783
01784
01785
01786
01787 psm->fi = rpmfiFree(psm->fi);
01788 {
01789 char * fstates = fi->fstates;
01790 fileAction * actions = fi->actions;
01791 int mapflags = fi->mapflags;
01792 rpmte savep;
01793 int scareMem = 1;
01794
01795 fi->fstates = NULL;
01796 fi->actions = NULL;
01797
01798 fi = rpmfiFree(fi);
01799
01800
01801 savep = rpmtsSetRelocateElement(ts, p);
01802 fi = rpmfiNew(ts, p->h, RPMTAG_BASENAMES, scareMem);
01803 (void) rpmtsSetRelocateElement(ts, savep);
01804
01805 if (fi != NULL) {
01806 fi->te = p;
01807 fi->fstates = _free(fi->fstates);
01808 fi->fstates = fstates;
01809 fi->actions = _free(fi->actions);
01810 fi->actions = actions;
01811 if (mapflags & CPIO_SBIT_CHECK)
01812 fi->mapflags |= CPIO_SBIT_CHECK;
01813 p->fi = fi;
01814 }
01815 }
01816 psm->fi = rpmfiLink(p->fi, NULL);
01817
01818 if ((xx = rpmpsmStage(psm, PSM_PKGINSTALL)) != 0) {
01819 ourrc++;
01820 xx = markLinkedFailed(ts, p);
01821 } else
01822 p->done = 1;
01823
01824 } else {
01825 ourrc++;
01826 }
01827
01828 if (gotfd) {
01829
01830 (void) ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE, 0, 0,
01831 rpmteKey(p), ts->notifyData);
01832
01833
01834 p->fd = NULL;
01835
01836 }
01837
01838 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_INSTALL), 0);
01839
01840 break;
01841
01842 case TR_REMOVED:
01843 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_ERASE), 0);
01844
01845 rpmMessage(RPMMESS_DEBUG, "========== --- %s %s-%s 0x%x\n",
01846 rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));
01847
01848
01849 if (p->linkFailed == 0) {
01850 if ((xx != rpmpsmStage(psm, PSM_PKGERASE)) != 0) {
01851 ourrc++;
01852 } else
01853 p->done = 1;
01854 } else
01855 ourrc++;
01856
01857 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_ERASE), 0);
01858
01859 break;
01860 }
01861
01862
01863
01864
01865 if (rpmteType(p) == TR_ADDED)
01866 p->h = headerFree(p->h);
01867
01868 xx = rpmdbSync(rpmtsGetRdb(ts));
01869
01870
01871 psm = rpmpsmFree(psm);
01872
01873
01874
01875
01876
01877 if (ourrc && rollbackFailures) {
01878 xx = rpmtsRollback(ts, ignoreSet, 1, p);
01879 break;
01880 }
01881 }
01882
01883
01884 pi = rpmtsiFree(pi);
01885
01886 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) {
01887 rpmMessage(RPMMESS_DEBUG, _("running post-transaction scripts\n"));
01888 pi = rpmtsiInit(ts);
01889 while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
01890 int haspostscript;
01891
01892 if ((fi = rpmtsiFi(pi)) == NULL)
01893 continue;
01894
01895 haspostscript = (fi->posttrans != NULL ? 1 : 0);
01896 p->fi = rpmfiFree(p->fi);
01897
01898
01899 if (!haspostscript)
01900 continue;
01901
01902 p->fd = ts->notify(p->h, RPMCALLBACK_INST_OPEN_FILE, 0, 0,
01903 rpmteKey(p), ts->notifyData);
01904 p->h = NULL;
01905 if (rpmteFd(p) != NULL) {
01906 rpmVSFlags ovsflags = rpmtsVSFlags(ts);
01907 rpmVSFlags vsflags = ovsflags | RPMVSF_NEEDPAYLOAD;
01908 rpmRC rpmrc;
01909 ovsflags = rpmtsSetVSFlags(ts, vsflags);
01910 rpmrc = rpmReadPackageFile(ts, rpmteFd(p),
01911 rpmteNEVR(p), &p->h);
01912 vsflags = rpmtsSetVSFlags(ts, ovsflags);
01913 switch (rpmrc) {
01914 default:
01915 p->fd = ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE,
01916 0, 0, rpmteKey(p), ts->notifyData);
01917 p->fd = NULL;
01918 break;
01919 case RPMRC_NOTTRUSTED:
01920 case RPMRC_NOKEY:
01921 case RPMRC_OK:
01922 break;
01923 }
01924 }
01925
01926
01927 if (rpmteFd(p) != NULL) {
01928 p->fi = rpmfiNew(ts, p->h, RPMTAG_BASENAMES, 1);
01929 if (p->fi != NULL)
01930 p->fi->te = p;
01931
01932 psm = rpmpsmNew(ts, p, p->fi);
01933
01934 assert(psm != NULL);
01935 psm->stepName = "posttrans";
01936 psm->scriptTag = RPMTAG_POSTTRANS;
01937 psm->progTag = RPMTAG_POSTTRANSPROG;
01938 xx = rpmpsmStage(psm, PSM_SCRIPT);
01939 psm = rpmpsmFree(psm);
01940
01941
01942 (void) ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE, 0, 0,
01943 rpmteKey(p), ts->notifyData);
01944
01945 p->fd = NULL;
01946 p->fi = rpmfiFree(p->fi);
01947 p->h = headerFree(p->h);
01948 }
01949
01950 }
01951 pi = rpmtsiFree(pi);
01952 }
01953
01954 lock = rpmtsFreeLock(lock);
01955
01956
01957 if (ourrc)
01958 return -1;
01959 else
01960 return 0;
01961
01962 }