summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES5
-rw-r--r--build.c3
-rw-r--r--build/pack.c2
-rw-r--r--gendiff2
-rw-r--r--lib/Makefile.am3
-rw-r--r--lib/depends.c43
-rw-r--r--lib/fsm.c4
-rw-r--r--lib/header.h4
-rw-r--r--lib/poptI.c16
-rw-r--r--lib/psm.c10
-rw-r--r--lib/rpmcli.h120
-rw-r--r--lib/rpminstall.c227
-rw-r--r--lib/rpmlib.h13
-rw-r--r--lib/verify.c23
-rw-r--r--rpm.spec.in14
-rw-r--r--rpmdb/rpmdb.c8
-rw-r--r--rpmio/rpmlog.c4
-rw-r--r--rpmio/tdigest.c2
-rwxr-xr-xrpmqv.c17
-rw-r--r--tests/Makefile.am2
20 files changed, 442 insertions, 80 deletions
diff --git a/CHANGES b/CHANGES
index c792c0478..373c0257c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -148,6 +148,11 @@
- 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 87258df55..3dd44cf33 100644
--- 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);
diff --git a/build/pack.c b/build/pack.c
index 6ebb7b948..a506f6b55 100644
--- a/build/pack.c
+++ b/build/pack.c
@@ -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 a90f6e4a3..c00ce5156 100644
--- 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
diff --git a/lib/Makefile.am b/lib/Makefile.am
index b7f6b353e..83a3b7412 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -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)
diff --git a/lib/depends.c b/lib/depends.c
index a6644934a..2517765da 100644
--- a/lib/depends.c
+++ b/lib/depends.c
@@ -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,
diff --git a/lib/fsm.c b/lib/fsm.c
index a938f6e77..30947b4c9 100644
--- 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;
}
}
}
diff --git a/lib/header.h b/lib/header.h
index f45d33fde..52e97dce1 100644
--- a/lib/header.h
+++ b/lib/header.h
@@ -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
diff --git a/lib/poptI.c b/lib/poptI.c
index 1b411a65e..eca9ad502 100644
--- a/lib/poptI.c
+++ b/lib/poptI.c
@@ -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,
diff --git a/lib/psm.c b/lib/psm.c
index 5d5ed6833..b0f1f301b 100644
--- 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);
diff --git a/lib/rpmcli.h b/lib/rpmcli.h
index 362af31f3..520c19536 100644
--- a/lib/rpmcli.h
+++ b/lib/rpmcli.h
@@ -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;
diff --git a/lib/rpminstall.c b/lib/rpminstall.c
index 01619a176..75d86e552 100644
--- a/lib/rpminstall.c
+++ b/lib/rpminstall.c
@@ -10,10 +10,12 @@
#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;
+}
diff --git a/lib/rpmlib.h b/lib/rpmlib.h
index b5b0b4276..8c5b97d2d 100644
--- a/lib/rpmlib.h
+++ b/lib/rpmlib.h
@@ -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
diff --git a/lib/verify.c b/lib/verify.c
index edc266649..ab32448f2 100644
--- a/lib/verify.c
+++ b/lib/verify.c
@@ -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) {
diff --git a/rpm.spec.in b/rpm.spec.in
index ba5aa65e0..b89e50ce7 100644
--- a/rpm.spec.in
+++ b/rpm.spec.in
@@ -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
diff --git a/rpmdb/rpmdb.c b/rpmdb/rpmdb.c
index c28fe7b14..c73fa4ee6 100644
--- a/rpmdb/rpmdb.c
+++ b/rpmdb/rpmdb.c
@@ -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);
diff --git a/rpmio/rpmlog.c b/rpmio/rpmlog.c
index 088448868..5c6a49ee0 100644
--- a/rpmio/rpmlog.c
+++ b/rpmio/rpmlog.c
@@ -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 */
diff --git a/rpmio/tdigest.c b/rpmio/tdigest.c
index d18d9db66..59b19a1e6 100644
--- a/rpmio/tdigest.c
+++ b/rpmio/tdigest.c
@@ -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 1c78425f4..6b0d883c0 100755
--- 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();
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ea8da3334..86e9cf9b2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -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: