- expose rpmShowProgress() and rpmVerifyDigest() in rpmcli.h.
authorjbj <devnull@localhost>
Fri, 6 Jul 2001 20:37:42 +0000 (20:37 +0000)
committerjbj <devnull@localhost>
Fri, 6 Jul 2001 20:37:42 +0000 (20:37 +0000)
- portability: avoid st_mtime, gendiff uses basename, etc (#47497).
- glibc-2.0.x has not __va_copy().
- popthelp.c: static copy of stpcpy/stpncpy for the deprived (#47500).

CVS patchset: 4921
CVS date: 2001/07/06 20:37:42

20 files changed:
CHANGES
build.c
build/pack.c
gendiff
lib/Makefile.am
lib/depends.c
lib/fsm.c
lib/header.h
lib/poptI.c
lib/psm.c
lib/rpmcli.h
lib/rpminstall.c
lib/rpmlib.h
lib/verify.c
rpm.spec.in
rpmdb/rpmdb.c
rpmio/rpmlog.c
rpmio/tdigest.c
rpmqv.c
tests/Makefile.am

diff --git a/CHANGES b/CHANGES
index c792c04..373c025 100644 (file)
--- a/CHANGES
+++ b/CHANGES
        - fix: sanity check for header size added in headerCopyLoad() (#46469).
        - fix: redundant entries in file manifests handled correctly (#46914).
        - map uid/gid from metadata into payload headers.
+       - add removetid to header during --repackage.
+       - expose rpmShowProgress() and rpmVerifyDigest() in rpmcli.h.
+       - portability: avoid st_mtime, gendiff uses basename, etc (#47497).
+       - glibc-2.0.x has not __va_copy().
+       - popthelp.c: static copy of stpcpy/stpncpy for the deprived (#47500).
 
 4.0 -> 4.0.[12]
        - add doxygen and lclint annotations most everywhere.
diff --git a/build.c b/build.c
index 87258df..3dd44cf 100644 (file)
--- a/build.c
+++ b/build.c
@@ -49,8 +49,7 @@ static int checkSpec(Header h)
        rc = 1;
     }
 
-    if (ts != NULL)
-       rpmtransFree(ts);
+    ts = rpmtransFree(ts);
     if (db != NULL)
        (void) rpmdbClose(db);
 
index 6ebb7b9..a506f6b 100644 (file)
@@ -85,7 +85,7 @@ static int cpio_doio(FD_t fdo, /*@unused@*/ Header h, CSA_t csa,
 
     failedFile = _free(failedFile);
     fmode = _free(fmode);
-    rpmtransFree(ts);
+    ts = rpmtransFree(ts);
 
     return rc;
 }
diff --git a/gendiff b/gendiff
index a90f6e4..c00ce51 100644 (file)
--- a/gendiff
+++ b/gendiff
@@ -9,6 +9,6 @@
 find $1 \( -name "*$2" -o -name ".*$2" \) -print |
 while read f; do
     U=-u
-    [ "${f##*/}" = "ChangeLog$2" ] && U=-U0
+    [ "`basename $f`" = "ChangeLog$2" ] && U=-U0
     diff ${U} $f `echo $f | sed s/$2\$//`
 done
index b7f6b35..83a3b74 100644 (file)
@@ -95,3 +95,6 @@ lclint:
 
 th: th.c librpm.la
        $(CC) $(CFLAGS) $(DEFS) $(INCLUDES) -o $@ $< $(mylibpaths) $(mylibs) $(LIBS)
+
+trb: trb.o librpm.la
+       $(LINK) @LDFLAGS_STATIC@ $(CFLAGS) $(DEFS) $(INCLUDES) -o $@ trb.o $(mylibs) $(LIBS)
index a664493..2517765 100644 (file)
@@ -753,8 +753,9 @@ static int intcmp(const void * a, const void * b)   /*@*/
  * @param ts           transaction set
  * @param dboffset     rpm database instance
  * @param depends      installed package of pair (or -1 on erase)
+ * @return             0 on success
  */
-static void removePackage(rpmTransactionSet ts, int dboffset, int depends)
+static int removePackage(rpmTransactionSet ts, int dboffset, int depends)
        /*@modifies ts @*/
 {
 
@@ -762,7 +763,7 @@ static void removePackage(rpmTransactionSet ts, int dboffset, int depends)
     if (ts->numRemovedPackages > 0 && ts->removedPackages != NULL) {
        if (bsearch(&dboffset, ts->removedPackages, ts->numRemovedPackages,
                        sizeof(int), intcmp) != NULL)
-           return;
+           return 0;
     }
 
     if (ts->numRemovedPackages == ts->allocedRemovedPackages) {
@@ -784,6 +785,8 @@ static void removePackage(rpmTransactionSet ts, int dboffset, int depends)
     ts->order[ts->orderCount].type = TR_REMOVED;
     ts->order[ts->orderCount].u.removed.dboffset = dboffset;
     ts->order[ts->orderCount++].u.removed.dependsOnIndex = depends;
+
+    return 0;
 }
 
 int rpmtransAddPackage(rpmTransactionSet ts, Header h, FD_t fd,
@@ -831,7 +834,7 @@ int rpmtransAddPackage(rpmTransactionSet ts, Header h, FD_t fd,
        mi = rpmdbInitIterator(ts->rpmdb, RPMTAG_NAME, name, 0);
        while((h2 = rpmdbNextIterator(mi)) != NULL) {
            if (rpmVersionCompare(h, h2))
-               removePackage(ts, rpmdbGetIteratorOffset(mi), alNum);
+               (void) removePackage(ts, rpmdbGetIteratorOffset(mi), alNum);
            else {
                uint_32 *p, multiLibMask = 0, oldmultiLibMask = 0;
 
@@ -881,7 +884,7 @@ int rpmtransAddPackage(rpmTransactionSet ts, Header h, FD_t fd,
                    headerMatchesDepFlags(h2,
                        obsoletes[j], obsoletesEVR[j], obsoletesFlags[j]))
                {
-                   removePackage(ts, rpmdbGetIteratorOffset(mi), alNum);
+                   (void) removePackage(ts, rpmdbGetIteratorOffset(mi), alNum);
                }
            }
            mi = rpmdbFreeIterator(mi);
@@ -901,24 +904,28 @@ void rpmtransAvailablePackage(rpmTransactionSet ts, Header h, const void * key)
     al = alAddPackage(&ts->availablePackages, h, key, NULL, NULL);
 }
 
-void rpmtransRemovePackage(rpmTransactionSet ts, int dboffset)
+int rpmtransRemovePackage(rpmTransactionSet ts, int dboffset)
 {
-    removePackage(ts, dboffset, -1);
+    return removePackage(ts, dboffset, -1);
 }
 
-void rpmtransFree(rpmTransactionSet ts)
+rpmTransactionSet rpmtransFree(rpmTransactionSet ts)
 {
-    alFree(&ts->addedPackages);
-    alFree(&ts->availablePackages);
-    ts->di = _free(ts->di);
-    ts->removedPackages = _free(ts->removedPackages);
-    ts->order = _free(ts->order);
-    if (ts->scriptFd != NULL)
-       ts->scriptFd = fdFree(ts->scriptFd, "rpmtransSetScriptFd (rpmtransFree");
-    ts->rootDir = _free(ts->rootDir);
-    ts->currDir = _free(ts->currDir);
-
-    ts = _free(ts);
+    if (ts) {
+       alFree(&ts->addedPackages);
+       alFree(&ts->availablePackages);
+       ts->di = _free(ts->di);
+       ts->removedPackages = _free(ts->removedPackages);
+       ts->order = _free(ts->order);
+       if (ts->scriptFd != NULL)
+           ts->scriptFd =
+               fdFree(ts->scriptFd, "rpmtransSetScriptFd (rpmtransFree");
+       ts->rootDir = _free(ts->rootDir);
+       ts->currDir = _free(ts->currDir);
+
+       ts = _free(ts);
+    }
+    return NULL;
 }
 
 rpmDependencyConflict rpmdepFreeConflicts(rpmDependencyConflict conflicts,
index a938f6e..30947b4 100644 (file)
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -1697,12 +1697,12 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
                if (!rc)
                    rc = fsmStage(fsm, FSM_CHMOD);
                if (!rc) {
-                   time_t st_mtime = st->st_mtime;
+                   time_t mtime = st->st_mtime;
                    TFI_t fi = fsmGetFi(fsm);
                    if (fi->fmtimes)
                        st->st_mtime = fi->fmtimes[fsm->ix];
                    rc = fsmStage(fsm, FSM_UTIME);
-                   st->st_mtime = st_mtime;
+                   st->st_mtime = mtime;
                }
            }
        }
index f45d33f..52e97dc 100644 (file)
@@ -143,8 +143,8 @@ enum headerSprintfExtenstionType {
 
 /** \ingroup header
  * HEADER_EXT_TAG format function prototype.
- * This will only ever be passed RPM_TYPE_INT32 or RPM_TYPE_STRING to
- * help keep things simple
+ * This will only ever be passed RPM_INT32_TYPE or RPM_STRING_TYPE to
+ * help keep things simple.
  *
  * @param type         tag type
  * @param data         tag value
index 1b411a6..eca9ad5 100644 (file)
@@ -9,10 +9,15 @@
 
 #include "debug.h"
 
+/*@-redecl@*/
+extern time_t get_date(const char * p, void * now);    /* XXX expedient lies */
+/*@=redecl@*/
+
 struct rpmInstallArguments_s rpmIArgs;
 
 #define        POPT_RELOCATE           1016
 #define        POPT_EXCLUDEPATH        1019
+#define        POPT_ROLLBACK           1024
 
 /*@exits@*/ static void argerror(const char * desc)
        /*@modifies fileSystem @*/
@@ -21,6 +26,7 @@ struct rpmInstallArguments_s rpmIArgs;
     exit(EXIT_FAILURE);
 
 }
+
 /**
  */
 static void installArgCallback( /*@unused@*/ poptContext con,
@@ -62,6 +68,13 @@ static void installArgCallback( /*@unused@*/ poptContext con,
        /*@=kepttrans@*/
        ia->numRelocations++;
       }        break;
+    case POPT_ROLLBACK:
+      {        time_t tid;
+       tid = get_date(arg, NULL);
+       if (tid == (time_t)-1)
+           argerror(_("malformed rollback time"));
+       ia->rbtid = tid;
+      }        break;
     }
 }
 
@@ -185,6 +198,9 @@ struct poptOption rpmInstallPoptTable[] = {
  { "replacepkgs", '\0', POPT_BIT_SET,
        &rpmIArgs.probFilter, RPMPROB_FILTER_REPLACEPKG,
        N_("reinstall if the package is already present"), NULL},
+ { "rollback", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_ROLLBACK,
+       N_("deinstall new package(s), reinstall old package(s), back to date"),
+       N_("<date>") },
  { "test", '\0', POPT_BIT_SET, &rpmIArgs.transFlags, RPMTRANS_FLAG_TEST,
        N_("don't install, but tell if it would work or not"), NULL},
  { "upgrade", 'U', POPT_BIT_SET,
index 5d5ed68..b0f1f30 100644 (file)
--- a/lib/psm.c
+++ b/lib/psm.c
@@ -765,8 +765,7 @@ exit:
        freeFi(fi);
        fi = _free(fi);
     }
-    if (ts)
-       rpmtransFree(ts);
+    ts = rpmtransFree(ts);
 
     return rc;
 }
@@ -1472,6 +1471,13 @@ assert(psm->mi == NULL);
                }
            }
 
+           /* Add remove transaction id to header. */
+           if (psm->oh)
+           {   int_32 tid = ts->id;
+               (void) headerAddEntry(psm->oh, RPMTAG_REMOVETID,
+                       RPM_INT32_TYPE, &tid, 1);
+           }
+
            /* Retrieve type of payload compression. */
            /*@-nullstate@*/    /* FIX: psm->oh may be NULL */
            rc = psmStage(psm, PSM_RPMIO_FLAGS);
index 362af31..520c195 100644 (file)
@@ -196,6 +196,15 @@ int rpmQuery(QVA_t qva, rpmQVSources source, const char * arg)
 int showVerifyPackage(QVA_t qva, /*@only@*/ rpmdb db, Header h)
        /*@modifies db, h, fileSystem @*/;
 
+/**
+ * Check original header digest.
+ * @todo Make digest check part of rpmdb iterator.
+ * @param h            header
+ * @return             0 on success (or unavailable), 1 on digest mismatch
+ */
+int rpmVerifyDigest(Header h)
+       /*@modifies nothing @*/;
+
 /** \ingroup rpmcli
  * Verify package install.
  * @param qva          parsed query/verify options
@@ -299,13 +308,120 @@ struct rpmInstallArguments_s {
     rpmprobFilterFlags probFilter;
     rpmInstallInterfaceFlags installInterfaceFlags;
     rpmEraseInterfaceFlags eraseInterfaceFlags;
-/*@only@*/ rpmRelocation * relocations;
+/*@only@*/ /*@null@*/ rpmRelocation * relocations;
     int numRelocations;
     int noDeps;
     int incldocs;
-    const char * prefix;
+/*@null@*/ const char * prefix;
+/*@observer@*/ /*@null@*/ const char * rootdir;
+    int_32 rbtid;              /*!< from --rollback */
 };
 
+/**
+ * A rollback transaction id element.
+ */
+typedef /*@abstract@*/ struct IDT_s {
+    unsigned int instance;     /*!< installed package transaction id. */
+/*@owned@*/ /*@null@*/ const char * key; /*! removed package file name. */
+    Header h;                  /*!< removed package header. */
+    union {
+       int_32 i32;             /*!< install/remove transaction id */
+    } val;
+} * IDT;
+
+/**
+ * A rollback transaction id index.
+ */
+typedef /*@abstract@*/ struct IDTindex_s {
+    int delta;                 /*!< no. elements to realloc as a chunk. */
+    int size;                  /*!< size of id index element. */
+    int alloced;               /*!< current number of elements allocated. */
+    int nidt;                  /*!< current number of elements initialized. */
+/*@only@*/ /*@null@*/ IDT idt; /*!< id index elements. */
+} * IDTX;
+
+/**
+ * Destroy id index.
+ * @param idtx         id index
+ * @return             NULL always
+ */
+/*@null@*/ IDTX IDTXfree(/*@only@*/ /*@null@*/ IDTX idtx)
+       /*@modifies idtx @*/;
+
+/**
+ * Create id index.
+ * @return             new id index
+ */
+/*@only@*/ IDTX IDTXnew(void)
+       /*@*/;
+
+/**
+ * Insure that index has room for "need" elements.
+ * @param idtx         id index
+ * @param need         additional no. of elements needed
+ * @return             id index (with room for "need" elements)
+ */
+/*@only@*/ /*@null@*/ IDTX IDTXgrow(/*@only@*/ /*@null@*/ IDTX idtx, int need)
+       /*@modifies idtx @*/;
+
+/**
+ * Sort tag (instance,value) pairs.
+ * @param idtx         id index
+ * @return             id index
+ */
+/*@only@*/ /*@null@*/ IDTX IDTXsort(/*@only@*/ /*@null@*/ IDTX idtx)
+       /*@modifies idtx @*/;
+
+/**
+ * Load tag (instance,value) pairs from rpm databse, and return sorted id index.
+ * @param db           rpm database
+ * @param tag          rpm tag
+ * @return             id index
+ */
+/*@only@*/ /*@null@*/ IDTX IDTXload(rpmdb db, rpmTag tag)
+       /*@modifies db @*/;
+
+/**
+ * Load tag (instance,value) pairs from packages, and return sorted id index.
+ * @param db           glob expression
+ * @param tag          rpm tag
+ * @return             id index
+ */
+/*@only@*/ /*@null@*/ IDTX IDTXglob(const char * globstr, rpmTag tag)
+       /*@modifies fileSystem @*/;
+
+
+/**
+ * The rpm CLI generic transaction callback.
+ * @deprecated Transaction callback arguments need to change, so don't rely on
+ * this routine in the rpmcli API.
+ *
+ * @param arg          per-callback private data (e.g. an rpm header)
+ * @param what         callback identifier
+ * @param amount       per-callback progress info
+ * @param total                per-callback progress info
+ * @param pkgkey       opaque header key (e.g. file name or PyObject)
+ * @param data         private data (e.g. rpmInstallInterfaceFlags)
+ * @return             per-callback data (e.g. an opened FD_t)
+ */
+/*@null@*/ void * rpmShowProgress(/*@null@*/ const void * arg,
+               const rpmCallbackType what,
+               const unsigned long amount,
+               const unsigned long total,
+               /*@null@*/ const void * pkgKey,
+               /*@null@*/ void * data)
+       /*@modifies fileSystem @*/;
+
+extern int packagesTotal;
+
+/** \ingroup rpmcli
+ * Rollback transactions, erasing new, reinstalling old, package(s).
+ * @return             0 on success
+ */
+int rpmRollback(struct rpmInstallArguments_s * ia,
+               /*@null@*/ const char ** argv)
+       /*@modifies fileSystem @*/;
+
 /** \ingroup rpmcli
  */
 extern struct rpmInstallArguments_s rpmIArgs;
index 01619a1..75d86e5 100644 (file)
 #include "misc.h"      /* XXX for rpmGlob() */
 #include "debug.h"
 
-/*@access rpmTransactionSet@*/ /* XXX compared with NULL */
-/*@access rpmProblemSet@*/     /* XXX compared with NULL */
-/*@access Header@*/            /* XXX compared with NULL */
-/*@access FD_t@*/              /* XXX compared with NULL */
+/*@access rpmTransactionSet @*/        /* XXX compared with NULL */
+/*@access rpmProblemSet @*/    /* XXX compared with NULL */
+/*@access Header @*/           /* XXX compared with NULL */
+/*@access FD_t @*/             /* XXX compared with NULL */
+/*@access IDTX @*/
+/*@access IDT @*/
 
 /* Define if you want percentage progress in the hash bars when
  * writing to a tty (ordinary hash bars otherwise) --claudio
@@ -23,7 +25,7 @@
 static int hashesPrinted = 0;
 
 #ifdef FANCY_HASH
-static int packagesTotal = 0;
+int packagesTotal = 0;
 static int progressTotal = 0;
 static int progressCurrent = 0;
 #endif
@@ -76,10 +78,8 @@ static void printHash(const unsigned long amount, const unsigned long total)
     }
 }
 
-/**
- */
-static /*@null@*/
-void * showProgress(/*@null@*/ const void * arg, const rpmCallbackType what,
+void * rpmShowProgress(/*@null@*/ const void * arg,
+                       const rpmCallbackType what,
                        const unsigned long amount,
                        const unsigned long total,
                        /*@null@*/ const void * pkgKey,
@@ -514,8 +514,9 @@ restart:
        packagesTotal = numRPMS;
 #endif
        rpmMessage(RPMMESS_DEBUG, _("installing binary packages\n"));
-       rc = rpmRunTransactions(ts, showProgress, (void *) ((long)notifyFlags),
-                                   NULL, &probs, transFlags, probFilter);
+       rc = rpmRunTransactions(ts, rpmShowProgress,
+                       (void *) ((long)notifyFlags),
+                       NULL, &probs, transFlags, probFilter);
 
        if (rc < 0) {
            numFailed += numRPMS;
@@ -539,7 +540,7 @@ restart:
 
            if (!(transFlags & RPMTRANS_FLAG_TEST)) {
                rpmRC rpmrc = rpmInstallSourcePackage(rootdir, fd, NULL,
-                       showProgress, (void *) ((long)notifyFlags), NULL);
+                       rpmShowProgress, (void *) ((long)notifyFlags), NULL);
                if (rpmrc != RPMRC_OK) numFailed++;
            }
 
@@ -548,7 +549,7 @@ restart:
     }
 
 exit:
-    if (ts) rpmtransFree(ts);
+    ts = rpmtransFree(ts);
     for (i = 0; i < numPkgs; i++) {
        if (pkgState[i] == 1)
            (void) Unlink(pkgURL[i]);
@@ -611,7 +612,7 @@ int rpmErase(const char * rootdir, const char ** argv,
            while ((h = rpmdbNextIterator(mi)) != NULL) {
                unsigned int recOffset = rpmdbGetIteratorOffset(mi);
                if (recOffset) {
-                   rpmtransRemovePackage(ts, recOffset);
+                   (void) rpmtransRemovePackage(ts, recOffset);
                    numPackages++;
                }
            }
@@ -641,7 +642,7 @@ int rpmErase(const char * rootdir, const char ** argv,
                                        transFlags, 0);
     }
 
-    rpmtransFree(ts);
+    ts = rpmtransFree(ts);
     (void) rpmdbClose(db);
 
     return numFailed;
@@ -684,3 +685,199 @@ int rpmInstallSource(const char * rootdir, const char * arg,
 
     return rc;
 }
+
+static int reverse = -1;
+
+/**
+ */
+static int IDTintcmp(const void * a, const void * b)
+       /*@*/
+{
+    /*@-castexpose@*/
+    return ( reverse * (((IDT)a)->val.i32 - ((IDT)b)->val.i32) );
+    /*@=castexpose@*/
+}
+
+IDTX IDTXfree(IDTX idtx)
+{
+    if (idtx) {
+       int i;
+       if (idtx->idt)
+       for (i = 0; i < idtx->nidt; i++) {
+           IDT idt = idtx->idt + i;
+           idt->h = headerFree(idt->h);
+           idt->key = _free(idt->key);
+       }
+       idtx->idt = _free(idtx->idt);
+       idtx = _free(idtx);
+    }
+    return NULL;
+}
+
+IDTX IDTXnew(void)
+{
+    IDTX idtx = xcalloc(1, sizeof(*idtx));
+    idtx->delta = 10;
+    idtx->size = sizeof(*((IDT)0));
+    return idtx;
+}
+
+IDTX IDTXgrow(IDTX idtx, int need)
+{
+    if (need < 0) return NULL;
+    if (idtx == NULL)
+       idtx = IDTXnew();
+    if (need == 0) return idtx;
+
+    if ((idtx->nidt + need) > idtx->alloced) {
+       while (need > 0) {
+           idtx->alloced += idtx->delta;
+           need -= idtx->delta;
+       }
+       idtx->idt = xrealloc(idtx->idt, (idtx->alloced * idtx->size) );
+    }
+    return idtx;
+}
+
+IDTX IDTXsort(IDTX idtx)
+{
+    if (idtx != NULL && idtx->idt != NULL && idtx->nidt > 0)
+       qsort(idtx->idt, idtx->nidt, idtx->size, IDTintcmp);
+    return idtx;
+}
+
+IDTX IDTXload(rpmdb db, rpmTag tag)
+{
+    IDTX idtx = NULL;
+    rpmdbMatchIterator mi;
+    HGE_t hge = (HGE_t) headerGetEntry;
+    Header h;
+
+    mi = rpmdbInitIterator(db, tag, NULL, 0);
+    while ((h = rpmdbNextIterator(mi)) != NULL) {
+       rpmTagType type;
+       int_32 count;
+       int_32 * tidp;
+
+       tidp = NULL;
+       if (!hge(h, tag, &type, (void **)&tidp, &count) || tidp == NULL)
+           continue;
+
+       if (type == RPM_INT32_TYPE && (*tidp == 0 || *tidp == -1))
+           continue;
+
+       idtx = IDTXgrow(idtx, 1);
+       if (idtx == NULL)
+           continue;
+       if (idtx->idt == NULL)
+           continue;
+
+       {   IDT idt;
+           /*@-nullderef@*/
+           idt = idtx->idt + idtx->nidt;
+           /*@=nullderef@*/
+           idt->h = NULL;
+           idt->key = NULL;
+           idt->instance = rpmdbGetIteratorOffset(mi);
+           idt->val.i32 = *tidp;
+       }
+       idtx->nidt++;
+    }
+    mi = rpmdbFreeIterator(mi);
+
+    return IDTXsort(idtx);
+}
+
+IDTX IDTXglob(const char * globstr, rpmTag tag)
+{
+    IDTX idtx = NULL;
+    HGE_t hge = (HGE_t) headerGetEntry;
+    Header h;
+    int_32 * tidp;
+    FD_t fd;
+    const char ** av = NULL;
+    int ac = 0;
+    int rc;
+    int i;
+
+    ac = 0;
+    av = NULL;
+    rc = rpmGlob(globstr, &ac, &av);
+
+    if (rc == 0)
+    for (i = 0; i < ac; i++) {
+       rpmTagType type;
+       int_32 count;
+       int isSource;
+       rpmRC rpmrc;
+
+       fd = Fopen(av[i], "r.ufdio");
+       if (fd == NULL || Ferror(fd)) {
+            rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), av[i],
+                        Fstrerror(fd));
+           if (fd) (void) Fclose(fd);
+           continue;
+       }
+
+       rpmrc = rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL);
+       if (rpmrc != RPMRC_OK || isSource) {
+           (void) Fclose(fd);
+           continue;
+       }
+
+       tidp = NULL;
+       if (hge(h, tag, &type, (void **) &tidp, &count) && tidp) {
+
+           idtx = IDTXgrow(idtx, 1);
+           if (idtx == NULL || idtx->idt == NULL) {
+               h = headerFree(h);
+               (void) Fclose(fd);
+               continue;
+           }
+           {   IDT idt;
+               idt = idtx->idt + idtx->nidt;
+               idt->h = headerLink(h);
+               idt->key = av[i];
+               av[i] = NULL;
+               idt->instance = 0;
+               idt->val.i32 = *tidp;
+           }
+           idtx->nidt++;
+       }
+
+       h = headerFree(h);
+       (void) Fclose(fd);
+    }
+
+    for (i = 0; i < ac; i++)
+       av[i] = _free(av[i]);
+    av = _free(av);
+
+    return idtx;
+}
+
+int rpmRollback(/*@unused@*/ struct rpmInstallArguments_s * ia,
+               /*@unused@*/ const char ** argv)
+{
+    rpmdb db = NULL;
+    rpmTransactionSet ts = NULL;
+    IDTX itids = NULL;
+    const char * globstr = rpmExpand("%{_repackage_dir}/*.rpm", NULL);
+    IDTX rtids = NULL;
+    int rc;
+
+    rc = rpmdbOpen(ia->rootdir, &db, O_RDWR, 0644);
+
+    ts = rpmtransCreateSet(db, ia->rootdir);
+
+    itids = IDTXload(db, RPMTAG_INSTALLTID);
+    rtids = IDTXglob(globstr, RPMTAG_REMOVETID);
+
+    globstr = _free(globstr);
+    rtids = IDTXfree(rtids);
+    itids = IDTXfree(itids);
+
+    ts =  rpmtransFree(ts);
+
+    return 0;
+}
index b5b0b42..8c5b97d 100644 (file)
@@ -865,7 +865,7 @@ int rpmdbSetIteratorModified(/*@null@*/ rpmdbMatchIterator mi, int modified)
 /** \ingroup rpmdb
  * Add package header to rpm database and indices.
  * @param db           rpm database
- * @param iid          install transaction id (or -1 to skip)
+ * @param iid          install transaction id (iid = 0 or -1 to skip)
  * @param h            header
  * @return             0 on success
  */
@@ -875,11 +875,11 @@ int rpmdbAdd(rpmdb db, int iid, Header h)
 /** \ingroup rpmdb
  * Remove package header from rpm database and indices.
  * @param db           rpm database
- * @param rid          remove transaction id (or -1 to skip)
+ * @param rid          remove transaction id (rid = 0 or -1 to skip)
  * @param offset       location in Packages dbi
  * @return             0 on success
  */
-int rpmdbRemove(rpmdb db, int rid, unsigned int offset)
+int rpmdbRemove(rpmdb db, /*@unused@*/ int rid, unsigned int offset)
        /*@modifies db, fileSystem @*/;
 
 /** \ingroup rpmdb
@@ -1231,15 +1231,18 @@ void rpmtransAvailablePackage(rpmTransactionSet ts, Header h,
  * Add package to be removed to unordered transaction set.
  * @param ts           transaction set
  * @param dboffset     rpm database instance
+ * @return             0 on success
  */
-void rpmtransRemovePackage(rpmTransactionSet ts, int dboffset)
+int rpmtransRemovePackage(rpmTransactionSet ts, int dboffset)
        /*@modifies ts @*/;
 
 /** \ingroup rpmtrans
  * Destroy transaction set.
  * @param ts           transaction set
+ * @return             NULL always
  */
-void rpmtransFree( /*@only@*/ rpmTransactionSet ts)
+/*@null@*/ rpmTransactionSet
+rpmtransFree(/*@only@*//*@null@*/ rpmTransactionSet ts)
        /*@modifies ts @*/;
 
 /** \ingroup rpmtrans
index edc2666..ab32448 100644 (file)
@@ -313,18 +313,11 @@ int rpmVerifyScript(const char * rootDir, Header h, /*@null@*/ FD_t scriptFd)
     rc = psmStage(psm, PSM_SCRIPT);
     freeFi(fi);
     fi = _free(fi);
-    rpmtransFree(ts);
+    ts = rpmtransFree(ts);
     return rc;
 }
 
-/**
- * Check original header digest.
- * @todo Make digest check part of rpmdb iterator.
- * @param h            header
- * @return             0 on succes, 1 digest mismatch
- */
-static int verifyDigest(Header h)
-       /*@modifies nothing @*/
+int rpmVerifyDigest(Header h)
 {
     HGE_t hge = (HGE_t)headerGetEntry; /* XXX headerGetEntryMinMemory? */
     HFD_t hfd = headerFreeData;
@@ -486,17 +479,17 @@ exit:
 static int verifyDependencies(rpmdb rpmdb, Header h)
        /*@modifies h @*/
 {
-    rpmTransactionSet rpmdep;
+    rpmTransactionSet ts;
     rpmDependencyConflict conflicts;
     int numConflicts;
     int rc = 0;                /* assume no problems */
     int i;
 
-    rpmdep = rpmtransCreateSet(rpmdb, NULL);
-    (void) rpmtransAddPackage(rpmdep, h, NULL, NULL, 0, NULL);
+    ts = rpmtransCreateSet(rpmdb, NULL);
+    (void) rpmtransAddPackage(ts, h, NULL, NULL, 0, NULL);
 
-    (void) rpmdepCheck(rpmdep, &conflicts, &numConflicts);
-    rpmtransFree(rpmdep);
+    (void) rpmdepCheck(ts, &conflicts, &numConflicts);
+    ts = rpmtransFree(ts);
 
     if (numConflicts) {
        const char *n, *v, *r;
@@ -546,7 +539,7 @@ int showVerifyPackage(QVA_t qva, rpmdb rpmdb, Header h)
     int rc;
 
     if (qva->qva_flags & VERIFY_DIGEST) {
-       if ((rc = verifyDigest(h)) != 0)
+       if ((rc = rpmVerifyDigest(h)) != 0)
            ec = rc;
     }
     if (qva->qva_flags & VERIFY_DEPS) {
index ba5aa65..b89e50c 100644 (file)
@@ -334,13 +334,13 @@ fi
 
 %files build
 %defattr(-,root,root)
-%dir %{__prefix}/src/redhat
-%dir %{__prefix}/src/redhat/BUILD
-%dir %{__prefix}/src/redhat/SPECS
-%dir %{__prefix}/src/redhat/SOURCES
-%dir %{__prefix}/src/redhat/SRPMS
-%dir %{__prefix}/src/redhat/RPMS
-%{__prefix}/src/redhat/RPMS/*
+%dir %{__prefix}/src/@RPMCANONVENDOR@
+%dir %{__prefix}/src/@RPMCANONVENDOR@/BUILD
+%dir %{__prefix}/src/@RPMCANONVENDOR@/SPECS
+%dir %{__prefix}/src/@RPMCANONVENDOR@/SOURCES
+%dir %{__prefix}/src/@RPMCANONVENDOR@/SRPMS
+%dir %{__prefix}/src/@RPMCANONVENDOR@/RPMS
+%{__prefix}/src/@RPMCANONVENDOR@/RPMS/*
 %rpmattr       %{__prefix}/bin/rpmbuild
 %rpmattr       %{__prefix}/lib/rpm/brp-*
 %rpmattr       %{__prefix}/lib/rpm/check-prereqs
index c28fe7b..c73fa4e 100644 (file)
@@ -2209,7 +2209,7 @@ static INLINE int removeIndexEntry(dbiIndex dbi, DBC * dbcursor,
 }
 
 /* XXX install.c uninstall.c */
-int rpmdbRemove(rpmdb rpmdb, int rid, unsigned int hdrNum)
+int rpmdbRemove(rpmdb rpmdb, /*@unused@*/ int rid, unsigned int hdrNum)
 {
     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
     HFD_t hfd = headerFreeData;
@@ -2230,11 +2230,13 @@ int rpmdbRemove(rpmdb rpmdb, int rid, unsigned int hdrNum)
        return 1;
     }
 
+#ifdef DYING
     /* Add remove transaction id to header. */
-    if (rid > 0) {
+    if (rid != 0 && rid != -1) {
        int_32 tid = rid;
        (void) headerAddEntry(h, RPMTAG_REMOVETID, RPM_INT32_TYPE, &tid, 1);
     }
+#endif
 
     {  const char *n, *v, *r;
        (void) headerNVR(h, &n, &v, &r);
@@ -2428,7 +2430,7 @@ int rpmdbAdd(rpmdb rpmdb, int iid, Header h)
     int rc = 0;
     int xx;
 
-    if (iid > 0) {
+    if (iid != 0 && iid != -1) {
        int_32 tid = iid;
        (void) headerRemoveEntry(h, RPMTAG_REMOVETID);
        (void) headerAddEntry(h, RPMTAG_INSTALLTID, RPM_INT32_TYPE, &tid, 1);
index 0884488..5c6a49e 100644 (file)
@@ -136,9 +136,13 @@ static void vrpmlog (unsigned code, const char *fmt, va_list ap)
 
     /* Allocate a sufficently large buffer for output. */
     while (1) {
+#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0
+       /*@-unrecog@*/ nb = vsnprintf(msgbuf, msgnb, fmt, ap); /*@=unrecog@*/
+#else
        va_list apc;
        /*@-sysunrecog -usedef@*/ __va_copy(apc, ap); /*@=sysunrecog =usedef@*/
        /*@-unrecog@*/ nb = vsnprintf(msgbuf, msgnb, fmt, apc); /*@=unrecog@*/
+#endif
        if (nb > -1 && nb < msgnb)
            break;
        if (nb > -1)            /* glibc 2.1 */
index d18d9db..59b19a1 100644 (file)
@@ -11,7 +11,7 @@ static struct poptOption optionsTable[] = {
  { "sha1",'\0', POPT_BIT_SET,  &flags, RPMDIGEST_SHA1, NULL, NULL },
  { "native",'\0', POPT_BIT_SET, &flags, RPMDIGEST_NATIVE,      NULL, NULL },
  { "debug",'d', POPT_ARG_VAL, &_rpmio_debug, -1,       NULL, NULL },
- { NULL, '\0', 0, NULL, 0,     NULL, NULL }
+  POPT_TABLEEND
 };
 
 int
diff --git a/rpmqv.c b/rpmqv.c
index 1c78425..6b0d883 100755 (executable)
--- a/rpmqv.c
+++ b/rpmqv.c
@@ -42,7 +42,8 @@ enum modes {
 
     MODE_INSTALL       = (1 <<  1),
     MODE_ERASE         = (1 <<  2),
-#define        MODES_IE (MODE_INSTALL | MODE_ERASE)
+    MODE_ROLLBACK      = (1 << 14),
+#define        MODES_IE (MODE_INSTALL | MODE_ERASE | MODE_ROLLBACK)
 
     MODE_BUILD         = (1 <<  4),
     MODE_REBUILD       = (1 <<  5),
@@ -59,6 +60,7 @@ enum modes {
     MODE_VERIFYDB      = (1 << 13),
 #define        MODES_DB (MODE_INITDB | MODE_REBUILDDB | MODE_VERIFYDB)
 
+
     MODE_UNKNOWN       = 0
 };
 
@@ -916,6 +918,9 @@ int main(int argc, const char ** argv)
 
     case MODE_INSTALL:
 
+       if (!poptPeekArg(optCon))
+           argerror(_("no packages given for install"));
+
        /* RPMTRANS_FLAG_BUILD_PROBS */
        /* RPMTRANS_FLAG_KEEPOBSOLETE */
 
@@ -928,9 +933,6 @@ int main(int argc, const char ** argv)
 
        if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS;
 
-       if (!poptPeekArg(optCon))
-           argerror(_("no packages given for install"));
-
        /* we've already ensured !(!ia->prefix && !ia->relocations) */
        if (ia->prefix) {
            ia->relocations = xmalloc(2 * sizeof(*ia->relocations));
@@ -948,6 +950,12 @@ int main(int argc, const char ** argv)
                        ia->transFlags, ia->installInterfaceFlags, ia->probFilter,
                        ia->relocations);
        break;
+
+    case MODE_ROLLBACK:
+       ia->rootdir = rootdir;
+       ec += rpmRollback(ia, (const char **)poptGetArgs(optCon));
+       break;
+
 #endif /* IAM_RPMEIU */
 
 #ifdef IAM_RPMQV
@@ -1044,6 +1052,7 @@ int main(int argc, const char ** argv)
 #if !defined(IAM_RPMEIU)
     case MODE_INSTALL:
     case MODE_ERASE:
+    case MODE_ROLLBACK:
 #endif
     case MODE_UNKNOWN:
        if (!showVersion && !help && !noUsageMsg) printUsage();
index ea8da33..86e9cf9 100644 (file)
@@ -11,8 +11,10 @@ check-recursive: ./usr/ ./bin ./var
        make -C .. DESTDIR=`pwd` install
        cp rpmrc macros ./$(pkglibdir)
        rm -f ./@GZIPBIN@
+       if [ ! -d ./`dirname @GZIPBIN@` ] ; then mkdir -p ./`dirname @GZIPBIN@` ; fi
        ln -s @GZIPBIN@ ./@GZIPBIN@
        rm -f ./@BZIP2BIN@
+       if [ ! -d ./`dirname @BZIP2BIN@` ] ; then mkdir -p ./`dirname @BZIP2BIN@` ; fi
        ln -s @BZIP2BIN@ ./@BZIP2BIN@
 
 clean-local: