- python: stuff package name into a string for repackage callbacks.
- rollback: re-create empty transaction set for multiple rollbacks.
- fix: %%basename typo (Dmitry V. Levin<ldv@altlinux.org>).
- fix: queryformat segfaults (Dmitry V. Levin<ldv@altlinux.org>).
CVS patchset: 5639
CVS date: 2002/08/15 18:50:46
- create /var/lib/rpm if non-existent in, say, a chroot.
- erased packages are now repackaged into /var/spool/repackage.
- fix: rebuilddb stat'ed target, not source, for rename sanity, take 2.
+ - python: explicit method to set transFlags.
+ - python: stuff package name into a string for repackage callbacks.
+ - rollback: re-create empty transaction set for multiple rollbacks.
+ - fix: %%basename typo (Dmitry V. Levin<ldv@altlinux.org>).
+ - fix: queryformat segfaults (Dmitry V. Levin<ldv@altlinux.org>).
4.0.3 -> 4.0.4:
- solaris: translate i86pc to i386 (#57182).
if (rpmrc == RPMRC_OK) {
res = qva->qva_showPackage(qva, ts, h);
h = headerFree(h);
- rpmtsClean(ts);
+ rpmtsEmpty(ts);
continue;
}
if (argv != NULL)
while ((arg = *argv++) != NULL) {
ec += rpmQueryVerify(qva, ts, arg);
- rpmtsClean(ts);
+ rpmtsEmpty(ts);
}
/*@=boundsread@*/
}
eiu->pkgURL = _free(eiu->pkgURL);
eiu->argv = _free(eiu->argv);
+ rpmtsEmpty(ts);
+
return eiu->numFailed;
}
/*@=bounds@*/
ps = rpmpsFree(ps);
}
+ rpmtsEmpty(ts);
+
return numFailed;
}
int numAdded;
int numRemoved;
rpmps ps;
+ int _unsafe_rollbacks = 0;
+ rpmtransFlags transFlags = ia->transFlags;
if (argv != NULL && *argv != NULL) {
rc = -1;
goto exit;
}
+ _unsafe_rollbacks = rpmExpandNumeric("%{?_unsafe_rollbacks}");
+
vsflags = rpmExpandNumeric("%{?_vsflags_erase}");
if (ia->qva_flags & VERIFY_DIGEST)
vsflags |= _RPMVSF_NODIGESTS;
vsflags |= RPMVSF_NEEDPAYLOAD; /* XXX no legacy signatures */
ovsflags = rpmtsSetVSFlags(ts, vsflags);
- (void) rpmtsSetFlags(ts, ia->transFlags);
+ (void) rpmtsSetFlags(ts, transFlags);
itids = IDTXload(ts, RPMTAG_INSTALLTID);
if (itids != NULL) {
if (thistid == 0 || thistid < ia->rbtid)
break;
+ rpmtsEmpty(ts);
+ (void) rpmtsSetFlags(ts, transFlags);
+
/* Install the previously erased packages for this transaction. */
while (rp != NULL && rp->val.u32 == thistid) {
-/*@-nullpass@*/ /* FIX: rp->key may be NULL */
- rpmMessage(RPMMESS_DEBUG, "\t+++ %s\n", rp->key);
-/*@=nullpass@*/
+ rpmMessage(RPMMESS_DEBUG, "\t+++ install %s\n",
+ (rp->key ? rp->key : "???"));
/*@-abstract@*/
rc = rpmtsAddInstallElement(ts, rp->h, (fnpyKey)rp->key,
while (ip != NULL && ip->val.u32 == thistid) {
rpmMessage(RPMMESS_DEBUG,
- "\t--- rpmdb instance #%u\n", ip->instance);
+ "\t--- erase h#%u\n", ip->instance);
rc = rpmtsAddEraseElement(ts, ip->h, ip->instance);
if (rc != 0)
goto exit;
numRemoved++;
-#ifdef NOTYET /* XXX don't count erasures yet */
- rpmcliPackagesTotal++;
-#endif
- if (!(ia->installInterfaceFlags & ifmask))
+
+ if (_unsafe_rollbacks)
+ rpmcliPackagesTotal++;
+
+ if (!(ia->installInterfaceFlags & ifmask)) {
ia->installInterfaceFlags |= INSTALL_ERASE;
+ (void) rpmtsSetFlags(ts, (transFlags | RPMTRANS_FLAG_REVERSE));
+ }
#ifdef NOTYET
ip->instance = 0;
}
}
+
} while (1);
exit:
-
rtids = IDTXfree(rtids);
itids = IDTXfree(itids);
+ rpmtsEmpty(ts);
+ (void) rpmtsSetFlags(ts, transFlags);
+
return rc;
}
void rpmtsClean(rpmts ts)
{
rpmtsi pi; rpmte p;
+
if (ts == NULL)
return;
rpmtsCleanDig(ts);
}
+void rpmtsEmpty(rpmts ts)
+{
+ rpmtsi pi; rpmte p;
+ int oc;
+
+ if (ts == NULL)
+ return;
+
+/*@-nullstate@*/ /* FIX: partial annotations */
+ rpmtsClean(ts);
+/*@=nullstate@*/
+
+ for (pi = rpmtsiInit(ts), oc = 0; (p = rpmtsiNext(pi, 0)) != NULL; oc++) {
+/*@-type -unqualifiedtrans @*/
+ ts->order[oc] = rpmteFree(ts->order[oc]);
+/*@=type =unqualifiedtrans @*/
+ }
+ pi = rpmtsiFree(pi);
+
+ ts->orderCount = 0;
+
+ ts->numRemovedPackages = 0;
+}
+
rpmts rpmtsFree(rpmts ts)
{
rpmtsi pi; rpmte p;
int oc;
+
if (ts == NULL)
return NULL;
if (ts->nrefs > 0)
return NULL;
+/*@-nullstate@*/ /* FIX: partial annotations */
+ rpmtsEmpty(ts);
+/*@=nullstate@*/
+
(void) rpmtsCloseDB(ts);
(void) rpmtsCloseSDB(ts);
+ ts->removedPackages = _free(ts->removedPackages);
+
ts->availablePackages = rpmalFree(ts->availablePackages);
ts->numAvailablePackages = 0;
ts->dsi = _free(ts->dsi);
- ts->removedPackages = _free(ts->removedPackages);
+
if (ts->scriptFd != NULL) {
ts->scriptFd = fdFree(ts->scriptFd, "rpmtsFree");
ts->scriptFd = NULL;
ts->rootDir = _free(ts->rootDir);
ts->currDir = _free(ts->currDir);
- for (pi = rpmtsiInit(ts), oc = 0; (p = rpmtsiNext(pi, 0)) != NULL; oc++) {
-/*@-type -unqualifiedtrans @*/
- ts->order[oc] = rpmteFree(ts->order[oc]);
-/*@=type =unqualifiedtrans @*/
- }
- pi = rpmtsiFree(pi);
/*@-type +voidabstract @*/ /* FIX: double indirection */
ts->order = _free(ts->order);
/*@=type =voidabstract @*/
+ ts->orderAlloced = 0;
if (ts->pkpkt != NULL)
ts->pkpkt = _free(ts->pkpkt);
ts->pkpktlen = 0;
memset(ts->pksignid, 0, sizeof(ts->pksignid));
-/*@-nullstate@*/ /* FIX: partial annotations */
- rpmtsClean(ts);
-/*@=nullstate@*/
-
/*@-refcounttrans@*/ ts = _free(ts); /*@=refcounttrans@*/
/*@=usereleased@*/
/*@modifies ts @*/;
/** \ingroup rpmts
- * Re-create an empty transaction set.
+ * Free memory needed only for dependency checks and ordering.
* @param ts transaction set
*/
void rpmtsClean(rpmts ts)
/*@modifies ts @*/;
/** \ingroup rpmts
+ * Re-create an empty transaction set.
+ * @param ts transaction set
+ */
+void rpmtsEmpty(rpmts ts)
+ /*@modifies ts @*/;
+
+/** \ingroup rpmts
* Destroy transaction set, closing the database as well.
* @param ts transaction set
* @return NULL always
int xx;
int i;
- rpmtsClean(ts);
+ rpmtsEmpty(ts);
(void) rpmtsAddInstallElement(ts, h, NULL, 0, NULL);
xx = rpmtsCheck(ts);
ps = rpmpsFree(ps);
- rpmtsClean(ts);
+ rpmtsEmpty(ts);
return rc;
}
if (argv != NULL)
while ((arg = *argv++) != NULL) {
ec += rpmQueryVerify(qva, ts, arg);
- rpmtsClean(ts);
+ rpmtsEmpty(ts);
}
/*@=boundsread@*/
}
if (qva->qva_showPackage == showVerifyPackage)
qva->qva_showPackage = NULL;
+ rpmtsEmpty(ts);
+
return ec;
}
* rpm.RPMDEP_SENSE_REQUIRES are set to show a dependency as a
* requirement or a conflict.
*
- * - order() Do a topological sort of added element relations.
+ * - ts.order() Do a topological sort of added element relations.
* @return None
*
- * - run(flags,problemSetFilter,callback,data) Attempt to execute a
- * transaction set. After the transaction set has been populated
- * with install and upgrade actions, it can be executed by invoking
- * the run() method.
- * @param flags - modifies the behavior of the transaction set as it is
- * processed. The following values can be locical ORed
- * together:
+ * - ts.setFlags(transFlags) Set transaction set flags.
+ * @param transFlags - bit(s) to controll transaction operations. The
+ * following values can be logically OR'ed together:
* - rpm.RPMTRANS_FLAG_TEST - test mode, do not modify the RPM
* database, change any files, or run any package scripts
* - rpm.RPMTRANS_FLAG_BUILD_PROBS - only build a list of
* being performed.
* - rpm.RPMTRANS_FLAG_KEEPOBSOLETE - do not remove obsoleted
* packages.
+ * @return previous transFlags
+ *
+ * - run(problemSetFilter,callback,data) Attempt to execute a
+ * transaction set. After the transaction set has been populated
+ * with install and upgrade actions, it can be executed by invoking
+ * the run() method.
* @param problemSetFilter - control bit(s) to ignore classes of problems,
* any of
* - rpm.RPMPROB_FILTER_IGNOREOS -
const void * pkgKey, rpmCallbackData data)
/*@*/
{
+ Header h = (Header) hd;
struct rpmtsCallbackType_s * cbInfo = data;
+ PyObject * pkgObj = (PyObject *) pkgKey;
PyObject * args, * result;
static FD_t fd;
if (cbInfo->pythonError) return NULL;
if (cbInfo->cb == Py_None) return NULL;
- if (!pkgKey) pkgKey = Py_None;
+ /* Synthesize a python object for callback (if necessary). */
+ if (pkgObj == NULL) {
+ if (h) {
+ const char * n = NULL;
+ (void) headerNVR(h, &n, NULL, NULL);
+ pkgObj = Py_BuildValue("s", n);
+ } else {
+ pkgObj = Py_None;
+ Py_INCREF(pkgObj);
+ }
+ } else
+ Py_INCREF(pkgObj);
PyEval_RestoreThread(cbInfo->_save);
- args = Py_BuildValue("(illOO)", what, amount, total, pkgKey, cbInfo->data);
+ args = Py_BuildValue("(illOO)", what, amount, total, pkgObj, cbInfo->data);
result = PyEval_CallObject(cbInfo->cb, args);
Py_DECREF(args);
+ Py_DECREF(pkgObj);
if (!result) {
cbInfo->pythonError = 1;
/** \ingroup python
*/
+static PyObject * rpmts_SetFlags(rpmtsObject * s, PyObject * args)
+ /*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
+ /*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
+{
+ rpmtransFlags transFlags = 0;
+
+ if (!PyArg_ParseTuple(args, "i:SetFlags", &transFlags))
+ return NULL;
+
+if (_rpmts_debug)
+fprintf(stderr, "*** rpmts_SetFlags(%p) ts %p transFlags %x\n", s, s->ts, transFlags);
+
+ return Py_BuildValue("i", rpmtsSetFlags(s->ts, transFlags));
+}
+
+/** \ingroup python
+ */
static PyObject * rpmts_Run(rpmtsObject * s, PyObject * args)
/*@globals rpmGlobalMacroContext, _Py_NoneStruct @*/
/*@modifies s, rpmGlobalMacroContext, _Py_NoneStruct @*/
{
- int flags, ignoreSet;
+ int ignoreSet;
int rc, i;
PyObject * list;
rpmps ps;
struct rpmtsCallbackType_s cbInfo;
- if (!PyArg_ParseTuple(args, "iiOO:Run", &flags, &ignoreSet, &cbInfo.cb,
+ if (!PyArg_ParseTuple(args, "iOO:Run", &ignoreSet, &cbInfo.cb,
&cbInfo.data))
return NULL;
(void) rpmtsSetNotifyCallback(s->ts, rpmtsCallback, (void *) &cbInfo);
}
- (void) rpmtsSetFlags(s->ts, flags);
if (_rpmts_debug)
-fprintf(stderr, "*** rpmts_Run(%p) ts %p flags %x ignore %x\n", s, s->ts, s->ts->transFlags, ignoreSet);
+fprintf(stderr, "*** rpmts_Run(%p) ts %p ignore %x\n", s, s->ts, ignoreSet);
rc = rpmtsRun(s->ts, NULL, ignoreSet);
ps = rpmtsProblems(s->ts);
NULL },
{"order", (PyCFunction) rpmts_Order, METH_VARARGS,
NULL },
+ {"setFlags", (PyCFunction) rpmts_SetFlags, METH_VARARGS,
+"ts.setFlags(transFlags) -> previous transFlags\n\
+- Set control bit(s) for processing a transaction set.\n\
+ Note: This method sets bit(s) passed as the first argument to ts.run()\n" },
{"run", (PyCFunction) rpmts_Run, METH_VARARGS,
NULL },
{"clean", (PyCFunction) rpmts_Clean, METH_VARARGS,
%define version @VERSION@
Version: %{version}
%{expand: %%define rpm_version %{version}}
-Release: 0.80
+Release: 0.81
Group: System Environment/Base
Source: ftp://ftp.rpm.org/pub/rpm/dist/rpm-4.0.x/rpm-%{rpm_version}.tar.gz
Copyright: GPL
%{__prefix}/include/popt.h
%changelog
+* Thu Aug 15 2002 Jeff Johnson <jbj@redhat.com> 4.1-0.81
+- rollback: re-create empty transaction set for multiple rollbacks.
+- fix: %%basename typo (Dmitry V. Levin<ldv@altlinux.org>).
+- fix: queryformat segfaults (Dmitry V. Levin<ldv@altlinux.org>).
+
* Wed Aug 14 2002 Jeff Johnson <jbj@redhat.com> 4.1-0.80
- fix: rebuilddb stat'ed target, not source, for rename sanity, take 2.
+- python: explicit method to set transFlags.
+- python: stuff package name into a string for repackage/erase callbacks.
* Tue Aug 13 2002 Jeff Johnson <jbj@redhat.com> 4.1-0.79
- supply transitive closure for CLI packages from rpmdb-redhat database.
&token->u.cond.numIfTokens, &end, PARSER_IN_EXPR, errmsg))
return 1;
- if (!*end) {
+ /* XXX fix segfault on "rpm -q rpm --qf='%|NAME?{%}:{NAME}|\n'"*/
+ if (!(end && *end)) {
/*@-observertrans -readonlytrans@*/
if (errmsg) *errmsg = _("} expected in expression");
/*@=observertrans =readonlytrans@*/
&token->u.cond.numElseTokens, &end, PARSER_IN_EXPR,
errmsg))
return 1;
- if (!*end) {
+
+ /* XXX fix segfault on "rpm -q rpm --qf='%|NAME?{a}:{%}|{NAME}\n'" */
+ if (!(end && *end)) {
/*@-observertrans -readonlytrans@*/
if (errmsg) *errmsg = _("} expected in expression");
/*@=observertrans =readonlytrans@*/
if (STREQ("basename", f, fn)) {
if ((b = strrchr(buf, '/')) == NULL)
b = buf;
+ else
+ b++;
#if NOTYET
/* XXX watchout for conflict with %dir */
} else if (STREQ("dirname", f, fn)) {
EXTRA_DIST = rpminject.c rpmsort.c
-EXTRA_PROGRAMS = rpminject rpmsort tblob
+EXTRA_PROGRAMS = rpminject rpmsort
LDADD = \
$(top_builddir)/build/librpmbuild.la \
rpmsort_SOURCES = rpmsort.c
rpmsort_LDFLAGS = @LDFLAGS_STATIC@
-tblob_SOURCES = tblob.c
-tblob_LDFLAGS = @LDFLAGS_STATIC@
-
$(PROGRAMS): $(LDADD)