00001
00005 #include "system.h"
00006 #include <rpmlib.h>
00007
00008 #include <rpmmacro.h>
00009
00010 #include "fsm.h"
00011 #include "psm.h"
00012
00013 #include "rpmdb.h"
00014
00015 #include "rpmds.h"
00016
00017 #include "rpmlock.h"
00018
00019 #define _RPMFI_INTERNAL
00020 #include "rpmfi.h"
00021
00022 #define _RPMTE_INTERNAL
00023 #include "rpmte.h"
00024
00025 #define _RPMTS_INTERNAL
00026 #include "rpmts.h"
00027
00028 #include "cpio.h"
00029 #include "fprint.h"
00030 #include "legacy.h"
00031 #include "misc.h"
00032
00033 #include "debug.h"
00034
00035
00036
00037
00038
00039
00040 #include "rpmcli.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 extern void * rpmShowProgress( const void * arg,
00066 const rpmCallbackType what,
00067 const unsigned long amount,
00068 const unsigned long total,
00069 fnpyKey key,
00070 void * data)
00071 ;
00072
00075 static int archOkay( const char * pkgArch)
00076
00077 {
00078 if (pkgArch == NULL) return 0;
00079 return (rpmMachineScore(RPM_MACHTABLE_INSTARCH, pkgArch) ? 1 : 0);
00080 }
00081
00084 static int osOkay( const char * pkgOs)
00085
00086 {
00087 if (pkgOs == NULL) return 0;
00088 return (rpmMachineScore(RPM_MACHTABLE_INSTOS, pkgOs) ? 1 : 0);
00089 }
00090
00093 static int sharedCmp(const void * one, const void * two)
00094
00095 {
00096 sharedFileInfo a = (sharedFileInfo) one;
00097 sharedFileInfo b = (sharedFileInfo) two;
00098
00099 if (a->otherPkg < b->otherPkg)
00100 return -1;
00101 else if (a->otherPkg > b->otherPkg)
00102 return 1;
00103
00104 return 0;
00105 }
00106
00107 static int isDocFile(rpmfi fi)
00108 {
00109 const char *fn = rpmfiFN(fi);
00110 char *s = strstr(fn, "/usr/share/doc/");
00111 return (s == fn);
00112 }
00113
00122
00123
00124 static int handleInstInstalledFiles(const rpmts ts,
00125 rpmte p, rpmfi fi,
00126 sharedFileInfo shared,
00127 int sharedCount, int reportConflicts)
00128
00129
00130 {
00131 uint_32 tscolor = rpmtsColor(ts);
00132 uint_32 prefcolor = rpmtsPrefColor(ts);
00133 uint_32 otecolor, tecolor;
00134 uint_32 oFColor, FColor;
00135 const char * altNEVR = NULL;
00136 rpmfi otherFi = NULL;
00137 int numReplaced = 0;
00138 rpmps ps;
00139 int i;
00140
00141 { rpmdbMatchIterator mi;
00142 Header h;
00143 int scareMem = 0;
00144
00145 mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES,
00146 &shared->otherPkg, sizeof(shared->otherPkg));
00147 while ((h = rpmdbNextIterator(mi)) != NULL) {
00148 altNEVR = hGetNEVRA(h, NULL);
00149 otherFi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
00150 break;
00151 }
00152 mi = rpmdbFreeIterator(mi);
00153 }
00154
00155
00156 tecolor = rpmteColor(p);
00157 tecolor &= tscolor;
00158
00159
00160 otecolor = 0;
00161 otherFi = rpmfiInit(otherFi, 0);
00162 if (otherFi != NULL)
00163 while (rpmfiNext(otherFi) >= 0)
00164 otecolor |= rpmfiFColor(otherFi);
00165 otecolor &= tscolor;
00166
00167 if (otherFi == NULL)
00168 return 1;
00169
00170 fi->replaced = xcalloc(sharedCount, sizeof(*fi->replaced));
00171
00172 ps = rpmtsProblems(ts);
00173 for (i = 0; i < sharedCount; i++, shared++) {
00174 int otherFileNum, fileNum;
00175 int isCfgFile;
00176 int isGhostFile;
00177
00178 otherFileNum = shared->otherFileNum;
00179 (void) rpmfiSetFX(otherFi, otherFileNum);
00180 oFColor = rpmfiFColor(otherFi);
00181 oFColor &= tscolor;
00182
00183 fileNum = shared->pkgFileNum;
00184 (void) rpmfiSetFX(fi, fileNum);
00185 FColor = rpmfiFColor(fi);
00186 FColor &= tscolor;
00187
00188 isCfgFile = ((rpmfiFFlags(otherFi) | rpmfiFFlags(fi)) & RPMFILE_CONFIG);
00189 isGhostFile = ((rpmfiFFlags(otherFi) & RPMFILE_GHOST) && (rpmfiFFlags(fi) & RPMFILE_GHOST));
00190
00191 #ifdef DYING
00192
00193 if (otherStates && otherStates[otherFileNum] != RPMFILE_STATE_NORMAL)
00194 continue;
00195 #endif
00196
00197 if (XFA_SKIPPING(fi->actions[fileNum]))
00198 continue;
00199
00200 if (!(fi->mapflags & CPIO_SBIT_CHECK)) {
00201 int_16 omode = rpmfiFMode(otherFi);
00202 if (S_ISREG(omode) && (omode & 06000) != 0) {
00203 fi->mapflags |= CPIO_SBIT_CHECK;
00204 }
00205 }
00206
00207 if (isGhostFile)
00208 continue;
00209
00210 if (rpmfiCompare(otherFi, fi)) {
00211 int rConflicts;
00212
00213 rConflicts = reportConflicts;
00214
00215 if (tscolor != 0 && FColor != 0 && FColor != oFColor)
00216 {
00217 if (oFColor & prefcolor) {
00218 fi->actions[fileNum] = FA_SKIPCOLOR;
00219 rConflicts = 0;
00220 } else
00221 if (FColor & prefcolor) {
00222 fi->actions[fileNum] = FA_CREATE;
00223 rConflicts = 0;
00224 }
00225 }
00226
00227
00228 if (rConflicts && isDocFile(fi)) {
00229 fi->actions[i] = FA_CREATE;
00230 rConflicts = 0;
00231 }
00232
00233 if (rConflicts) {
00234 rpmpsAppend(ps, RPMPROB_FILE_CONFLICT,
00235 rpmteNEVRA(p), rpmteKey(p),
00236 rpmfiDN(fi), rpmfiBN(fi),
00237 altNEVR,
00238 0);
00239 }
00240
00241 if ( !(isCfgFile || XFA_SKIPPING(fi->actions[fileNum])) ) {
00242
00243 if (!shared->isRemoved)
00244 fi->replaced[numReplaced++] = *shared;
00245
00246 }
00247 }
00248
00249
00250 if (isCfgFile) {
00251 int skipMissing =
00252 ((rpmtsFlags(ts) & RPMTRANS_FLAG_ALLFILES) ? 0 : 1);
00253 fileAction action = rpmfiDecideFate(otherFi, fi, skipMissing);
00254 fi->actions[fileNum] = action;
00255 }
00256 fi->replacedSizes[fileNum] = rpmfiFSize(otherFi);
00257 }
00258 ps = rpmpsFree(ps);
00259
00260 altNEVR = _free(altNEVR);
00261 otherFi = rpmfiFree(otherFi);
00262
00263 fi->replaced = xrealloc(fi->replaced,
00264 sizeof(*fi->replaced) * (numReplaced + 1));
00265 fi->replaced[numReplaced].otherPkg = 0;
00266
00267 return 0;
00268 }
00269
00270
00273
00274 static int handleRmvdInstalledFiles(const rpmts ts, rpmfi fi,
00275 sharedFileInfo shared, int sharedCount)
00276
00277
00278 {
00279 HGE_t hge = fi->hge;
00280 Header h;
00281 const char * otherStates;
00282 int i, xx;
00283
00284 rpmdbMatchIterator mi;
00285
00286 mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES,
00287 &shared->otherPkg, sizeof(shared->otherPkg));
00288 h = rpmdbNextIterator(mi);
00289 if (h == NULL) {
00290 mi = rpmdbFreeIterator(mi);
00291 return 1;
00292 }
00293
00294 xx = hge(h, RPMTAG_FILESTATES, NULL, (void **) &otherStates, NULL);
00295
00296
00297 for (i = 0; i < sharedCount; i++, shared++) {
00298 int otherFileNum, fileNum;
00299 otherFileNum = shared->otherFileNum;
00300 fileNum = shared->pkgFileNum;
00301
00302 if (otherStates[otherFileNum] != RPMFILE_STATE_NORMAL)
00303 continue;
00304
00305 fi->actions[fileNum] = FA_SKIP;
00306 }
00307
00308
00309 mi = rpmdbFreeIterator(mi);
00310
00311 return 0;
00312 }
00313
00314 #define ISROOT(_d) (((_d)[0] == '/' && (_d)[1] == '\0') ? "" : (_d))
00315
00316
00317 int _fps_debug = 0;
00318
00319 static int fpsCompare (const void * one, const void * two)
00320
00321 {
00322 const struct fingerPrint_s * a = (const struct fingerPrint_s *)one;
00323 const struct fingerPrint_s * b = (const struct fingerPrint_s *)two;
00324 int adnlen = strlen(a->entry->dirName);
00325 int asnlen = (a->subDir ? strlen(a->subDir) : 0);
00326 int abnlen = strlen(a->baseName);
00327 int bdnlen = strlen(b->entry->dirName);
00328 int bsnlen = (b->subDir ? strlen(b->subDir) : 0);
00329 int bbnlen = strlen(b->baseName);
00330 char * afn, * bfn, * t;
00331 int rc = 0;
00332
00333 if (adnlen == 1 && asnlen != 0) adnlen = 0;
00334 if (bdnlen == 1 && bsnlen != 0) bdnlen = 0;
00335
00336
00337 afn = t = alloca(adnlen+asnlen+abnlen+2);
00338 if (adnlen) t = stpcpy(t, a->entry->dirName);
00339 *t++ = '/';
00340 if (a->subDir && asnlen) t = stpcpy(t, a->subDir);
00341 if (abnlen) t = stpcpy(t, a->baseName);
00342 if (afn[0] == '/' && afn[1] == '/') afn++;
00343
00344 bfn = t = alloca(bdnlen+bsnlen+bbnlen+2);
00345 if (bdnlen) t = stpcpy(t, b->entry->dirName);
00346 *t++ = '/';
00347 if (b->subDir && bsnlen) t = stpcpy(t, b->subDir);
00348 if (bbnlen) t = stpcpy(t, b->baseName);
00349 if (bfn[0] == '/' && bfn[1] == '/') bfn++;
00350
00351
00352 rc = strcmp(afn, bfn);
00353
00354 if (_fps_debug)
00355 fprintf(stderr, "\trc(%d) = strcmp(\"%s\", \"%s\")\n", rc, afn, bfn);
00356
00357
00358
00359 if (_fps_debug)
00360 fprintf(stderr, "\t%s/%s%s\trc %d\n",
00361 ISROOT(b->entry->dirName),
00362 (b->subDir ? b->subDir : ""),
00363 b->baseName,
00364 rc
00365 );
00366
00367
00368 return rc;
00369 }
00370
00371
00372 static int _linear_fps_search = 0;
00373
00374 static int findFps(const struct fingerPrint_s * fiFps,
00375 const struct fingerPrint_s * otherFps,
00376 int otherFc)
00377
00378 {
00379 int otherFileNum;
00380
00381
00382 if (_fps_debug)
00383 fprintf(stderr, "==> %s/%s%s\n",
00384 ISROOT(fiFps->entry->dirName),
00385 (fiFps->subDir ? fiFps->subDir : ""),
00386 fiFps->baseName);
00387
00388
00389 if (_linear_fps_search) {
00390
00391 linear:
00392 for (otherFileNum = 0; otherFileNum < otherFc; otherFileNum++, otherFps++) {
00393
00394
00395 if (_fps_debug)
00396 fprintf(stderr, "\t%4d %s/%s%s\n", otherFileNum,
00397 ISROOT(otherFps->entry->dirName),
00398 (otherFps->subDir ? otherFps->subDir : ""),
00399 otherFps->baseName);
00400
00401
00402
00403 if (fiFps == otherFps)
00404 break;
00405
00406
00407
00408 if (FP_EQUAL((*fiFps), (*otherFps)))
00409 break;
00410
00411 }
00412
00413 if (otherFileNum == otherFc) {
00414
00415 if (_fps_debug)
00416 fprintf(stderr, "*** FP_EQUAL NULL %s/%s%s\n",
00417 ISROOT(fiFps->entry->dirName),
00418 (fiFps->subDir ? fiFps->subDir : ""),
00419 fiFps->baseName);
00420
00421 }
00422
00423 return otherFileNum;
00424
00425 } else {
00426
00427 const struct fingerPrint_s * bingoFps;
00428
00429
00430 bingoFps = bsearch(fiFps, otherFps, otherFc, sizeof(*otherFps), fpsCompare);
00431
00432 if (bingoFps == NULL) {
00433
00434 if (_fps_debug)
00435 fprintf(stderr, "*** bingoFps NULL %s/%s%s\n",
00436 ISROOT(fiFps->entry->dirName),
00437 (fiFps->subDir ? fiFps->subDir : ""),
00438 fiFps->baseName);
00439
00440 goto linear;
00441 }
00442
00443
00444
00445 if (!(fiFps == bingoFps || FP_EQUAL((*fiFps), (*bingoFps)))) {
00446
00447 if (_fps_debug)
00448 fprintf(stderr, "*** BAD %s/%s%s\n",
00449 ISROOT(bingoFps->entry->dirName),
00450 (bingoFps->subDir ? bingoFps->subDir : ""),
00451 bingoFps->baseName);
00452
00453 goto linear;
00454 }
00455
00456 otherFileNum = (bingoFps != NULL ? (bingoFps - otherFps) : 0);
00457
00458 }
00459
00460 return otherFileNum;
00461 }
00462
00466
00467 static void handleOverlappedFiles(const rpmts ts,
00468 const rpmte p, rpmfi fi)
00469
00470
00471 {
00472 uint_32 fixupSize = 0;
00473 rpmps ps;
00474 const char * fn;
00475 int i, j;
00476
00477 ps = rpmtsProblems(ts);
00478 fi = rpmfiInit(fi, 0);
00479 if (fi != NULL)
00480 while ((i = rpmfiNext(fi)) >= 0) {
00481 uint_32 tscolor = rpmtsColor(ts);
00482 uint_32 prefcolor = rpmtsPrefColor(ts);
00483 uint_32 oFColor, FColor;
00484 struct fingerPrint_s * fiFps;
00485 int otherPkgNum, otherFileNum;
00486 rpmfi otherFi;
00487 int_32 FFlags;
00488 int_16 FMode;
00489 const rpmfi * recs;
00490 int numRecs;
00491
00492 if (XFA_SKIPPING(fi->actions[i]))
00493 continue;
00494
00495 fn = rpmfiFN(fi);
00496 fiFps = fi->fps + i;
00497 FFlags = rpmfiFFlags(fi);
00498 FMode = rpmfiFMode(fi);
00499 FColor = rpmfiFColor(fi);
00500 FColor &= tscolor;
00501
00502 fixupSize = 0;
00503
00504
00505
00506
00507
00508
00509
00510 (void) htGetEntry(ts->ht, fiFps,
00511 (const void ***) &recs, &numRecs, NULL);
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535 for (j = 0; j < numRecs && recs[j] != fi; j++)
00536 {};
00537
00538
00539 otherFileNum = -1;
00540 otherFi = NULL;
00541 for (otherPkgNum = j - 1; otherPkgNum >= 0; otherPkgNum--) {
00542 struct fingerPrint_s * otherFps;
00543 int otherFc;
00544
00545 otherFi = recs[otherPkgNum];
00546
00547
00548 if (rpmteType(p) == TR_ADDED && rpmteType(otherFi->te) != TR_ADDED)
00549 continue;
00550
00551 otherFps = otherFi->fps;
00552 otherFc = rpmfiFC(otherFi);
00553
00554 otherFileNum = findFps(fiFps, otherFps, otherFc);
00555 (void) rpmfiSetFX(otherFi, otherFileNum);
00556
00557
00558 if (otherFi->actions[otherFileNum] != FA_UNKNOWN)
00559 break;
00560 }
00561
00562 oFColor = rpmfiFColor(otherFi);
00563 oFColor &= tscolor;
00564
00565
00566 switch (rpmteType(p)) {
00567 case TR_ADDED:
00568 {
00569 int reportConflicts =
00570 !(rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACENEWFILES);
00571 int done = 0;
00572
00573 if (otherPkgNum < 0) {
00574
00575 if (fi->actions[i] != FA_UNKNOWN)
00576 break;
00577 if (rpmfiConfigConflict(fi)) {
00578
00579 fi->actions[i] = (FFlags & RPMFILE_NOREPLACE)
00580 ? FA_ALTNAME : FA_BACKUP;
00581 } else {
00582 fi->actions[i] = FA_CREATE;
00583 }
00584 break;
00585 }
00586
00587 assert(otherFi != NULL);
00588
00589 if (rpmfiCompare(otherFi, fi)) {
00590 int rConflicts;
00591
00592 rConflicts = reportConflicts;
00593
00594 if (tscolor != 0) {
00595 if (FColor & prefcolor) {
00596
00597 if (!XFA_SKIPPING(fi->actions[i])) {
00598
00599 if (strcmp(fn, "/usr/sbin/libgcc_post_upgrade")
00600 && strcmp(fn, "/usr/sbin/glibc_post_upgrade"))
00601 otherFi->actions[otherFileNum] = FA_SKIPCOLOR;
00602 }
00603 fi->actions[i] = FA_CREATE;
00604 rConflicts = 0;
00605 } else
00606 if (oFColor & prefcolor) {
00607
00608 if (XFA_SKIPPING(fi->actions[i]))
00609 otherFi->actions[otherFileNum] = FA_CREATE;
00610 fi->actions[i] = FA_SKIPCOLOR;
00611 rConflicts = 0;
00612 } else
00613 if (FColor == 0 && oFColor == 0) {
00614
00615 otherFi->actions[otherFileNum] = FA_CREATE;
00616 fi->actions[i] = FA_CREATE;
00617 rConflicts = 0;
00618 }
00619 done = 1;
00620 }
00621
00622
00623 if (rConflicts && isDocFile(fi)) {
00624 fi->actions[i] = FA_CREATE;
00625 rConflicts = 0;
00626 }
00627
00628 if (rConflicts) {
00629 rpmpsAppend(ps, RPMPROB_NEW_FILE_CONFLICT,
00630 rpmteNEVRA(p), rpmteKey(p),
00631 fn, NULL,
00632 rpmteNEVRA(otherFi->te),
00633 0);
00634 }
00635 }
00636
00637
00638 fixupSize = rpmfiFSize(otherFi);
00639
00640 if (rpmfiConfigConflict(fi)) {
00641
00642 fi->actions[i] = (FFlags & RPMFILE_NOREPLACE)
00643 ? FA_ALTNAME : FA_SKIP;
00644 } else {
00645 if (!done)
00646 fi->actions[i] = FA_CREATE;
00647 }
00648 } break;
00649
00650 case TR_REMOVED:
00651 if (otherPkgNum >= 0) {
00652 assert(otherFi != NULL);
00653
00654 if (otherFi->actions[otherFileNum] != FA_ERASE) {
00655
00656 fi->actions[i] = FA_SKIP;
00657 break;
00658 }
00659
00660 otherFi->actions[otherFileNum] = FA_SKIP;
00661 }
00662 if (XFA_SKIPPING(fi->actions[i]))
00663 break;
00664 if (rpmfiFState(fi) != RPMFILE_STATE_NORMAL)
00665 break;
00666 if (!(S_ISREG(FMode) && (FFlags & RPMFILE_CONFIG))) {
00667 fi->actions[i] = FA_ERASE;
00668 break;
00669 }
00670
00671
00672 { char md5sum[50];
00673 const unsigned char * MD5 = rpmfiMD5(fi);
00674 if (!domd5(fn, md5sum, 0, NULL) && memcmp(MD5, md5sum, 16)) {
00675 fi->actions[i] = FA_BACKUP;
00676 break;
00677 }
00678 }
00679 fi->actions[i] = FA_ERASE;
00680 break;
00681 }
00682
00683
00684
00685 rpmtsUpdateDSI(ts, fiFps->entry->dev, rpmfiFSize(fi),
00686 fi->replacedSizes[i], fixupSize, fi->actions[i]);
00687
00688 }
00689 ps = rpmpsFree(ps);
00690 }
00691
00699 static int ensureOlder(rpmts ts,
00700 const rpmte p, const Header h)
00701
00702 {
00703 int_32 reqFlags = (RPMSENSE_LESS | RPMSENSE_EQUAL);
00704 const char * reqEVR;
00705 rpmds req;
00706 char * t;
00707 int nb;
00708 int rc;
00709
00710 if (p == NULL || h == NULL)
00711 return 1;
00712
00713
00714 nb = strlen(rpmteNEVR(p)) + (rpmteE(p) != NULL ? strlen(rpmteE(p)) : 0) + 1;
00715 t = alloca(nb);
00716 *t = '\0';
00717 reqEVR = t;
00718 if (rpmteE(p) != NULL) t = stpcpy( stpcpy(t, rpmteE(p)), ":");
00719 if (rpmteV(p) != NULL) t = stpcpy(t, rpmteV(p));
00720 *t++ = '-';
00721 if (rpmteR(p) != NULL) t = stpcpy(t, rpmteR(p));
00722
00723
00724 req = rpmdsSingle(RPMTAG_REQUIRENAME, rpmteN(p), reqEVR, reqFlags);
00725 rc = rpmdsNVRMatchesDep(h, req, _rpmds_nopromote);
00726 req = rpmdsFree(req);
00727
00728 if (rc == 0) {
00729 rpmps ps = rpmtsProblems(ts);
00730 const char * altNEVR = hGetNEVRA(h, NULL);
00731 rpmpsAppend(ps, RPMPROB_OLDPACKAGE,
00732 rpmteNEVRA(p), rpmteKey(p),
00733 NULL, NULL,
00734 altNEVR,
00735 0);
00736 altNEVR = _free(altNEVR);
00737 ps = rpmpsFree(ps);
00738 rc = 1;
00739 } else
00740 rc = 0;
00741
00742 return rc;
00743 }
00744
00750
00751
00752 static void skipFiles(const rpmts ts, rpmfi fi)
00753
00754
00755 {
00756 uint_32 tscolor = rpmtsColor(ts);
00757 uint_32 FColor;
00758 int noConfigs = (rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONFIGS);
00759 int noDocs = (rpmtsFlags(ts) & RPMTRANS_FLAG_NODOCS);
00760 char ** netsharedPaths = NULL;
00761 const char ** languages;
00762 const char * dn, * bn;
00763 int dnlen, bnlen, ix;
00764 const char * s;
00765 int * drc;
00766 char * dff;
00767 int dc;
00768 int i, j;
00769
00770 if (!noDocs)
00771 noDocs = rpmExpandNumeric("%{_excludedocs}");
00772
00773 { const char *tmpPath = rpmExpand("%{_netsharedpath}", NULL);
00774
00775 if (tmpPath && *tmpPath != '%')
00776 netsharedPaths = splitString(tmpPath, strlen(tmpPath), ':');
00777
00778 tmpPath = _free(tmpPath);
00779 }
00780
00781 s = rpmExpand("%{_install_langs}", NULL);
00782
00783 if (!(s && *s != '%'))
00784 s = _free(s);
00785 if (s) {
00786 languages = (const char **) splitString(s, strlen(s), ':');
00787 s = _free(s);
00788 } else
00789 languages = NULL;
00790
00791
00792
00793 dc = rpmfiDC(fi);
00794 drc = alloca(dc * sizeof(*drc));
00795 memset(drc, 0, dc * sizeof(*drc));
00796 dff = alloca(dc * sizeof(*dff));
00797 memset(dff, 0, dc * sizeof(*dff));
00798
00799 fi = rpmfiInit(fi, 0);
00800 if (fi != NULL)
00801 while ((i = rpmfiNext(fi)) >= 0)
00802 {
00803 char ** nsp;
00804
00805 bn = rpmfiBN(fi);
00806 bnlen = strlen(bn);
00807 ix = rpmfiDX(fi);
00808 dn = rpmfiDN(fi);
00809 dnlen = strlen(dn);
00810 if (dn == NULL)
00811 continue;
00812
00813 drc[ix]++;
00814
00815
00816 if (XFA_SKIPPING(fi->actions[i])) {
00817 drc[ix]--; dff[ix] = 1;
00818 continue;
00819 }
00820
00821
00822 FColor = rpmfiFColor(fi);
00823 if (tscolor && FColor && !(tscolor & FColor)) {
00824 drc[ix]--; dff[ix] = 1;
00825 fi->actions[i] = FA_SKIPCOLOR;
00826 continue;
00827 }
00828
00829
00830
00831
00832
00833
00834 for (nsp = netsharedPaths; nsp && *nsp; nsp++) {
00835 int len;
00836
00837 len = strlen(*nsp);
00838 if (dnlen >= len) {
00839 if (strncmp(dn, *nsp, len))
00840 continue;
00841
00842 if (!(dn[len] == '/' || dn[len] == '\0'))
00843 continue;
00844 } else {
00845 if (len < (dnlen + bnlen))
00846 continue;
00847 if (strncmp(dn, *nsp, dnlen))
00848 continue;
00849
00850 if ((s = strchr((*nsp) + dnlen, '/')) != NULL && s[1] != '\0')
00851 continue;
00852 if (strncmp(bn, (*nsp) + dnlen, bnlen))
00853 continue;
00854 len = dnlen + bnlen;
00855
00856 if (!((*nsp)[len] == '/' || (*nsp)[len] == '\0'))
00857 continue;
00858 }
00859
00860 break;
00861 }
00862
00863 if (nsp && *nsp) {
00864 drc[ix]--; dff[ix] = 1;
00865 fi->actions[i] = FA_SKIPNETSHARED;
00866 continue;
00867 }
00868
00869
00870
00871
00872 if (languages != NULL && fi->flangs != NULL && *fi->flangs[i]) {
00873 const char **lang, *l, *le;
00874 for (lang = languages; *lang != NULL; lang++) {
00875 if (!strcmp(*lang, "all"))
00876 break;
00877 for (l = fi->flangs[i]; *l != '\0'; l = le) {
00878 for (le = l; *le != '\0' && *le != '|'; le++)
00879 {};
00880 if ((le-l) > 0 && !strncmp(*lang, l, (le-l)))
00881 break;
00882 if (*le == '|') le++;
00883 }
00884 if (*l != '\0')
00885 break;
00886 }
00887 if (*lang == NULL) {
00888 drc[ix]--; dff[ix] = 1;
00889 fi->actions[i] = FA_SKIPNSTATE;
00890 continue;
00891 }
00892 }
00893
00894
00895
00896
00897 if (noConfigs && (rpmfiFFlags(fi) & RPMFILE_CONFIG)) {
00898 drc[ix]--; dff[ix] = 1;
00899 fi->actions[i] = FA_SKIPNSTATE;
00900 continue;
00901 }
00902
00903
00904
00905
00906 if (noDocs && (rpmfiFFlags(fi) & RPMFILE_DOC)) {
00907 drc[ix]--; dff[ix] = 1;
00908 fi->actions[i] = FA_SKIPNSTATE;
00909 continue;
00910 }
00911 }
00912
00913
00914 #ifndef NOTYET
00915 if (fi != NULL)
00916 for (j = 0; j < dc; j++)
00917 #else
00918 if ((fi = rpmfiInitD(fi)) != NULL)
00919 while (j = rpmfiNextD(fi) >= 0)
00920 #endif
00921 {
00922
00923 if (drc[j]) continue;
00924 if (!dff[j]) continue;
00925
00926
00927 dn = fi->dnl[j]; dnlen = strlen(dn) - 1;
00928 bn = dn + dnlen; bnlen = 0;
00929 while (bn > dn && bn[-1] != '/') {
00930 bnlen++;
00931 dnlen--;
00932 bn--;
00933 }
00934
00935
00936 fi = rpmfiInit(fi, 0);
00937 if (fi != NULL)
00938 while ((i = rpmfiNext(fi)) >= 0) {
00939 const char * fdn, * fbn;
00940 int_16 fFMode;
00941
00942 if (XFA_SKIPPING(fi->actions[i]))
00943 continue;
00944
00945 fFMode = rpmfiFMode(fi);
00946
00947 if (whatis(fFMode) != XDIR)
00948 continue;
00949 fdn = rpmfiDN(fi);
00950 if (strlen(fdn) != dnlen)
00951 continue;
00952 if (strncmp(fdn, dn, dnlen))
00953 continue;
00954 fbn = rpmfiBN(fi);
00955 if (strlen(fbn) != bnlen)
00956 continue;
00957 if (strncmp(fbn, bn, bnlen))
00958 continue;
00959 rpmMessage(RPMMESS_DEBUG, _("excluding directory %s\n"), dn);
00960 fi->actions[i] = FA_SKIPNSTATE;
00961 break;
00962 }
00963 }
00964
00965
00966 if (netsharedPaths) freeSplitString(netsharedPaths);
00967 #ifdef DYING
00968 fi->flangs = _free(fi->flangs);
00969 #endif
00970 if (languages) freeSplitString((char **)languages);
00971
00972 }
00973
00974
00975
00982 static
00983 rpmfi rpmtsiFi(const rpmtsi tsi)
00984
00985 {
00986 rpmfi fi = NULL;
00987
00988 if (tsi != NULL && tsi->ocsave != -1) {
00989
00990 rpmte te = rpmtsElement(tsi->ts, tsi->ocsave);
00991
00992 if (te != NULL && (fi = te->fi) != NULL)
00993 fi->te = te;
00994
00995
00996 }
00997
00998 return fi;
00999
01000 }
01001
01009 static rpmRC _rpmtsRollback(rpmts rollbackTransaction)
01010
01011
01012
01013 {
01014 int rc = 0;
01015 int numAdded = 0;
01016 int numRemoved = 0;
01017 int_32 tid;
01018 rpmtsi tsi;
01019 rpmte te;
01020 rpmps ps;
01021
01022
01023
01024
01025
01026 tid = rpmtsGetTid(rollbackTransaction);
01027
01028
01029
01030
01031 tsi = rpmtsiInit(rollbackTransaction);
01032 while((te = rpmtsiNext(tsi, 0)) != NULL) {
01033 switch (rpmteType(te)) {
01034 case TR_ADDED:
01035 numAdded++;
01036 break;
01037 case TR_REMOVED:
01038 numRemoved++;
01039 break;
01040 default:
01041 break;
01042 }
01043 }
01044 tsi = rpmtsiFree(tsi);
01045
01046 rpmMessage(RPMMESS_NORMAL, _("Transaction failed...rolling back\n"));
01047 rpmMessage(RPMMESS_NORMAL,
01048 _("Rollback packages (+%d/-%d) to %-24.24s (0x%08x):\n"),
01049 numAdded, numRemoved, ctime(&tid), tid);
01050
01051
01052 rc = rpmtsCheck(rollbackTransaction);
01053 ps = rpmtsProblems(rollbackTransaction);
01054 if (rc != 0 && rpmpsNumProblems(ps) > 0) {
01055 rpmMessage(RPMMESS_ERROR, _("Failed dependencies:\n"));
01056 rpmpsPrint(NULL, ps);
01057 ps = rpmpsFree(ps);
01058 return -1;
01059 }
01060 ps = rpmpsFree(ps);
01061
01062
01063 rc = rpmtsOrder(rollbackTransaction);
01064 if (rc != 0) {
01065 rpmMessage(RPMMESS_ERROR,
01066 _("Could not order auto-rollback transaction!\n"));
01067 return -1;
01068 }
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081 rc = rpmtsRun(rollbackTransaction, NULL,
01082 RPMPROB_FILTER_REPLACEPKG
01083 | RPMPROB_FILTER_REPLACEOLDFILES
01084 | RPMPROB_FILTER_REPLACENEWFILES
01085 | RPMPROB_FILTER_OLDPACKAGE
01086 );
01087 ps = rpmtsProblems(rollbackTransaction);
01088 if (rc > 0 && rpmpsNumProblems(ps) > 0)
01089 rpmpsPrint(stderr, ps);
01090 ps = rpmpsFree(ps);
01091
01092
01093
01094
01095
01096
01097 tsi = rpmtsiInit(rollbackTransaction);
01098 while((te = rpmtsiNext(tsi, 0)) != NULL) {
01099 rpmMessage(RPMMESS_NORMAL, _("Cleaning up repackaged packages:\n"));
01100 switch (rpmteType(te)) {
01101
01102 case TR_ADDED:
01103
01104 if(te->key) {
01105 rpmMessage(RPMMESS_NORMAL, _("\tRemoving %s:\n"), te->key);
01106 (void) unlink(te->key);
01107 }
01108 break;
01109
01110
01111 default:
01112 break;
01113 }
01114 }
01115 tsi = rpmtsiFree(tsi);
01116
01117
01118 rollbackTransaction = rpmtsFree(rollbackTransaction);
01119
01120 return rc;
01121 }
01122
01134 static rpmRC getRepackageHeaderFromTE(rpmts ts, rpmte te,
01135 Header *hdrp,
01136 const char **fnp)
01137
01138
01139
01140 {
01141 int_32 tid;
01142 const char * name;
01143 const char * rpname = NULL;
01144 const char * _repackage_dir = NULL;
01145 const char * globStr = "-*.rpm";
01146 char * rp = NULL;
01147 IDTX rtids = NULL;
01148 IDT rpIDT;
01149 int nrids = 0;
01150 int nb;
01151 Header h = NULL;
01152 int rc = RPMRC_NOTFOUND;
01153 int xx;
01154
01155 rpmMessage(RPMMESS_DEBUG,
01156 _("Getting repackaged header from transaction element\n"));
01157
01158
01159 if (hdrp)
01160 *hdrp = NULL;
01161 if (fnp)
01162 *fnp = NULL;
01163
01164
01165 tid = rpmtsGetTid(ts);
01166
01167
01168
01169 _repackage_dir = rpmExpand("%{?_repackage_dir}", NULL);
01170 if (_repackage_dir == NULL) goto exit;
01171
01172
01173
01174
01175 name = rpmteN(te);
01176 nb = strlen(_repackage_dir) + strlen(name) + strlen(globStr) + 2;
01177 rp = memset((char *) malloc(nb), 0, nb);
01178 xx = snprintf(rp, nb, "%s/%s%s.rpm", _repackage_dir, name, globStr);
01179
01180
01181 rpmMessage(RPMMESS_DEBUG, _("\tLooking for %s...\n"), rp);
01182 rtids = IDTXglob(ts, rp, RPMTAG_REMOVETID);
01183 rp = _free(rp);
01184 if (rtids != NULL) {
01185 rpmMessage(RPMMESS_DEBUG, _("\tMatches found.\n"));
01186 rpIDT = rtids->idt;
01187 nrids = rtids->nidt;
01188 } else {
01189 rpmMessage(RPMMESS_DEBUG, _("\tNo matches found.\n"));
01190 goto exit;
01191 }
01192
01193
01194
01195
01196
01197 do {
01198
01199
01200
01201 if (rpIDT == NULL) {
01202 rpmMessage(RPMMESS_DEBUG, _("\tRepackaged package not found!.\n"));
01203 break;
01204 }
01205
01206
01207 if (rpIDT->val.u32 != tid) {
01208 nrids--;
01209 if (nrids > 0)
01210 rpIDT++;
01211 else
01212 rpIDT = NULL;
01213 continue;
01214 }
01215
01216
01217
01218
01219
01220
01221
01222
01223 rpmMessage(RPMMESS_DEBUG, _("\tREMOVETID matched INSTALLTID.\n"));
01224 if (headerGetEntry(rpIDT->h, RPMTAG_NAME, NULL, (void **) &rpname, NULL)) {
01225 rpmMessage(RPMMESS_DEBUG, _("\t\tName: %s.\n"), rpname);
01226 if (!strcmp(name,rpname)) {
01227
01228 h = headerLink(rpIDT->h);
01229 nb = strlen(rpIDT->key) + 1;
01230 rp = memset((char *) malloc(nb), 0, nb);
01231 rp = strncat(rp, rpIDT->key, nb);
01232 rc = RPMRC_OK;
01233 break;
01234 }
01235 }
01236
01237
01238 nrids--;
01239 if (nrids > 0)
01240 rpIDT++;
01241 else
01242 rpIDT = NULL;
01243 } while (1);
01244
01245
01246 exit:
01247 if (rc != RPMRC_NOTFOUND && h != NULL && hdrp != NULL) {
01248 rpmMessage(RPMMESS_DEBUG, _("\tRepackaged Package was %s...\n"), rp);
01249 if (hdrp != NULL)
01250 *hdrp = headerLink(h);
01251
01252 if (fnp != NULL)
01253 *fnp = rp;
01254 else
01255 rp = _free(rp);
01256
01257 }
01258 if (h != NULL)
01259 h = headerFree(h);
01260 rtids = IDTXfree(rtids);
01261 return rc;
01262 }
01263
01273 static rpmRC _rpmtsAddRollbackElement(rpmts rollbackTransaction,
01274 rpmts runningTransaction, rpmte te)
01275
01276
01277
01278 {
01279 Header h = NULL;
01280 Header rph = NULL;
01281 char * rpn;
01282 unsigned int db_instance = 0;
01283 rpmtsi pi;
01284 rpmte p;
01285 int rc = RPMRC_FAIL;
01286
01287 switch(rpmteType(te)) {
01288 case TR_ADDED:
01289 { rpmdbMatchIterator mi;
01290
01291 rpmMessage(RPMMESS_DEBUG,
01292 _("Adding install element to auto-rollback transaction.\n"));
01293
01294
01295
01296
01297 db_instance = rpmteDBInstance(te);
01298 if (db_instance == 0) {
01299
01300 rpmMessage(RPMMESS_FATALERROR,
01301 _("Could not get install element database instance!\n"));
01302 break;
01303 }
01304
01305
01306 mi = rpmtsInitIterator(rollbackTransaction,
01307 RPMDBI_PACKAGES, &db_instance, sizeof(db_instance));
01308 h = rpmdbNextIterator(mi);
01309 if (h != NULL) h = headerLink(h);
01310 mi = rpmdbFreeIterator(mi);
01311 if (h == NULL) {
01312
01313 rpmMessage(RPMMESS_FATALERROR,
01314 _("Could not get header for auto-rollback transaction!\n"));
01315 break;
01316 }
01317
01318
01319 rc = getRepackageHeaderFromTE(runningTransaction, te, &rph, &rpn);
01320 switch(rc) {
01321 case RPMRC_OK:
01322
01323 rpmMessage(RPMMESS_DEBUG,
01324 _("\tAdded repackaged package header: %s.\n"), rpn);
01325 rpmMessage(RPMMESS_DEBUG,
01326 _("\tAdded from install element %s.\n"), rpmteNEVRA(te));
01327 rc = rpmtsAddInstallElement(rollbackTransaction, headerLink(rph),
01328 (fnpyKey) rpn, 1, te->relocs);
01329 break;
01330
01331 case RPMRC_NOTFOUND:
01332
01333
01334
01335 rpmMessage(RPMMESS_DEBUG, _("\tAdded erase element.\n"));
01336 rpmMessage(RPMMESS_DEBUG,
01337 _("\tAdded from install element %s.\n"), rpmteNEVRA(te));
01338 rc = rpmtsAddEraseElement(rollbackTransaction, h, db_instance);
01339 break;
01340
01341 default:
01342
01343 rpmMessage(RPMMESS_FATALERROR,
01344 _("Could not get repackaged header for auto-rollback transaction!\n"));
01345 break;
01346 }
01347 } break;
01348
01349 case TR_REMOVED:
01350 rpmMessage(RPMMESS_DEBUG,
01351 _("Add erase element to auto-rollback transaction.\n"));
01352
01353
01354
01355
01356 pi = rpmtsiInit(rollbackTransaction);
01357 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01358 if (!strcmp(rpmteN(p), rpmteN(te))) {
01359 rpmMessage(RPMMESS_DEBUG, _("\tFound existing upgrade element.\n"));
01360 rpmMessage(RPMMESS_DEBUG, _("\tNot adding erase element for %s.\n"),
01361 rpmteN(te));
01362 rc = RPMRC_OK;
01363 pi = rpmtsiFree(pi);
01364 goto cleanup;
01365 }
01366 }
01367 pi = rpmtsiFree(pi);
01368
01369
01370
01371
01372 rc = getRepackageHeaderFromTE(runningTransaction, te, &rph, &rpn);
01373 switch(rc) {
01374 case RPMRC_OK:
01375
01376 rpmMessage(RPMMESS_DEBUG,
01377 _("\tAdded repackaged package %s.\n"), rpn);
01378 rpmMessage(RPMMESS_DEBUG,
01379 _("\tAdded from erase element %s.\n"), rpmteNEVRA(te));
01380 rc = rpmtsAddInstallElement(rollbackTransaction, rph,
01381 (fnpyKey) rpn, 1, te->relocs);
01382 if (rc != RPMRC_OK)
01383 rpmMessage(RPMMESS_FATALERROR,
01384 _("Could not add erase element to auto-rollback transaction.\n"));
01385 break;
01386
01387 case RPMRC_NOTFOUND:
01388
01389 rpmMessage(RPMMESS_DEBUG,
01390 _("\tNo repackaged package...nothing to do.\n"));
01391 rc = RPMRC_OK;
01392 break;
01393
01394 default:
01395 rpmMessage(RPMMESS_FATALERROR,
01396 _("Failure reading repackaged package!\n"));
01397 break;
01398 }
01399 break;
01400
01401 default:
01402 break;
01403 }
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414 cleanup:
01415
01416 if (h != NULL)
01417 h = headerFree(h);
01418 if (rph != NULL)
01419 rph = headerFree(rph);
01420 return rc;
01421 }
01422
01423 static int isFailedKey(alKey *failedKeys, int nkeys, alKey pkgKey)
01424 {
01425 int i;
01426 for (i = 0; i < nkeys; i++) {
01427 if (failedKeys[i] == pkgKey)
01428 return 1;
01429 }
01430 return 0;
01431 }
01432
01433 #define NOTIFY(_ts, _al) if ((_ts)->notify) (void) (_ts)->notify _al
01434
01435 int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
01436 {
01437 uint_32 tscolor = rpmtsColor(ts);
01438 int i, j;
01439 int ourrc = 0;
01440 int totalFileCount = 0;
01441 rpmfi fi;
01442 sharedFileInfo shared, sharedList;
01443 int numShared;
01444 int nexti;
01445 alKey * failedKeys = NULL;
01446 fingerPrintCache fpc;
01447 rpmps ps;
01448 rpmpsm psm;
01449 rpmtsi pi; rpmte p;
01450 rpmtsi qi; rpmte q;
01451 int numAdded;
01452 int numRemoved;
01453 rpmts rollbackTransaction = NULL;
01454 int rollbackOnFailure = 0;
01455 void * lock = NULL;
01456 int xx;
01457 mode_t oldmask;
01458
01459
01460 if (rpmtsNElements(ts) <= 0)
01461 return -1;
01462
01463
01464 oldmask = umask(022);
01465
01466
01467 rollbackOnFailure = rpmExpandNumeric(
01468 "%{?_rollback_transaction_on_failure}");
01469 if (rpmtsGetType(ts) & (RPMTRANS_TYPE_ROLLBACK
01470 | RPMTRANS_TYPE_AUTOROLLBACK)) {
01471 rollbackOnFailure = 0;
01472 }
01473
01474
01475
01476
01477
01478 if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) {
01479 rollbackOnFailure = 0;
01480 } else {
01481 lock = rpmtsAcquireLock(ts);
01482 if (lock == NULL) {
01483 umask(oldmask);
01484 return -1;
01485 }
01486 }
01487
01488
01489 if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOSCRIPTS)
01490 (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers));
01491 if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERS)
01492 (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransTriggers));
01493
01494 if (rpmtsFlags(ts) & RPMTRANS_FLAG_JUSTDB)
01495 (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers));
01496
01497 ts->probs = rpmpsFree(ts->probs);
01498 ts->probs = rpmpsCreate();
01499
01500
01501 { int dbmode = (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)
01502 ? O_RDONLY : (O_RDWR|O_CREAT);
01503
01504
01505 if (rpmtsOpenDB(ts, dbmode)) {
01506 rpmtsFreeLock(lock);
01507 umask(oldmask);
01508 return -1;
01509 }
01510 }
01511
01512 ts->ignoreSet = ignoreSet;
01513 { const char * currDir = currentDirectory();
01514 rpmtsSetCurrDir(ts, currDir);
01515 currDir = _free(currDir);
01516 }
01517
01518 (void) rpmtsSetChrootDone(ts, 0);
01519
01520 { int_32 tid = (int_32) time(NULL);
01521 (void) rpmtsSetTid(ts, tid);
01522 }
01523
01524
01525 xx = rpmtsInitDSI(ts);
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536 rpmMessage(RPMMESS_DEBUG, _("sanity checking %d elements\n"), rpmtsNElements(ts));
01537 ps = rpmtsProblems(ts);
01538
01539 pi = rpmtsiInit(ts);
01540
01541 while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
01542 rpmdbMatchIterator mi;
01543 int fc;
01544
01545 if ((fi = rpmtsiFi(pi)) == NULL)
01546 continue;
01547 fc = rpmfiFC(fi);
01548
01549
01550 #if !defined(__ia64__)
01551 if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_IGNOREARCH))
01552 if (!archOkay(rpmteA(p)))
01553 rpmpsAppend(ps, RPMPROB_BADARCH,
01554 rpmteNEVRA(p), rpmteKey(p),
01555 rpmteA(p), NULL,
01556 NULL, 0);
01557 #endif
01558
01559 if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_IGNOREOS))
01560 if (!osOkay(rpmteO(p)))
01561 rpmpsAppend(ps, RPMPROB_BADOS,
01562 rpmteNEVRA(p), rpmteKey(p),
01563 rpmteO(p), NULL,
01564 NULL, 0);
01565
01566 if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_OLDPACKAGE)) {
01567 Header h;
01568 mi = rpmtsInitIterator(ts, RPMTAG_NAME, rpmteN(p), 0);
01569 while ((h = rpmdbNextIterator(mi)) != NULL)
01570 xx = ensureOlder(ts, p, h);
01571 mi = rpmdbFreeIterator(mi);
01572 }
01573
01574 if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEPKG)) {
01575 mi = rpmtsInitIterator(ts, RPMTAG_NAME, rpmteN(p), 0);
01576 xx = rpmdbSetIteratorRE(mi, RPMTAG_EPOCH, RPMMIRE_STRCMP,
01577 rpmteE(p));
01578 xx = rpmdbSetIteratorRE(mi, RPMTAG_VERSION, RPMMIRE_STRCMP,
01579 rpmteV(p));
01580 xx = rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, RPMMIRE_STRCMP,
01581 rpmteR(p));
01582 if (tscolor) {
01583 xx = rpmdbSetIteratorRE(mi, RPMTAG_ARCH, RPMMIRE_STRCMP,
01584 rpmteA(p));
01585 xx = rpmdbSetIteratorRE(mi, RPMTAG_OS, RPMMIRE_STRCMP,
01586 rpmteO(p));
01587 }
01588
01589 while (rpmdbNextIterator(mi) != NULL) {
01590 rpmpsAppend(ps, RPMPROB_PKG_INSTALLED,
01591 rpmteNEVRA(p), rpmteKey(p),
01592 NULL, NULL,
01593 NULL, 0);
01594 break;
01595 }
01596 mi = rpmdbFreeIterator(mi);
01597 }
01598
01599
01600 totalFileCount += fc;
01601
01602 }
01603 pi = rpmtsiFree(pi);
01604 ps = rpmpsFree(ps);
01605
01606
01607 pi = rpmtsiInit(ts);
01608 while ((p = rpmtsiNext(pi, TR_REMOVED)) != NULL) {
01609 int fc;
01610
01611 if ((fi = rpmtsiFi(pi)) == NULL)
01612 continue;
01613 fc = rpmfiFC(fi);
01614
01615 totalFileCount += fc;
01616 }
01617 pi = rpmtsiFree(pi);
01618
01619
01620
01621
01622 if (!((rpmtsFlags(ts) & (RPMTRANS_FLAG_BUILD_PROBS|RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_NOPRE))
01623 || (ts->probs->numProblems &&
01624 (okProbs == NULL || rpmpsTrim(ts->probs, okProbs))))) {
01625 rpmMessage(RPMMESS_DEBUG, _("running pre-transaction scripts\n"));
01626 pi = rpmtsiInit(ts);
01627 while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
01628 if ((fi = rpmtsiFi(pi)) == NULL)
01629 continue;
01630
01631
01632 if (fi->pretrans == NULL)
01633 continue;
01634
01635 p->fd = ts->notify(p->h, RPMCALLBACK_INST_OPEN_FILE, 0, 0,
01636 rpmteKey(p), ts->notifyData);
01637 p->h = NULL;
01638 if (rpmteFd(p) != NULL) {
01639 rpmVSFlags ovsflags = rpmtsVSFlags(ts);
01640 rpmVSFlags vsflags = ovsflags | RPMVSF_NEEDPAYLOAD;
01641 rpmRC rpmrc;
01642 ovsflags = rpmtsSetVSFlags(ts, vsflags);
01643 rpmrc = rpmReadPackageFile(ts, rpmteFd(p),
01644 rpmteNEVR(p), &p->h);
01645 vsflags = rpmtsSetVSFlags(ts, ovsflags);
01646 switch (rpmrc) {
01647 default:
01648
01649 p->fd = ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE,
01650 0, 0,
01651 rpmteKey(p), ts->notifyData);
01652
01653 p->fd = NULL;
01654 break;
01655 case RPMRC_NOTTRUSTED:
01656 case RPMRC_NOKEY:
01657 case RPMRC_OK:
01658 break;
01659 }
01660 }
01661
01662
01663 if (rpmteFd(p) != NULL) {
01664 fi = rpmfiNew(ts, p->h, RPMTAG_BASENAMES, 1);
01665 if (fi != NULL) {
01666 fi->te = p;
01667 p->fi = fi;
01668 }
01669
01670 psm = rpmpsmNew(ts, p, p->fi);
01671
01672 assert(psm != NULL);
01673 psm->scriptTag = RPMTAG_PRETRANS;
01674 psm->progTag = RPMTAG_PRETRANSPROG;
01675 xx = rpmpsmStage(psm, PSM_SCRIPT);
01676 psm = rpmpsmFree(psm);
01677
01678
01679 (void) ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE, 0, 0,
01680 rpmteKey(p), ts->notifyData);
01681
01682 p->fd = NULL;
01683 p->h = headerFree(p->h);
01684 }
01685
01686 }
01687 pi = rpmtsiFree(pi);
01688 }
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699 rpmMessage(RPMMESS_DEBUG, _("computing %d file fingerprints\n"), totalFileCount);
01700
01701 numAdded = numRemoved = 0;
01702 pi = rpmtsiInit(ts);
01703 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01704 int fc;
01705
01706 if ((fi = rpmtsiFi(pi)) == NULL)
01707 continue;
01708 fc = rpmfiFC(fi);
01709
01710
01711 switch (rpmteType(p)) {
01712 case TR_ADDED:
01713 numAdded++;
01714 fi->record = 0;
01715
01716 if (fc > 0)
01717 skipFiles(ts, fi);
01718 break;
01719 case TR_REMOVED:
01720 numRemoved++;
01721 fi->record = rpmteDBOffset(p);
01722 break;
01723 }
01724
01725
01726 fi->fps = (fc > 0 ? xmalloc(fc * sizeof(*fi->fps)) : NULL);
01727 }
01728 pi = rpmtsiFree(pi);
01729
01730 if (!rpmtsChrootDone(ts)) {
01731 const char * rootDir = rpmtsRootDir(ts);
01732 xx = chdir("/");
01733
01734 if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/') {
01735
01736 xx = rpmdbOpenAll(ts->rdb);
01737 xx = chroot(rootDir);
01738 }
01739
01740 (void) rpmtsSetChrootDone(ts, 1);
01741 }
01742
01743 ts->ht = htCreate(totalFileCount * 2, 0, 0, fpHashFunction, fpEqual);
01744 fpc = fpCacheCreate(totalFileCount);
01745
01746
01747
01748
01749 pi = rpmtsiInit(ts);
01750 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01751 int fc;
01752
01753 (void) rpmdbCheckSignals();
01754
01755 if ((fi = rpmtsiFi(pi)) == NULL)
01756 continue;
01757 fc = rpmfiFC(fi);
01758
01759 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
01760 fpLookupList(fpc, fi->dnl, fi->bnl, fi->dil, fc, fi->fps);
01761
01762 fi = rpmfiInit(fi, 0);
01763 if (fi != NULL)
01764 while ((i = rpmfiNext(fi)) >= 0) {
01765 if (XFA_SKIPPING(fi->actions[i]))
01766 continue;
01767
01768 htAddEntry(ts->ht, fi->fps + i, (void *) fi);
01769
01770 }
01771
01772 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), fc);
01773
01774 }
01775 pi = rpmtsiFree(pi);
01776
01777 NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_START, 6, ts->orderCount,
01778 NULL, ts->notifyData));
01779
01780
01781
01782
01783 rpmMessage(RPMMESS_DEBUG, _("computing file dispositions\n"));
01784 ps = rpmtsProblems(ts);
01785 pi = rpmtsiInit(ts);
01786 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01787 dbiIndexSet * matches;
01788 int knownBad;
01789 int fc;
01790
01791 (void) rpmdbCheckSignals();
01792
01793 if ((fi = rpmtsiFi(pi)) == NULL)
01794 continue;
01795 fc = rpmfiFC(fi);
01796
01797 NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_PROGRESS, rpmtsiOc(pi),
01798 ts->orderCount, NULL, ts->notifyData));
01799
01800 if (fc == 0) continue;
01801
01802 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
01803
01804 matches = xcalloc(fc, sizeof(*matches));
01805 if (rpmdbFindFpList(rpmtsGetRdb(ts), fi->fps, matches, fc)) {
01806 ps = rpmpsFree(ps);
01807 rpmtsFreeLock(lock);
01808 umask(oldmask);
01809 return 1;
01810 }
01811
01812 numShared = 0;
01813 fi = rpmfiInit(fi, 0);
01814 while ((i = rpmfiNext(fi)) >= 0)
01815 numShared += dbiIndexSetCount(matches[i]);
01816
01817
01818 shared = sharedList = xcalloc((numShared + 1), sizeof(*sharedList));
01819
01820 fi = rpmfiInit(fi, 0);
01821 while ((i = rpmfiNext(fi)) >= 0) {
01822
01823
01824
01825
01826 for (j = 0; j < dbiIndexSetCount(matches[i]); j++) {
01827 int ro;
01828 ro = dbiIndexRecordOffset(matches[i], j);
01829 knownBad = 0;
01830 qi = rpmtsiInit(ts);
01831 while ((q = rpmtsiNext(qi, TR_REMOVED)) != NULL) {
01832 if (ro == knownBad)
01833 break;
01834 if (rpmteDBOffset(q) == ro)
01835 knownBad = ro;
01836 }
01837 qi = rpmtsiFree(qi);
01838
01839 shared->pkgFileNum = i;
01840 shared->otherPkg = dbiIndexRecordOffset(matches[i], j);
01841 shared->otherFileNum = dbiIndexRecordFileNumber(matches[i], j);
01842 shared->isRemoved = (knownBad == ro);
01843 shared++;
01844 }
01845 matches[i] = dbiFreeIndexSet(matches[i]);
01846 }
01847 numShared = shared - sharedList;
01848 shared->otherPkg = -1;
01849 matches = _free(matches);
01850
01851
01852 qsort(sharedList, numShared, sizeof(*shared), sharedCmp);
01853
01854
01855
01856 for (i = 0; i < numShared; i = nexti) {
01857 int beingRemoved;
01858
01859 shared = sharedList + i;
01860
01861
01862 for (nexti = i + 1; nexti < numShared; nexti++) {
01863 if (sharedList[nexti].otherPkg != shared->otherPkg)
01864 break;
01865 }
01866
01867
01868 beingRemoved = 0;
01869 if (ts->removedPackages != NULL)
01870 for (j = 0; j < ts->numRemovedPackages; j++) {
01871 if (ts->removedPackages[j] != shared->otherPkg)
01872 continue;
01873 beingRemoved = 1;
01874 break;
01875 }
01876
01877
01878 switch (rpmteType(p)) {
01879 case TR_ADDED:
01880 xx = handleInstInstalledFiles(ts, p, fi, shared, nexti - i,
01881 !(beingRemoved || (rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEOLDFILES)));
01882 break;
01883 case TR_REMOVED:
01884 if (!beingRemoved)
01885 xx = handleRmvdInstalledFiles(ts, fi, shared, nexti - i);
01886 break;
01887 }
01888 }
01889
01890
01891 free(sharedList);
01892
01893
01894 handleOverlappedFiles(ts, p, fi);
01895
01896
01897 switch (rpmteType(p)) {
01898 case TR_ADDED:
01899 rpmtsCheckDSIProblems(ts, p);
01900 break;
01901 case TR_REMOVED:
01902 break;
01903 }
01904
01905 if (rpmteType(p) == TR_REMOVED) {
01906 fi = rpmfiInit(fi, 0);
01907 while ((i = rpmfiNext(fi)) >= 0) {
01908 int_16 mode;
01909 if (XFA_SKIPPING(fi->actions[i]))
01910 continue;
01911 (void) rpmfiSetFX(fi, i);
01912 mode = rpmfiFMode(fi);
01913 if (S_ISREG(mode) && (mode & 06000) != 0) {
01914 fi->mapflags |= CPIO_SBIT_CHECK;
01915 }
01916 }
01917 }
01918 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), fc);
01919 }
01920 pi = rpmtsiFree(pi);
01921 ps = rpmpsFree(ps);
01922
01923 if (rpmtsChrootDone(ts)) {
01924 const char * rootDir = rpmtsRootDir(ts);
01925 const char * currDir = rpmtsCurrDir(ts);
01926
01927 if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/')
01928 xx = chroot(".");
01929
01930 (void) rpmtsSetChrootDone(ts, 0);
01931 if (currDir != NULL)
01932 xx = chdir(currDir);
01933 }
01934
01935 NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_STOP, 6, ts->orderCount,
01936 NULL, ts->notifyData));
01937
01938
01939
01940
01941 pi = rpmtsiInit(ts);
01942 while ((p = rpmtsiNext(pi, 0)) != NULL) {
01943 if ((fi = rpmtsiFi(pi)) == NULL)
01944 continue;
01945 if (rpmfiFC(fi) == 0)
01946 continue;
01947 fi->fps = _free(fi->fps);
01948 }
01949 pi = rpmtsiFree(pi);
01950
01951 fpc = fpCacheFree(fpc);
01952 ts->ht = htFree(ts->ht);
01953
01954
01955
01956
01957 if ((rpmtsFlags(ts) & RPMTRANS_FLAG_BUILD_PROBS)
01958 || (ts->probs->numProblems &&
01959 (okProbs == NULL || rpmpsTrim(ts->probs, okProbs)))
01960 )
01961 {
01962 rpmtsFreeLock(lock);
01963 umask(oldmask);
01964 return ts->orderCount;
01965 }
01966
01967
01968
01969
01970
01971
01972 if (rollbackOnFailure) {
01973 rpmtransFlags tsFlags;
01974 rpmVSFlags ovsflags;
01975 rpmVSFlags vsflags;
01976
01977 rpmMessage(RPMMESS_DEBUG,
01978 _("Creating auto-rollback transaction\n"));
01979
01980 rollbackTransaction = rpmtsCreate();
01981
01982
01983
01984
01985
01986
01987
01988 vsflags = rpmExpandNumeric("%{?_vsflags_erase}");
01989 vsflags |= _RPMVSF_NODIGESTS;
01990 vsflags |= _RPMVSF_NOSIGNATURES;
01991 vsflags |= RPMVSF_NOHDRCHK;
01992 vsflags |= RPMVSF_NEEDPAYLOAD;
01993 ovsflags = rpmtsSetVSFlags(ts, vsflags);
01994
01995
01996
01997
01998
01999
02000 rpmtsSetType(rollbackTransaction, RPMTRANS_TYPE_AUTOROLLBACK);
02001
02002
02003 tsFlags = rpmtsSetFlags(rollbackTransaction, rpmtsFlags(ts));
02004
02005
02006 rpmtsSetRootDir(rollbackTransaction, rpmtsRootDir(ts));
02007
02008
02009
02010
02011 xx = rpmtsSetNotifyCallback(rollbackTransaction, ts->notify, ts->notifyData);
02012
02013
02014 xx = rpmtsScoreInit(ts, rollbackTransaction);
02015 }
02016
02017
02018
02019
02020 if (rpmtsFlags(ts) & (RPMTRANS_FLAG_DIRSTASH | RPMTRANS_FLAG_REPACKAGE)) {
02021 int progress;
02022
02023 progress = 0;
02024 pi = rpmtsiInit(ts);
02025 while ((p = rpmtsiNext(pi, 0)) != NULL) {
02026
02027 if ((fi = rpmtsiFi(pi)) == NULL)
02028 continue;
02029 switch (rpmteType(p)) {
02030 case TR_ADDED:
02031 break;
02032 case TR_REMOVED:
02033 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_REPACKAGE))
02034 break;
02035 if (!progress)
02036 NOTIFY(ts, (NULL, RPMCALLBACK_REPACKAGE_START,
02037 7, numRemoved, NULL, ts->notifyData));
02038
02039 NOTIFY(ts, (NULL, RPMCALLBACK_REPACKAGE_PROGRESS, progress,
02040 numRemoved, NULL, ts->notifyData));
02041 progress++;
02042
02043 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_REPACKAGE), 0);
02044
02045
02046 fi->mapflags |= CPIO_MAP_ABSOLUTE;
02047 fi->mapflags |= CPIO_MAP_ADDDOT;
02048 fi->mapflags |= CPIO_ALL_HARDLINKS;
02049 psm = rpmpsmNew(ts, p, fi);
02050 assert(psm != NULL);
02051 xx = rpmpsmStage(psm, PSM_PKGSAVE);
02052 psm = rpmpsmFree(psm);
02053 fi->mapflags &= ~CPIO_MAP_ABSOLUTE;
02054 fi->mapflags &= ~CPIO_MAP_ADDDOT;
02055 fi->mapflags &= ~CPIO_ALL_HARDLINKS;
02056
02057 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_REPACKAGE), 0);
02058
02059 break;
02060 }
02061 }
02062 pi = rpmtsiFree(pi);
02063 if (progress) {
02064 NOTIFY(ts, (NULL, RPMCALLBACK_REPACKAGE_STOP, 7, numRemoved,
02065 NULL, ts->notifyData));
02066 }
02067 }
02068
02069
02070
02071
02072 failedKeys = xmalloc(ts->orderCount * sizeof(*failedKeys));
02073 for (i = 0; i < ts->orderCount; i++)
02074 failedKeys[i] = (alKey)-2;
02075
02076 pi = rpmtsiInit(ts);
02077
02078 while ((p = rpmtsiNext(pi, 0)) != NULL) {
02079 alKey pkgKey;
02080 int gotfd;
02081
02082 gotfd = 0;
02083 if ((fi = rpmtsiFi(pi)) == NULL)
02084 continue;
02085
02086 psm = rpmpsmNew(ts, p, fi);
02087 assert(psm != NULL);
02088 psm->unorderedSuccessor =
02089 (rpmtsiOc(pi) >= rpmtsUnorderedSuccessors(ts, -1) ? 1 : 0);
02090
02091 switch (rpmteType(p)) {
02092 case TR_ADDED:
02093 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_INSTALL), 0);
02094
02095 pkgKey = rpmteAddedKey(p);
02096
02097 rpmMessage(RPMMESS_DEBUG, "========== +++ %s %s-%s 0x%x\n",
02098 rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));
02099
02100 p->h = NULL;
02101
02102 {
02103
02104 p->fd = ts->notify(p->h, RPMCALLBACK_INST_OPEN_FILE, 0, 0,
02105 rpmteKey(p), ts->notifyData);
02106
02107 if (rpmteFd(p) != NULL) {
02108 rpmVSFlags ovsflags = rpmtsVSFlags(ts);
02109 rpmVSFlags vsflags = ovsflags | RPMVSF_NEEDPAYLOAD;
02110 rpmRC rpmrc;
02111
02112 ovsflags = rpmtsSetVSFlags(ts, vsflags);
02113 rpmrc = rpmReadPackageFile(ts, rpmteFd(p),
02114 rpmteNEVR(p), &p->h);
02115 vsflags = rpmtsSetVSFlags(ts, ovsflags);
02116
02117 switch (rpmrc) {
02118 default:
02119
02120 p->fd = ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE,
02121 0, 0,
02122 rpmteKey(p), ts->notifyData);
02123
02124 p->fd = NULL;
02125 ourrc++;
02126
02127
02128
02129 if (rollbackOnFailure) {
02130 rpmMessage(RPMMESS_ERROR,
02131 _("Add failed. Could not read package header.\n"));
02132
02133 p->h = headerFree(p->h);
02134 xx = rpmdbSync(rpmtsGetRdb(ts));
02135 psm = rpmpsmFree(psm);
02136 p->fi = rpmfiFree(p->fi);
02137 pi = rpmtsiFree(pi);
02138
02139
02140 xx = _rpmtsRollback(rollbackTransaction);
02141 failedKeys = _free(failedKeys);
02142 umask(oldmask);
02143 return -1;
02144 }
02145 break;
02146 case RPMRC_NOTTRUSTED:
02147 case RPMRC_NOKEY:
02148 case RPMRC_OK:
02149 break;
02150 }
02151 if (rpmteFd(p) != NULL) gotfd = 1;
02152 }
02153 }
02154
02155
02156 if (rpmteFd(p) != NULL) {
02157
02158
02159
02160
02161 psm->fi = rpmfiFree(psm->fi);
02162 {
02163 char * fstates = fi->fstates;
02164 fileAction * actions = fi->actions;
02165 sharedFileInfo replaced = fi->replaced;
02166 int mapflags = fi->mapflags;
02167 rpmte savep;
02168 int numShared = 0;
02169
02170 if (replaced != NULL) {
02171 for (replaced; replaced->otherPkg; replaced++) {
02172 numShared++;
02173 }
02174 if (numShared > 0) {
02175 replaced = xcalloc(numShared + 1,
02176 sizeof(*fi->replaced));
02177 memcpy(replaced, fi->replaced,
02178 sizeof(*fi->replaced) * (numShared + 1));
02179 }
02180 }
02181
02182 fi->fstates = NULL;
02183 fi->actions = NULL;
02184 fi->replaced = NULL;
02185
02186 fi = rpmfiFree(fi);
02187
02188
02189 savep = rpmtsSetRelocateElement(ts, p);
02190 fi = rpmfiNew(ts, p->h, RPMTAG_BASENAMES, 1);
02191 (void) rpmtsSetRelocateElement(ts, savep);
02192
02193 if (fi != NULL) {
02194 fi->te = p;
02195 fi->fstates = _free(fi->fstates);
02196 fi->fstates = fstates;
02197 fi->actions = _free(fi->actions);
02198 fi->actions = actions;
02199 if (replaced != NULL)
02200 fi->replaced = replaced;
02201 if (mapflags & CPIO_SBIT_CHECK)
02202 fi->mapflags |= CPIO_SBIT_CHECK;
02203 p->fi = fi;
02204 }
02205 }
02206 psm->fi = rpmfiLink(p->fi, NULL);
02207
02208
02209 if (rpmpsmStage(psm, PSM_PKGINSTALL)) {
02210 ourrc++;
02211 failedKeys[rpmtsiOc(pi)] = pkgKey;
02212
02213
02214
02215 if (rollbackOnFailure) {
02216 rpmMessage(RPMMESS_ERROR,
02217 _("Add failed in rpmpsmStage().\n"));
02218
02219 p->h = headerFree(p->h);
02220 xx = rpmdbSync(rpmtsGetRdb(ts));
02221 psm = rpmpsmFree(psm);
02222 p->fi = rpmfiFree(p->fi);
02223 pi = rpmtsiFree(pi);
02224
02225
02226 xx = _rpmtsRollback(rollbackTransaction);
02227 failedKeys = _free(failedKeys);
02228 umask(oldmask);
02229 return -1;
02230 }
02231 }
02232
02233
02234
02235
02236
02237 if (rollbackOnFailure) {
02238 int rc;
02239
02240 rc = _rpmtsAddRollbackElement(rollbackTransaction, ts, p);
02241 if (rc != RPMRC_OK) {
02242
02243 p->h = headerFree(p->h);
02244 xx = rpmdbSync(rpmtsGetRdb(ts));
02245 psm = rpmpsmFree(psm);
02246 p->fi = rpmfiFree(p->fi);
02247 pi = rpmtsiFree(pi);
02248
02249
02250 rollbackTransaction = rpmtsFree(rollbackTransaction);
02251 failedKeys = _free(failedKeys);
02252 umask(oldmask);
02253 return -1;
02254 }
02255 }
02256
02257 } else {
02258 ourrc++;
02259 failedKeys[rpmtsiOc(pi)] = pkgKey;
02260
02261
02262
02263
02264 if (rollbackOnFailure) {
02265 rpmMessage(RPMMESS_ERROR, _("Add failed. Could not get file list.\n"));
02266
02267 p->h = headerFree(p->h);
02268 xx = rpmdbSync(rpmtsGetRdb(ts));
02269 psm = rpmpsmFree(psm);
02270 p->fi = rpmfiFree(p->fi);
02271 pi = rpmtsiFree(pi);
02272
02273
02274 xx = _rpmtsRollback(rollbackTransaction);
02275 failedKeys = _free(failedKeys);
02276 umask(oldmask);
02277 return -1;
02278 }
02279 }
02280
02281 if (gotfd) {
02282
02283 (void) ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE, 0, 0,
02284 rpmteKey(p), ts->notifyData);
02285
02286
02287 p->fd = NULL;
02288
02289 }
02290
02291 p->h = headerFree(p->h);
02292
02293 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_INSTALL), 0);
02294
02295 break;
02296
02297 case TR_REMOVED:
02298 (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_ERASE), 0);
02299
02300 rpmMessage(RPMMESS_DEBUG, "========== --- %s %s-%s 0x%x\n",
02301 rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));
02302
02303
02304
02305
02306
02307 if (!isFailedKey(failedKeys, rpmtsiOc(pi), rpmteDependsOnKey(p))) {
02308 if (rpmpsmStage(psm, PSM_PKGERASE)) {
02309 ourrc++;
02310
02311
02312
02313
02314 if (rollbackOnFailure) {
02315 rpmMessage(RPMMESS_ERROR,
02316 _("Erase failed failed in rpmpsmStage().\n"));
02317
02318 xx = rpmdbSync(rpmtsGetRdb(ts));
02319 psm = rpmpsmFree(psm);
02320 p->fi = rpmfiFree(p->fi);
02321 pi = rpmtsiFree(pi);
02322
02323
02324 xx = _rpmtsRollback(rollbackTransaction);
02325 failedKeys = _free(failedKeys);
02326 umask(oldmask);
02327 return -1;
02328 }
02329 }
02330
02331
02332
02333
02334
02335 if (rollbackOnFailure) {
02336 int rc;
02337
02338 rc = _rpmtsAddRollbackElement(rollbackTransaction, ts, p);
02339
02340 if (rc != RPMRC_OK) {
02341
02342 xx = rpmdbSync(rpmtsGetRdb(ts));
02343 psm = rpmpsmFree(psm);
02344 p->fi = rpmfiFree(p->fi);
02345 pi = rpmtsiFree(pi);
02346
02347
02348 rollbackTransaction = rpmtsFree(rollbackTransaction);
02349 failedKeys = _free(failedKeys);
02350 umask(oldmask);
02351 return -1;
02352 }
02353 }
02354 }
02355
02356 (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_ERASE), 0);
02357
02358 break;
02359 }
02360 xx = rpmdbSync(rpmtsGetRdb(ts));
02361
02362
02363 psm = rpmpsmFree(psm);
02364
02365
02366 #ifdef DYING
02367
02368 p->fi = rpmfiFree(p->fi);
02369
02370 #endif
02371
02372 }
02373
02374 pi = rpmtsiFree(pi);
02375
02376
02377 if (rollbackOnFailure && rollbackTransaction != NULL)
02378 rollbackTransaction = rpmtsFree(rollbackTransaction);
02379
02380 if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_NOPOST))) {
02381 rpmMessage(RPMMESS_DEBUG, _("running post-transaction scripts\n"));
02382 pi = rpmtsiInit(ts);
02383 while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
02384 int haspostscript;
02385
02386 if ((fi = rpmtsiFi(pi)) == NULL)
02387 continue;
02388
02389 haspostscript = (fi->posttrans != NULL ? 1 : 0);
02390 p->fi = rpmfiFree(p->fi);
02391
02392
02393 if (!haspostscript)
02394 continue;
02395
02396 p->fd = ts->notify(p->h, RPMCALLBACK_INST_OPEN_FILE, 0, 0,
02397 rpmteKey(p), ts->notifyData);
02398 p->h = NULL;
02399 if (rpmteFd(p) != NULL) {
02400 rpmVSFlags ovsflags = rpmtsVSFlags(ts);
02401 rpmVSFlags vsflags = ovsflags | RPMVSF_NEEDPAYLOAD;
02402 rpmRC rpmrc;
02403 ovsflags = rpmtsSetVSFlags(ts, vsflags);
02404 rpmrc = rpmReadPackageFile(ts, rpmteFd(p),
02405 rpmteNEVR(p), &p->h);
02406 vsflags = rpmtsSetVSFlags(ts, ovsflags);
02407 switch (rpmrc) {
02408 default:
02409 p->fd = ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE,
02410 0, 0, rpmteKey(p), ts->notifyData);
02411 p->fd = NULL;
02412 break;
02413 case RPMRC_NOTTRUSTED:
02414 case RPMRC_NOKEY:
02415 case RPMRC_OK:
02416 break;
02417 }
02418 }
02419
02420 if (rpmteFd(p) != NULL) {
02421 p->fi = rpmfiNew(ts, p->h, RPMTAG_BASENAMES, 1);
02422 if (p->fi != NULL)
02423 p->fi->te = p;
02424
02425 psm = rpmpsmNew(ts, p, p->fi);
02426
02427 assert(psm != NULL);
02428 psm->scriptTag = RPMTAG_POSTTRANS;
02429 psm->progTag = RPMTAG_POSTTRANSPROG;
02430 xx = rpmpsmStage(psm, PSM_SCRIPT);
02431 psm = rpmpsmFree(psm);
02432
02433
02434 (void) ts->notify(p->h, RPMCALLBACK_INST_CLOSE_FILE, 0, 0,
02435 rpmteKey(p), ts->notifyData);
02436
02437 p->fd = NULL;
02438 p->fi = rpmfiFree(p->fi);
02439 p->h = headerFree(p->h);
02440 }
02441 }
02442 pi = rpmtsiFree(pi);
02443 }
02444
02445 failedKeys = _free(failedKeys);
02446 rpmtsFreeLock(lock);
02447 umask(oldmask);
02448
02449
02450 if (ourrc)
02451 return -1;
02452 else
02453 return 0;
02454
02455 }