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 const char *fn = rpmGetPath("%{?_install_file_context_path}", NULL);
00321 if (fn != NULL && *fn != '\0')
00322 xx = matchpathcon_init(fn);
00323 fn = _free(fn);
00324 }
00325 (void) rpmtsSetFlags(ts, ia->transFlags);
00326 (void) rpmtsSetDFlags(ts, ia->depFlags);
00327
00328
00329 if (rpmExpandNumeric("%{?_rollback_transaction_on_failure}")) {
00330 if (ia->arbtid) {
00331 time_t ttid = (time_t)ia->arbtid;
00332 rpmMessage(RPMMESS_DEBUG, D_("Autorollback Goal: %-24.24s (0x%08x)\n"),
00333 ctime(&ttid), ia->arbtid);
00334 rpmtsSetARBGoal(ts, ia->arbtid);
00335 }
00336 }
00337
00338 probFilter = ia->probFilter;
00339 relocations = ia->relocations;
00340
00341 if (ia->installInterfaceFlags & INSTALL_UPGRADE)
00342 vsflags = rpmExpandNumeric("%{?_vsflags_erase}");
00343 else
00344 vsflags = rpmExpandNumeric("%{?_vsflags_install}");
00345 if (ia->qva_flags & VERIFY_DIGEST)
00346 vsflags |= _RPMVSF_NODIGESTS;
00347 if (ia->qva_flags & VERIFY_SIGNATURE)
00348 vsflags |= _RPMVSF_NOSIGNATURES;
00349 if (ia->qva_flags & VERIFY_HDRCHK)
00350 vsflags |= RPMVSF_NOHDRCHK;
00351 ovsflags = rpmtsSetVSFlags(ts, (vsflags | RPMVSF_NEEDPAYLOAD));
00352
00353 { int notifyFlags;
00354 notifyFlags = ia->installInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 );
00355 xx = rpmtsSetNotifyCallback(ts,
00356 rpmShowProgress, (void *) ((long)notifyFlags));
00357 }
00358
00359 if ((eiu->relocations = relocations) != NULL) {
00360 while (eiu->relocations->oldPath)
00361 eiu->relocations++;
00362 if (eiu->relocations->newPath == NULL)
00363 eiu->relocations = NULL;
00364 }
00365
00366
00367
00368
00369 for (eiu->fnp = fileArgv; *eiu->fnp != NULL; eiu->fnp++) {
00370
00371 av = _free(av); ac = 0;
00372 fn = rpmgiEscapeSpaces(*eiu->fnp);
00373 rc = rpmGlob(fn, &ac, &av);
00374 fn = _free(fn);
00375 if (rc || ac == 0) {
00376 rpmError(RPMERR_OPEN, _("File not found by glob: %s\n"), *eiu->fnp);
00377 continue;
00378 }
00379
00380 eiu->argv = xrealloc(eiu->argv, (eiu->argc+ac+1) * sizeof(*eiu->argv));
00381 memcpy(eiu->argv+eiu->argc, av, ac * sizeof(*av));
00382 eiu->argc += ac;
00383 eiu->argv[eiu->argc] = NULL;
00384 }
00385
00386 av = _free(av); ac = 0;
00387
00388 restart:
00389
00390 if (eiu->pkgx >= eiu->numPkgs) {
00391 eiu->numPkgs = eiu->pkgx + eiu->argc;
00392 eiu->pkgURL = xrealloc(eiu->pkgURL,
00393 (eiu->numPkgs + 1) * sizeof(*eiu->pkgURL));
00394 memset(eiu->pkgURL + eiu->pkgx, 0,
00395 ((eiu->argc + 1) * sizeof(*eiu->pkgURL)));
00396 eiu->pkgState = xrealloc(eiu->pkgState,
00397 (eiu->numPkgs + 1) * sizeof(*eiu->pkgState));
00398 memset(eiu->pkgState + eiu->pkgx, 0,
00399 ((eiu->argc + 1) * sizeof(*eiu->pkgState)));
00400 }
00401
00402
00403 for (i = 0; i < eiu->argc; i++) {
00404 fileURL = _free(fileURL);
00405 fileURL = eiu->argv[i];
00406 eiu->argv[i] = NULL;
00407
00408 #ifdef NOTYET
00409 if (fileURL[0] == '=') {
00410 rpmds this = rpmdsSingle(RPMTAG_REQUIRENAME, fileURL+1, NULL, 0);
00411
00412 xx = rpmtsSolve(ts, this, NULL);
00413 if (ts->suggests && ts->nsuggests > 0) {
00414 fileURL = _free(fileURL);
00415 fileURL = ts->suggests[0];
00416 ts->suggests[0] = NULL;
00417 while (ts->nsuggests-- > 0) {
00418 if (ts->suggests[ts->nsuggests] == NULL)
00419 continue;
00420 ts->suggests[ts->nsuggests] = _free(ts->suggests[ts->nsuggests]);
00421 }
00422 ts->suggests = _free(ts->suggests);
00423 rpmMessage(RPMMESS_DEBUG, D_("Adding goal: %s\n"), fileURL);
00424 eiu->pkgURL[eiu->pkgx] = fileURL;
00425 fileURL = NULL;
00426 eiu->pkgx++;
00427 }
00428 this = rpmdsFree(this);
00429 } else
00430 #endif
00431
00432 switch (urlIsURL(fileURL)) {
00433 case URL_IS_HTTPS:
00434 case URL_IS_HTTP:
00435 case URL_IS_FTP:
00436 { const char *tfn;
00437
00438 if (rpmIsVerbose())
00439 fprintf(stdout, _("Retrieving %s\n"), fileURL);
00440
00441 { char tfnbuf[64];
00442 const char * rootDir = rpmtsRootDir(ts);
00443 if (!(rootDir && * rootDir))
00444 rootDir = "";
00445 strcpy(tfnbuf, "rpm-xfer.XXXXXX");
00446 (void) mktemp(tfnbuf);
00447 tfn = rpmGenPath(rootDir, "%{_tmppath}/", tfnbuf);
00448 }
00449
00450
00451
00452 rpmMessage(RPMMESS_DEBUG, D_(" ... as %s\n"), tfn);
00453 rc = urlGetFile(fileURL, tfn);
00454 if (rc < 0) {
00455 rpmMessage(RPMMESS_ERROR,
00456 _("skipping %s - transfer failed - %s\n"),
00457 fileURL, ftpStrerror(rc));
00458 eiu->numFailed++;
00459 eiu->pkgURL[eiu->pkgx] = NULL;
00460 tfn = _free(tfn);
00461 break;
00462 }
00463 eiu->pkgState[eiu->pkgx] = 1;
00464 eiu->pkgURL[eiu->pkgx] = tfn;
00465 eiu->pkgx++;
00466 } break;
00467 case URL_IS_PATH:
00468 case URL_IS_DASH:
00469 case URL_IS_HKP:
00470 default:
00471 eiu->pkgURL[eiu->pkgx] = fileURL;
00472 fileURL = NULL;
00473 eiu->pkgx++;
00474 break;
00475 }
00476 }
00477 fileURL = _free(fileURL);
00478
00479 if (eiu->numFailed) goto exit;
00480
00481
00482 for (eiu->fnp = eiu->pkgURL+eiu->prevx;
00483 *eiu->fnp != NULL;
00484 eiu->fnp++, eiu->prevx++)
00485 {
00486 const char * fileName;
00487
00488 rpmMessage(RPMMESS_DEBUG, "============== %s\n", *eiu->fnp);
00489 (void) urlPath(*eiu->fnp, &fileName);
00490
00491
00492 eiu->fd = Fopen(*eiu->fnp, "r");
00493 if (eiu->fd == NULL || Ferror(eiu->fd)) {
00494 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), *eiu->fnp,
00495 Fstrerror(eiu->fd));
00496 if (eiu->fd != NULL) {
00497 xx = Fclose(eiu->fd);
00498 eiu->fd = NULL;
00499 }
00500 eiu->numFailed++; *eiu->fnp = NULL;
00501 continue;
00502 }
00503
00504
00505 tvsflags = rpmtsSetVSFlags(ts, vsflags);
00506 eiu->rpmrc = rpmReadPackageFile(ts, eiu->fd, *eiu->fnp, &eiu->h);
00507 tvsflags = rpmtsSetVSFlags(ts, tvsflags);
00508 xx = Fclose(eiu->fd);
00509 eiu->fd = NULL;
00510
00511 switch (eiu->rpmrc) {
00512 case RPMRC_FAIL:
00513 rpmMessage(RPMMESS_ERROR, _("%s cannot be installed\n"), *eiu->fnp);
00514 eiu->numFailed++; *eiu->fnp = NULL;
00515 continue;
00516 break;
00517 case RPMRC_NOTFOUND:
00518 goto maybe_manifest;
00519 break;
00520 case RPMRC_NOTTRUSTED:
00521 case RPMRC_NOKEY:
00522 case RPMRC_OK:
00523 default:
00524 break;
00525 }
00526
00527 eiu->isSource = (headerIsEntry(eiu->h, RPMTAG_SOURCERPM) == 0);
00528
00529 if (eiu->isSource) {
00530 rpmMessage(RPMMESS_DEBUG, D_("\tadded source package [%d]\n"),
00531 eiu->numSRPMS);
00532 eiu->sourceURL = xrealloc(eiu->sourceURL,
00533 (eiu->numSRPMS + 2) * sizeof(*eiu->sourceURL));
00534 eiu->sourceURL[eiu->numSRPMS] = *eiu->fnp;
00535 *eiu->fnp = NULL;
00536 eiu->numSRPMS++;
00537 eiu->sourceURL[eiu->numSRPMS] = NULL;
00538 continue;
00539 }
00540
00541 if (eiu->relocations) {
00542 const char ** paths;
00543 int pft;
00544 int c;
00545
00546 if (headerGetEntry(eiu->h, RPMTAG_PREFIXES, &pft, &paths, &c)
00547 && c == 1)
00548 {
00549 eiu->relocations->oldPath = xstrdup(paths[0]);
00550 paths = headerFreeData(paths, pft);
00551 } else {
00552 const char * name;
00553 xx = headerNVR(eiu->h, &name, NULL, NULL);
00554 rpmMessage(RPMMESS_ERROR,
00555 _("package %s is not relocatable\n"), name);
00556 eiu->numFailed++;
00557 goto exit;
00558
00559 }
00560 }
00561
00562
00563 if (ia->installInterfaceFlags & INSTALL_FRESHEN) {
00564 rpmdbMatchIterator mi;
00565 const char * name;
00566 Header oldH;
00567 int count;
00568
00569 xx = headerNVR(eiu->h, &name, NULL, NULL);
00570 mi = rpmtsInitIterator(ts, RPMTAG_NAME, name, 0);
00571 count = rpmdbGetIteratorCount(mi);
00572 while ((oldH = rpmdbNextIterator(mi)) != NULL) {
00573 if (rpmVersionCompare(oldH, eiu->h) < 0)
00574 continue;
00575
00576 count = 0;
00577 break;
00578 }
00579 mi = rpmdbFreeIterator(mi);
00580 if (count == 0) {
00581 eiu->h = headerFree(eiu->h);
00582 continue;
00583 }
00584
00585 }
00586
00587
00588 rc = rpmtsAddInstallElement(ts, eiu->h, (fnpyKey)fileName,
00589 (ia->installInterfaceFlags & INSTALL_UPGRADE) != 0,
00590 relocations);
00591
00592
00593
00594 eiu->h = headerFree(eiu->h);
00595 if (eiu->relocations)
00596 eiu->relocations->oldPath = _free(eiu->relocations->oldPath);
00597
00598 switch(rc) {
00599 case 0:
00600 rpmMessage(RPMMESS_DEBUG, D_("\tadded binary package [%d]\n"),
00601 eiu->numRPMS);
00602 eiu->numRPMS++;
00603 break;
00604 case 1:
00605 rpmMessage(RPMMESS_WARNING,
00606 _("package file %s was skipped\n"), *eiu->fnp);
00607 break;
00608 case 2:
00609 rpmMessage(RPMMESS_ERROR,
00610 _("file %s requires a newer version of RPM\n"),
00611 *eiu->fnp);
00612 eiu->numFailed++;
00613 goto exit;
00614 break;
00615 }
00616
00617 continue;
00618
00619 maybe_manifest:
00620
00621 eiu->fd = Fopen(*eiu->fnp, "r.fpio");
00622 if (eiu->fd == NULL || Ferror(eiu->fd)) {
00623 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), *eiu->fnp,
00624 Fstrerror(eiu->fd));
00625 if (eiu->fd != NULL) {
00626 xx = Fclose(eiu->fd);
00627 eiu->fd = NULL;
00628 }
00629 eiu->numFailed++; *eiu->fnp = NULL;
00630 break;
00631 }
00632
00633
00634
00635 rc = rpmReadPackageManifest(eiu->fd, &eiu->argc, &eiu->argv);
00636
00637 if (rc != RPMRC_OK)
00638 rpmError(RPMERR_MANIFEST, _("%s: not an rpm package (or package manifest): %s\n"),
00639 *eiu->fnp, Fstrerror(eiu->fd));
00640 xx = Fclose(eiu->fd);
00641 eiu->fd = NULL;
00642
00643
00644 if (rc == RPMRC_OK) {
00645 eiu->prevx++;
00646 goto restart;
00647 }
00648
00649 eiu->numFailed++; *eiu->fnp = NULL;
00650 break;
00651 }
00652
00653 rpmMessage(RPMMESS_DEBUG, D_("found %d source and %d binary packages\n"),
00654 eiu->numSRPMS, eiu->numRPMS);
00655
00656 if (eiu->numFailed) goto exit;
00657
00658 if (eiu->numRPMS && !(ia->installInterfaceFlags & INSTALL_NODEPS)) {
00659
00660 if (rpmtsCheck(ts)) {
00661 eiu->numFailed = eiu->numPkgs;
00662 stopInstall = 1;
00663 }
00664
00665 ps = rpmtsProblems(ts);
00666 if (!stopInstall && rpmpsNumProblems(ps) > 0) {
00667 rpmMessage(RPMMESS_ERROR, _("Failed dependencies:\n"));
00668 rpmpsPrint(NULL, ps);
00669 eiu->numFailed = eiu->numPkgs;
00670 stopInstall = 1;
00671
00672
00673 if (ts->suggests != NULL && ts->nsuggests > 0) {
00674 rpmMessage(RPMMESS_NORMAL, _(" Suggested resolutions:\n"));
00675 for (i = 0; i < ts->nsuggests; i++) {
00676 const char * str = ts->suggests[i];
00677
00678 if (str == NULL)
00679 break;
00680
00681 rpmMessage(RPMMESS_NORMAL, "\t%s\n", str);
00682
00683 ts->suggests[i] = NULL;
00684 str = _free(str);
00685 }
00686 ts->suggests = _free(ts->suggests);
00687 }
00688
00689 }
00690 ps = rpmpsFree(ps);
00691 }
00692
00693 if (eiu->numRPMS && !(ia->installInterfaceFlags & INSTALL_NOORDER)) {
00694 if (rpmtsOrder(ts)) {
00695 eiu->numFailed = eiu->numPkgs;
00696 stopInstall = 1;
00697 }
00698 }
00699
00700 if (eiu->numRPMS && !stopInstall) {
00701
00702 rpmcliPackagesTotal += eiu->numSRPMS;
00703
00704 rpmMessage(RPMMESS_DEBUG, D_("installing binary packages\n"));
00705
00706
00707 rpmtsClean(ts);
00708
00709 rc = rpmtsRun(ts, NULL, probFilter);
00710 ps = rpmtsProblems(ts);
00711
00712 if (rc < 0) {
00713 eiu->numFailed += eiu->numRPMS;
00714 } else if (rc > 0) {
00715 eiu->numFailed += rc;
00716 if (rpmpsNumProblems(ps) > 0)
00717 rpmpsPrint(stderr, ps);
00718 }
00719 ps = rpmpsFree(ps);
00720 }
00721
00722 if (eiu->numSRPMS && !stopInstall) {
00723 if (eiu->sourceURL != NULL)
00724 for (i = 0; i < eiu->numSRPMS; i++) {
00725 if (eiu->sourceURL[i] == NULL) continue;
00726 eiu->fd = Fopen(eiu->sourceURL[i], "r");
00727 if (eiu->fd == NULL || Ferror(eiu->fd)) {
00728 rpmMessage(RPMMESS_ERROR, _("cannot open file %s: %s\n"),
00729 eiu->sourceURL[i], Fstrerror(eiu->fd));
00730 if (eiu->fd != NULL) {
00731 xx = Fclose(eiu->fd);
00732 eiu->fd = NULL;
00733 }
00734 continue;
00735 }
00736
00737 if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) {
00738 eiu->rpmrc = rpmInstallSourcePackage(ts, eiu->fd, NULL, NULL);
00739 if (eiu->rpmrc != RPMRC_OK) eiu->numFailed++;
00740 }
00741
00742 xx = Fclose(eiu->fd);
00743 eiu->fd = NULL;
00744 }
00745 }
00746
00747 exit:
00748 if (eiu->pkgURL != NULL)
00749 for (i = 0; i < eiu->numPkgs; i++) {
00750 if (eiu->pkgURL[i] == NULL) continue;
00751 if (eiu->pkgState[i] == 1)
00752 (void) Unlink(eiu->pkgURL[i]);
00753 eiu->pkgURL[i] = _free(eiu->pkgURL[i]);
00754 }
00755 eiu->pkgState = _free(eiu->pkgState);
00756 eiu->pkgURL = _free(eiu->pkgURL);
00757 eiu->argv = _free(eiu->argv);
00758
00759 rpmtsEmpty(ts);
00760
00761 return eiu->numFailed;
00762 }
00763
00764
00765 int rpmErase(rpmts ts, QVA_t ia, const char ** argv)
00766 {
00767 int count;
00768 const char ** arg;
00769 int numFailed = 0;
00770 int stopUninstall = 0;
00771 int numPackages = 0;
00772 rpmVSFlags vsflags, ovsflags;
00773 rpmps ps;
00774
00775 if (argv == NULL) return 0;
00776
00777 vsflags = rpmExpandNumeric("%{?_vsflags_erase}");
00778 if (ia->qva_flags & VERIFY_DIGEST)
00779 vsflags |= _RPMVSF_NODIGESTS;
00780 if (ia->qva_flags & VERIFY_SIGNATURE)
00781 vsflags |= _RPMVSF_NOSIGNATURES;
00782 if (ia->qva_flags & VERIFY_HDRCHK)
00783 vsflags |= RPMVSF_NOHDRCHK;
00784 ovsflags = rpmtsSetVSFlags(ts, vsflags);
00785
00786 if (rpmExpandNumeric("%{?_repackage_all_erasures}"))
00787 ia->transFlags |= RPMTRANS_FLAG_REPACKAGE;
00788
00789 (void) rpmtsSetFlags(ts, ia->transFlags);
00790 (void) rpmtsSetDFlags(ts, ia->depFlags);
00791
00792
00793 if (rpmExpandNumeric("%{?_rollback_transaction_on_failure}")) {
00794 if (ia->arbtid) {
00795 time_t ttid = (time_t)ia->arbtid;
00796 rpmMessage(RPMMESS_DEBUG, D_("Autorollback Goal: %-24.24s (0x%08x)\n"),
00797 ctime(&ttid), ia->arbtid);
00798 rpmtsSetARBGoal(ts, ia->arbtid);
00799 }
00800 }
00801
00802 #ifdef NOTYET
00803 { int notifyFlags;
00804 notifyFlags = ia->installInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 );
00805 xx = rpmtsSetNotifyCallback(ts,
00806 rpmShowProgress, (void *) ((long)notifyFlags));
00807 }
00808 #endif
00809
00810 ts->goal = TSM_ERASE;
00811
00812 for (arg = argv; *arg; arg++) {
00813 rpmdbMatchIterator mi;
00814
00815
00816 mi = rpmtsInitIterator(ts, RPMDBI_LABEL, *arg, 0);
00817 if (mi == NULL) {
00818 rpmMessage(RPMMESS_ERROR, _("package %s is not installed\n"), *arg);
00819 numFailed++;
00820 } else {
00821 Header h;
00822 count = 0;
00823 while ((h = rpmdbNextIterator(mi)) != NULL) {
00824 unsigned int recOffset = rpmdbGetIteratorOffset(mi);
00825
00826 if (!(count++ == 0 || (ia->installInterfaceFlags & INSTALL_ALLMATCHES))) {
00827 rpmMessage(RPMMESS_ERROR, _("\"%s\" specifies multiple packages\n"),
00828 *arg);
00829 numFailed++;
00830 break;
00831 }
00832 if (recOffset) {
00833 (void) rpmtsAddEraseElement(ts, h, recOffset);
00834 numPackages++;
00835 }
00836 }
00837 }
00838 mi = rpmdbFreeIterator(mi);
00839 }
00840
00841 if (numFailed) goto exit;
00842
00843 if (!(ia->installInterfaceFlags & INSTALL_NODEPS)) {
00844
00845 if (rpmtsCheck(ts)) {
00846 numFailed = numPackages;
00847 stopUninstall = 1;
00848 }
00849
00850 ps = rpmtsProblems(ts);
00851 if (!stopUninstall && rpmpsNumProblems(ps) > 0) {
00852 rpmMessage(RPMMESS_ERROR, _("Failed dependencies:\n"));
00853 rpmpsPrint(NULL, ps);
00854 numFailed += numPackages;
00855 stopUninstall = 1;
00856 }
00857 ps = rpmpsFree(ps);
00858 }
00859
00860 if (!stopUninstall && !(ia->installInterfaceFlags & INSTALL_NOORDER)) {
00861 if (rpmtsOrder(ts)) {
00862 numFailed += numPackages;
00863 stopUninstall = 1;
00864 }
00865 }
00866
00867 if (numPackages > 0 && !stopUninstall) {
00868
00869
00870 rpmtsClean(ts);
00871
00872 numPackages = rpmtsRun(ts, NULL, 0);
00873 ps = rpmtsProblems(ts);
00874 if (rpmpsNumProblems(ps) > 0)
00875 rpmpsPrint(NULL, ps);
00876 numFailed += numPackages;
00877 stopUninstall = 1;
00878 ps = rpmpsFree(ps);
00879 }
00880
00881 exit:
00882 rpmtsEmpty(ts);
00883
00884 return numFailed;
00885 }
00886
00887 int rpmInstallSource(rpmts ts, const char * arg,
00888 const char ** specFilePtr, const char ** cookie)
00889 {
00890 FD_t fd;
00891 int rc;
00892
00893
00894 fd = Fopen(arg, "r");
00895 if (fd == NULL || Ferror(fd)) {
00896 rpmMessage(RPMMESS_ERROR, _("cannot open %s: %s\n"), arg, Fstrerror(fd));
00897 if (fd != NULL) (void) Fclose(fd);
00898 return 1;
00899 }
00900
00901 if (rpmIsVerbose())
00902 fprintf(stdout, _("Installing %s\n"), arg);
00903
00904 {
00905 rpmVSFlags ovsflags =
00906 rpmtsSetVSFlags(ts, (rpmtsVSFlags(ts) | RPMVSF_NEEDPAYLOAD));
00907 rpmRC rpmrc = rpmInstallSourcePackage(ts, fd, specFilePtr, cookie);
00908 rc = (rpmrc == RPMRC_OK ? 0 : 1);
00909 ovsflags = rpmtsSetVSFlags(ts, ovsflags);
00910 }
00911 if (rc != 0) {
00912 rpmMessage(RPMMESS_ERROR, _("%s cannot be installed\n"), arg);
00913
00914 if (specFilePtr && *specFilePtr)
00915 *specFilePtr = _free(*specFilePtr);
00916 if (cookie && *cookie)
00917 *cookie = _free(*cookie);
00918
00919 }
00920
00921 (void) Fclose(fd);
00922
00923 return rc;
00924 }