00001
00005 #include "system.h"
00006
00007 #include <rpmcli.h>
00008
00009 #include "rpmdb.h"
00010 #ifdef NOTYET
00011 #include "rpmds.h"
00012 #endif
00013
00014 #include "rpmte.h"
00015 #define _RPMTS_INTERNAL
00016 #include "rpmts.h"
00017
00018 #include "manifest.h"
00019 #include "misc.h"
00020 #include "rpmgi.h"
00021 #include "debug.h"
00022
00023
00024
00025
00026 int rpmcliPackagesTotal = 0;
00027
00028 int rpmcliHashesCurrent = 0;
00029
00030 int rpmcliHashesTotal = 0;
00031
00032 unsigned long long rpmcliProgressCurrent = 0;
00033
00034 unsigned long long rpmcliProgressTotal = 0;
00035
00042 static void printHash(const unsigned long long amount, const unsigned long long total)
00043
00044
00045
00046
00047 {
00048 int hashesNeeded;
00049
00050 rpmcliHashesTotal = (isatty (STDOUT_FILENO) ? 44 : 50);
00051
00052 if (rpmcliHashesCurrent != rpmcliHashesTotal) {
00053
00054 float pct = (total ? (((float) amount) / total) : 1.0);
00055 hashesNeeded = (rpmcliHashesTotal * pct) + 0.5;
00056
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
00081 pct = (rpmcliProgressTotal
00082 ? (((float) rpmcliProgressCurrent) / rpmcliProgressTotal)
00083 : 1);
00084
00085 fprintf(stdout, " [%3d%%]", (int)((100 * pct) + 0.5));
00086 }
00087 fprintf(stdout, "\n");
00088 }
00089 (void) fflush(stdout);
00090 }
00091 }
00092
00093 void * rpmShowProgress( const void * arg,
00094 const rpmCallbackType what,
00095 const unsigned long long amount,
00096 const unsigned long long total,
00097 fnpyKey key,
00098 void * data)
00099
00100
00101
00102
00103 {
00104
00105 Header h = (Header) arg;
00106
00107 char * s;
00108 int flags = (int) ((long)data);
00109 void * rc = NULL;
00110
00111 const char * filename = (const char *)key;
00112
00113 static FD_t fd = NULL;
00114 int xx;
00115
00116 switch (what) {
00117 case RPMCALLBACK_INST_OPEN_FILE:
00118
00119 if (filename == NULL || filename[0] == '\0')
00120 return NULL;
00121
00122 fd = Fopen(filename, "r");
00123
00124 if (fd == NULL || Ferror(fd)) {
00125 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), filename,
00126 Fstrerror(fd));
00127 if (fd != NULL) {
00128 xx = Fclose(fd);
00129 fd = NULL;
00130 }
00131 } else {
00132 long oldfl;
00133 fd = fdLink(fd, "persist (showProgress)");
00134 oldfl=Fcntl(fd, F_GETFD, 0);
00135 if(oldfl >= 0) {
00136 oldfl |= FD_CLOEXEC;
00137 Fcntl(fd, F_SETFD, (void*)oldfl);
00138 }
00139 }
00140
00141
00142 return (void *)fd;
00143
00144 break;
00145
00146 case RPMCALLBACK_INST_CLOSE_FILE:
00147
00148 fd = fdFree(fd, "persist (showProgress)");
00149
00150 if (fd != NULL) {
00151 xx = Fclose(fd);
00152 fd = NULL;
00153 }
00154 break;
00155
00156 case RPMCALLBACK_INST_START:
00157 rpmcliHashesCurrent = 0;
00158 if (h == NULL || !(flags & INSTALL_LABEL))
00159 break;
00160
00161 if (flags & INSTALL_HASH) {
00162 s = headerSprintf(h, "%{NAME}",
00163 rpmTagTable, rpmHeaderFormats, NULL);
00164 if (isatty (STDOUT_FILENO))
00165 fprintf(stdout, "%4d:%-23.23s", (int)rpmcliProgressCurrent + 1, s);
00166 else
00167 fprintf(stdout, "%-28.28s", s);
00168 (void) fflush(stdout);
00169 s = _free(s);
00170 } else {
00171 s = headerSprintf(h, "%{NAME}-%{VERSION}-%{RELEASE}",
00172 rpmTagTable, rpmHeaderFormats, NULL);
00173 fprintf(stdout, "%s\n", s);
00174 (void) fflush(stdout);
00175 s = _free(s);
00176 }
00177 break;
00178
00179 case RPMCALLBACK_TRANS_PROGRESS:
00180 case RPMCALLBACK_INST_PROGRESS:
00181
00182 if (flags & INSTALL_PERCENT)
00183 fprintf(stdout, "%%%% %f\n", (double) (total
00184 ? ((((float) amount) / total) * 100)
00185 : 100.0));
00186 else if (flags & INSTALL_HASH)
00187 printHash(amount, total);
00188
00189 (void) fflush(stdout);
00190 break;
00191
00192 case RPMCALLBACK_TRANS_START:
00193 rpmcliHashesCurrent = 0;
00194 rpmcliProgressTotal = 1;
00195 rpmcliProgressCurrent = 0;
00196 if (!(flags & INSTALL_LABEL))
00197 break;
00198 if (flags & INSTALL_HASH)
00199 fprintf(stdout, "%-28s", _("Preparing..."));
00200 else
00201 fprintf(stdout, "%s\n", _("Preparing packages for installation..."));
00202 (void) fflush(stdout);
00203 break;
00204
00205 case RPMCALLBACK_TRANS_STOP:
00206 if (flags & INSTALL_HASH)
00207 printHash(1, 1);
00208 rpmcliProgressTotal = rpmcliPackagesTotal;
00209 rpmcliProgressCurrent = 0;
00210 break;
00211
00212 case RPMCALLBACK_REPACKAGE_START:
00213 rpmcliHashesCurrent = 0;
00214 rpmcliProgressTotal = total;
00215 rpmcliProgressCurrent = 0;
00216 if (!(flags & INSTALL_LABEL))
00217 break;
00218 if (flags & INSTALL_HASH)
00219 fprintf(stdout, "%-28s\n", _("Repackaging..."));
00220 else
00221 fprintf(stdout, "%s\n", _("Repackaging erased files..."));
00222 (void) fflush(stdout);
00223 break;
00224
00225 case RPMCALLBACK_REPACKAGE_PROGRESS:
00226 if (amount && (flags & INSTALL_HASH))
00227 printHash(1, 1);
00228 break;
00229
00230 case RPMCALLBACK_REPACKAGE_STOP:
00231 rpmcliProgressTotal = total;
00232 rpmcliProgressCurrent = total;
00233 if (flags & INSTALL_HASH)
00234 printHash(1, 1);
00235 rpmcliProgressTotal = rpmcliPackagesTotal;
00236 rpmcliProgressCurrent = 0;
00237 if (!(flags & INSTALL_LABEL))
00238 break;
00239 if (flags & INSTALL_HASH)
00240 fprintf(stdout, "%-28s\n", _("Upgrading..."));
00241 else
00242 fprintf(stdout, "%s\n", _("Upgrading packages..."));
00243 (void) fflush(stdout);
00244 break;
00245
00246 case RPMCALLBACK_UNINST_PROGRESS:
00247 break;
00248 case RPMCALLBACK_UNINST_START:
00249 break;
00250 case RPMCALLBACK_UNINST_STOP:
00251 break;
00252 case RPMCALLBACK_UNPACK_ERROR:
00253 break;
00254 case RPMCALLBACK_CPIO_ERROR:
00255 break;
00256 case RPMCALLBACK_UNKNOWN:
00257 default:
00258 break;
00259 }
00260
00261 return rc;
00262 }
00263
00264 typedef const char * str_t;
00265
00266 struct rpmEIU {
00267 Header h;
00268 FD_t fd;
00269 int numFailed;
00270 int numPkgs;
00271
00272 str_t * pkgURL;
00273
00274 str_t * fnp;
00275
00276 char * pkgState;
00277 int prevx;
00278 int pkgx;
00279 int numRPMS;
00280 int numSRPMS;
00281
00282 str_t * sourceURL;
00283 int isSource;
00284 int argc;
00285
00286 str_t * argv;
00287
00288 rpmRelocation relocations;
00289 rpmRC rpmrc;
00290 };
00291
00293
00294 int rpmInstall(rpmts ts, QVA_t ia, const char ** fileArgv)
00295 {
00296 struct rpmEIU * eiu = memset(alloca(sizeof(*eiu)), 0, sizeof(*eiu));
00297 rpmps ps;
00298 rpmprobFilterFlags probFilter;
00299 rpmRelocation relocations;
00300 const char * fileURL = NULL;
00301 int stopInstall = 0;
00302 const char ** av = NULL;
00303 const char *fn;
00304 rpmVSFlags vsflags, ovsflags, tvsflags;
00305 int ac = 0;
00306 int rc;
00307 int xx;
00308 int i;
00309
00310 if (fileArgv == NULL) goto exit;
00311
00312 ts->goal = TSM_INSTALL;
00313 rpmcliPackagesTotal = 0;
00314
00315 if (rpmExpandNumeric("%{?_repackage_all_erasures}"))
00316 ia->transFlags |= RPMTRANS_FLAG_REPACKAGE;
00317
00318
00319 if (!(ia->transFlags & RPMTRANS_FLAG_NOCONTEXTS)) {
00320 rpmsx sx = rpmtsREContext(ts);
00321 if (sx == NULL) {
00322 fn = rpmGetPath("%{?_install_file_context_path}", NULL);
00323 if (fn != NULL && *fn != '\0') {
00324 sx = rpmsxNew(fn);
00325 (void) rpmtsSetREContext(ts, sx);
00326 }
00327 fn = _free(fn);
00328 }
00329 sx = rpmsxFree(sx);
00330 }
00331 (void) rpmtsSetFlags(ts, ia->transFlags);
00332 (void) rpmtsSetDFlags(ts, ia->depFlags);
00333
00334
00335 if (rpmExpandNumeric("%{?_rollback_transaction_on_failure}")) {
00336 if (ia->arbtid) {
00337 time_t ttid = (time_t)ia->arbtid;
00338 rpmMessage(RPMMESS_DEBUG, _("Autorollback Goal: %-24.24s (0x%08x)\n"),
00339 ctime(&ttid), ia->arbtid);
00340 rpmtsSetARBGoal(ts, ia->arbtid);
00341 }
00342 }
00343
00344 probFilter = ia->probFilter;
00345 relocations = ia->relocations;
00346
00347 if (ia->installInterfaceFlags & INSTALL_UPGRADE)
00348 vsflags = rpmExpandNumeric("%{?_vsflags_erase}");
00349 else
00350 vsflags = rpmExpandNumeric("%{?_vsflags_install}");
00351 if (ia->qva_flags & VERIFY_DIGEST)
00352 vsflags |= _RPMVSF_NODIGESTS;
00353 if (ia->qva_flags & VERIFY_SIGNATURE)
00354 vsflags |= _RPMVSF_NOSIGNATURES;
00355 if (ia->qva_flags & VERIFY_HDRCHK)
00356 vsflags |= RPMVSF_NOHDRCHK;
00357 ovsflags = rpmtsSetVSFlags(ts, (vsflags | RPMVSF_NEEDPAYLOAD));
00358
00359 { int notifyFlags;
00360 notifyFlags = ia->installInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 );
00361 xx = rpmtsSetNotifyCallback(ts,
00362 rpmShowProgress, (void *) ((long)notifyFlags));
00363 }
00364
00365 if ((eiu->relocations = relocations) != NULL) {
00366 while (eiu->relocations->oldPath)
00367 eiu->relocations++;
00368 if (eiu->relocations->newPath == NULL)
00369 eiu->relocations = NULL;
00370 }
00371
00372
00373
00374
00375 for (eiu->fnp = fileArgv; *eiu->fnp != NULL; eiu->fnp++) {
00376
00377 av = _free(av); ac = 0;
00378 fn = rpmgiEscapeSpaces(*eiu->fnp);
00379 rc = rpmGlob(fn, &ac, &av);
00380 fn = _free(fn);
00381 if (rc || ac == 0) {
00382 rpmError(RPMERR_OPEN, _("File not found by glob: %s\n"), *eiu->fnp);
00383 continue;
00384 }
00385
00386 eiu->argv = xrealloc(eiu->argv, (eiu->argc+ac+1) * sizeof(*eiu->argv));
00387 memcpy(eiu->argv+eiu->argc, av, ac * sizeof(*av));
00388 eiu->argc += ac;
00389 eiu->argv[eiu->argc] = NULL;
00390 }
00391
00392 av = _free(av); ac = 0;
00393
00394 restart:
00395
00396 if (eiu->pkgx >= eiu->numPkgs) {
00397 eiu->numPkgs = eiu->pkgx + eiu->argc;
00398 eiu->pkgURL = xrealloc(eiu->pkgURL,
00399 (eiu->numPkgs + 1) * sizeof(*eiu->pkgURL));
00400 memset(eiu->pkgURL + eiu->pkgx, 0,
00401 ((eiu->argc + 1) * sizeof(*eiu->pkgURL)));
00402 eiu->pkgState = xrealloc(eiu->pkgState,
00403 (eiu->numPkgs + 1) * sizeof(*eiu->pkgState));
00404 memset(eiu->pkgState + eiu->pkgx, 0,
00405 ((eiu->argc + 1) * sizeof(*eiu->pkgState)));
00406 }
00407
00408
00409 for (i = 0; i < eiu->argc; i++) {
00410 fileURL = _free(fileURL);
00411 fileURL = eiu->argv[i];
00412 eiu->argv[i] = NULL;
00413
00414 #ifdef NOTYET
00415 if (fileURL[0] == '=') {
00416 rpmds this = rpmdsSingle(RPMTAG_REQUIRENAME, fileURL+1, NULL, 0);
00417
00418 xx = rpmtsSolve(ts, this, NULL);
00419 if (ts->suggests && ts->nsuggests > 0) {
00420 fileURL = _free(fileURL);
00421 fileURL = ts->suggests[0];
00422 ts->suggests[0] = NULL;
00423 while (ts->nsuggests-- > 0) {
00424 if (ts->suggests[ts->nsuggests] == NULL)
00425 continue;
00426 ts->suggests[ts->nsuggests] = _free(ts->suggests[ts->nsuggests]);
00427 }
00428 ts->suggests = _free(ts->suggests);
00429 rpmMessage(RPMMESS_DEBUG, _("Adding goal: %s\n"), fileURL);
00430 eiu->pkgURL[eiu->pkgx] = fileURL;
00431 fileURL = NULL;
00432 eiu->pkgx++;
00433 }
00434 this = rpmdsFree(this);
00435 } else
00436 #endif
00437
00438 switch (urlIsURL(fileURL)) {
00439 case URL_IS_HTTPS:
00440 case URL_IS_HTTP:
00441 case URL_IS_FTP:
00442 { const char *tfn;
00443
00444 if (rpmIsVerbose())
00445 fprintf(stdout, _("Retrieving %s\n"), fileURL);
00446
00447 { char tfnbuf[64];
00448 const char * rootDir = rpmtsRootDir(ts);
00449 if (!(rootDir && * rootDir))
00450 rootDir = "";
00451 strcpy(tfnbuf, "rpm-xfer.XXXXXX");
00452 (void) mktemp(tfnbuf);
00453 tfn = rpmGenPath(rootDir, "%{_tmppath}/", tfnbuf);
00454 }
00455
00456
00457
00458 rpmMessage(RPMMESS_DEBUG, _(" ... as %s\n"), tfn);
00459 rc = urlGetFile(fileURL, tfn);
00460 if (rc < 0) {
00461 rpmMessage(RPMMESS_ERROR,
00462 _("skipping %s - transfer failed - %s\n"),
00463 fileURL, ftpStrerror(rc));
00464 eiu->numFailed++;
00465 eiu->pkgURL[eiu->pkgx] = NULL;
00466 tfn = _free(tfn);
00467 break;
00468 }
00469 eiu->pkgState[eiu->pkgx] = 1;
00470 eiu->pkgURL[eiu->pkgx] = tfn;
00471 eiu->pkgx++;
00472 } break;
00473 case URL_IS_PATH:
00474 case URL_IS_DASH:
00475 case URL_IS_HKP:
00476 default:
00477 eiu->pkgURL[eiu->pkgx] = fileURL;
00478 fileURL = NULL;
00479 eiu->pkgx++;
00480 break;
00481 }
00482 }
00483 fileURL = _free(fileURL);
00484
00485 if (eiu->numFailed) goto exit;
00486
00487
00488 for (eiu->fnp = eiu->pkgURL+eiu->prevx;
00489 *eiu->fnp != NULL;
00490 eiu->fnp++, eiu->prevx++)
00491 {
00492 const char * fileName;
00493
00494 rpmMessage(RPMMESS_DEBUG, "============== %s\n", *eiu->fnp);
00495 (void) urlPath(*eiu->fnp, &fileName);
00496
00497
00498 eiu->fd = Fopen(*eiu->fnp, "r");
00499 if (eiu->fd == NULL || Ferror(eiu->fd)) {
00500 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), *eiu->fnp,
00501 Fstrerror(eiu->fd));
00502 if (eiu->fd != NULL) {
00503 xx = Fclose(eiu->fd);
00504 eiu->fd = NULL;
00505 }
00506 eiu->numFailed++; *eiu->fnp = NULL;
00507 continue;
00508 }
00509
00510
00511 tvsflags = rpmtsSetVSFlags(ts, vsflags);
00512 eiu->rpmrc = rpmReadPackageFile(ts, eiu->fd, *eiu->fnp, &eiu->h);
00513 tvsflags = rpmtsSetVSFlags(ts, tvsflags);
00514 xx = Fclose(eiu->fd);
00515 eiu->fd = NULL;
00516
00517 switch (eiu->rpmrc) {
00518 case RPMRC_FAIL:
00519 rpmMessage(RPMMESS_ERROR, _("%s cannot be installed\n"), *eiu->fnp);
00520 eiu->numFailed++; *eiu->fnp = NULL;
00521 continue;
00522 break;
00523 case RPMRC_NOTFOUND:
00524 goto maybe_manifest;
00525 break;
00526 case RPMRC_NOTTRUSTED:
00527 case RPMRC_NOKEY:
00528 case RPMRC_OK:
00529 default:
00530 break;
00531 }
00532
00533 eiu->isSource = (headerIsEntry(eiu->h, RPMTAG_SOURCERPM) == 0);
00534
00535 if (eiu->isSource) {
00536 rpmMessage(RPMMESS_DEBUG, _("\tadded source package [%d]\n"),
00537 eiu->numSRPMS);
00538 eiu->sourceURL = xrealloc(eiu->sourceURL,
00539 (eiu->numSRPMS + 2) * sizeof(*eiu->sourceURL));
00540 eiu->sourceURL[eiu->numSRPMS] = *eiu->fnp;
00541 *eiu->fnp = NULL;
00542 eiu->numSRPMS++;
00543 eiu->sourceURL[eiu->numSRPMS] = NULL;
00544 continue;
00545 }
00546
00547 if (eiu->relocations) {
00548 const char ** paths;
00549 int pft;
00550 int c;
00551
00552 if (headerGetEntry(eiu->h, RPMTAG_PREFIXES, &pft,
00553 (void **) &paths, &c) && (c == 1))
00554 {
00555 eiu->relocations->oldPath = xstrdup(paths[0]);
00556 paths = headerFreeData(paths, pft);
00557 } else {
00558 const char * name;
00559 xx = headerNVR(eiu->h, &name, NULL, NULL);
00560 rpmMessage(RPMMESS_ERROR,
00561 _("package %s is not relocatable\n"), name);
00562 eiu->numFailed++;
00563 goto exit;
00564
00565 }
00566 }
00567
00568
00569 if (ia->installInterfaceFlags & INSTALL_FRESHEN) {
00570 rpmdbMatchIterator mi;
00571 const char * name;
00572 Header oldH;
00573 int count;
00574
00575 xx = headerNVR(eiu->h, &name, NULL, NULL);
00576 mi = rpmtsInitIterator(ts, RPMTAG_NAME, name, 0);
00577 count = rpmdbGetIteratorCount(mi);
00578 while ((oldH = rpmdbNextIterator(mi)) != NULL) {
00579 if (rpmVersionCompare(oldH, eiu->h) < 0)
00580 continue;
00581
00582 count = 0;
00583 break;
00584 }
00585 mi = rpmdbFreeIterator(mi);
00586 if (count == 0) {
00587 eiu->h = headerFree(eiu->h);
00588 continue;
00589 }
00590
00591 }
00592
00593
00594 rc = rpmtsAddInstallElement(ts, eiu->h, (fnpyKey)fileName,
00595 (ia->installInterfaceFlags & INSTALL_UPGRADE) != 0,
00596 relocations);
00597
00598
00599
00600 eiu->h = headerFree(eiu->h);
00601 if (eiu->relocations)
00602 eiu->relocations->oldPath = _free(eiu->relocations->oldPath);
00603
00604 switch(rc) {
00605 case 0:
00606 rpmMessage(RPMMESS_DEBUG, _("\tadded binary package [%d]\n"),
00607 eiu->numRPMS);
00608 eiu->numRPMS++;
00609 break;
00610 case 1:
00611 rpmMessage(RPMMESS_WARNING,
00612 _("package file %s was skipped\n"), *eiu->fnp);
00613 break;
00614 case 2:
00615 rpmMessage(RPMMESS_ERROR,
00616 _("file %s requires a newer version of RPM\n"),
00617 *eiu->fnp);
00618 eiu->numFailed++;
00619 goto exit;
00620 break;
00621 }
00622
00623 continue;
00624
00625 maybe_manifest:
00626
00627 eiu->fd = Fopen(*eiu->fnp, "r.fpio");
00628 if (eiu->fd == NULL || Ferror(eiu->fd)) {
00629 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), *eiu->fnp,
00630 Fstrerror(eiu->fd));
00631 if (eiu->fd != NULL) {
00632 xx = Fclose(eiu->fd);
00633 eiu->fd = NULL;
00634 }
00635 eiu->numFailed++; *eiu->fnp = NULL;
00636 break;
00637 }
00638
00639
00640
00641 rc = rpmReadPackageManifest(eiu->fd, &eiu->argc, &eiu->argv);
00642
00643 if (rc != RPMRC_OK)
00644 rpmError(RPMERR_MANIFEST, _("%s: not an rpm package (or package manifest): %s\n"),
00645 *eiu->fnp, Fstrerror(eiu->fd));
00646 xx = Fclose(eiu->fd);
00647 eiu->fd = NULL;
00648
00649
00650 if (rc == RPMRC_OK) {
00651 eiu->prevx++;
00652 goto restart;
00653 }
00654
00655 eiu->numFailed++; *eiu->fnp = NULL;
00656 break;
00657 }
00658
00659 rpmMessage(RPMMESS_DEBUG, _("found %d source and %d binary packages\n"),
00660 eiu->numSRPMS, eiu->numRPMS);
00661
00662 if (eiu->numFailed) goto exit;
00663
00664 if (eiu->numRPMS && !(ia->installInterfaceFlags & INSTALL_NODEPS)) {
00665
00666 if (rpmtsCheck(ts)) {
00667 eiu->numFailed = eiu->numPkgs;
00668 stopInstall = 1;
00669 }
00670
00671 ps = rpmtsProblems(ts);
00672 if (!stopInstall && rpmpsNumProblems(ps) > 0) {
00673 rpmMessage(RPMMESS_ERROR, _("Failed dependencies:\n"));
00674 rpmpsPrint(NULL, ps);
00675 eiu->numFailed = eiu->numPkgs;
00676 stopInstall = 1;
00677
00678
00679 if (ts->suggests != NULL && ts->nsuggests > 0) {
00680 rpmMessage(RPMMESS_NORMAL, _(" Suggested resolutions:\n"));
00681 for (i = 0; i < ts->nsuggests; i++) {
00682 const char * str = ts->suggests[i];
00683
00684 if (str == NULL)
00685 break;
00686
00687 rpmMessage(RPMMESS_NORMAL, "\t%s\n", str);
00688
00689 ts->suggests[i] = NULL;
00690 str = _free(str);
00691 }
00692 ts->suggests = _free(ts->suggests);
00693 }
00694
00695 }
00696 ps = rpmpsFree(ps);
00697 }
00698
00699 if (eiu->numRPMS && !(ia->installInterfaceFlags & INSTALL_NOORDER)) {
00700 if (rpmtsOrder(ts)) {
00701 eiu->numFailed = eiu->numPkgs;
00702 stopInstall = 1;
00703 }
00704 }
00705
00706 if (eiu->numRPMS && !stopInstall) {
00707
00708 rpmcliPackagesTotal += eiu->numSRPMS;
00709
00710 rpmMessage(RPMMESS_DEBUG, _("installing binary packages\n"));
00711
00712
00713 rpmtsClean(ts);
00714
00715 rc = rpmtsRun(ts, NULL, probFilter);
00716 ps = rpmtsProblems(ts);
00717
00718 if (rc < 0) {
00719 eiu->numFailed += eiu->numRPMS;
00720 } else if (rc > 0) {
00721 eiu->numFailed += rc;
00722 if (rpmpsNumProblems(ps) > 0)
00723 rpmpsPrint(stderr, ps);
00724 }
00725 ps = rpmpsFree(ps);
00726 }
00727
00728 if (eiu->numSRPMS && !stopInstall) {
00729 if (eiu->sourceURL != NULL)
00730 for (i = 0; i < eiu->numSRPMS; i++) {
00731 if (eiu->sourceURL[i] == NULL) continue;
00732 eiu->fd = Fopen(eiu->sourceURL[i], "r");
00733 if (eiu->fd == NULL || Ferror(eiu->fd)) {
00734 rpmMessage(RPMMESS_ERROR, _("cannot open file %s: %s\n"),
00735 eiu->sourceURL[i], Fstrerror(eiu->fd));
00736 if (eiu->fd != NULL) {
00737 xx = Fclose(eiu->fd);
00738 eiu->fd = NULL;
00739 }
00740 continue;
00741 }
00742
00743 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) {
00744 eiu->rpmrc = rpmInstallSourcePackage(ts, eiu->fd, NULL, NULL);
00745 if (eiu->rpmrc != RPMRC_OK) eiu->numFailed++;
00746 }
00747
00748 xx = Fclose(eiu->fd);
00749 eiu->fd = NULL;
00750 }
00751 }
00752
00753 exit:
00754 if (eiu->pkgURL != NULL)
00755 for (i = 0; i < eiu->numPkgs; i++) {
00756 if (eiu->pkgURL[i] == NULL) continue;
00757 if (eiu->pkgState[i] == 1)
00758 (void) Unlink(eiu->pkgURL[i]);
00759 eiu->pkgURL[i] = _free(eiu->pkgURL[i]);
00760 }
00761 eiu->pkgState = _free(eiu->pkgState);
00762 eiu->pkgURL = _free(eiu->pkgURL);
00763 eiu->argv = _free(eiu->argv);
00764
00765 rpmtsEmpty(ts);
00766
00767 return eiu->numFailed;
00768 }
00769
00770
00771 int rpmErase(rpmts ts, QVA_t ia, const char ** argv)
00772 {
00773 int count;
00774 const char ** arg;
00775 int numFailed = 0;
00776 int stopUninstall = 0;
00777 int numPackages = 0;
00778 rpmVSFlags vsflags, ovsflags;
00779 rpmps ps;
00780
00781 if (argv == NULL) return 0;
00782
00783 vsflags = rpmExpandNumeric("%{?_vsflags_erase}");
00784 if (ia->qva_flags & VERIFY_DIGEST)
00785 vsflags |= _RPMVSF_NODIGESTS;
00786 if (ia->qva_flags & VERIFY_SIGNATURE)
00787 vsflags |= _RPMVSF_NOSIGNATURES;
00788 if (ia->qva_flags & VERIFY_HDRCHK)
00789 vsflags |= RPMVSF_NOHDRCHK;
00790 ovsflags = rpmtsSetVSFlags(ts, vsflags);
00791
00792 if (rpmExpandNumeric("%{?_repackage_all_erasures}"))
00793 ia->transFlags |= RPMTRANS_FLAG_REPACKAGE;
00794
00795 (void) rpmtsSetFlags(ts, ia->transFlags);
00796 (void) rpmtsSetDFlags(ts, ia->depFlags);
00797
00798
00799 if (rpmExpandNumeric("%{?_rollback_transaction_on_failure}")) {
00800 if (ia->arbtid) {
00801 time_t ttid = (time_t)ia->arbtid;
00802 rpmMessage(RPMMESS_DEBUG, _("Autorollback Goal: %-24.24s (0x%08x)\n"),
00803 ctime(&ttid), ia->arbtid);
00804 rpmtsSetARBGoal(ts, ia->arbtid);
00805 }
00806 }
00807
00808 #ifdef NOTYET
00809 { int notifyFlags;
00810 notifyFlags = ia->installInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 );
00811 xx = rpmtsSetNotifyCallback(ts,
00812 rpmShowProgress, (void *) ((long)notifyFlags));
00813 }
00814 #endif
00815
00816 ts->goal = TSM_ERASE;
00817
00818 for (arg = argv; *arg; arg++) {
00819 rpmdbMatchIterator mi;
00820
00821
00822 mi = rpmtsInitIterator(ts, RPMDBI_LABEL, *arg, 0);
00823 if (mi == NULL) {
00824 rpmMessage(RPMMESS_ERROR, _("package %s is not installed\n"), *arg);
00825 numFailed++;
00826 } else {
00827 Header h;
00828 count = 0;
00829 while ((h = rpmdbNextIterator(mi)) != NULL) {
00830 unsigned int recOffset = rpmdbGetIteratorOffset(mi);
00831
00832 if (!(count++ == 0 || (ia->installInterfaceFlags & INSTALL_ALLMATCHES))) {
00833 rpmMessage(RPMMESS_ERROR, _("\"%s\" specifies multiple packages\n"),
00834 *arg);
00835 numFailed++;
00836 break;
00837 }
00838 if (recOffset) {
00839 (void) rpmtsAddEraseElement(ts, h, recOffset);
00840 numPackages++;
00841 }
00842 }
00843 }
00844 mi = rpmdbFreeIterator(mi);
00845 }
00846
00847 if (numFailed) goto exit;
00848
00849 if (!(ia->installInterfaceFlags & INSTALL_NODEPS)) {
00850
00851 if (rpmtsCheck(ts)) {
00852 numFailed = numPackages;
00853 stopUninstall = 1;
00854 }
00855
00856 ps = rpmtsProblems(ts);
00857 if (!stopUninstall && rpmpsNumProblems(ps) > 0) {
00858 rpmMessage(RPMMESS_ERROR, _("Failed dependencies:\n"));
00859 rpmpsPrint(NULL, ps);
00860 numFailed += numPackages;
00861 stopUninstall = 1;
00862 }
00863 ps = rpmpsFree(ps);
00864 }
00865
00866 if (!stopUninstall && !(ia->installInterfaceFlags & INSTALL_NOORDER)) {
00867 if (rpmtsOrder(ts)) {
00868 numFailed += numPackages;
00869 stopUninstall = 1;
00870 }
00871 }
00872
00873 if (numPackages > 0 && !stopUninstall) {
00874
00875
00876 rpmtsClean(ts);
00877
00878 numPackages = rpmtsRun(ts, NULL, 0);
00879 ps = rpmtsProblems(ts);
00880 if (rpmpsNumProblems(ps) > 0)
00881 rpmpsPrint(NULL, ps);
00882 numFailed += numPackages;
00883 stopUninstall = 1;
00884 ps = rpmpsFree(ps);
00885 }
00886
00887 exit:
00888 rpmtsEmpty(ts);
00889
00890 return numFailed;
00891 }
00892
00893 int rpmInstallSource(rpmts ts, const char * arg,
00894 const char ** specFilePtr, const char ** cookie)
00895 {
00896 FD_t fd;
00897 int rc;
00898
00899
00900 fd = Fopen(arg, "r");
00901 if (fd == NULL || Ferror(fd)) {
00902 rpmMessage(RPMMESS_ERROR, _("cannot open %s: %s\n"), arg, Fstrerror(fd));
00903 if (fd != NULL) (void) Fclose(fd);
00904 return 1;
00905 }
00906
00907 if (rpmIsVerbose())
00908 fprintf(stdout, _("Installing %s\n"), arg);
00909
00910 {
00911 rpmVSFlags ovsflags =
00912 rpmtsSetVSFlags(ts, (rpmtsVSFlags(ts) | RPMVSF_NEEDPAYLOAD));
00913 rpmRC rpmrc = rpmInstallSourcePackage(ts, fd, specFilePtr, cookie);
00914 rc = (rpmrc == RPMRC_OK ? 0 : 1);
00915 ovsflags = rpmtsSetVSFlags(ts, ovsflags);
00916 }
00917 if (rc != 0) {
00918 rpmMessage(RPMMESS_ERROR, _("%s cannot be installed\n"), arg);
00919
00920 if (specFilePtr && *specFilePtr)
00921 *specFilePtr = _free(*specFilePtr);
00922 if (cookie && *cookie)
00923 *cookie = _free(*cookie);
00924
00925 }
00926
00927 (void) Fclose(fd);
00928
00929 return rc;
00930 }