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