/* Add erase elements for older packages of same color (if any). */ static int addSelfErasures(rpmts ts, rpm_color_t tscolor, int op, rpmte p, rpm_color_t hcolor, Header h) { Header oh; rpmdbMatchIterator mi = rpmtsInitIterator(ts, RPMDBI_NAME, rpmteN(p), 0); int rc = 0; int cmp; while((oh = rpmdbNextIterator(mi)) != NULL) { /* Ignore colored packages not in our rainbow. */ if (skipColor(tscolor, hcolor, headerGetNumber(oh, RPMTAG_HEADERCOLOR))) continue; cmp = rpmVersionCompare(h, oh); /* On upgrade, skip packages that contain identical NEVR. */ if ((op == RPMTE_UPGRADE) && (cmp == 0)) continue; /* On reinstall, skip packages with differing NEVR. */ if ((op == RPMTE_REINSTALL) && (cmp != 0)) continue; if (removePackage(ts, oh, p)) { rc = 1; break; } } rpmdbFreeIterator(mi); return rc; }
struct RpmHeadersDiff * rpmhdrs_diff (struct RpmHeaders *l1, struct RpmHeaders *l2) { int n1 = 0; int n2 = 0; struct RpmHeadersDiff *ret = rpmhdrs_diff_new (); while (n1 < l1->hs->len) { Header h1 = l1->hs->pdata[n1]; if (n2 >= l2->hs->len) { g_ptr_array_add (ret->hs_del, h1); ++n1; } else { Header h2 = l2->hs->pdata[n2]; int cmp = header_name_cmp (h1, h2); if (cmp > 0) { g_ptr_array_add (ret->hs_add, h2); ++n2; } else if (cmp < 0) { g_ptr_array_add (ret->hs_del, h1); ++n1; } else { cmp = rpmVersionCompare (h1, h2); if (!cmp) { ++n1; ++n2; continue; } g_ptr_array_add (ret->hs_mod_old, h1); ++n1; g_ptr_array_add (ret->hs_mod_new, h2); ++n2; } } } while (n2 < l2->hs->len) { Header h2 = l2->hs->pdata[n2]; g_ptr_array_add (ret->hs_add, h2); ++n2; } return ret; }
PyObject * versionCompare (PyObject * self, PyObject * args, PyObject * kwds) { hdrObject * h1, * h2; char * kwlist[] = {"version0", "version1", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O!", kwlist, &hdr_Type, &h1, &hdr_Type, &h2)) return NULL; return Py_BuildValue("i", rpmVersionCompare(h1->h, h2->h)); }
static int header_cmp_p (gconstpointer gph1, gconstpointer gph2) { const Header *ph1 = gph1; const Header *ph2 = gph2; Header h1 = *ph1; Header h2 = *ph2; int cmp = header_name_cmp (h1, h2); if (!cmp) cmp = rpmVersionCompare (h1, h2); return cmp; }
/* 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); }
/* Add erase elements for older packages of same color (if any). */ static int addUpgradeErasures(rpmts ts, rpm_color_t tscolor, rpmte p, rpm_color_t hcolor, Header h) { Header oh; rpmdbMatchIterator mi = rpmtsInitIterator(ts, RPMDBI_NAME, rpmteN(p), 0); int rc = 0; while((oh = rpmdbNextIterator(mi)) != NULL) { /* Ignore colored packages not in our rainbow. */ if (skipColor(tscolor, hcolor, headerGetNumber(oh, RPMTAG_HEADERCOLOR))) continue; /* Skip packages that contain identical NEVR. */ if (rpmVersionCompare(h, oh) == 0) continue; if (removePackage(ts, oh, p)) { rc = 1; break; } } rpmdbFreeIterator(mi); return rc; }
/** @todo Generalize --freshen policies. */ int rpmInstall(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_t fileArgv) { struct rpmEIU * eiu = xcalloc(1, sizeof(*eiu)); rpmps ps; rpmprobFilterFlags probFilter; rpmRelocation * relocations; char * fileURL = NULL; int stopInstall = 0; rpmVSFlags vsflags, ovsflags, tvsflags; int rc; int xx; int i; if (fileArgv == NULL) goto exit; rpmcliPackagesTotal = 0; (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)); } if ((eiu->relocations = relocations) != NULL) { while (eiu->relocations->oldPath) eiu->relocations++; if (eiu->relocations->newPath == NULL) eiu->relocations = NULL; } /* Build fully globbed list of arguments in argv[argc]. */ for (eiu->fnp = fileArgv; *eiu->fnp != NULL; eiu->fnp++) { ARGV_t av = NULL; int ac = 0; char * fn; fn = rpmEscapeSpaces(*eiu->fnp); rc = rpmGlob(fn, &ac, &av); fn = _free(fn); if (rc || ac == 0) { rpmlog(RPMLOG_ERR, _("File not found by glob: %s\n"), *eiu->fnp); eiu->numFailed++; continue; } argvAppend(&(eiu->argv), av); argvFree(av); eiu->argc += ac; } restart: /* Allocate sufficient storage for next set of args. */ if (eiu->pkgx >= eiu->numPkgs) { eiu->numPkgs = eiu->pkgx + eiu->argc; eiu->pkgURL = xrealloc(eiu->pkgURL, (eiu->numPkgs + 1) * sizeof(*eiu->pkgURL)); memset(eiu->pkgURL + eiu->pkgx, 0, ((eiu->argc + 1) * sizeof(*eiu->pkgURL))); eiu->pkgState = xrealloc(eiu->pkgState, (eiu->numPkgs + 1) * sizeof(*eiu->pkgState)); memset(eiu->pkgState + eiu->pkgx, 0, ((eiu->argc + 1) * sizeof(*eiu->pkgState))); } /* Retrieve next set of args, cache on local storage. */ for (i = 0; i < eiu->argc; i++) { fileURL = _free(fileURL); fileURL = eiu->argv[i]; eiu->argv[i] = NULL; switch (urlIsURL(fileURL)) { case URL_IS_HTTPS: case URL_IS_HTTP: case URL_IS_FTP: { char *tfn; FD_t tfd; if (rpmIsVerbose()) fprintf(stdout, _("Retrieving %s\n"), fileURL); tfd = rpmMkTempFile(rpmtsRootDir(ts), &tfn); if (tfd && tfn) { Fclose(tfd); rc = urlGetFile(fileURL, tfn); } else { rc = -1; } if (rc != 0) { rpmlog(RPMLOG_ERR, _("skipping %s - transfer failed\n"), fileURL); eiu->numFailed++; eiu->pkgURL[eiu->pkgx] = NULL; tfn = _free(tfn); break; } eiu->pkgState[eiu->pkgx] = 1; eiu->pkgURL[eiu->pkgx] = tfn; eiu->pkgx++; } break; case URL_IS_PATH: case URL_IS_DASH: /* WRONG WRONG WRONG */ case URL_IS_HKP: /* WRONG WRONG WRONG */ default: eiu->pkgURL[eiu->pkgx] = fileURL; fileURL = NULL; eiu->pkgx++; break; } } fileURL = _free(fileURL); if (eiu->numFailed) goto exit; /* Continue processing file arguments, building transaction set. */ for (eiu->fnp = eiu->pkgURL+eiu->prevx; *eiu->fnp != NULL; eiu->fnp++, eiu->prevx++) { 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; 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; } eiu->isSource = headerIsSource(eiu->h); if (eiu->isSource) { rpmlog(RPMLOG_DEBUG, "\tadded source package [%d]\n", eiu->numSRPMS); eiu->sourceURL = xrealloc(eiu->sourceURL, (eiu->numSRPMS + 2) * sizeof(*eiu->sourceURL)); eiu->sourceURL[eiu->numSRPMS] = *eiu->fnp; *eiu->fnp = NULL; eiu->numSRPMS++; eiu->sourceURL[eiu->numSRPMS] = NULL; continue; } if (eiu->relocations) { struct rpmtd_s prefixes; headerGet(eiu->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); 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; } 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, (ia->installInterfaceFlags & INSTALL_UPGRADE) != 0, relocations); /* XXX reference held by transaction set */ eiu->h = headerFree(eiu->h); if (eiu->relocations) eiu->relocations->oldPath = _free(eiu->relocations->oldPath); switch(rc) { case 0: rpmlog(RPMLOG_DEBUG, "\tadded binary package [%d]\n", eiu->numRPMS); break; case 1: rpmlog(RPMLOG_ERR, _("error reading from file %s\n"), *eiu->fnp); 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; break; } 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_ERR, _("%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", eiu->numSRPMS, eiu->numRPMS); 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; } 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->numSRPMS && !stopInstall) { if (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++; } 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]); } eiu->pkgState = _free(eiu->pkgState); eiu->pkgURL = _free(eiu->pkgURL); eiu->argv = _free(eiu->argv); rc = eiu->numFailed; free(eiu); rpmtsEmpty(ts); return rc; }
void rpmhdrs_diff_prnt_block (gboolean changelogs, struct RpmHeadersDiff *diff) { int num = 0; g_assert (diff->hs_mod_old->len == diff->hs_mod_new->len); if (diff->hs_mod_old->len) { gboolean done = FALSE; for (num = 0; num < diff->hs_mod_new->len; ++num) { Header ho = diff->hs_mod_old->pdata[num]; Header hn = diff->hs_mod_new->pdata[num]; struct rpmtd_s ochanges_date_s; _cleanup_rpmtddata_ rpmtd ochanges_date = NULL; struct rpmtd_s ochanges_name_s; _cleanup_rpmtddata_ rpmtd ochanges_name = NULL; struct rpmtd_s ochanges_text_s; _cleanup_rpmtddata_ rpmtd ochanges_text = NULL; struct rpmtd_s nchanges_date_s; _cleanup_rpmtddata_ rpmtd nchanges_date = NULL; struct rpmtd_s nchanges_name_s; _cleanup_rpmtddata_ rpmtd nchanges_name = NULL; struct rpmtd_s nchanges_text_s; _cleanup_rpmtddata_ rpmtd nchanges_text = NULL; int ocnum = 0; int ncnum = 0; uint64_t ochange_date = 0; const char *ochange_name = NULL; const char *ochange_text = NULL; uint64_t nchange_date = 0; const char *nchange_name = NULL; const char *nchange_text = NULL; g_assert (!header_name_cmp (ho, hn)); if (rpmVersionCompare (ho, hn) > 0) continue; if (!done) { done = TRUE; g_print ("Upgraded:\n"); } printf (" "); pkg_print (hn); if (!changelogs) continue; /* Load the old %changelog entries */ ochanges_date = &ochanges_date_s; headerGet (ho, RPMTAG_CHANGELOGTIME, ochanges_date, HEADERGET_MINMEM); ochanges_name = &ochanges_name_s; headerGet (ho, RPMTAG_CHANGELOGNAME, ochanges_name, HEADERGET_MINMEM); ochanges_text = &ochanges_text_s; headerGet (ho, RPMTAG_CHANGELOGTEXT, ochanges_text, HEADERGET_MINMEM); ocnum = rpmtdCount (ochanges_date); if (!ocnum) continue; /* Load the new %changelog entries */ nchanges_date = &nchanges_date_s; headerGet (hn, RPMTAG_CHANGELOGTIME, nchanges_date, HEADERGET_MINMEM); nchanges_name = &nchanges_name_s; headerGet (hn, RPMTAG_CHANGELOGNAME, nchanges_name, HEADERGET_MINMEM); nchanges_text = &nchanges_text_s; headerGet (hn, RPMTAG_CHANGELOGTEXT, nchanges_text, HEADERGET_MINMEM); ncnum = rpmtdCount (nchanges_date); if (!ncnum) continue; /* Load the latest old %changelog entry. */ ochange_date = rpmtdGetNumber (ochanges_date); ochange_name = rpmtdGetString (ochanges_name); ochange_text = rpmtdGetString (ochanges_text); while (ncnum > 0) { GDateTime *dt = NULL; g_autofree char *date_time_str = NULL; /* Load next new %changelog entry, starting at the newest. */ rpmtdNext (nchanges_date); rpmtdNext (nchanges_name); rpmtdNext (nchanges_text); nchange_date = rpmtdGetNumber (nchanges_date); nchange_name = rpmtdGetString (nchanges_name); nchange_text = rpmtdGetString (nchanges_text); /* If we are now older than, or match, the latest old %changelog * then we are done. */ if (ochange_date > nchange_date) break; if ((ochange_date == nchange_date) && g_str_equal (ochange_name, nchange_name) && g_str_equal (ochange_text, nchange_text)) break; /* Otherwise, print. */ dt = g_date_time_new_from_unix_utc (nchange_date); date_time_str = g_date_time_format (dt, "%a %b %d %Y"); g_date_time_unref (dt); printf ("* %s %s\n%s\n\n", date_time_str, nchange_name, nchange_text); --ncnum; } } done = FALSE; for (num = 0; num < diff->hs_mod_new->len; ++num) { Header ho = diff->hs_mod_old->pdata[num]; Header hn = diff->hs_mod_new->pdata[num]; g_assert (!header_name_cmp (ho, hn)); if (rpmVersionCompare (ho, hn) < 0) continue; if (!done) { done = TRUE; g_print ("Downgraded:\n"); } printf (" "); pkg_print (hn); } } if (diff->hs_del->len) { g_print ("Removed:\n"); for (num = 0; num < diff->hs_del->len; ++num) { Header hd = diff->hs_del->pdata[num]; printf (" "); pkg_print (hd); } } if (diff->hs_add->len) { g_print ("Added:\n"); for (num = 0; num < diff->hs_add->len; ++num) { Header ha = diff->hs_add->pdata[num]; printf (" "); pkg_print (ha); } } rpmhdrs_diff_free (diff); }