X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Frpminstall.c;h=a3623fd3a5863a34b9d65646f80c226e259807dd;hb=9cf156d6583a9f9581000bb12ff047980ebcef03;hp=2b1196afef73c9ad8ad0332cb138aa56bb987cf9;hpb=d2406a7e1754e7a7dc8136d9132929df36e5f230;p=platform%2Fupstream%2Frpm.git diff --git a/lib/rpminstall.c b/lib/rpminstall.c index 2b1196a..a3623fd 100644 --- a/lib/rpminstall.c +++ b/lib/rpminstall.c @@ -13,14 +13,15 @@ #include #include +#include "lib/rpmgi.h" #include "lib/manifest.h" #include "debug.h" -int rpmcliPackagesTotal = 0; -int rpmcliHashesCurrent = 0; -int rpmcliHashesTotal = 0; -int rpmcliProgressCurrent = 0; -int rpmcliProgressTotal = 0; +static int rpmcliPackagesTotal = 0; +static int rpmcliHashesCurrent = 0; +static int rpmcliHashesTotal = 0; +static int rpmcliProgressCurrent = 0; +static int rpmcliProgressTotal = 0; /** * Print a CLI progress bar. @@ -28,11 +29,11 @@ int rpmcliProgressTotal = 0; * @param amount current * @param total final */ -static void printHash(const rpm_off_t amount, const rpm_off_t total) +static void printHash(const rpm_loff_t amount, const rpm_loff_t total) { int hashesNeeded; - rpmcliHashesTotal = (isatty (STDOUT_FILENO) ? 44 : 50); + rpmcliHashesTotal = (isatty (STDOUT_FILENO) ? 34 : 40); if (rpmcliHashesCurrent != rpmcliHashesTotal) { float pct = (total ? (((float) amount) / total) : 1.0); @@ -71,20 +72,38 @@ static void printHash(const rpm_off_t amount, const rpm_off_t total) } } +static rpmVSFlags setvsFlags(struct rpmInstallArguments_s * ia) +{ + rpmVSFlags vsflags; + + if (ia->installInterfaceFlags & (INSTALL_UPGRADE | INSTALL_ERASE)) + vsflags = rpmExpandNumeric("%{?_vsflags_erase}"); + else + vsflags = rpmExpandNumeric("%{?_vsflags_install}"); + + if (rpmcliQueryFlags & VERIFY_DIGEST) + vsflags |= _RPMVSF_NODIGESTS; + if (rpmcliQueryFlags & VERIFY_SIGNATURE) + vsflags |= _RPMVSF_NOSIGNATURES; + if (rpmcliQueryFlags & VERIFY_HDRCHK) + vsflags |= RPMVSF_NOHDRCHK; + + return vsflags; +} + void * rpmShowProgress(const void * arg, const rpmCallbackType what, - const rpm_off_t amount, - const rpm_off_t total, + const rpm_loff_t amount, + const rpm_loff_t total, fnpyKey key, void * data) { Header h = (Header) arg; - char * s; int flags = (int) ((long)data); void * rc = NULL; const char * filename = (const char *)key; static FD_t fd = NULL; - int xx; + static int state = -1; switch (what) { case RPMCALLBACK_INST_OPEN_FILE: @@ -96,48 +115,62 @@ void * rpmShowProgress(const void * arg, rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), filename, Fstrerror(fd)); if (fd != NULL) { - xx = Fclose(fd); + Fclose(fd); fd = NULL; } } else - fd = fdLink(fd, RPMDBG_M("persist (showProgress)")); + fd = fdLink(fd); return (void *)fd; break; case RPMCALLBACK_INST_CLOSE_FILE: /* FIX: still necessary? */ - fd = fdFree(fd, RPMDBG_M("persist (showProgress)")); + fd = fdFree(fd); if (fd != NULL) { - xx = Fclose(fd); + Fclose(fd); fd = NULL; } break; case RPMCALLBACK_INST_START: + case RPMCALLBACK_UNINST_START: + if (state != what) { + state = what; + if (flags & INSTALL_HASH) { + if (what == RPMCALLBACK_INST_START) { + fprintf(stdout, _("Updating / installing...\n")); + } else { + fprintf(stdout, _("Cleaning up / removing...\n")); + } + fflush(stdout); + } + } + rpmcliHashesCurrent = 0; if (h == NULL || !(flags & INSTALL_LABEL)) break; - /* @todo Remove headerSprintf() on a progress callback. */ if (flags & INSTALL_HASH) { - s = headerSprintf(h, "%{NAME}", - rpmTagTable, rpmHeaderFormats, NULL); + char *s = headerGetAsString(h, RPMTAG_NEVR); if (isatty (STDOUT_FILENO)) - fprintf(stdout, "%4d:%-23.23s", rpmcliProgressCurrent + 1, s); + fprintf(stdout, "%4d:%-33.33s", rpmcliProgressCurrent + 1, s); else - fprintf(stdout, "%-28.28s", s); + fprintf(stdout, "%-38.38s", s); (void) fflush(stdout); - s = _free(s); + free(s); } else { - s = headerSprintf(h, "%{NAME}-%{VERSION}-%{RELEASE}", - rpmTagTable, rpmHeaderFormats, NULL); + char *s = headerGetAsString(h, RPMTAG_NEVRA); fprintf(stdout, "%s\n", s); (void) fflush(stdout); - s = _free(s); + free(s); } break; + case RPMCALLBACK_INST_STOP: + break; + case RPMCALLBACK_TRANS_PROGRESS: case RPMCALLBACK_INST_PROGRESS: + case RPMCALLBACK_UNINST_PROGRESS: if (flags & INSTALL_PERCENT) fprintf(stdout, "%%%% %f\n", (double) (total ? ((((float) amount) / total) * 100) @@ -151,12 +184,14 @@ void * rpmShowProgress(const void * arg, rpmcliHashesCurrent = 0; rpmcliProgressTotal = 1; rpmcliProgressCurrent = 0; + rpmcliPackagesTotal = total; + state = what; if (!(flags & INSTALL_LABEL)) break; if (flags & INSTALL_HASH) - fprintf(stdout, "%-28s", _("Preparing...")); + fprintf(stdout, "%-38s", _("Preparing...")); else - fprintf(stdout, "%s\n", _("Preparing packages for installation...")); + fprintf(stdout, "%s\n", _("Preparing packages...")); (void) fflush(stdout); break; @@ -167,10 +202,6 @@ void * rpmShowProgress(const void * arg, rpmcliProgressCurrent = 0; break; - case RPMCALLBACK_UNINST_PROGRESS: - break; - case RPMCALLBACK_UNINST_START: - break; case RPMCALLBACK_UNINST_STOP: break; case RPMCALLBACK_UNPACK_ERROR: @@ -179,6 +210,10 @@ void * rpmShowProgress(const void * arg, break; case RPMCALLBACK_SCRIPT_ERROR: break; + case RPMCALLBACK_SCRIPT_START: + break; + case RPMCALLBACK_SCRIPT_STOP: + break; case RPMCALLBACK_UNKNOWN: default: break; @@ -187,9 +222,16 @@ void * rpmShowProgress(const void * arg, return rc; } +static void setNotifyFlag(struct rpmInstallArguments_s * ia, + rpmts ts) +{ + int notifyFlags; + + notifyFlags = ia->installInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 ); + rpmtsSetNotifyCallback(ts, rpmShowProgress, (void *) ((long)notifyFlags)); +} + struct rpmEIU { - Header h; - FD_t fd; int numFailed; int numPkgs; char ** pkgURL; @@ -200,53 +242,169 @@ struct rpmEIU { int numRPMS; int numSRPMS; char ** sourceURL; - int isSource; int argc; char ** argv; rpmRelocation * relocations; rpmRC rpmrc; }; +static int rpmcliTransaction(rpmts ts, struct rpmInstallArguments_s * ia, + int numPackages) +{ + rpmps ps; + + int rc = 0; + int stop = 0; + + int eflags = ia->installInterfaceFlags & INSTALL_ERASE; + + if (!(ia->installInterfaceFlags & INSTALL_NODEPS)) { + + if (rpmtsCheck(ts)) { + rc = numPackages; + stop = 1; + } + + ps = rpmtsProblems(ts); + if (!stop && rpmpsNumProblems(ps) > 0) { + rpmlog(RPMLOG_ERR, _("Failed dependencies:\n")); + rpmpsPrint(NULL, ps); + rc = numPackages; + stop = 1; + } + ps = rpmpsFree(ps); + } + + if (!stop && !(ia->installInterfaceFlags & INSTALL_NOORDER)) { + if (rpmtsOrder(ts)) { + rc = numPackages; + stop = 1; + } + } + + if (numPackages && !stop) { + rpmlog(RPMLOG_DEBUG, eflags ? "erasing packages\n" : + "installing binary packages\n"); + rpmtsClean(ts); + rc = rpmtsRun(ts, NULL, ia->probFilter); + + ps = rpmtsProblems(ts); + + if ((rpmpsNumProblems(ps) > 0) && (eflags? 1 : (rc > 0))) + rpmpsPrint((eflags? NULL : stderr), ps); + ps = rpmpsFree(ps); + } + + return rc; +} + +static int tryReadManifest(struct rpmEIU * eiu) +{ + int rc; + + /* Try to read a package manifest. */ + FD_t fd = Fopen(*eiu->fnp, "r.ufdio"); + if (fd == NULL || Ferror(fd)) { + rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), *eiu->fnp, + Fstrerror(fd)); + if (fd != NULL) { + Fclose(fd); + fd = NULL; + } + eiu->numFailed++; *eiu->fnp = NULL; + return RPMRC_FAIL; + } + + /* Read list of packages from manifest. */ + rc = rpmReadPackageManifest(fd, &eiu->argc, &eiu->argv); + if (rc != RPMRC_OK) + rpmlog(RPMLOG_ERR, _("%s: not an rpm package (or package manifest): %s\n"), + *eiu->fnp, Fstrerror(fd)); + Fclose(fd); + fd = NULL; + + if (rc != RPMRC_OK) + eiu->numFailed++; *eiu->fnp = NULL; + + return rc; +} + +static int tryReadHeader(rpmts ts, struct rpmEIU * eiu, Header * hdrp) +{ + /* Try to read the header from a package file. */ + FD_t fd = Fopen(*eiu->fnp, "r.ufdio"); + if (fd == NULL || Ferror(fd)) { + rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), *eiu->fnp, + Fstrerror(fd)); + if (fd != NULL) { + Fclose(fd); + fd = NULL; + } + eiu->numFailed++; *eiu->fnp = NULL; + return RPMRC_FAIL; + } + + /* Read the header, verifying signatures (if present). */ + eiu->rpmrc = rpmReadPackageFile(ts, fd, *eiu->fnp, hdrp); + Fclose(fd); + fd = NULL; + + /* Honor --nomanifest */ + if (eiu->rpmrc == RPMRC_NOTFOUND && (giFlags & RPMGI_NOMANIFEST)) + eiu->rpmrc = RPMRC_FAIL; + + if(eiu->rpmrc == RPMRC_FAIL) { + rpmlog(RPMLOG_ERR, _("%s cannot be installed\n"), *eiu->fnp); + eiu->numFailed++; *eiu->fnp = NULL; + } + + return RPMRC_OK; +} + + +/* On --freshen, verify package is installed and newer */ +static int checkFreshenStatus(rpmts ts, Header h) +{ + rpmdbMatchIterator mi = NULL; + const char * name = headerGetString(h, RPMTAG_NAME); + const char *arch = headerGetString(h, RPMTAG_ARCH); + Header oldH = NULL; + + if (name != NULL) + mi = rpmtsInitIterator(ts, RPMDBI_NAME, name, 0); + if (rpmtsColor(ts) && arch) + rpmdbSetIteratorRE(mi, RPMTAG_ARCH, RPMMIRE_DEFAULT, arch); + + while ((oldH = rpmdbNextIterator(mi)) != NULL) { + /* Package is newer than those currently installed. */ + if (rpmVersionCompare(oldH, h) < 0) + break; + } + + rpmdbFreeIterator(mi); + return (oldH != NULL); +} + /** @todo Generalize --freshen policies. */ int rpmInstall(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_t fileArgv) { - struct rpmEIU * eiu = memset(alloca(sizeof(*eiu)), 0, sizeof(*eiu)); - rpmps ps; - rpmprobFilterFlags probFilter; + struct rpmEIU * eiu = xcalloc(1, sizeof(*eiu)); rpmRelocation * relocations; char * fileURL = NULL; - int stopInstall = 0; - rpmVSFlags vsflags, ovsflags, tvsflags; + rpmVSFlags vsflags, ovsflags; int rc; - int xx; int i; - if (fileArgv == NULL) goto exit; + vsflags = setvsFlags(ia); + ovsflags = rpmtsSetVSFlags(ts, (vsflags | RPMVSF_NEEDPAYLOAD)); - rpmcliPackagesTotal = 0; + if (fileArgv == NULL) goto exit; (void) rpmtsSetFlags(ts, ia->transFlags); - probFilter = ia->probFilter; relocations = ia->relocations; - if (ia->installInterfaceFlags & INSTALL_UPGRADE) - vsflags = rpmExpandNumeric("%{?_vsflags_erase}"); - else - vsflags = rpmExpandNumeric("%{?_vsflags_install}"); - if (ia->qva_flags & VERIFY_DIGEST) - vsflags |= _RPMVSF_NODIGESTS; - if (ia->qva_flags & VERIFY_SIGNATURE) - vsflags |= _RPMVSF_NOSIGNATURES; - if (ia->qva_flags & VERIFY_HDRCHK) - vsflags |= RPMVSF_NOHDRCHK; - ovsflags = rpmtsSetVSFlags(ts, (vsflags | RPMVSF_NEEDPAYLOAD)); - - { int notifyFlags; - notifyFlags = ia->installInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 ); - xx = rpmtsSetNotifyCallback(ts, - rpmShowProgress, (void *) ((long)notifyFlags)); - } + setNotifyFlag(ia, ts); if ((eiu->relocations = relocations) != NULL) { while (eiu->relocations->oldPath) @@ -266,6 +424,7 @@ int rpmInstall(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_t fileArgv) fn = _free(fn); if (rc || ac == 0) { rpmlog(RPMLOG_ERR, _("File not found by glob: %s\n"), *eiu->fnp); + eiu->numFailed++; continue; } @@ -298,13 +457,13 @@ restart: case URL_IS_HTTPS: case URL_IS_HTTP: case URL_IS_FTP: - { char *tfn; + { char *tfn = NULL; FD_t tfd; if (rpmIsVerbose()) fprintf(stdout, _("Retrieving %s\n"), fileURL); - tfd = rpmMkTemp(rpmtsRootDir(ts), &tfn); + tfd = rpmMkTempFile(rpmtsRootDir(ts), &tfn); if (tfd && tfn) { Fclose(tfd); rc = urlGetFile(fileURL, tfn); @@ -314,8 +473,7 @@ restart: if (rc != 0) { rpmlog(RPMLOG_ERR, - _("skipping %s - transfer failed - %s\n"), - fileURL, ftpStrerror(rc)); + _("skipping %s - transfer failed\n"), fileURL); eiu->numFailed++; eiu->pkgURL[eiu->pkgx] = NULL; tfn = _free(tfn); @@ -344,50 +502,24 @@ restart: *eiu->fnp != NULL; eiu->fnp++, eiu->prevx++) { + Header h = NULL; const char * fileName; rpmlog(RPMLOG_DEBUG, "============== %s\n", *eiu->fnp); (void) urlPath(*eiu->fnp, &fileName); - /* Try to read the header from a package file. */ - eiu->fd = Fopen(*eiu->fnp, "r.ufdio"); - if (eiu->fd == NULL || Ferror(eiu->fd)) { - rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), *eiu->fnp, - Fstrerror(eiu->fd)); - if (eiu->fd != NULL) { - xx = Fclose(eiu->fd); - eiu->fd = NULL; - } - eiu->numFailed++; *eiu->fnp = NULL; + if (tryReadHeader(ts, eiu, &h) == RPMRC_FAIL) continue; - } - /* Read the header, verifying signatures (if present). */ - tvsflags = rpmtsSetVSFlags(ts, vsflags); - eiu->rpmrc = rpmReadPackageFile(ts, eiu->fd, *eiu->fnp, &eiu->h); - tvsflags = rpmtsSetVSFlags(ts, tvsflags); - xx = Fclose(eiu->fd); - eiu->fd = NULL; - - switch (eiu->rpmrc) { - case RPMRC_FAIL: - rpmlog(RPMLOG_ERR, _("%s cannot be installed\n"), *eiu->fnp); - eiu->numFailed++; *eiu->fnp = NULL; - continue; - break; - case RPMRC_NOTFOUND: - goto maybe_manifest; - break; - case RPMRC_NOTTRUSTED: - case RPMRC_NOKEY: - case RPMRC_OK: - default: - break; + if (eiu->rpmrc == RPMRC_NOTFOUND) { + rc = tryReadManifest(eiu); + if (rc == RPMRC_OK) { + eiu->prevx++; + goto restart; + } } - eiu->isSource = headerIsSource(eiu->h); - - if (eiu->isSource) { + if (headerIsSource(h)) { rpmlog(RPMLOG_DEBUG, "\tadded source package [%d]\n", eiu->numSRPMS); eiu->sourceURL = xrealloc(eiu->sourceURL, @@ -400,56 +532,31 @@ restart: } if (eiu->relocations) { - const char ** paths; - rpmTagType pft; - rpm_count_t c; - - if (headerGetEntry(eiu->h, RPMTAG_PREFIXES, &pft, - (rpm_data_t *) &paths, &c) && (c == 1)) - { - eiu->relocations->oldPath = xstrdup(paths[0]); - paths = headerFreeData(paths, pft); + struct rpmtd_s prefixes; + + headerGet(h, RPMTAG_PREFIXES, &prefixes, HEADERGET_DEFAULT); + if (rpmtdCount(&prefixes) == 1) { + eiu->relocations->oldPath = xstrdup(rpmtdGetString(&prefixes)); + rpmtdFreeData(&prefixes); } else { - const char * name; - xx = headerNVR(eiu->h, &name, NULL, NULL); - rpmlog(RPMLOG_ERR, - _("package %s is not relocatable\n"), name); + rpmlog(RPMLOG_ERR, _("package %s is not relocatable\n"), + headerGetString(h, RPMTAG_NAME)); eiu->numFailed++; goto exit; } } - /* On --freshen, verify package is installed and newer */ - if (ia->installInterfaceFlags & INSTALL_FRESHEN) { - rpmdbMatchIterator mi; - const char * name; - Header oldH; - int count; - - xx = headerNVR(eiu->h, &name, NULL, NULL); - mi = rpmtsInitIterator(ts, RPMTAG_NAME, name, 0); - count = rpmdbGetIteratorCount(mi); - while ((oldH = rpmdbNextIterator(mi)) != NULL) { - if (rpmVersionCompare(oldH, eiu->h) < 0) - continue; - /* same or newer package already installed */ - count = 0; - break; + if (ia->installInterfaceFlags & INSTALL_FRESHEN) + if (checkFreshenStatus(ts, h) != 1) { + headerFree(h); + continue; } - mi = rpmdbFreeIterator(mi); - if (count == 0) { - eiu->h = headerFree(eiu->h); - continue; - } - /* Package is newer than those currently installed. */ - } - rc = rpmtsAddInstallElement(ts, eiu->h, (fnpyKey)fileName, + rc = rpmtsAddInstallElement(ts, h, (fnpyKey)fileName, (ia->installInterfaceFlags & INSTALL_UPGRADE) != 0, relocations); - /* XXX reference held by transaction set */ - eiu->h = headerFree(eiu->h); + headerFree(h); if (eiu->relocations) eiu->relocations->oldPath = _free(eiu->relocations->oldPath); @@ -464,13 +571,6 @@ restart: eiu->numFailed++; goto exit; break; - case 2: - rpmlog(RPMLOG_ERR, - _("file %s requires a newer version of RPM\n"), - *eiu->fnp); - eiu->numFailed++; - goto exit; - break; default: eiu->numFailed++; goto exit; @@ -478,39 +578,6 @@ restart: } eiu->numRPMS++; - continue; - -maybe_manifest: - /* Try to read a package manifest. */ - eiu->fd = Fopen(*eiu->fnp, "r.fpio"); - if (eiu->fd == NULL || Ferror(eiu->fd)) { - rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), *eiu->fnp, - Fstrerror(eiu->fd)); - if (eiu->fd != NULL) { - xx = Fclose(eiu->fd); - eiu->fd = NULL; - } - eiu->numFailed++; *eiu->fnp = NULL; - break; - } - - /* Read list of packages from manifest. */ -/* FIX: *eiu->argv can be NULL */ - rc = rpmReadPackageManifest(eiu->fd, &eiu->argc, &eiu->argv); - if (rc != RPMRC_OK) - rpmlog(RPMLOG_NOTICE, _("%s: not an rpm package (or package manifest): %s\n"), - *eiu->fnp, Fstrerror(eiu->fd)); - xx = Fclose(eiu->fd); - eiu->fd = NULL; - - /* If successful, restart the query loop. */ - if (rc == RPMRC_OK) { - eiu->prevx++; - goto restart; - } - - eiu->numFailed++; *eiu->fnp = NULL; - break; } rpmlog(RPMLOG_DEBUG, "found %d source and %d binary packages\n", @@ -518,205 +585,105 @@ maybe_manifest: if (eiu->numFailed) goto exit; - if (eiu->numRPMS && !(ia->installInterfaceFlags & INSTALL_NODEPS)) { - - if (rpmtsCheck(ts)) { - eiu->numFailed = eiu->numPkgs; - stopInstall = 1; - } - - ps = rpmtsProblems(ts); - if (!stopInstall && rpmpsNumProblems(ps) > 0) { - rpmlog(RPMLOG_ERR, _("Failed dependencies:\n")); - rpmpsPrint(NULL, ps); - eiu->numFailed = eiu->numPkgs; - stopInstall = 1; - - if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOSUGGEST)) - rpmtsPrintSuggests(ts); - - } - ps = rpmpsFree(ps); - } - - if (eiu->numRPMS && !(ia->installInterfaceFlags & INSTALL_NOORDER)) { - if (rpmtsOrder(ts)) { - eiu->numFailed = eiu->numPkgs; - stopInstall = 1; - } - } - - if (eiu->numRPMS && !stopInstall) { - - rpmcliPackagesTotal += eiu->numSRPMS; - - rpmlog(RPMLOG_DEBUG, "installing binary packages\n"); - - /* Drop added/available package indices and dependency sets. */ - rpmtsClean(ts); - - rc = rpmtsRun(ts, NULL, probFilter); - ps = rpmtsProblems(ts); - - if (rc < 0) { - eiu->numFailed += eiu->numRPMS; - } else if (rc > 0) { - eiu->numFailed += rc; - if (rpmpsNumProblems(ps) > 0) - rpmpsPrint(stderr, ps); - } - ps = rpmpsFree(ps); + if (eiu->numRPMS) { + int rc = rpmcliTransaction(ts, ia, eiu->numPkgs); + if (rc < 0) + eiu->numFailed += eiu->numRPMS; + else if (rc > 0) + eiu->numFailed += rc; } - if (eiu->numSRPMS && !stopInstall) { - if (eiu->sourceURL != NULL) + if (eiu->numSRPMS && (eiu->sourceURL != NULL)) { for (i = 0; i < eiu->numSRPMS; i++) { rpmdbCheckSignals(); - if (eiu->sourceURL[i] == NULL) continue; - eiu->fd = Fopen(eiu->sourceURL[i], "r.ufdio"); - if (eiu->fd == NULL || Ferror(eiu->fd)) { - rpmlog(RPMLOG_ERR, _("cannot open file %s: %s\n"), - eiu->sourceURL[i], Fstrerror(eiu->fd)); - if (eiu->fd != NULL) { - xx = Fclose(eiu->fd); - eiu->fd = NULL; - } - continue; - } - - if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) { - eiu->rpmrc = rpmInstallSourcePackage(ts, eiu->fd, NULL, NULL); - if (eiu->rpmrc != RPMRC_OK) eiu->numFailed++; + if (eiu->sourceURL[i] != NULL) { + rc = RPMRC_OK; + if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) + rc = rpmInstallSource(ts, eiu->sourceURL[i], NULL, NULL); + if (rc != 0) + eiu->numFailed++; } - - xx = Fclose(eiu->fd); - eiu->fd = NULL; } } exit: - if (eiu->pkgURL != NULL) - for (i = 0; i < eiu->numPkgs; i++) { - if (eiu->pkgURL[i] == NULL) continue; - if (eiu->pkgState[i] == 1) - (void) unlink(eiu->pkgURL[i]); - eiu->pkgURL[i] = _free(eiu->pkgURL[i]); + if (eiu->pkgURL != NULL) { + for (i = 0; i < eiu->numPkgs; i++) { + if (eiu->pkgURL[i] == NULL) continue; + if (eiu->pkgState[i] == 1) + (void) unlink(eiu->pkgURL[i]); + eiu->pkgURL[i] = _free(eiu->pkgURL[i]); + } } eiu->pkgState = _free(eiu->pkgState); eiu->pkgURL = _free(eiu->pkgURL); eiu->argv = _free(eiu->argv); + rc = eiu->numFailed; + free(eiu); rpmtsEmpty(ts); + rpmtsSetVSFlags(ts, ovsflags); - return eiu->numFailed; + return rc; } int rpmErase(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_const_t argv) { - int count; char * const * arg; + char *qfmt = NULL; int numFailed = 0; - int stopUninstall = 0; int numPackages = 0; rpmVSFlags vsflags, ovsflags; - rpmps ps; if (argv == NULL) return 0; - vsflags = rpmExpandNumeric("%{?_vsflags_erase}"); - if (ia->qva_flags & VERIFY_DIGEST) - vsflags |= _RPMVSF_NODIGESTS; - if (ia->qva_flags & VERIFY_SIGNATURE) - vsflags |= _RPMVSF_NOSIGNATURES; - if (ia->qva_flags & VERIFY_HDRCHK) - vsflags |= RPMVSF_NOHDRCHK; + vsflags = setvsFlags(ia); ovsflags = rpmtsSetVSFlags(ts, vsflags); - /* XXX suggest mechanism only meaningful when installing */ - ia->transFlags |= RPMTRANS_FLAG_NOSUGGEST; - (void) rpmtsSetFlags(ts, ia->transFlags); -#ifdef NOTYET /* XXX no callbacks on erase yet */ - { int notifyFlags, xx; - notifyFlags = ia->eraseInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 ); - xx = rpmtsSetNotifyCallback(ts, - rpmShowProgress, (void *) ((long)notifyFlags)); - } -#endif + setNotifyFlag(ia, ts); + qfmt = rpmExpand("%{?_query_all_fmt}\n", NULL); for (arg = argv; *arg; arg++) { - rpmdbMatchIterator mi; + rpmdbMatchIterator mi = rpmtsInitIterator(ts, RPMDBI_LABEL, *arg, 0); + int matches = rpmdbGetIteratorCount(mi); + int erasing = 1; - /* XXX HACK to get rpmdbFindByLabel out of the API */ - mi = rpmtsInitIterator(ts, RPMDBI_LABEL, *arg, 0); - if (mi == NULL) { + if (! matches) { rpmlog(RPMLOG_ERR, _("package %s is not installed\n"), *arg); numFailed++; } else { Header h; /* XXX iterator owns the reference */ - count = 0; - while ((h = rpmdbNextIterator(mi)) != NULL) { - unsigned int recOffset = rpmdbGetIteratorOffset(mi); - if (!(count++ == 0 || (ia->eraseInterfaceFlags & UNINSTALL_ALLMATCHES))) { - rpmlog(RPMLOG_ERR, _("\"%s\" specifies multiple packages\n"), + if (matches > 1 && + !(ia->installInterfaceFlags & UNINSTALL_ALLMATCHES)) { + rpmlog(RPMLOG_ERR, _("\"%s\" specifies multiple packages:\n"), *arg); - numFailed++; - break; - } - if (recOffset) { - (void) rpmtsAddEraseElement(ts, h, recOffset); + numFailed++; + erasing = 0; + } + + while ((h = rpmdbNextIterator(mi)) != NULL) { + if (erasing) { + (void) rpmtsAddEraseElement(ts, h, -1); numPackages++; + } else { + char *nevra = headerFormat(h, qfmt, NULL); + rpmlog(RPMLOG_NOTICE, " %s", nevra); + free(nevra); } } } - mi = rpmdbFreeIterator(mi); + rpmdbFreeIterator(mi); } + free(qfmt); if (numFailed) goto exit; - - if (!(ia->eraseInterfaceFlags & UNINSTALL_NODEPS)) { - - if (rpmtsCheck(ts)) { - numFailed = numPackages; - stopUninstall = 1; - } - - ps = rpmtsProblems(ts); - if (!stopUninstall && rpmpsNumProblems(ps) > 0) { - rpmlog(RPMLOG_ERR, _("Failed dependencies:\n")); - rpmpsPrint(NULL, ps); - numFailed += numPackages; - stopUninstall = 1; - } - ps = rpmpsFree(ps); - } - - if (!stopUninstall && !(ia->installInterfaceFlags & INSTALL_NOORDER)) { - if (rpmtsOrder(ts)) { - numFailed += numPackages; - stopUninstall = 1; - } - } - - if (numPackages && !stopUninstall) { - (void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_REVERSE)); - - /* Drop added/available package indices and dependency sets. */ - rpmtsClean(ts); - - numPackages = rpmtsRun(ts, NULL, ia->probFilter & (RPMPROB_FILTER_DISKSPACE|RPMPROB_FILTER_DISKNODES)); - ps = rpmtsProblems(ts); - if (rpmpsNumProblems(ps) > 0) - rpmpsPrint(NULL, ps); - numFailed += numPackages; - stopUninstall = 1; - ps = rpmpsFree(ps); - } - + numFailed = rpmcliTransaction(ts, ia, numPackages); exit: rpmtsEmpty(ts); + rpmtsSetVSFlags(ts, ovsflags); return numFailed; } @@ -735,15 +702,15 @@ int rpmInstallSource(rpmts ts, const char * arg, return 1; } - if (rpmIsVerbose()) + if (rpmIsVerbose() && specFilePtr != NULL) fprintf(stdout, _("Installing %s\n"), arg); { rpmVSFlags ovsflags = - rpmtsSetVSFlags(ts, (rpmtsVSFlags(ts) | RPMVSF_NEEDPAYLOAD)); + rpmtsSetVSFlags(ts, (specFilePtr) ? (rpmtsVSFlags(ts) | RPMVSF_NEEDPAYLOAD) : rpmtsVSFlags(ts)); rpmRC rpmrc = rpmInstallSourcePackage(ts, fd, specFilePtr, cookie); rc = (rpmrc == RPMRC_OK ? 0 : 1); - ovsflags = rpmtsSetVSFlags(ts, ovsflags); + rpmtsSetVSFlags(ts, ovsflags); } if (rc != 0) { rpmlog(RPMLOG_ERR, _("%s cannot be installed\n"), arg);