- python: explicit method to set transFlags.
authorjbj <devnull@localhost>
Thu, 15 Aug 2002 18:50:46 +0000 (18:50 +0000)
committerjbj <devnull@localhost>
Thu, 15 Aug 2002 18:50:46 +0000 (18:50 +0000)
- 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

CHANGES
lib/query.c
lib/rpminstall.c
lib/rpmts.c
lib/rpmts.h
lib/verify.c
python/rpmts-py.c
rpm.spec.in
rpmdb/header.c
rpmio/macro.c
tools/Makefile.am

diff --git a/CHANGES b/CHANGES
index 336fd5c..ca45ab2 100644 (file)
--- a/CHANGES
+++ b/CHANGES
        - 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).
index e34c483..13799e8 100644 (file)
@@ -589,7 +589,7 @@ restart:
            if (rpmrc == RPMRC_OK) {
                res = qva->qva_showPackage(qva, ts, h);
                h = headerFree(h);
-               rpmtsClean(ts);
+               rpmtsEmpty(ts);
                continue;
            }
 
@@ -944,7 +944,7 @@ int rpmcliQuery(rpmts ts, QVA_t qva, const char ** argv)
        if (argv != NULL)
        while ((arg = *argv++) != NULL) {
            ec += rpmQueryVerify(qva, ts, arg);
-           rpmtsClean(ts);
+           rpmtsEmpty(ts);
        }
 /*@=boundsread@*/
     }
index b6df7d1..7bc2505 100644 (file)
@@ -714,6 +714,8 @@ exit:
     eiu->pkgURL = _free(eiu->pkgURL);
     eiu->argv = _free(eiu->argv);
 
+    rpmtsEmpty(ts);
+
     return eiu->numFailed;
 }
 /*@=bounds@*/
@@ -811,6 +813,8 @@ int rpmErase(rpmts ts,
        ps = rpmpsFree(ps);
     }
 
+    rpmtsEmpty(ts);
+
     return numFailed;
 }
 
@@ -1049,12 +1053,16 @@ int rpmRollback(rpmts ts, struct rpmInstallArguments_s * ia, const char ** argv)
     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;
@@ -1065,7 +1073,7 @@ int rpmRollback(rpmts ts, struct rpmInstallArguments_s * ia, const char ** argv)
     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) {
@@ -1119,12 +1127,14 @@ int rpmRollback(rpmts ts, struct rpmInstallArguments_s * ia, const char ** argv)
        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,
@@ -1152,18 +1162,21 @@ int rpmRollback(rpmts ts, struct rpmInstallArguments_s * ia, const char ** argv)
        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;
@@ -1222,12 +1235,15 @@ int rpmRollback(rpmts ts, struct rpmInstallArguments_s * ia, const char ** argv)
            }
        }
 
+
     } while (1);
 
 exit:
-
     rtids = IDTXfree(rtids);
     itids = IDTXfree(itids);
 
+    rpmtsEmpty(ts);
+    (void) rpmtsSetFlags(ts, transFlags);
+
     return rc;
 }
index da8a956..d06d658 100644 (file)
@@ -546,6 +546,7 @@ void rpmtsCleanDig(rpmts ts)
 void rpmtsClean(rpmts ts)
 {
     rpmtsi pi; rpmte p;
+
     if (ts == NULL)
        return;
 
@@ -566,10 +567,35 @@ void rpmtsClean(rpmts ts)
     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;
 
@@ -579,15 +605,21 @@ rpmts rpmtsFree(rpmts ts)
     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;
@@ -595,25 +627,16 @@ rpmts rpmtsFree(rpmts ts)
     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@*/
 
index d729d7d..1aa882e 100644 (file)
@@ -424,13 +424,20 @@ void rpmtsCleanDig(rpmts ts)
        /*@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
index a586125..fcb7f3a 100644 (file)
@@ -372,7 +372,7 @@ static int verifyDependencies(/*@unused@*/ QVA_t qva, rpmts ts,
     int xx;
     int i;
 
-    rpmtsClean(ts);
+    rpmtsEmpty(ts);
     (void) rpmtsAddInstallElement(ts, h, NULL, 0, NULL);
 
     xx = rpmtsCheck(ts);
@@ -419,7 +419,7 @@ static int verifyDependencies(/*@unused@*/ QVA_t qva, rpmts ts,
 
     ps = rpmpsFree(ps);
 
-    rpmtsClean(ts);
+    rpmtsEmpty(ts);
 
     return rc;
 }
@@ -493,7 +493,7 @@ int rpmcliVerify(rpmts ts, QVA_t qva, const char ** argv)
        if (argv != NULL)
        while ((arg = *argv++) != NULL) {
            ec += rpmQueryVerify(qva, ts, arg);
-           rpmtsClean(ts);
+           rpmtsEmpty(ts);
        }
 /*@=boundsread@*/
     }
@@ -502,5 +502,7 @@ int rpmcliVerify(rpmts ts, QVA_t qva, const char ** argv)
     if (qva->qva_showPackage == showVerifyPackage)
         qva->qva_showPackage = NULL;
 
+    rpmtsEmpty(ts);
+
     return ec;
 }
index 8deac8a..c413f3d 100644 (file)
@@ -105,16 +105,12 @@ static int _rpmts_debug = 0;
  *     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
@@ -130,6 +126,12 @@ static int _rpmts_debug = 0;
  *             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 - 
@@ -929,20 +931,34 @@ rpmtsCallback(/*@unused@*/ const void * hd, const rpmCallbackType what,
                         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;
@@ -984,17 +1000,34 @@ fprintf(stderr, "\t%ld:%ld key %p\n", amount, total, pkgKey);
 
 /** \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;
 
@@ -1010,10 +1043,9 @@ static PyObject * rpmts_Run(rpmtsObject * s, PyObject * args)
        (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);
@@ -1173,6 +1205,10 @@ static struct PyMethodDef rpmts_methods[] = {
        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,
index b166104..efb3308 100644 (file)
@@ -17,7 +17,7 @@ Name: rpm
 %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
@@ -519,8 +519,15 @@ fi
 %{__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.
index ea8aac5..e16782f 100644 (file)
@@ -2507,7 +2507,8 @@ static int parseExpression(sprintfToken token, char * str,
                    &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@*/
@@ -2552,7 +2553,9 @@ static int parseExpression(sprintfToken token, char * str,
                        &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@*/
index 4610555..1498f68 100644 (file)
@@ -1061,6 +1061,8 @@ doFoo(MacroBuf mb, int negate, const char * f, size_t fn,
     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)) {
index 9c62bcf..61e75d4 100644 (file)
@@ -15,7 +15,7 @@ INCLUDES = -I. \
 
 EXTRA_DIST =   rpminject.c rpmsort.c
 
-EXTRA_PROGRAMS = rpminject rpmsort tblob
+EXTRA_PROGRAMS = rpminject rpmsort
 
 LDADD = \
        $(top_builddir)/build/librpmbuild.la \
@@ -48,7 +48,4 @@ rpminject_LDFLAGS =   @LDFLAGS_STATIC@
 rpmsort_SOURCES =      rpmsort.c
 rpmsort_LDFLAGS =      @LDFLAGS_STATIC@
 
-tblob_SOURCES =                tblob.c
-tblob_LDFLAGS =                @LDFLAGS_STATIC@
-
 $(PROGRAMS): $(LDADD)