Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

lib/rpminstall.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 
00007 #include <rpmcli.h>
00008 
00009 #include "rpmdb.h"
00010 #include "rpmds.h"
00011 
00012 #define _RPMTS_INTERNAL         /* ts->goal, ts->dbmode, ts->suggests */
00013 #include "rpmts.h"
00014 
00015 #include "manifest.h"
00016 #include "misc.h"       /* XXX for rpmGlob() */
00017 #include "debug.h"
00018 
00019 /*@access rpmts @*/     /* XXX ts->goal, ts->dbmode */
00020 /*@access rpmps @*/     /* XXX compared with NULL */
00021 /*@access Header @*/            /* XXX compared with NULL */
00022 /*@access rpmdb @*/             /* XXX compared with NULL */
00023 /*@access FD_t @*/              /* XXX compared with NULL */
00024 /*@access IDTX @*/
00025 /*@access IDT @*/
00026 
00027 /*@unchecked@*/
00028 int rpmcliPackagesTotal = 0;
00029 /*@unchecked@*/
00030 int rpmcliHashesCurrent = 0;
00031 /*@unchecked@*/
00032 int rpmcliHashesTotal = 0;
00033 /*@unchecked@*/
00034 int rpmcliProgressCurrent = 0;
00035 /*@unchecked@*/
00036 int rpmcliProgressTotal = 0;
00037 
00044 static void printHash(const unsigned long amount, const unsigned long total)
00045         /*@globals rpmcliHashesCurrent, rpmcliHashesTotal,
00046                 rpmcliProgressCurrent, fileSystem @*/
00047         /*@modifies rpmcliHashesCurrent, rpmcliHashesTotal,
00048                 rpmcliProgressCurrent, fileSystem @*/
00049 {
00050     int hashesNeeded;
00051 
00052     rpmcliHashesTotal = (isatty (STDOUT_FILENO) ? 44 : 50);
00053 
00054     if (rpmcliHashesCurrent != rpmcliHashesTotal) {
00055         float pct = (total ? (((float) amount) / total) : 1.0);
00056         hashesNeeded = (rpmcliHashesTotal * pct) + 0.5;
00057         while (hashesNeeded > rpmcliHashesCurrent) {
00058             if (isatty (STDOUT_FILENO)) {
00059                 int i;
00060                 for (i = 0; i < rpmcliHashesCurrent; i++)
00061                     (void) putchar ('#');
00062                 for (; i < rpmcliHashesTotal; i++)
00063                     (void) putchar (' ');
00064                 fprintf(stdout, "(%3d%%)", (int)((100 * pct) + 0.5));
00065                 for (i = 0; i < (rpmcliHashesTotal + 6); i++)
00066                     (void) putchar ('\b');
00067             } else
00068                 fprintf(stdout, "#");
00069 
00070             rpmcliHashesCurrent++;
00071         }
00072         (void) fflush(stdout);
00073 
00074         if (rpmcliHashesCurrent == rpmcliHashesTotal) {
00075             int i;
00076             rpmcliProgressCurrent++;
00077             if (isatty(STDOUT_FILENO)) {
00078                 for (i = 1; i < rpmcliHashesCurrent; i++)
00079                     (void) putchar ('#');
00080                 pct = (rpmcliProgressTotal
00081                     ? (((float) rpmcliProgressCurrent) / rpmcliProgressTotal)
00082                     : 1);
00083                 fprintf(stdout, " [%3d%%]", (int)((100 * pct) + 0.5));
00084             }
00085             fprintf(stdout, "\n");
00086         }
00087         (void) fflush(stdout);
00088     }
00089 }
00090 
00091 void * rpmShowProgress(/*@null@*/ const void * arg,
00092                         const rpmCallbackType what,
00093                         const unsigned long amount,
00094                         const unsigned long total,
00095                         /*@null@*/ fnpyKey key,
00096                         /*@null@*/ void * data)
00097         /*@globals rpmcliHashesCurrent, rpmcliProgressCurrent, rpmcliProgressTotal,
00098                 fileSystem @*/
00099         /*@modifies rpmcliHashesCurrent, rpmcliProgressCurrent, rpmcliProgressTotal,
00100                 fileSystem @*/
00101 {
00102     /*@-castexpose@*/
00103     Header h = (Header) arg;
00104     /*@=castexpose@*/
00105     char * s;
00106     int flags = (int) ((long)data);
00107     void * rc = NULL;
00108     /*@-assignexpose -abstract @*/
00109     const char * filename = (const char *)key;
00110     /*@=assignexpose =abstract @*/
00111     static FD_t fd = NULL;
00112     int xx;
00113 
00114     switch (what) {
00115     case RPMCALLBACK_INST_OPEN_FILE:
00116 /*@-boundsread@*/
00117         if (filename == NULL || filename[0] == '\0')
00118             return NULL;
00119 /*@=boundsread@*/
00120         fd = Fopen(filename, "r.ufdio");
00121         /*@-type@*/ /* FIX: still necessary? */
00122         if (fd == NULL || Ferror(fd)) {
00123             rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), filename,
00124                         Fstrerror(fd));
00125             if (fd) {
00126                 xx = Fclose(fd);
00127                 fd = NULL;
00128             }
00129         } else
00130             fd = fdLink(fd, "persist (showProgress)");
00131         /*@=type@*/
00132         return fd;
00133         /*@notreached@*/ break;
00134 
00135     case RPMCALLBACK_INST_CLOSE_FILE:
00136         /*@-type@*/ /* FIX: still necessary? */
00137         fd = fdFree(fd, "persist (showProgress)");
00138         /*@=type@*/
00139         if (fd) {
00140             xx = Fclose(fd);
00141             fd = NULL;
00142         }
00143         break;
00144 
00145     case RPMCALLBACK_INST_START:
00146         rpmcliHashesCurrent = 0;
00147         if (h == NULL || !(flags & INSTALL_LABEL))
00148             break;
00149         /* @todo Remove headerSprintf() on a progress callback. */
00150         if (flags & INSTALL_HASH) {
00151             s = headerSprintf(h, "%{NAME}",
00152                                 rpmTagTable, rpmHeaderFormats, NULL);
00153             if (isatty (STDOUT_FILENO))
00154                 fprintf(stdout, "%4d:%-23.23s", rpmcliProgressCurrent + 1, s);
00155             else
00156                 fprintf(stdout, "%-28.28s", s);
00157             (void) fflush(stdout);
00158             s = _free(s);
00159         } else {
00160             s = headerSprintf(h, "%{NAME}-%{VERSION}-%{RELEASE}",
00161                                   rpmTagTable, rpmHeaderFormats, NULL);
00162             fprintf(stdout, "%s\n", s);
00163             (void) fflush(stdout);
00164             s = _free(s);
00165         }
00166         break;
00167 
00168     case RPMCALLBACK_TRANS_PROGRESS:
00169     case RPMCALLBACK_INST_PROGRESS:
00170         if (flags & INSTALL_PERCENT)
00171             fprintf(stdout, "%%%% %f\n", (double) (total
00172                                 ? ((((float) amount) / total) * 100)
00173                                 : 100.0));
00174         else if (flags & INSTALL_HASH)
00175             printHash(amount, total);
00176         (void) fflush(stdout);
00177         break;
00178 
00179     case RPMCALLBACK_TRANS_START:
00180         rpmcliHashesCurrent = 0;
00181         rpmcliProgressTotal = 1;
00182         rpmcliProgressCurrent = 0;
00183         if (!(flags & INSTALL_LABEL))
00184             break;
00185         if (flags & INSTALL_HASH)
00186             fprintf(stdout, "%-28s", _("Preparing..."));
00187         else
00188             fprintf(stdout, "%s\n", _("Preparing packages for installation..."));
00189         (void) fflush(stdout);
00190         break;
00191 
00192     case RPMCALLBACK_TRANS_STOP:
00193         if (flags & INSTALL_HASH)
00194             printHash(1, 1);    /* Fixes "preparing..." progress bar */
00195         rpmcliProgressTotal = rpmcliPackagesTotal;
00196         rpmcliProgressCurrent = 0;
00197         break;
00198 
00199     case RPMCALLBACK_REPACKAGE_START:
00200         rpmcliHashesCurrent = 0;
00201         rpmcliProgressTotal = total;
00202         rpmcliProgressCurrent = 0;
00203         if (!(flags & INSTALL_LABEL))
00204             break;
00205         if (flags & INSTALL_HASH)
00206             fprintf(stdout, "%-28s\n", _("Repackaging..."));
00207         else
00208             fprintf(stdout, "%s\n", _("Repackaging erased files..."));
00209         (void) fflush(stdout);
00210         break;
00211 
00212     case RPMCALLBACK_REPACKAGE_PROGRESS:
00213         if (amount && (flags & INSTALL_HASH))
00214             printHash(1, 1);    /* Fixes "preparing..." progress bar */
00215         break;
00216 
00217     case RPMCALLBACK_REPACKAGE_STOP:
00218         rpmcliProgressTotal = total;
00219         rpmcliProgressCurrent = total;
00220         if (flags & INSTALL_HASH)
00221             printHash(1, 1);    /* Fixes "preparing..." progress bar */
00222         rpmcliProgressTotal = rpmcliPackagesTotal;
00223         rpmcliProgressCurrent = 0;
00224         if (!(flags & INSTALL_LABEL))
00225             break;
00226         if (flags & INSTALL_HASH)
00227             fprintf(stdout, "%-28s\n", _("Upgrading..."));
00228         else
00229             fprintf(stdout, "%s\n", _("Upgrading packages..."));
00230         (void) fflush(stdout);
00231         break;
00232 
00233     case RPMCALLBACK_UNINST_PROGRESS:
00234         break;
00235     case RPMCALLBACK_UNINST_START:
00236         break;
00237     case RPMCALLBACK_UNINST_STOP:
00238         break;
00239     case RPMCALLBACK_UNPACK_ERROR:
00240         break;
00241     case RPMCALLBACK_CPIO_ERROR:
00242         break;
00243     case RPMCALLBACK_UNKNOWN:
00244     default:
00245         break;
00246     }
00247 
00248     return rc;
00249 }       
00250 
00251 typedef /*@only@*/ /*@null@*/ const char * str_t;
00252 
00253 struct rpmEIU {
00254     Header h;
00255     FD_t fd;
00256     int numFailed;
00257     int numPkgs;
00258 /*@only@*/
00259     str_t * pkgURL;
00260 /*@dependent@*/ /*@null@*/
00261     str_t * fnp;
00262 /*@only@*/
00263     char * pkgState;
00264     int prevx;
00265     int pkgx;
00266     int numRPMS;
00267     int numSRPMS;
00268 /*@only@*/ /*@null@*/
00269     str_t * sourceURL;
00270     int isSource;
00271     int argc;
00272 /*@only@*/ /*@null@*/
00273     str_t * argv;
00274 /*@dependent@*/
00275     rpmRelocation * relocations;
00276     rpmRC rpmrc;
00277 };
00278 
00280 /*@-bounds@*/
00281 int rpmInstall(rpmts ts,
00282                 struct rpmInstallArguments_s * ia,
00283                 const char ** fileArgv)
00284 {
00285     struct rpmEIU * eiu = memset(alloca(sizeof(*eiu)), 0, sizeof(*eiu));
00286     rpmps ps;
00287     rpmprobFilterFlags probFilter;
00288     rpmRelocation * relocations;
00289 /*@only@*/ /*@null@*/ const char * fileURL = NULL;
00290     int stopInstall = 0;
00291     const char ** av = NULL;
00292     rpmVSFlags vsflags, ovsflags, tvsflags;
00293     int ac = 0;
00294     int rc;
00295     int xx;
00296     int i;
00297 
00298     if (fileArgv == NULL) goto exit;
00299 
00300     ts->goal = TSM_INSTALL;
00301     rpmcliPackagesTotal = 0;
00302 
00303     if (rpmExpandNumeric("%{?_repackage_all_erasures}"))
00304         ia->transFlags |= RPMTRANS_FLAG_REPACKAGE;
00305 
00306     (void) rpmtsSetFlags(ts, ia->transFlags);
00307     probFilter = ia->probFilter;
00308     relocations = ia->relocations;
00309 
00310     if (ia->installInterfaceFlags & INSTALL_UPGRADE)
00311         vsflags = rpmExpandNumeric("%{?_vsflags_erase}");
00312     else
00313         vsflags = rpmExpandNumeric("%{?_vsflags_install}");
00314     if (ia->qva_flags & VERIFY_DIGEST)
00315         vsflags |= _RPMVSF_NODIGESTS;
00316     if (ia->qva_flags & VERIFY_SIGNATURE)
00317         vsflags |= _RPMVSF_NOSIGNATURES;
00318     if (ia->qva_flags & VERIFY_HDRCHK)
00319         vsflags |= RPMVSF_NOHDRCHK;
00320     ovsflags = rpmtsSetVSFlags(ts, (vsflags | RPMVSF_NEEDPAYLOAD));
00321 
00322     {   int notifyFlags;
00323         notifyFlags = ia->installInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 );
00324         xx = rpmtsSetNotifyCallback(ts,
00325                         rpmShowProgress, (void *) ((long)notifyFlags));
00326     }
00327 
00328     if ((eiu->relocations = relocations) != NULL) {
00329         while (eiu->relocations->oldPath)
00330             eiu->relocations++;
00331         if (eiu->relocations->newPath == NULL)
00332             eiu->relocations = NULL;
00333     }
00334 
00335     /* Build fully globbed list of arguments in argv[argc]. */
00336     /*@-branchstate@*/
00337     /*@-temptrans@*/
00338     for (eiu->fnp = fileArgv; *eiu->fnp != NULL; eiu->fnp++) {
00339     /*@=temptrans@*/
00340         av = _free(av); ac = 0;
00341         rc = rpmGlob(*eiu->fnp, &ac, &av);
00342         if (rc || ac == 0) continue;
00343 
00344         eiu->argv = xrealloc(eiu->argv, (eiu->argc+ac+1) * sizeof(*eiu->argv));
00345         memcpy(eiu->argv+eiu->argc, av, ac * sizeof(*av));
00346         eiu->argc += ac;
00347         eiu->argv[eiu->argc] = NULL;
00348     }
00349     /*@=branchstate@*/
00350     av = _free(av);     ac = 0;
00351 
00352 restart:
00353     /* Allocate sufficient storage for next set of args. */
00354     if (eiu->pkgx >= eiu->numPkgs) {
00355         eiu->numPkgs = eiu->pkgx + eiu->argc;
00356         eiu->pkgURL = xrealloc(eiu->pkgURL,
00357                         (eiu->numPkgs + 1) * sizeof(*eiu->pkgURL));
00358         memset(eiu->pkgURL + eiu->pkgx, 0,
00359                         ((eiu->argc + 1) * sizeof(*eiu->pkgURL)));
00360         eiu->pkgState = xrealloc(eiu->pkgState,
00361                         (eiu->numPkgs + 1) * sizeof(*eiu->pkgState));
00362         memset(eiu->pkgState + eiu->pkgx, 0,
00363                         ((eiu->argc + 1) * sizeof(*eiu->pkgState)));
00364     }
00365 
00366     /* Retrieve next set of args, cache on local storage. */
00367     for (i = 0; i < eiu->argc; i++) {
00368         fileURL = _free(fileURL);
00369         fileURL = eiu->argv[i];
00370         eiu->argv[i] = NULL;
00371 
00372 #ifdef  NOTYET
00373 if (fileURL[0] == '=') {
00374     rpmds this = rpmdsSingle(RPMTAG_REQUIRENAME, fileURL+1, NULL, 0);
00375 
00376     xx = rpmtsSolve(ts, this, NULL);
00377     if (ts->suggests && ts->nsuggests > 0) {
00378         fileURL = _free(fileURL);
00379         fileURL = ts->suggests[0];
00380         ts->suggests[0] = NULL;
00381         while (ts->nsuggests-- > 0) {
00382             if (ts->suggests[ts->nsuggests] == NULL)
00383                 continue;
00384             ts->suggests[ts->nsuggests] = _free(ts->suggests[ts->nsuggests]);
00385         }
00386         ts->suggests = _free(ts->suggests);
00387         rpmMessage(RPMMESS_DEBUG, _("Adding goal: %s\n"), fileURL);
00388         eiu->pkgURL[eiu->pkgx] = fileURL;
00389         fileURL = NULL;
00390         eiu->pkgx++;
00391     }
00392     this = rpmdsFree(this);
00393 } else
00394 #endif
00395 
00396         switch (urlIsURL(fileURL)) {
00397         case URL_IS_FTP:
00398         case URL_IS_HTTP:
00399         {   const char *tfn;
00400 
00401             if (rpmIsVerbose())
00402                 fprintf(stdout, _("Retrieving %s\n"), fileURL);
00403 
00404             {   char tfnbuf[64];
00405                 const char * rootDir = rpmtsRootDir(ts);
00406                 if (!(rootDir && * rootDir))
00407                     rootDir = "";
00408                 strcpy(tfnbuf, "rpm-xfer.XXXXXX");
00409                 (void) mktemp(tfnbuf);
00410                 tfn = rpmGenPath(rootDir, "%{_tmppath}/", tfnbuf);
00411             }
00412 
00413             /* XXX undefined %{name}/%{version}/%{release} here */
00414             /* XXX %{_tmpdir} does not exist */
00415             rpmMessage(RPMMESS_DEBUG, _(" ... as %s\n"), tfn);
00416             rc = urlGetFile(fileURL, tfn);
00417             if (rc < 0) {
00418                 rpmMessage(RPMMESS_ERROR,
00419                         _("skipping %s - transfer failed - %s\n"),
00420                         fileURL, ftpStrerror(rc));
00421                 eiu->numFailed++;
00422                 eiu->pkgURL[eiu->pkgx] = NULL;
00423                 tfn = _free(tfn);
00424                 /*@switchbreak@*/ break;
00425             }
00426             eiu->pkgState[eiu->pkgx] = 1;
00427             eiu->pkgURL[eiu->pkgx] = tfn;
00428             eiu->pkgx++;
00429         }   /*@switchbreak@*/ break;
00430         case URL_IS_PATH:
00431         default:
00432             eiu->pkgURL[eiu->pkgx] = fileURL;
00433             fileURL = NULL;
00434             eiu->pkgx++;
00435             /*@switchbreak@*/ break;
00436         }
00437     }
00438     fileURL = _free(fileURL);
00439 
00440     if (eiu->numFailed) goto exit;
00441 
00442     /* Continue processing file arguments, building transaction set. */
00443     for (eiu->fnp = eiu->pkgURL+eiu->prevx;
00444          *eiu->fnp != NULL;
00445          eiu->fnp++, eiu->prevx++)
00446     {
00447         const char * fileName;
00448 
00449         rpmMessage(RPMMESS_DEBUG, "============== %s\n", *eiu->fnp);
00450         (void) urlPath(*eiu->fnp, &fileName);
00451 
00452         /* Try to read the header from a package file. */
00453         eiu->fd = Fopen(*eiu->fnp, "r.ufdio");
00454         if (eiu->fd == NULL || Ferror(eiu->fd)) {
00455             rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), *eiu->fnp,
00456                         Fstrerror(eiu->fd));
00457             if (eiu->fd) {
00458                 xx = Fclose(eiu->fd);
00459                 eiu->fd = NULL;
00460             }
00461             eiu->numFailed++; *eiu->fnp = NULL;
00462             continue;
00463         }
00464 
00465         /* Read the header, verifying signatures (if present). */
00466         tvsflags = rpmtsSetVSFlags(ts, vsflags);
00467         eiu->rpmrc = rpmReadPackageFile(ts, eiu->fd, *eiu->fnp, &eiu->h);
00468         tvsflags = rpmtsSetVSFlags(ts, tvsflags);
00469         xx = Fclose(eiu->fd);
00470         eiu->fd = NULL;
00471 
00472         switch (eiu->rpmrc) {
00473         case RPMRC_FAIL:
00474             rpmMessage(RPMMESS_ERROR, _("%s cannot be installed\n"), *eiu->fnp);
00475             eiu->numFailed++; *eiu->fnp = NULL;
00476             continue;
00477             /*@notreached@*/ /*@switchbreak@*/ break;
00478         case RPMRC_NOTFOUND:
00479             goto maybe_manifest;
00480             /*@notreached@*/ /*@switchbreak@*/ break;
00481         case RPMRC_NOTTRUSTED:
00482         case RPMRC_NOKEY:
00483         case RPMRC_OK:
00484         default:
00485             /*@switchbreak@*/ break;
00486         }
00487 
00488         eiu->isSource = headerIsEntry(eiu->h, RPMTAG_SOURCEPACKAGE);
00489 
00490         if (eiu->isSource) {
00491             rpmMessage(RPMMESS_DEBUG, "\tadded source package [%d]\n",
00492                 eiu->numSRPMS);
00493             eiu->sourceURL = xrealloc(eiu->sourceURL,
00494                                 (eiu->numSRPMS + 2) * sizeof(*eiu->sourceURL));
00495             eiu->sourceURL[eiu->numSRPMS] = *eiu->fnp;
00496             *eiu->fnp = NULL;
00497             eiu->numSRPMS++;
00498             eiu->sourceURL[eiu->numSRPMS] = NULL;
00499             continue;
00500         }
00501 
00502         if (eiu->relocations) {
00503             const char ** paths;
00504             int pft;
00505             int c;
00506 
00507             if (headerGetEntry(eiu->h, RPMTAG_PREFIXES, &pft,
00508                                        (void **) &paths, &c) && (c == 1))
00509             {
00510                 eiu->relocations->oldPath = xstrdup(paths[0]);
00511                 paths = headerFreeData(paths, pft);
00512             } else {
00513                 const char * name;
00514                 xx = headerNVR(eiu->h, &name, NULL, NULL);
00515                 rpmMessage(RPMMESS_ERROR,
00516                                _("package %s is not relocateable\n"), name);
00517                 eiu->numFailed++;
00518                 goto exit;
00519                 /*@notreached@*/
00520             }
00521         }
00522 
00523         /* On --freshen, verify package is installed and newer */
00524         if (ia->installInterfaceFlags & INSTALL_FRESHEN) {
00525             rpmdbMatchIterator mi;
00526             const char * name;
00527             Header oldH;
00528             int count;
00529 
00530             xx = headerNVR(eiu->h, &name, NULL, NULL);
00531             mi = rpmtsInitIterator(ts, RPMTAG_NAME, name, 0);
00532             count = rpmdbGetIteratorCount(mi);
00533             while ((oldH = rpmdbNextIterator(mi)) != NULL) {
00534                 if (rpmVersionCompare(oldH, eiu->h) < 0)
00535                     /*@innercontinue@*/ continue;
00536                 /* same or newer package already installed */
00537                 count = 0;
00538                 /*@innerbreak@*/ break;
00539             }
00540             mi = rpmdbFreeIterator(mi);
00541             if (count == 0) {
00542                 eiu->h = headerFree(eiu->h);
00543                 continue;
00544             }
00545             /* Package is newer than those currently installed. */
00546         }
00547 
00548         /*@-abstract@*/
00549         rc = rpmtsAddInstallElement(ts, eiu->h, (fnpyKey)fileName,
00550                         (ia->installInterfaceFlags & INSTALL_UPGRADE) != 0,
00551                         relocations);
00552         /*@=abstract@*/
00553 
00554         /* XXX reference held by transaction set */
00555         eiu->h = headerFree(eiu->h);
00556         if (eiu->relocations)
00557             eiu->relocations->oldPath = _free(eiu->relocations->oldPath);
00558 
00559         switch(rc) {
00560         case 0:
00561             rpmMessage(RPMMESS_DEBUG, "\tadded binary package [%d]\n",
00562                         eiu->numRPMS);
00563             /*@switchbreak@*/ break;
00564         case 1:
00565             rpmMessage(RPMMESS_ERROR,
00566                             _("error reading from file %s\n"), *eiu->fnp);
00567             eiu->numFailed++;
00568             goto exit;
00569             /*@notreached@*/ /*@switchbreak@*/ break;
00570         case 2:
00571             rpmMessage(RPMMESS_ERROR,
00572                             _("file %s requires a newer version of RPM\n"),
00573                             *eiu->fnp);
00574             eiu->numFailed++;
00575             goto exit;
00576             /*@notreached@*/ /*@switchbreak@*/ break;
00577         }
00578 
00579         eiu->numRPMS++;
00580         continue;
00581 
00582 maybe_manifest:
00583         /* Try to read a package manifest. */
00584         eiu->fd = Fopen(*eiu->fnp, "r.fpio");
00585         if (eiu->fd == NULL || Ferror(eiu->fd)) {
00586             rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), *eiu->fnp,
00587                         Fstrerror(eiu->fd));
00588             if (eiu->fd) {
00589                 xx = Fclose(eiu->fd);
00590                 eiu->fd = NULL;
00591             }
00592             eiu->numFailed++; *eiu->fnp = NULL;
00593             break;
00594         }
00595 
00596         /* Read list of packages from manifest. */
00597         rc = rpmReadPackageManifest(eiu->fd, &eiu->argc, &eiu->argv);
00598         if (rc != RPMRC_OK)
00599             rpmError(RPMERR_MANIFEST, _("%s: not an rpm package (or package manifest): %s\n"),
00600                         *eiu->fnp, Fstrerror(eiu->fd));
00601         xx = Fclose(eiu->fd);
00602         eiu->fd = NULL;
00603 
00604         /* If successful, restart the query loop. */
00605         if (rc == RPMRC_OK) {
00606             eiu->prevx++;
00607             goto restart;
00608         }
00609 
00610         eiu->numFailed++; *eiu->fnp = NULL;
00611         break;
00612     }
00613 
00614     rpmMessage(RPMMESS_DEBUG, _("found %d source and %d binary packages\n"),
00615                 eiu->numSRPMS, eiu->numRPMS);
00616 
00617     if (eiu->numFailed) goto exit;
00618 
00619     if (eiu->numRPMS && !(ia->installInterfaceFlags & INSTALL_NODEPS)) {
00620 
00621         if (rpmtsCheck(ts)) {
00622             eiu->numFailed = eiu->numPkgs;
00623             stopInstall = 1;
00624         }
00625 
00626         ps = rpmtsProblems(ts);
00627         if (!stopInstall && rpmpsNumProblems(ps) > 0) {
00628             rpmMessage(RPMMESS_ERROR, _("Failed dependencies:\n"));
00629             rpmpsPrint(NULL, ps);
00630             eiu->numFailed = eiu->numPkgs;
00631             stopInstall = 1;
00632 
00633             /*@-branchstate@*/
00634             if (ts->suggests != NULL && ts->nsuggests > 0) {
00635                 rpmMessage(RPMMESS_NORMAL, _("    Suggested resolutions:\n"));
00636                 for (i = 0; i < ts->nsuggests; i++) {
00637                     const char * str = ts->suggests[i];
00638 
00639                     if (str == NULL)
00640                         break;
00641 
00642                     rpmMessage(RPMMESS_NORMAL, "\t%s\n", str);
00643                 
00644                     ts->suggests[i] = NULL;
00645                     str = _free(str);
00646                 }
00647                 ts->suggests = _free(ts->suggests);
00648             }
00649             /*@=branchstate@*/
00650         }
00651         ps = rpmpsFree(ps);
00652     }
00653 
00654     if (eiu->numRPMS && !(ia->installInterfaceFlags & INSTALL_NOORDER)) {
00655         if (rpmtsOrder(ts)) {
00656             eiu->numFailed = eiu->numPkgs;
00657             stopInstall = 1;
00658         }
00659     }
00660 
00661     if (eiu->numRPMS && !stopInstall) {
00662 
00663         rpmcliPackagesTotal += eiu->numSRPMS;
00664 
00665         rpmMessage(RPMMESS_DEBUG, _("installing binary packages\n"));
00666 
00667         /* Drop added/available package indices and dependency sets. */
00668         rpmtsClean(ts);
00669 
00670         rc = rpmtsRun(ts, NULL, probFilter);
00671         ps = rpmtsProblems(ts);
00672 
00673         if (rc < 0) {
00674             eiu->numFailed += eiu->numRPMS;
00675         } else if (rc > 0) {
00676             eiu->numFailed += rc;
00677             if (rpmpsNumProblems(ps) > 0)
00678                 rpmpsPrint(stderr, ps);
00679         }
00680         ps = rpmpsFree(ps);
00681     }
00682 
00683     if (eiu->numSRPMS && !stopInstall) {
00684         if (eiu->sourceURL != NULL)
00685         for (i = 0; i < eiu->numSRPMS; i++) {
00686             if (eiu->sourceURL[i] == NULL) continue;
00687             eiu->fd = Fopen(eiu->sourceURL[i], "r.ufdio");
00688             if (eiu->fd == NULL || Ferror(eiu->fd)) {
00689                 rpmMessage(RPMMESS_ERROR, _("cannot open file %s: %s\n"),
00690                            eiu->sourceURL[i], Fstrerror(eiu->fd));
00691                 if (eiu->fd) {
00692                     xx = Fclose(eiu->fd);
00693                     eiu->fd = NULL;
00694                 }
00695                 continue;
00696             }
00697 
00698             if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) {
00699                 eiu->rpmrc = rpmInstallSourcePackage(ts, eiu->fd, NULL, NULL);
00700                 if (eiu->rpmrc != RPMRC_OK) eiu->numFailed++;
00701             }
00702 
00703             xx = Fclose(eiu->fd);
00704             eiu->fd = NULL;
00705         }
00706     }
00707 
00708 exit:
00709     if (eiu->pkgURL != NULL)
00710     for (i = 0; i < eiu->numPkgs; i++) {
00711         if (eiu->pkgURL[i] == NULL) continue;
00712         if (eiu->pkgState[i] == 1)
00713             (void) Unlink(eiu->pkgURL[i]);
00714         eiu->pkgURL[i] = _free(eiu->pkgURL[i]);
00715     }
00716     eiu->pkgState = _free(eiu->pkgState);
00717     eiu->pkgURL = _free(eiu->pkgURL);
00718     eiu->argv = _free(eiu->argv);
00719 
00720     rpmtsEmpty(ts);
00721 
00722     return eiu->numFailed;
00723 }
00724 /*@=bounds@*/
00725 
00726 int rpmErase(rpmts ts,
00727                 const struct rpmInstallArguments_s * ia,
00728                 const char ** argv)
00729 {
00730     int count;
00731     const char ** arg;
00732     int numFailed = 0;
00733     int stopUninstall = 0;
00734     int numPackages = 0;
00735     rpmVSFlags vsflags, ovsflags;
00736     rpmps ps;
00737 
00738     if (argv == NULL) return 0;
00739 
00740     vsflags = rpmExpandNumeric("%{?_vsflags_erase}");
00741     if (ia->qva_flags & VERIFY_DIGEST)
00742         vsflags |= _RPMVSF_NODIGESTS;
00743     if (ia->qva_flags & VERIFY_SIGNATURE)
00744         vsflags |= _RPMVSF_NOSIGNATURES;
00745     if (ia->qva_flags & VERIFY_HDRCHK)
00746         vsflags |= RPMVSF_NOHDRCHK;
00747     ovsflags = rpmtsSetVSFlags(ts, vsflags);
00748 
00749     if (rpmExpandNumeric("%{?_repackage_all_erasures}"))
00750         ia->transFlags |= RPMTRANS_FLAG_REPACKAGE;
00751 
00752     (void) rpmtsSetFlags(ts, ia->transFlags);
00753 
00754 #ifdef  NOTYET  /* XXX no callbacks on erase yet */
00755     {   int notifyFlags;
00756         notifyFlags = ia->eraseInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 );
00757         xx = rpmtsSetNotifyCallback(ts,
00758                         rpmShowProgress, (void *) ((long)notifyFlags)
00759     }
00760 #endif
00761 
00762     ts->goal = TSM_ERASE;
00763 
00764     for (arg = argv; *arg; arg++) {
00765         rpmdbMatchIterator mi;
00766 
00767         /* XXX HACK to get rpmdbFindByLabel out of the API */
00768         mi = rpmtsInitIterator(ts, RPMDBI_LABEL, *arg, 0);
00769         count = rpmdbGetIteratorCount(mi);
00770         if (count <= 0) {
00771             rpmMessage(RPMMESS_ERROR, _("package %s is not installed\n"), *arg);
00772             numFailed++;
00773         } else if (!(count == 1 || (ia->eraseInterfaceFlags & UNINSTALL_ALLMATCHES))) {
00774             rpmMessage(RPMMESS_ERROR, _("\"%s\" specifies multiple packages\n"),
00775                         *arg);
00776             numFailed++;
00777         } else {
00778             Header h;   /* XXX iterator owns the reference */
00779             while ((h = rpmdbNextIterator(mi)) != NULL) {
00780                 unsigned int recOffset = rpmdbGetIteratorOffset(mi);
00781                 if (recOffset) {
00782                     (void) rpmtsAddEraseElement(ts, h, recOffset);
00783                     numPackages++;
00784                 }
00785             }
00786         }
00787         mi = rpmdbFreeIterator(mi);
00788     }
00789 
00790     if (!(ia->eraseInterfaceFlags & UNINSTALL_NODEPS)) {
00791 
00792         if (rpmtsCheck(ts)) {
00793             numFailed = numPackages;
00794             stopUninstall = 1;
00795         }
00796 
00797         ps = rpmtsProblems(ts);
00798         if (!stopUninstall && rpmpsNumProblems(ps) > 0) {
00799             rpmMessage(RPMMESS_ERROR, _("Failed dependencies:\n"));
00800             rpmpsPrint(NULL, ps);
00801             numFailed += numPackages;
00802             stopUninstall = 1;
00803         }
00804         ps = rpmpsFree(ps);
00805     }
00806 
00807     if (!stopUninstall) {
00808         (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_REVERSE));
00809 
00810         /* Drop added/available package indices and dependency sets. */
00811         rpmtsClean(ts);
00812 
00813         numPackages = rpmtsRun(ts, NULL, 0);
00814         ps = rpmtsProblems(ts);
00815         if (rpmpsNumProblems(ps) > 0)
00816             rpmpsPrint(NULL, ps);
00817         numFailed += numPackages;
00818         stopUninstall = 1;
00819         ps = rpmpsFree(ps);
00820     }
00821 
00822     rpmtsEmpty(ts);
00823 
00824     return numFailed;
00825 }
00826 
00827 int rpmInstallSource(rpmts ts, const char * arg,
00828                 const char ** specFilePtr, const char ** cookie)
00829 {
00830     FD_t fd;
00831     int rc;
00832 
00833 
00834     fd = Fopen(arg, "r.ufdio");
00835     if (fd == NULL || Ferror(fd)) {
00836         rpmMessage(RPMMESS_ERROR, _("cannot open %s: %s\n"), arg, Fstrerror(fd));
00837         if (fd) (void) Fclose(fd);
00838         return 1;
00839     }
00840 
00841     if (rpmIsVerbose())
00842         fprintf(stdout, _("Installing %s\n"), arg);
00843 
00844     {
00845         rpmVSFlags ovsflags =
00846                 rpmtsSetVSFlags(ts, (rpmtsVSFlags(ts) | RPMVSF_NEEDPAYLOAD));
00847         rpmRC rpmrc = rpmInstallSourcePackage(ts, fd, specFilePtr, cookie);
00848         rc = (rpmrc == RPMRC_OK ? 0 : 1);
00849         ovsflags = rpmtsSetVSFlags(ts, ovsflags);
00850     }
00851     if (rc != 0) {
00852         rpmMessage(RPMMESS_ERROR, _("%s cannot be installed\n"), arg);
00853         /*@-unqualifiedtrans@*/
00854         if (specFilePtr && *specFilePtr)
00855             *specFilePtr = _free(*specFilePtr);
00856         if (cookie && *cookie)
00857             *cookie = _free(*cookie);
00858         /*@=unqualifiedtrans@*/
00859     }
00860 
00861     (void) Fclose(fd);
00862 
00863     return rc;
00864 }
00865 
00866 /*@unchecked@*/
00867 static int reverse = -1;
00868 
00871 static int IDTintcmp(const void * a, const void * b)
00872         /*@*/
00873 {
00874     /*@-castexpose@*/
00875     return ( reverse * (((IDT)a)->val.u32 - ((IDT)b)->val.u32) );
00876     /*@=castexpose@*/
00877 }
00878 
00879 IDTX IDTXfree(IDTX idtx)
00880 {
00881     if (idtx) {
00882         int i;
00883         if (idtx->idt)
00884         for (i = 0; i < idtx->nidt; i++) {
00885             IDT idt = idtx->idt + i;
00886             idt->h = headerFree(idt->h);
00887             idt->key = _free(idt->key);
00888         }
00889         idtx->idt = _free(idtx->idt);
00890         idtx = _free(idtx);
00891     }
00892     return NULL;
00893 }
00894 
00895 IDTX IDTXnew(void)
00896 {
00897     IDTX idtx = xcalloc(1, sizeof(*idtx));
00898     idtx->delta = 10;
00899     idtx->size = sizeof(*((IDT)0));
00900     return idtx;
00901 }
00902 
00903 IDTX IDTXgrow(IDTX idtx, int need)
00904 {
00905     if (need < 0) return NULL;
00906     if (idtx == NULL)
00907         idtx = IDTXnew();
00908     if (need == 0) return idtx;
00909 
00910     if ((idtx->nidt + need) > idtx->alloced) {
00911         while (need > 0) {
00912             idtx->alloced += idtx->delta;
00913             need -= idtx->delta;
00914         }
00915         idtx->idt = xrealloc(idtx->idt, (idtx->alloced * idtx->size) );
00916     }
00917     return idtx;
00918 }
00919 
00920 IDTX IDTXsort(IDTX idtx)
00921 {
00922     if (idtx != NULL && idtx->idt != NULL && idtx->nidt > 0)
00923         qsort(idtx->idt, idtx->nidt, idtx->size, IDTintcmp);
00924     return idtx;
00925 }
00926 
00927 IDTX IDTXload(rpmts ts, rpmTag tag)
00928 {
00929     IDTX idtx = NULL;
00930     rpmdbMatchIterator mi;
00931     HGE_t hge = (HGE_t) headerGetEntry;
00932     Header h;
00933 
00934     /*@-branchstate@*/
00935     mi = rpmtsInitIterator(ts, tag, NULL, 0);
00936     while ((h = rpmdbNextIterator(mi)) != NULL) {
00937         rpmTagType type = RPM_NULL_TYPE;
00938         int_32 count = 0;
00939         int_32 * tidp;
00940 
00941         tidp = NULL;
00942         if (!hge(h, tag, &type, (void **)&tidp, &count) || tidp == NULL)
00943             continue;
00944 
00945         if (type == RPM_INT32_TYPE && (*tidp == 0 || *tidp == -1))
00946             continue;
00947 
00948         idtx = IDTXgrow(idtx, 1);
00949         if (idtx == NULL)
00950             continue;
00951         if (idtx->idt == NULL)
00952             continue;
00953 
00954         {   IDT idt;
00955             /*@-nullderef@*/
00956             idt = idtx->idt + idtx->nidt;
00957             /*@=nullderef@*/
00958             idt->h = headerLink(h);
00959             idt->key = NULL;
00960             idt->instance = rpmdbGetIteratorOffset(mi);
00961             idt->val.u32 = *tidp;
00962         }
00963         idtx->nidt++;
00964     }
00965     mi = rpmdbFreeIterator(mi);
00966     /*@=branchstate@*/
00967 
00968     return IDTXsort(idtx);
00969 }
00970 
00971 IDTX IDTXglob(rpmts ts, const char * globstr, rpmTag tag)
00972 {
00973     IDTX idtx = NULL;
00974     HGE_t hge = (HGE_t) headerGetEntry;
00975     Header h;
00976     int_32 * tidp;
00977     FD_t fd;
00978     const char ** av = NULL;
00979     int ac = 0;
00980     rpmRC rpmrc;
00981     int xx;
00982     int i;
00983 
00984     av = NULL;  ac = 0;
00985     xx = rpmGlob(globstr, &ac, &av);
00986 
00987     if (xx == 0)
00988     for (i = 0; i < ac; i++) {
00989         rpmTagType type;
00990         int_32 count;
00991         int isSource;
00992 
00993         fd = Fopen(av[i], "r.ufdio");
00994         if (fd == NULL || Ferror(fd)) {
00995             rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), av[i],
00996                         Fstrerror(fd));
00997             if (fd) (void) Fclose(fd);
00998             continue;
00999         }
01000 
01001         rpmrc = rpmReadPackageFile(ts, fd, av[i], &h);
01002         (void) Fclose(fd);
01003         switch (rpmrc) {
01004         default:
01005             goto bottom;
01006             /*@notreached@*/ /*@switchbreak@*/ break;
01007         case RPMRC_NOTTRUSTED:
01008         case RPMRC_NOKEY:
01009         case RPMRC_OK:
01010             isSource = headerIsEntry(h, RPMTAG_SOURCEPACKAGE);
01011             if (isSource)
01012                 goto bottom;
01013             /*@switchbreak@*/ break;
01014         }
01015 
01016         tidp = NULL;
01017         /*@-branchstate@*/
01018         if (hge(h, tag, &type, (void **) &tidp, &count) && tidp) {
01019 
01020             idtx = IDTXgrow(idtx, 1);
01021             if (idtx == NULL || idtx->idt == NULL)
01022                 goto bottom;
01023 
01024             {   IDT idt;
01025                 idt = idtx->idt + idtx->nidt;
01026                 idt->h = headerLink(h);
01027                 idt->key = av[i];
01028                 av[i] = NULL;
01029                 idt->instance = 0;
01030                 idt->val.u32 = *tidp;
01031             }
01032             idtx->nidt++;
01033         }
01034         /*@=branchstate@*/
01035 bottom:
01036         h = headerFree(h);
01037     }
01038 
01039     for (i = 0; i < ac; i++)
01040         av[i] = _free(av[i]);
01041     av = _free(av);     ac = 0;
01042 
01043     return idtx;
01044 }
01045 
01047 int rpmRollback(rpmts ts, struct rpmInstallArguments_s * ia, const char ** argv)
01048 {
01049     int ifmask= (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL|INSTALL_ERASE);
01050     unsigned thistid = 0xffffffff;
01051     unsigned prevtid;
01052     time_t tid;
01053     IDTX itids = NULL;
01054     IDTX rtids = NULL;
01055     IDT rp;
01056     int nrids = 0;
01057     IDT ip;
01058     int niids = 0;
01059     int rc = 0;
01060     int vsflags, ovsflags;
01061     int numAdded;
01062     int numRemoved;
01063     rpmps ps;
01064     int _unsafe_rollbacks = 0;
01065     rpmtransFlags transFlags = ia->transFlags;
01066 
01067     if (argv != NULL && *argv != NULL) {
01068         rc = -1;
01069         goto exit;
01070     }
01071 
01072     _unsafe_rollbacks = rpmExpandNumeric("%{?_unsafe_rollbacks}");
01073 
01074     vsflags = rpmExpandNumeric("%{?_vsflags_erase}");
01075     if (ia->qva_flags & VERIFY_DIGEST)
01076         vsflags |= _RPMVSF_NODIGESTS;
01077     if (ia->qva_flags & VERIFY_SIGNATURE)
01078         vsflags |= _RPMVSF_NOSIGNATURES;
01079     if (ia->qva_flags & VERIFY_HDRCHK)
01080         vsflags |= RPMVSF_NOHDRCHK;
01081     vsflags |= RPMVSF_NEEDPAYLOAD;      /* XXX no legacy signatures */
01082     ovsflags = rpmtsSetVSFlags(ts, vsflags);
01083 
01084     (void) rpmtsSetFlags(ts, transFlags);
01085 
01086     itids = IDTXload(ts, RPMTAG_INSTALLTID);
01087     if (itids != NULL) {
01088         ip = itids->idt;
01089         niids = itids->nidt;
01090     } else {
01091         ip = NULL;
01092         niids = 0;
01093     }
01094 
01095     {   const char * globstr = rpmExpand("%{_repackage_dir}/*.rpm", NULL);
01096         if (globstr == NULL || *globstr == '%') {
01097             globstr = _free(globstr);
01098             rc = -1;
01099             goto exit;
01100         }
01101         rtids = IDTXglob(ts, globstr, RPMTAG_REMOVETID);
01102         if (rtids != NULL) {
01103             rp = rtids->idt;
01104             nrids = rtids->nidt;
01105         } else {
01106             rp = NULL;
01107             nrids = 0;
01108         }
01109         globstr = _free(globstr);
01110     }
01111 
01112     {   int notifyFlags, xx;
01113         notifyFlags = ia->installInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 );
01114         xx = rpmtsSetNotifyCallback(ts,
01115                         rpmShowProgress, (void *) ((long)notifyFlags));
01116     }
01117 
01118     /* Run transactions until rollback goal is achieved. */
01119     do {
01120         prevtid = thistid;
01121         rc = 0;
01122         rpmcliPackagesTotal = 0;
01123         numAdded = 0;
01124         numRemoved = 0;
01125         ia->installInterfaceFlags &= ~ifmask;
01126 
01127         /* Find larger of the remaining install/erase transaction id's. */
01128         thistid = 0;
01129         if (ip != NULL && ip->val.u32 > thistid)
01130             thistid = ip->val.u32;
01131         if (rp != NULL && rp->val.u32 > thistid)
01132             thistid = rp->val.u32;
01133 
01134         /* If we've achieved the rollback goal, then we're done. */
01135         if (thistid == 0 || thistid < ia->rbtid)
01136             break;
01137 
01138         /* If we've reached the (configured) rollback goal, then we're done. */
01139         if (_unsafe_rollbacks && thistid <= _unsafe_rollbacks)
01140             break;
01141 
01142         rpmtsEmpty(ts);
01143         (void) rpmtsSetFlags(ts, transFlags);
01144 
01145         /* Install the previously erased packages for this transaction. */
01146         while (rp != NULL && rp->val.u32 == thistid) {
01147 
01148             rpmMessage(RPMMESS_DEBUG, "\t+++ install %s\n",
01149                         (rp->key ? rp->key : "???"));
01150 
01151 /*@-abstract@*/
01152             rc = rpmtsAddInstallElement(ts, rp->h, (fnpyKey)rp->key,
01153                                0, ia->relocations);
01154 /*@=abstract@*/
01155             if (rc != 0)
01156                 goto exit;
01157 
01158             numAdded++;
01159             rpmcliPackagesTotal++;
01160             if (!(ia->installInterfaceFlags & ifmask))
01161                 ia->installInterfaceFlags |= INSTALL_UPGRADE;
01162 
01163 #ifdef  NOTYET
01164             rp->h = headerFree(rp->h);
01165 #endif
01166             nrids--;
01167             if (nrids > 0)
01168                 rp++;
01169             else
01170                 rp = NULL;
01171         }
01172 
01173         /* Erase the previously installed packages for this transaction. */
01174         while (ip != NULL && ip->val.u32 == thistid) {
01175 
01176             rpmMessage(RPMMESS_DEBUG,
01177                         "\t--- erase h#%u\n", ip->instance);
01178 
01179             rc = rpmtsAddEraseElement(ts, ip->h, ip->instance);
01180             if (rc != 0)
01181                 goto exit;
01182 
01183             numRemoved++;
01184 
01185             if (_unsafe_rollbacks)
01186                 rpmcliPackagesTotal++;
01187 
01188             if (!(ia->installInterfaceFlags & ifmask)) {
01189                 ia->installInterfaceFlags |= INSTALL_ERASE;
01190                 (void) rpmtsSetFlags(ts, (transFlags | RPMTRANS_FLAG_REVERSE));
01191             }
01192 
01193 #ifdef  NOTYET
01194             ip->instance = 0;
01195 #endif
01196             niids--;
01197             if (niids > 0)
01198                 ip++;
01199             else
01200                 ip = NULL;
01201         }
01202 
01203         /* Anything to do? */
01204         if (rpmcliPackagesTotal <= 0)
01205             break;
01206 
01207         tid = (time_t)thistid;
01208         rpmMessage(RPMMESS_NORMAL,
01209                 _("Rollback packages (+%d/-%d) to %-24.24s (0x%08x):\n"),
01210                         numAdded, numRemoved, ctime(&tid), tid);
01211 
01212         rc = rpmtsCheck(ts);
01213         ps = rpmtsProblems(ts);
01214         if (rc != 0 && rpmpsNumProblems(ps) > 0) {
01215             rpmMessage(RPMMESS_ERROR, _("Failed dependencies:\n"));
01216             rpmpsPrint(NULL, ps);
01217             ps = rpmpsFree(ps);
01218             goto exit;
01219         }
01220         ps = rpmpsFree(ps);
01221 
01222         rc = rpmtsOrder(ts);
01223         if (rc != 0)
01224             goto exit;
01225 
01226         /* Drop added/available package indices and dependency sets. */
01227         rpmtsClean(ts);
01228 
01229         rc = rpmtsRun(ts, NULL, (ia->probFilter|RPMPROB_FILTER_OLDPACKAGE));
01230         ps = rpmtsProblems(ts);
01231         if (rc > 0 && rpmpsNumProblems(ps) > 0)
01232             rpmpsPrint(stderr, ps);
01233         ps = rpmpsFree(ps);
01234         if (rc)
01235             goto exit;
01236 
01237         /* Clean up after successful rollback. */
01238         if (rtids && !rpmIsDebug()) {
01239             int i;
01240             if (rtids->idt)
01241             for (i = 0; i < rtids->nidt; i++) {
01242                 IDT rrp = rtids->idt + i;
01243                 if (rrp->val.u32 != thistid)
01244                     /*@innercontinue@*/ continue;
01245                 if (rrp->key)   /* XXX can't happen */
01246                     (void) unlink(rrp->key);
01247             }
01248         }
01249 
01250 
01251     } while (1);
01252 
01253 exit:
01254     rtids = IDTXfree(rtids);
01255     itids = IDTXfree(itids);
01256 
01257     rpmtsEmpty(ts);
01258     (void) rpmtsSetFlags(ts, transFlags);
01259 
01260     return rc;
01261 }

Generated on Wed Sep 4 12:49:52 2002 for rpm by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002