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