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