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