Add iterators and reverse flag so that erase transactions can run backwards.
CVS patchset: 4556
CVS date: 2001/02/17 17:53:21
libdb3=""
libdb2=""
libdb1=""
+
dnl Check for Berkeley db3 API.
AC_CHECK_FUNC(db_create, [DBLIBSRCS="$DBLIBSRCS db3.c"],
AC_CHECK_LIB(db-3.1, db_create, [DBLIBSRCS="$DBLIBSRCS db3.c"; libdb3="-ldb-3.1"],
dnl Check for Berkeley db2 API.
dnl AC_CHECK_FUNC(db_open, [DBLIBSRCS="$DBLIBSRCS db2.c"],
-dnl AC_CHECK_LIB(db, db_open, [LIBS="$LIBS"; DBLIBSRCS="$DBLIBSRCS db2.c" ; libdb2="-ldb"])
+dnl AC_CHECK_LIB(db2, db_open, [LIBS="$LIBS"; DBLIBSRCS="$DBLIBSRCS db2.c" ; libdb2="-ldb2"],
+dnl AC_CHECK_LIB(db, db_open, [LIBS="$LIBS"; DBLIBSRCS="$DBLIBSRCS db2.c" ; libdb2="-ldb"],
+dnl )
+dnl )
dnl )
+
dnl Check for Berkeley db1 API retrofit to db2/db3 database.
-dnl AC_CHECK_FUNC(dbopen, [DBLIBSRCS="$DBLIBSRCS db1.c"],
+dnl AC_CHECK_FUNC(dbopen, [DBLIBSRCS="$DBLIBSRCS db1.c falloc.c"],
dnl AC_CHECK_LIB(db, dbopen, [DBLIBSRCS="$DBLIBSRCS db1.c"])
dnl )
lib_LTLIBRARIES = librpm.la
librpm_la_SOURCES = \
- cpio.c $(DBLIBSRCS) depends.c \
+ cpio.c $(DBLIBSRCS) dbconfig.c depends.c \
formats.c fprint.c fs.c fsm.c hash.c header.c \
md5.c md5sum.c misc.c package.c problems.c \
poptBT.c poptQV.c psm.c query.c \
static int _debug = 1; /* XXX if < 0 debugging, > 0 unusual error returns */
+#ifdef __LCLINT__
+typedef unsigned int u_int32_t;
+typedef unsigned short u_int16_t;
+typedef unsigned char u_int8_t;
+typedef int int32_t;
+#endif
+
+#define INLINE
+
#include "system.h"
+
#include <db2/db.h>
+
#include <rpmlib.h>
#include <rpmmacro.h>
#include <rpmurl.h> /* XXX urlPath proto */
#include "rpmdb.h"
#include "debug.h"
+/*@access rpmdb@*/
/*@access dbiIndex@*/
/*@access dbiIndexSet@*/
-static const char * db2basename = "packages.db2";
-
#if DB_VERSION_MAJOR == 2
#define __USE_DB2 1
/* XXX remap DB3 types back into DB2 types */
-static inline DBTYPE db3_to_dbtype(int dbitype)
+static INLINE DBTYPE db3_to_dbtype(int dbitype)
{
switch(dbitype) {
case 1: return DB_BTREE;
static int cvtdberr(dbiIndex dbi, const char * msg, int error, int printit) {
int rc = 0;
- if (error == 0)
- rc = 0;
- else if (error < 0)
- rc = 1;
- else if (error > 0)
- rc = -1;
+ rc = error;
if (printit && rc) {
if (msg)
}
static int db_fini(dbiIndex dbi, const char * dbhome, const char * dbfile,
- const char * dbsubfile)
+ /*@unused@*/ const char * dbsubfile)
{
- rpmdb rpmdb = dbi->dbi_rpmdb;
- DB_ENV * dbenv = (DB_ENV *)dbi->dbi_dbenv;
+ DB_ENV * dbenv = dbi->dbi_dbenv;
+ int rc;
#if defined(__USE_DB3)
- char **dbconfig = NULL;
- int rc;
+ rpmdb rpmdb = dbi->dbi_rpmdb;
if (dbenv == NULL) {
dbi->dbi_dbenv = NULL;
rc = cvtdberr(dbi, "dbenv->close", rc, _debug);
if (dbfile)
- rpmMessage(RPMMESS_DEBUG, _("closed db environment %s/%s(%s)\n"),
- dbhome, dbfile, dbsubfile);
+ rpmMessage(RPMMESS_DEBUG, _("closed db environment %s/%s\n"),
+ dbhome, dbfile);
if (rpmdb->db_remove_env || dbi->dbi_tear_down) {
int xx;
xx = db_env_create(&dbenv, 0);
xx = cvtdberr(dbi, "db_env_create", rc, _debug);
- xx = dbenv->remove(dbenv, dbhome, dbconfig, 0);
+#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 1
+ xx = dbenv->remove(dbenv, dbhome, 0);
+#else
+ xx = dbenv->remove(dbenv, dbhome, NULL, 0);
+#endif
xx = cvtdberr(dbi, "dbenv->remove", rc, _debug);
if (dbfile)
- rpmMessage(RPMMESS_DEBUG, _("removed db environment %s/%s(%s)\n"),
- dbhome, dbfile, dbsubfile);
+ rpmMessage(RPMMESS_DEBUG, _("removed db environment %s/%s\n"),
+ dbhome, dbfile);
}
return rc;
}
-static int db2_fsync_disable(int fd) {
+static int db2_fsync_disable(/*@unused@*/ int fd) {
return 0;
}
static int db_init(dbiIndex dbi, const char *dbhome, const char *dbfile,
- const char * dbsubfile, DB_ENV **dbenvp)
+ /*@unused@*/ const char * dbsubfile, /*@out@*/ DB_ENV **dbenvp)
{
rpmdb rpmdb = dbi->dbi_rpmdb;
DB_ENV *dbenv = NULL;
if ( dbi->dbi_mode & O_CREAT) eflags |= DB_CREATE;
if (dbfile)
- rpmMessage(RPMMESS_DEBUG, _("opening db environment %s/%s(%s) %s\n"),
- dbhome, dbfile, dbsubfile, prDbiOpenFlags(eflags, 1));
+ rpmMessage(RPMMESS_DEBUG, _("opening db environment %s/%s %s\n"),
+ dbhome, dbfile, prDbiOpenFlags(eflags, 1));
rc = db_env_create(&dbenv, dbi->dbi_cflags);
rc = cvtdberr(dbi, "db_env_create", rc, _debug);
/* dbenv->set_tx_max(???) */
/* dbenv->set_tx_recover(???) */
if (dbi->dbi_no_fsync) {
- xx = dbenv->set_func_fsync(dbenv, db2_fsync_disable);
- xx = cvtdberr(dbi, "dbenv->set_func_fsync", xx, _debug);
+#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 1
+ xx = db_env_set_func_fsync(db3_fsync_disable);
+#else
+ xx = dbenv->set_func_fsync(dbenv, db3_fsync_disable);
+#endif
+ xx = cvtdberr(dbi, "db_env_set_func_fsync", xx, _debug);
}
}
#else /* __USE_DB3 */
#endif /* __USE_DB3 */
#if defined(__USE_DB3)
+#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 1
+ rc = dbenv->open(dbenv, dbhome, eflags, dbi->dbi_perms);
+#else
rc = dbenv->open(dbenv, dbhome, NULL, eflags, dbi->dbi_perms);
+#endif
rc = cvtdberr(dbi, "dbenv->open", rc, _debug);
if (rc)
goto errxit;
#if defined(__USE_DB2) || defined(__USE_DB3)
int _printit;
+
rc = db->sync(db, flags);
/* XXX DB_INCOMPLETE is returned occaisionally with multiple access. */
_printit = (rc == DB_INCOMPLETE ? 0 : _debug);
return rc;
}
-static int db2c_dup(dbiIndex dbi, DBC * dbcursor, DBC ** dbcp, u_int32_t flags)
+/*@unused@*/ static int db2c_dup(dbiIndex dbi, DBC * dbcursor, DBC ** dbcp,
+ u_int32_t flags)
{
- int rc;
+ int rc = 0;
+#if defined(__USE_DB3)
rc = dbcursor->c_dup(dbcursor, dbcp, flags);
rc = cvtdberr(dbi, "dbcursor->c_dup", rc, _debug);
+#endif
return rc;
}
int rmw;
#ifdef NOTYET
- if ((dbi->dbi_eflags & DB_INIT_CDB) &&
- !(dbi->dbi_oflags & DB_RDONLY) &&
- !(dbi->dbi_mode & O_RDWR))
+ if ((dbi->dbi_eflags & DB_INIT_CDB) && !(dbi->dbi_oflags & DB_RDONLY))
rmw = DB_RMW;
else
#endif
rc = dbcursor->c_get(dbcursor, key, data, rmw | flags);
+ /* XXX DB_NOTFOUND can be returned */
_printit = (rc == DB_NOTFOUND ? 0 : _debug);
rc = cvtdberr(dbi, "dbcursor->c_get", rc, _printit);
return rc;
}
-static int db2c_put(dbiIndex dbi, DBC * dbcursor,
+static int db2c_put(dbiIndex dbi, /*@only@*/ DBC * dbcursor,
DBT * key, DBT * data, u_int32_t flags)
{
int rc;
return rc;
}
-static inline int db2c_close(dbiIndex dbi, DBC * dbcursor)
+static INLINE int db2c_close(dbiIndex dbi, DBC * dbcursor)
{
int rc;
return rc;
}
-static inline int db2c_open(dbiIndex dbi, DBC ** dbcp)
+static INLINE int db2c_open(dbiIndex dbi, /*@out@*/ DBC ** dbcp)
{
DB * db = dbi->dbi_db;
DB_TXN * txnid = NULL;
- int flags;
int rc;
#if defined(__USE_DB3)
- if ((dbi->dbi_eflags & DB_INIT_CDB) &&
- !(dbi->dbi_oflags & DB_RDONLY) &&
- !(dbi->dbi_mode & O_RDWR))
+ int flags;
+
+ if ((dbi->dbi_eflags & DB_INIT_CDB) && !(dbi->dbi_oflags & DB_RDONLY))
flags = DB_WRITECURSOR;
else
flags = 0;
#else /* __USE_DB3 */
rc = db->cursor(db, txnid, dbcp);
#endif /* __USE_DB3 */
- rc = cvtdberr(dbi, "db2copen", rc, _debug);
+ rc = cvtdberr(dbi, "db2c_open", rc, _debug);
return rc;
}
-static int db2cclose(dbiIndex dbi, DBC * dbcursor, unsigned int flags)
+static int db2cclose(dbiIndex dbi, /*@only@*/ DBC * dbcursor,
+ unsigned int flags)
{
int rc = 0;
+ /* XXX per-iterator cursors */
+ if (flags == 1)
+ return db2c_close(dbi, dbcursor);
+
+ if (!dbi->dbi_use_cursors)
+ return 0;
+
if (dbcursor == NULL)
dbcursor = dbi->dbi_rmw;
if (dbcursor) {
- rc = db2c_close(dbi, dbcursor);
if (dbcursor == dbi->dbi_rmw)
dbi->dbi_rmw = NULL;
+ rc = db2c_close(dbi, dbcursor);
}
return rc;
}
-static int db2copen(dbiIndex dbi, DBC ** dbcp, unsigned int flags)
+static int db2copen(dbiIndex dbi, /*@out@*/ DBC ** dbcp, unsigned int flags)
{
DBC * dbcursor;
int rc = 0;
- if ((dbcursor = dbi->dbi_rmw) != NULL) {
- if (dbcp) *dbcp = dbi->dbi_rmw;
+ /* XXX per-iterator cursors */
+ if (flags == 1)
+ return db2c_open(dbi, dbcp);
+
+ if (!dbi->dbi_use_cursors) {
+ if (dbcp) *dbcp = NULL;
return 0;
- } else if ((rc = db2c_open(dbi, &dbcursor)) == 0) {
- dbi->dbi_rmw = dbcursor;
+ }
+
+ if ((dbcursor = dbi->dbi_rmw) == NULL) {
+ if ((rc = db2c_open(dbi, &dbcursor)) == 0)
+ dbi->dbi_rmw = dbcursor;
}
if (dbcp)
- *dbcp = dbcursor;
+ *dbcp = dbi->dbi_rmw;
return rc;
}
-static int db2cput(dbiIndex dbi, const void * keyp, size_t keylen,
- const void * datap, size_t datalen, unsigned int flags)
+static int db2cput(dbiIndex dbi, DBC * dbcursor,
+ const void * keyp, size_t keylen,
+ const void * datap, size_t datalen,
+ /*@unused@*/ unsigned int flags)
{
DB * db = dbi->dbi_db;
DB_TXN * txnid = NULL;
data.data = (void *)datap;
data.size = datalen;
- if (!dbi->dbi_use_cursors) {
+ if (dbcursor == NULL) {
rc = db->put(db, txnid, &key, &data, 0);
rc = cvtdberr(dbi, "db->put", rc, _debug);
} else {
- DBC * dbcursor;
- if ((rc = db2copen(dbi, &dbcursor, 0)) != 0)
- return rc;
+ rc = db2c_put(dbi, dbcursor, &key, &data, DB_AFTER);
- rc = db2c_put(dbi, dbcursor, &key, &data, DB_KEYLAST);
-
- (void) db2cclose(dbi, dbcursor, 0);
}
return rc;
}
-static int db2cdel(dbiIndex dbi, const void * keyp, size_t keylen, unsigned int flags)
+static int db2cdel(dbiIndex dbi, DBC * dbcursor,
+ const void * keyp, size_t keylen,
+ /*@unused@*/ unsigned int flags)
{
DB * db = dbi->dbi_db;
DB_TXN * txnid = NULL;
key.data = (void *)keyp;
key.size = keylen;
- if (!dbi->dbi_use_cursors) {
+ if (dbcursor == NULL) {
rc = db->del(db, txnid, &key, 0);
rc = cvtdberr(dbi, "db->del", rc, _debug);
} else {
- DBC * dbcursor;
-
- if ((rc = db2copen(dbi, &dbcursor, 0)) != 0)
- return rc;
rc = db2c_get(dbi, dbcursor, &key, &data, DB_SET);
rc = db2c_del(dbi, dbcursor, 0);
}
- (void) db2c_close(dbi, dbcursor);
-
}
return rc;
}
-static int db2cget(dbiIndex dbi, void ** keyp, size_t * keylen,
- void ** datap, size_t * datalen, unsigned int flags)
+static int db2cget(dbiIndex dbi, DBC * dbcursor,
+ void ** keyp, size_t * keylen,
+ void ** datap, size_t * datalen,
+ /*@unused@*/ unsigned int flags)
{
DB * db = dbi->dbi_db;
DB_TXN * txnid = NULL;
if (datap) data.data = *datap;
if (datalen) data.size = *datalen;
- if (!dbi->dbi_use_cursors) {
+ if (dbcursor == NULL) {
int _printit;
rc = db->get(db, txnid, &key, &data, 0);
+ /* XXX DB_NOTFOUND can be returned */
_printit = (rc == DB_NOTFOUND ? 0 : _debug);
rc = cvtdberr(dbi, "db->get", rc, _printit);
} else {
- DBC * dbcursor;
-
- if ((rc = db2copen(dbi, &dbcursor, 0)) != 0)
- return rc;
/* XXX W2DO? db2 does DB_FIRST on uninitialized cursor? */
rc = db2c_get(dbi, dbcursor, &key, &data,
key.data == NULL ? DB_NEXT : DB_SET);
- if (rc > 0) /* DB_NOTFOUND */
- (void) db2cclose(dbi, dbcursor, 0);
}
if (rc == 0) {
static int db2byteswapped(dbiIndex dbi)
{
- DB * db = dbi->dbi_db;
int rc = 0;
#if defined(__USE_DB3)
+ DB * db = dbi->dbi_db;
+
rc = db->get_byteswapped(db);
#endif /* __USE_DB3 */
return rc;
}
-static int db2close(dbiIndex dbi, unsigned int flags)
+static int db2close(/*@only@*/ dbiIndex dbi, unsigned int flags)
{
rpmdb rpmdb = dbi->dbi_rpmdb;
const char * urlfn = NULL;
rc = cvtdberr(dbi, "db->close", rc, _debug);
db = dbi->dbi_db = NULL;
- if (dbfile)
- rpmMessage(RPMMESS_DEBUG, _("closed db index %s/%s(%s)\n"),
- dbhome, dbfile, dbsubfile);
+ rpmMessage(RPMMESS_DEBUG, _("closed db index %s/%s\n"),
+ dbhome, (dbfile ? dbfile : tagName(dbi->dbi_rpmtag)));
}
dbi->dbi_dbinfo = NULL;
}
- xx = db_fini(dbi, dbhome, dbfile, dbsubfile);
+ if (dbi->dbi_use_dbenv)
+ xx = db_fini(dbi, dbhome, dbfile, dbsubfile);
#else /* __USE_DB2 || __USE_DB3 */
if (urlfn)
free((void *)urlfn);
- db2Free(dbi);
+ db3Free(dbi);
return rc;
}
const char * dbhome;
const char * dbfile;
const char * dbsubfile;
+ extern struct _dbiVec db2vec;
dbiIndex dbi = NULL;
int rc = 0;
+ int xx;
#if defined(__USE_DB2) || defined(__USE_DB3)
DB * db = NULL;
DB_ENV * dbenv = NULL;
- DB_TXN * txnid = NULL;
u_int32_t oflags;
+ int _printit;
if (dbip)
*dbip = NULL;
}
oflags = (dbi->dbi_oeflags | dbi->dbi_oflags);
+ oflags &= ~DB_TRUNCATE; /* XXX this is dangerous */
+
#if 0 /* XXX rpmdb: illegal flag combination specified to DB->open */
if ( dbi->dbi_mode & O_EXCL) oflags |= DB_EXCL;
#endif
- if(!(dbi->dbi_mode & O_RDWR)) oflags |= DB_RDONLY;
- if ( dbi->dbi_mode & O_CREAT) oflags |= DB_CREATE;
- if ( dbi->dbi_mode & O_TRUNC) oflags |= DB_TRUNCATE;
- rc = db_init(dbi, dbhome, dbfile, dbsubfile, &dbenv);
+ if (dbi->dbi_temporary) {
+ oflags &= ~DB_RDONLY;
+ oflags |= DB_CREATE;
+ } else {
+ if(!(dbi->dbi_mode & O_RDWR)) oflags |= DB_RDONLY;
+ if ( dbi->dbi_mode & O_CREAT) oflags |= DB_CREATE;
+ if ( dbi->dbi_mode & O_TRUNC) oflags |= DB_TRUNCATE;
+ }
+
dbi->dbi_dbinfo = NULL;
- if (dbfile)
- rpmMessage(RPMMESS_DEBUG, _("opening db index %s/%s(%s) %s mode=0x%x\n"),
- dbhome, dbfile, dbsubfile, prDbiOpenFlags(oflags, 0), dbi->dbi_mode);
+ if (dbi->dbi_use_dbenv)
+ rc = db_init(dbi, dbhome, dbfile, dbsubfile, &dbenv);
+
+ rpmMessage(RPMMESS_DEBUG, _("opening db index %s/%s %s mode=0x%x\n"),
+ dbhome, (dbfile ? dbfile : tagName(dbi->dbi_rpmtag)),
+ prDbiOpenFlags(oflags, 0), dbi->dbi_mode);
if (rc == 0) {
#if defined(__USE_DB3)
}
dbi->dbi_dbinfo = NULL;
- rc = db->open(db, dbfile, dbsubfile,
+ { const char * dbfullpath;
+ const char * dbpath;
+ char * t;
+ int nb;
+
+ nb = strlen(dbhome);
+ if (dbfile) nb += 1 + strlen(dbfile);
+ dbfullpath = t = alloca(nb + 1);
+
+ t = stpcpy(t, dbhome);
+ if (dbfile)
+ t = stpcpy( stpcpy( t, "/"), dbfile);
+ dbpath = (!dbi->dbi_use_dbenv && !dbi->dbi_temporary)
+ ? dbfullpath : dbfile;
+
+ rc = db->open(db, dbpath, dbsubfile,
dbi->dbi_type, oflags, dbi->dbi_perms);
- rc = cvtdberr(dbi, "db->open", rc, _debug);
+ }
+
+ /* XXX return rc == errno without printing */
+ _printit = (rc > 0 ? 0 : _debug);
+ xx = cvtdberr(dbi, "db->open", rc, _printit);
- if (dbi->dbi_get_rmw_cursor) {
+ if (rc == 0 && dbi->dbi_get_rmw_cursor) {
DBC * dbcursor = NULL;
- int xx;
+ DB_TXN * txnid = NULL;
xx = db->cursor(db, txnid, &dbcursor,
((oflags & DB_RDONLY) ? 0 : DB_WRITECURSOR));
xx = cvtdberr(dbi, "db->cursor", xx, _debug);
dbi->dbi_rmw = dbcursor;
} else
dbi->dbi_rmw = NULL;
+
+ if (rc == 0 && dbi->dbi_lockdbfd) {
+ int fdno = -1;
+
+ if (!(db->fd(db, &fdno) == 0 && fdno >= 0)) {
+ rc = 1;
+ } else {
+ struct flock l;
+ l.l_whence = 0;
+ l.l_start = 0;
+ l.l_len = 0;
+ l.l_type = (dbi->dbi_mode & O_RDWR) ? F_WRLCK : F_RDLCK;
+ l.l_pid = 0;
+
+ if (fcntl(fdno, F_SETLK, (void *) &l)) {
+ rpmError(RPMERR_FLOCK,
+ _("cannot get %s lock on %s/%s\n"),
+ ((dbi->dbi_mode & O_RDWR)
+ ? _("exclusive") : _("shared")),
+ dbhome, dbfile);
+ rc = 1;
+ } else if (dbfile) {
+ rpmMessage(RPMMESS_DEBUG,
+ _("locked db index %s/%s\n"),
+ dbhome, dbfile);
+ }
+ }
+ }
}
-#else
+ }
+#else /* __USE_DB3 */
{ DB_INFO * dbinfo = xcalloc(1, sizeof(*dbinfo));
dbinfo->db_cachesize = dbi->dbi_cachesize;
dbinfo->db_lorder = dbi->dbi_lorder;
}
}
dbi->dbi_dbinfo = dbinfo;
- rc = db_open(dbfile, db3_to_dbtype(dbi->dbi_type), oflags,
+
+ { const char * dbfullpath;
+ const char * dbpath;
+ char * t;
+ int nb;
+
+ nb = strlen(dbhome);
+ if (dbfile) nb += 1 + strlen(dbfile);
+ dbfullpath = t = alloca(nb + 1);
+
+ t = stpcpy(t, dbhome);
+ if (dbfile)
+ t = stpcpy( stpcpy( t, "/"), dbfile);
+ dbpath = (!dbi->dbi_use_dbenv && !dbi->dbi_temporary)
+ ? dbfullpath : dbfile;
+
+ rc = db_open(dbpath, db3_to_dbtype(dbi->dbi_type), oflags,
dbi->dbi_perms, dbenv, dbinfo, &db);
- rc = cvtdberr(dbi, "db_open", rc, _debug);
+ }
+
+ /* XXX return rc == errno without printing */
+ _printit = (rc > 0 ? 0 : _debug);
+ xx = cvtdberr(dbi, "db->open", rc, _printit);
}
#endif /* __USE_DB3 */
}
if (dbip)
*dbip = NULL;
- if ((dbi = db2New(rpmdb, rpmtag)) == NULL)
+ if ((dbi = db3New(rpmdb, rpmtag)) == NULL)
return 1;
dbi->dbi_db = dbopen(dbfile, dbi->dbi_mode, dbi->dbi_perms,
db3_to_dbtype(dbi->dbi_type), dbopeninfo);
+
+ /* XXX return rc == errno without printing */
+ if (dbi->dbi_db == NULL) rc = errno;
#endif /* __USE_DB2 || __USE_DB3 */
if (rc == 0 && dbi->dbi_db != NULL && dbip != NULL) {
- rc = 0;
+ dbi->dbi_vec = &db2vec;
*dbip = dbi;
- } else {
- rc = 1;
- db3Free(dbi);
- }
+ } else
+ db2close(dbi, 0);
if (urlfn)
free((void *)urlfn);
return rc;
}
+/** \ingroup db2
+ */
struct _dbiVec db2vec = {
DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH,
db2open, db2close, db2sync, db2copen, db2cclose, db2cdel, db2cget, db2cput,
#if DB_VERSION_MAJOR == 3
#define __USE_DB3 1
-struct _dbiIndex db3dbi;
-
-/** \ingroup db3
- * Analogue to struct poptOption
- */
-struct dbOption {
- const char * longName; /* may be NULL */
- int argInfo;
- void * arg; /* depends on argInfo */
- int val; /* 0 means don't return, just update flag */
-};
-
-#define _POPT_SET_BIT (POPT_ARG_VAL|POPT_ARGFLAG_OR)
-
-/*@-immediatetrans@*/
-/** \ingroup db3
- */
-struct dbOption rdbOptions[] = {
- /* XXX DB_CXX_NO_EXCEPTIONS */
- { "xa_create", _POPT_SET_BIT, &db3dbi.dbi_cflags, DB_XA_CREATE },
-
- { "create", _POPT_SET_BIT, &db3dbi.dbi_oeflags, DB_CREATE },
- { "nommap", _POPT_SET_BIT, &db3dbi.dbi_oeflags, DB_NOMMAP },
- { "thread", _POPT_SET_BIT, &db3dbi.dbi_oeflags, DB_THREAD },
-
- { "force", _POPT_SET_BIT, &db3dbi.dbi_eflags, DB_FORCE },
- { "cdb", _POPT_SET_BIT, &db3dbi.dbi_eflags, DB_INIT_CDB },
- { "lock", _POPT_SET_BIT, &db3dbi.dbi_eflags, DB_INIT_LOCK },
- { "log", _POPT_SET_BIT, &db3dbi.dbi_eflags, DB_INIT_LOG },
- { "mpool", _POPT_SET_BIT, &db3dbi.dbi_eflags, DB_INIT_MPOOL },
- { "txn", _POPT_SET_BIT, &db3dbi.dbi_eflags, DB_INIT_TXN },
- { "recover", _POPT_SET_BIT, &db3dbi.dbi_eflags, DB_RECOVER },
- { "recover_fatal", _POPT_SET_BIT, &db3dbi.dbi_eflags, DB_RECOVER_FATAL },
- { "shared", _POPT_SET_BIT, &db3dbi.dbi_eflags, DB_SYSTEM_MEM },
- { "txn_nosync", _POPT_SET_BIT, &db3dbi.dbi_eflags, DB_TXN_NOSYNC },
- { "use_environ_root", _POPT_SET_BIT, &db3dbi.dbi_eflags, DB_USE_ENVIRON_ROOT },
- { "use_environ", _POPT_SET_BIT, &db3dbi.dbi_eflags, DB_USE_ENVIRON },
- { "lockdown", _POPT_SET_BIT, &db3dbi.dbi_eflags, DB_LOCKDOWN },
- { "private", _POPT_SET_BIT, &db3dbi.dbi_eflags, DB_PRIVATE },
-
- { "txn_sync", _POPT_SET_BIT, &db3dbi.dbi_tflags, DB_TXN_SYNC },
- { "txn_nowait",_POPT_SET_BIT, &db3dbi.dbi_tflags, DB_TXN_NOWAIT },
-
- { "excl", _POPT_SET_BIT, &db3dbi.dbi_oflags, DB_EXCL },
- { "rdonly", _POPT_SET_BIT, &db3dbi.dbi_oflags, DB_RDONLY },
- { "truncate", _POPT_SET_BIT, &db3dbi.dbi_oflags, DB_TRUNCATE },
- { "fcntl_locking",_POPT_SET_BIT, &db3dbi.dbi_oflags, DB_FCNTL_LOCKING },
-
- { "btree", POPT_ARG_VAL, &db3dbi.dbi_type, DB_BTREE },
- { "hash", POPT_ARG_VAL, &db3dbi.dbi_type, DB_HASH },
- { "recno", POPT_ARG_VAL, &db3dbi.dbi_type, DB_RECNO },
- { "queue", POPT_ARG_VAL, &db3dbi.dbi_type, DB_QUEUE },
- { "unknown", POPT_ARG_VAL, &db3dbi.dbi_type, DB_UNKNOWN },
-
- { "root", POPT_ARG_STRING, &db3dbi.dbi_root, 0 },
- { "home", POPT_ARG_STRING, &db3dbi.dbi_home, 0 },
- { "file", POPT_ARG_STRING, &db3dbi.dbi_file, 0 },
- { "subfile", POPT_ARG_STRING, &db3dbi.dbi_subfile, 0 },
- { "mode", POPT_ARG_INT, &db3dbi.dbi_mode, 0 },
- { "perms", POPT_ARG_INT, &db3dbi.dbi_perms, 0 },
-
- { "teardown", POPT_ARG_NONE, &db3dbi.dbi_tear_down, 0 },
- { "usecursors",POPT_ARG_NONE, &db3dbi.dbi_use_cursors, 0 },
- { "usedbenv", POPT_ARG_NONE, &db3dbi.dbi_use_dbenv, 0 },
- { "rmwcursor", POPT_ARG_NONE, &db3dbi.dbi_get_rmw_cursor, 0 },
- { "nofsync", POPT_ARG_NONE, &db3dbi.dbi_no_fsync, 0 },
- { "nodbsync", POPT_ARG_NONE, &db3dbi.dbi_no_dbsync, 0 },
- { "lockdbfd", POPT_ARG_NONE, &db3dbi.dbi_lockdbfd, 0 },
- { "temporary", POPT_ARG_NONE, &db3dbi.dbi_temporary, 0 },
- { "debug", POPT_ARG_NONE, &db3dbi.dbi_debug, 0 },
-
- { "cachesize", POPT_ARG_INT, &db3dbi.dbi_cachesize, 0 },
- { "errpfx", POPT_ARG_STRING, &db3dbi.dbi_errpfx, 0 },
- { "region_init", POPT_ARG_VAL, &db3dbi.dbi_region_init, 1 },
- { "tas_spins", POPT_ARG_INT, &db3dbi.dbi_tas_spins, 0 },
-
- { "chkpoint", _POPT_SET_BIT, &db3dbi.dbi_verbose, DB_VERB_CHKPOINT },
- { "deadlock", _POPT_SET_BIT, &db3dbi.dbi_verbose, DB_VERB_DEADLOCK },
- { "recovery", _POPT_SET_BIT, &db3dbi.dbi_verbose, DB_VERB_RECOVERY },
- { "waitsfor", _POPT_SET_BIT, &db3dbi.dbi_verbose, DB_VERB_WAITSFOR },
- { "verbose", POPT_ARG_VAL, &db3dbi.dbi_verbose, -1 },
-
- { "lk_oldest", POPT_ARG_VAL, &db3dbi.dbi_lk_detect, DB_LOCK_OLDEST },
- { "lk_random", POPT_ARG_VAL, &db3dbi.dbi_lk_detect, DB_LOCK_RANDOM },
- { "lk_youngest", POPT_ARG_VAL, &db3dbi.dbi_lk_detect, DB_LOCK_YOUNGEST },
-/* XXX lk_conflicts matrix */
- { "lk_max", POPT_ARG_INT, &db3dbi.dbi_lk_max, 0 },
-
- { "lg_bsize", POPT_ARG_INT, &db3dbi.dbi_lg_bsize, 0 },
- { "lg_max", POPT_ARG_INT, &db3dbi.dbi_lg_max, 0 },
-
-/* XXX tx_recover */
- { "tx_max", POPT_ARG_INT, &db3dbi.dbi_tx_max, 0 },
-
- { "lorder", POPT_ARG_INT, &db3dbi.dbi_lorder, 0 },
-
- { "mp_mmapsize", POPT_ARG_INT, &db3dbi.dbi_mp_mmapsize, 0 },
- { "mp_size", POPT_ARG_INT, &db3dbi.dbi_mp_size, 0 },
- { "pagesize", POPT_ARG_INT, &db3dbi.dbi_pagesize, 0 },
-
-/* XXX bt_minkey */
-/* XXX bt_compare */
-/* XXX bt_dup_compare */
-/* XXX bt_prefix */
- { "bt_dup", _POPT_SET_BIT, &db3dbi.dbi_bt_flags, DB_DUP },
- { "bt_dupsort",_POPT_SET_BIT, &db3dbi.dbi_bt_flags, DB_DUPSORT },
- { "bt_recnum", _POPT_SET_BIT, &db3dbi.dbi_bt_flags, DB_RECNUM },
- { "bt_revsplitoff", _POPT_SET_BIT, &db3dbi.dbi_bt_flags, DB_REVSPLITOFF },
-
- { "h_dup", _POPT_SET_BIT, &db3dbi.dbi_h_flags, DB_DUP },
- { "h_dupsort", _POPT_SET_BIT, &db3dbi.dbi_h_flags, DB_DUPSORT },
- { "h_ffactor", POPT_ARG_INT, &db3dbi.dbi_h_ffactor, 0 },
- { "h_nelem", POPT_ARG_INT, &db3dbi.dbi_h_nelem, 0 },
-
- { "re_renumber", _POPT_SET_BIT, &db3dbi.dbi_re_flags, DB_RENUMBER },
- { "re_snapshot",_POPT_SET_BIT, &db3dbi.dbi_re_flags, DB_SNAPSHOT },
- { "re_delim", POPT_ARG_INT, &db3dbi.dbi_re_delim, 0 },
- { "re_len", POPT_ARG_INT, &db3dbi.dbi_re_len, 0 },
- { "re_pad", POPT_ARG_INT, &db3dbi.dbi_re_pad, 0 },
- { "re_source", POPT_ARG_STRING, &db3dbi.dbi_re_source, 0 },
-
- { NULL, 0, NULL, 0 }
-};
-/*@=immediatetrans@*/
-
-static int dbSaveLong(const struct dbOption * opt, long aLong) {
- if (opt->argInfo & POPT_ARGFLAG_NOT)
- aLong = ~aLong;
- switch (opt->argInfo & POPT_ARGFLAG_LOGICALOPS) {
- case 0:
- *((long *) opt->arg) = aLong;
- break;
- case POPT_ARGFLAG_OR:
- *((long *) opt->arg) |= aLong;
- break;
- case POPT_ARGFLAG_AND:
- *((long *) opt->arg) &= aLong;
- break;
- case POPT_ARGFLAG_XOR:
- *((long *) opt->arg) ^= aLong;
- break;
- default:
- return POPT_ERROR_BADOPERATION;
- /*@notreached@*/ break;
- }
- return 0;
-}
-
-static int dbSaveInt(const struct dbOption * opt, long aLong) {
- if (opt->argInfo & POPT_ARGFLAG_NOT)
- aLong = ~aLong;
- switch (opt->argInfo & POPT_ARGFLAG_LOGICALOPS) {
- case 0:
- *((int *) opt->arg) = aLong;
- break;
- case POPT_ARGFLAG_OR:
- *((int *) opt->arg) |= aLong;
- break;
- case POPT_ARGFLAG_AND:
- *((int *) opt->arg) &= aLong;
- break;
- case POPT_ARGFLAG_XOR:
- *((int *) opt->arg) ^= aLong;
- break;
- default:
- return POPT_ERROR_BADOPERATION;
- /*@notreached@*/ break;
- }
- return 0;
-}
-
-void db3Free(dbiIndex dbi) {
- if (dbi) {
- if (dbi->dbi_root) free((void *)dbi->dbi_root);
- if (dbi->dbi_home) free((void *)dbi->dbi_home);
- if (dbi->dbi_file) free((void *)dbi->dbi_file);
- if (dbi->dbi_subfile) free((void *)dbi->dbi_subfile);
- if (dbi->dbi_errpfx) free((void *)dbi->dbi_errpfx);
- if (dbi->dbi_re_source) free((void *)dbi->dbi_re_source);
- if (dbi->dbi_dbenv) free(dbi->dbi_dbenv);
- if (dbi->dbi_dbinfo) free(dbi->dbi_dbinfo);
- free((void *)dbi);
- }
-}
-
-static const char *db3_config_default =
- "db3:hash:mpool:cdb:usecursors:verbose:mp_mmapsize=8Mb:mp_size=512Kb:pagesize=512:perms=0644";
-
-dbiIndex db3New(rpmdb rpmdb, int rpmtag)
-{
- dbiIndex dbi = xcalloc(1, sizeof(*dbi));
- char dbiTagMacro[128];
- char * dbOpts;
-
- sprintf(dbiTagMacro, "%%{_dbi_config_%s}", tagName(rpmtag));
- dbOpts = rpmExpand(dbiTagMacro, NULL);
- if (!(dbOpts && *dbOpts && *dbOpts != '%')) {
- if (dbOpts) {
- free(dbOpts);
- dbOpts = NULL;
- }
- dbOpts = rpmExpand("%{_dbi_config}", NULL);
- if (!(dbOpts && *dbOpts && *dbOpts != '%')) {
- dbOpts = rpmExpand(db3_config_default, NULL);
- }
- }
-
- if (dbOpts && *dbOpts && *dbOpts != '%') {
- char *o, *oe;
- char *p, *pe;
- for (o = dbOpts; o && *o; o = oe) {
- struct dbOption *opt;
-
- while (*o && isspace(*o))
- o++;
- for (oe = o; oe && *oe; oe++) {
- if (isspace(*oe))
- break;
- if (oe[0] == ':' && !(oe[1] == '/' && oe[2] == '/'))
- break;
- }
- if (oe && *oe)
- *oe++ = '\0';
- if (*o == '\0')
- continue;
- for (pe = o; pe && *pe && *pe != '='; pe++)
- ;
- p = (pe ? *pe++ = '\0', pe : NULL);
-
- for (opt = rdbOptions; opt->longName != NULL; opt++) {
- if (strcmp(o, opt->longName))
- continue;
- break;
- }
- if (opt->longName == NULL) {
- rpmError(RPMERR_DBCONFIG,
- _("unrecognized db option: \"%s\" ignored\n"), o);
- continue;
- }
-
- switch (opt->argInfo & POPT_ARG_MASK) {
- long aLong;
-
- case POPT_ARG_NONE:
- (void) dbSaveInt(opt, 1L);
- break;
- case POPT_ARG_VAL:
- (void) dbSaveInt(opt, (long)opt->val);
- break;
- case POPT_ARG_STRING:
- { const char ** t = opt->arg;
- if (*t) free((void *)*t);
- *t = xstrdup( (p ? p : "") );
- } break;
-
- case POPT_ARG_INT:
- case POPT_ARG_LONG:
- aLong = strtol(p, &pe, 0);
- if (pe) {
- if (!xstrncasecmp(pe, "Mb", 2))
- aLong *= 1024 * 1024;
- else if (!xstrncasecmp(pe, "Kb", 2))
- aLong *= 1024;
- else if (*pe != '\0') {
- rpmError(RPMERR_DBCONFIG,
- _("%s has invalid numeric value, skipped\n"),
- opt->longName);
- continue;
- }
- }
-
- if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_LONG) {
- if (aLong == LONG_MIN || aLong == LONG_MAX) {
- rpmError(RPMERR_DBCONFIG,
- _("%s has too large or too small long value, skipped\n"),
- opt->longName);
- continue;
- }
- (void) dbSaveLong(opt, aLong);
- break;
- } else {
- if (aLong > INT_MAX || aLong < INT_MIN) {
- rpmError(RPMERR_DBCONFIG,
- _("%s has too large or too small integer value, skipped\n"),
- opt->longName);
- continue;
- }
- (void) dbSaveInt(opt, aLong);
- }
- break;
- default:
- break;
- }
- }
- }
-
- free(dbOpts);
-
- *dbi = db3dbi; /* structure assignment */
- memset(&db3dbi, 0, sizeof(db3dbi));
-
- if (!(dbi->dbi_perms & 0600))
- dbi->dbi_perms = 0644;
- dbi->dbi_mode = rpmdb->db_mode;
- dbi->dbi_rpmdb = rpmdb;
- dbi->dbi_rpmtag = rpmtag;
-
- switch (rpmtag) {
- case RPMDBI_PACKAGES:
- case RPMDBI_DEPENDS:
- dbi->dbi_jlen = 1 * sizeof(int_32);
- break;
- default:
- dbi->dbi_jlen = 2 * sizeof(int_32);
- break;
- }
- return dbi;
-}
-
-static /*@exposed@*/ const char *const prDbiOpenFlags(int dbflags, int print_dbenv_flags)
-{
- static char buf[256];
- struct dbOption *opt;
- char * oe;
-
- oe = buf;
- *oe = '\0';
- for (opt = rdbOptions; opt->longName != NULL; opt++) {
- if (opt->argInfo != _POPT_SET_BIT)
- continue;
- if (print_dbenv_flags) {
- if (!(opt->arg == &db3dbi.dbi_oeflags ||
- opt->arg == &db3dbi.dbi_eflags))
- continue;
- } else {
- if (!(opt->arg == &db3dbi.dbi_oeflags ||
- opt->arg == &db3dbi.dbi_oflags))
- continue;
- }
- if ((dbflags & opt->val) != opt->val)
- continue;
- if (oe != buf)
- *oe++ = ':';
- oe = stpcpy(oe, opt->longName);
- dbflags &= ~opt->val;
- }
- if (dbflags) {
- if (oe != buf)
- *oe++ = ':';
- sprintf(oe, "0x%x", (unsigned)dbflags);
- }
- return buf;
-}
-
#if defined(__USE_DB2) || defined(__USE_DB3)
#if defined(__USE_DB2)
static /*@observer@*/ const char * db_strerror(int error)
rc = cvtdberr(dbi, "dbenv->close", rc, _debug);
if (dbfile)
- rpmMessage(RPMMESS_DEBUG, _("closed db environment %s/%s\n"),
+ rpmMessage(RPMMESS_DEBUG, _("closed db environment %s/%s\n"),
dbhome, dbfile);
if (rpmdb->db_remove_env || dbi->dbi_tear_down) {
#else /* __USE_DB3 */
rc = db->cursor(db, txnid, dbcp);
#endif /* __USE_DB3 */
- rc = cvtdberr(dbi, "db3copen", rc, _debug);
+ rc = cvtdberr(dbi, "db3c_open", rc, _debug);
return rc;
}
/*!< Packages sorted by dependencies. */
int orderCount; /*!< No. of transaction elements. */
int orderAlloced; /*!< No. of allocated transaction elements. */
+/*@shared@*/ TFI_t flList; /*!< Transaction element(s) file info. */
+ int flEntries; /*!< No. of transaction elements. */
int chrootDone; /*!< Has chroot(2) been been done? */
/*@only@*/ const char * rootDir;/*!< Path to top of install tree. */
/*@only@*/ const char * currDir;/*!< Current working directory. */
*/
void db3Free( /*@only@*/ /*@null@*/ dbiIndex dbi);
+/** \ingroup db3
+ * Format db3 open flags for debugging print.
+ * @param dbflags db open flags
+ * @param print_dbenv_flags format db env flags instead?
+ * @return formatted flags (static buffer)
+ */
+/*@exposed@*/ const char *const prDbiOpenFlags(int dbflags,
+ int print_dbenv_flags);
+
/** \ingroup dbi
* Return handle for an index database.
* @param rpmdb rpm database
}
if (!stopUninstall) {
+ transFlags |= RPMTRANS_FLAG_REVERSE;
numFailed += rpmRunTransactions(ts, NULL, NULL, NULL, &probs,
transFlags, 0);
}
RPMTRANS_FLAG_PKGUNDO = (1 << 12),
RPMTRANS_FLAG_COMMIT = (1 << 13),
RPMTRANS_FLAG_UNDO = (1 << 14),
+ RPMTRANS_FLAG_REVERSE = (1 << 15),
} rpmtransFlags;
/** \ingroup rpmtrans
} rpmlibProvides[] = {
{ "rpmlib(VersionedDependencies)", "3.0.3-1",
(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
- "PreReq:, Provides:, and Obsoletes: dependencies support versions." },
+ N_("PreReq:, Provides:, and Obsoletes: dependencies support versions.") },
{ "rpmlib(CompressedFileNames)", "3.0.4-1",
(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
- "file names stored as (dirName,BaseName,dirIndex) tuple, not as path."},
+ N_("file names stored as (dirName,baseName,dirIndex) tuple, not as path.")},
{ "rpmlib(PayloadIsBzip2)", "3.0.5-1",
(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
- "package payload compressed using bzip2." },
+ N_("package payload compressed using bzip2.") },
{ "rpmlib(PayloadFilesHavePrefix)", "4.0-1",
(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
- "package payload files have \"./\" prefix." },
+ N_("package payload files have \"./\" prefix.") },
{ "rpmlib(ExplicitPackageProvide)", "4.0-1",
(RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
- "package name-version-release not implicitly provided." },
- { "rpmlib(HeaderLoadSortsTags)", "4.0.1-1", RPMSENSE_EQUAL,
- "header tags are always sorted after being loaded." },
+ N_("package name-version-release not implicitly provided.") },
+ { "rpmlib(HeaderLoadSortsTags)", "4.0.1-1",
+ ( RPMSENSE_EQUAL),
+ N_("header tags are always sorted after being loaded.") },
{ NULL, NULL, 0 }
};
#define XSTRCMP(a, b) ((!(a) && !(b)) || ((a) && (b) && !strcmp((a), (b))))
+
+/**
+ * Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
+ * @param this memory to free
+ * @retval NULL always
+ */
+static /*@null@*/ void * _free(/*@only@*/ /*@null@*/ const void * this) {
+ if (this) free((void *)this);
+ return NULL;
+}
+
static void freeFl(rpmTransactionSet ts, TFI_t flList)
{
TFI_t fi;
if (languages) freeSplitString((char **)languages);
}
+/**
+ * Iterator across transaction elements, forward on install, backward on erase.
+ */
+struct tsIterator_s {
+/*@kept@*/ rpmTransactionSet ts; /*!< transaction set. */
+ int reverse; /*!< reversed traversal? */
+ int ocsave; /*!< last returned iterator index. */
+ int oc; /*!< iterator index. */
+};
+
+/**
+ */
+static int tsGetOc(void * this) {
+ struct tsIterator_s * iter = this;
+ int oc = iter->ocsave;
+ return oc;
+}
+
+/**
+ */
+static struct availablePackage * tsGetAlp(void * this) {
+ struct tsIterator_s * iter = this;
+ struct availablePackage * alp = NULL;
+ int oc = iter->ocsave;
+
+ if (oc != -1) {
+ rpmTransactionSet ts = iter->ts;
+ TFI_t fi = ts->flList + oc;
+ if (fi->type == TR_ADDED)
+ alp = ts->addedPackages.list + ts->order[oc].u.addedIndex;
+ }
+ return alp;
+}
+
+/**
+ * Destroy transaction element iterator.
+ * @param this transaction element iterator
+ * @retval NULL always
+ */
+static /*@null@*/ void * tsFreeIterator(/*@only@*//*@null@*/ const void * this)
+{
+ return _free((void *)this);
+}
+
+/**
+ * Create transaction element iterator.
+ * @param this transaction set
+ * @return transaction element iterator
+ */
+static void * tsInitIterator(/*@kept@*/ const void * this)
+{
+ rpmTransactionSet ts = (void *)this;
+ struct tsIterator_s * iter = NULL;
+
+ iter = xcalloc(1, sizeof(*iter));
+ iter->ts = ts;
+ iter->oc = ((ts->transFlags & RPMTRANS_FLAG_REVERSE)
+ ? (ts->orderCount - 1) : 0);
+ iter->ocsave = iter->oc;
+ return iter;
+}
+
+/**
+ * Return next transaction element's file info.
+ * @param this file info iterator
+ * @return next index, -1 on termination
+ */
+static TFI_t tsNextIterator(void * this) {
+ struct tsIterator_s * iter = this;
+ rpmTransactionSet ts = iter->ts;
+ TFI_t fi = NULL;
+ int oc = -1;
+
+ if (iter->reverse) {
+ if (iter->oc >= 0) oc = iter->oc--;
+ } else {
+ if (iter->oc < ts->orderCount) oc = iter->oc++;
+ }
+ iter->ocsave = oc;
+ if (oc != -1)
+ fi = ts->flList + oc;
+ return fi;
+}
+
#define NOTIFY(_ts, _al) if ((_ts)->notify) (void) (_ts)->notify _al
int rpmRunTransactions( rpmTransactionSet ts,
rpmtransFlags transFlags, rpmprobFilterFlags ignoreSet)
{
int i, j;
- int rc, ourrc = 0;
+ int ourrc = 0;
struct availablePackage * alp;
Header * hdrs;
int totalFileCount = 0;
hashTable ht;
- TFI_t flList, fi;
+ TFI_t fi;
struct diskspaceInfo * dip;
struct sharedFileInfo * shared, * sharedList;
int numShared;
- int flEntries;
int nexti;
int lastFailed;
int oc;
fingerPrintCache fpc;
+ void * tsi;
/* FIXME: what if the same package is included in ts twice? */
/* ===============================================
* Initialize file list:
*/
- flEntries = ts->addedPackages.size + ts->numRemovedPackages;
- flList = alloca(sizeof(*flList) * (flEntries));
+ ts->flEntries = ts->addedPackages.size + ts->numRemovedPackages;
+ ts->flList = alloca(sizeof(*ts->flList) * (ts->flEntries));
/*
* FIXME?: we'd be better off assembling one very large file list and
* calling fpLookupList only once. I'm not sure that the speedup is
* worth the trouble though.
*/
- for (oc = 0, fi = flList; oc < ts->orderCount; oc++, fi++) {
+ for (oc = 0, fi = ts->flList; oc < ts->orderCount; oc++, fi++) {
const char **preTrans;
int preTransCount;
/* ===============================================
* Add fingerprint for each file not skipped.
*/
- for (fi = flList; (fi - flList) < flEntries; fi++) {
+ for (fi = ts->flList; (fi - ts->flList) < ts->flEntries; fi++) {
fpLookupList(fpc, fi->dnl, fi->bnl, fi->dil, fi->fc, fi->fps);
for (i = 0; i < fi->fc; i++) {
if (XFA_SKIPPING(fi->actions[i]))
}
}
- NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_START, 6, flEntries,
+ NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_START, 6, ts->flEntries,
NULL, ts->notifyData));
/* ===============================================
* Compute file disposition for each package in transaction set.
*/
- for (fi = flList; (fi - flList) < flEntries; fi++) {
+ for (fi = ts->flList; (fi - ts->flList) < ts->flEntries; fi++) {
dbiIndexSet * matches;
int knownBad;
- NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_PROGRESS, (fi - flList), flEntries,
- NULL, ts->notifyData));
+ NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_PROGRESS, (fi - ts->flList),
+ ts->flEntries, NULL, ts->notifyData));
if (fi->fc == 0) continue;
}
}
- NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_STOP, 6, flEntries,
+ NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_STOP, 6, ts->flEntries,
NULL, ts->notifyData));
if (ts->chrootDone) {
* Free unused memory as soon as possible.
*/
- for (oc = 0, fi = flList; oc < ts->orderCount; oc++, fi++) {
+ for (oc = 0, fi = ts->flList; oc < ts->orderCount; oc++, fi++) {
if (fi->fc == 0)
continue;
if (fi->fps) {
(ts->probs->numProblems && (!okProbs || psTrim(okProbs, ts->probs)))) {
*newProbs = ts->probs;
- for (alp = ts->addedPackages.list, fi = flList;
+ for (alp = ts->addedPackages.list, fi = ts->flList;
(alp - ts->addedPackages.list) < ts->addedPackages.size;
alp++, fi++) {
headerFree(hdrs[alp - ts->addedPackages.list]);
}
- freeFl(ts, flList);
+ freeFl(ts, ts->flList);
return ts->orderCount;
}
* Save removed files before erasing.
*/
if (ts->transFlags & (RPMTRANS_FLAG_DIRSTASH | RPMTRANS_FLAG_REPACKAGE)) {
- for (oc = 0, fi = flList; oc < ts->orderCount; oc++, fi++) {
+ for (oc = 0, fi = ts->flList; oc < ts->orderCount; oc++, fi++) {
switch (ts->order[oc].type) {
case TR_ADDED:
break;
*/
lastFailed = -2; /* erased packages have -1 */
- for (oc = 0, fi = flList; oc < ts->orderCount; oc++, fi++) {
+#ifdef DYING
+ for (oc = 0, fi = ts->flList; oc < ts->orderCount; oc++, fi++)
+#else
+ tsi = tsInitIterator(ts);
+ while ((fi = tsNextIterator(tsi)) != NULL)
+#endif
+ {
int gotfd;
gotfd = 0;
- switch (ts->order[oc].type) {
+#ifdef DYING
+ switch (ts->order[oc].type)
+#else
+ switch (fi->type)
+#endif
+ {
case TR_ADDED:
+#ifdef DYING
i = ts->order[oc].u.addedIndex;
alp = ts->addedPackages.list + i;
+#else
+ alp = tsGetAlp(tsi);
+assert(alp == fi->ap);
+ i = alp - ts->addedPackages.list;
+#endif
if (alp->fd == NULL) {
alp->fd = ts->notify(fi->h, RPMCALLBACK_INST_OPEN_FILE, 0, 0,
}
break;
case TR_REMOVED:
+ oc = tsGetOc(tsi);
/* If install failed, then we shouldn't erase. */
if (ts->order[oc].u.removed.dependsOnIndex == lastFailed)
break;
}
(void) rpmdbSync(ts->rpmdb);
}
+#ifndef DYING
+ tsi = tsFreeIterator(tsi);
+#endif
- freeFl(ts, flList);
+ freeFl(ts, ts->flList);
if (ourrc)
return -1;
build/reqprov.c
build/spec.c
lib/cpio.c
-lib/depends.c
lib/db1.c
lib/db2.c
lib/db3.c
+lib/dbconfig.c
+lib/depends.c
lib/falloc.c
lib/formats.c
lib/fprint.c
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2001-02-12 13:55-0500\n"
+"POT-Creation-Date: 2001-02-15 15:44-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
msgid " failed - "
msgstr ""
-#. XXX legacy epoch-less requires/conflicts compatibility
-#: lib/depends.c:565
+#: lib/db1.c:92 lib/db2.c:117 lib/db3.c:102
#, c-format
-msgid ""
-"the \"B\" dependency needs an epoch (assuming same as \"A\")\n"
-"\tA %s\tB %s\n"
+msgid "db%d error(%d) from %s: %s\n"
msgstr ""
-#: lib/depends.c:594
+#: lib/db1.c:95 lib/db2.c:120 lib/db3.c:105
#, c-format
-msgid " %s A %s\tB %s\n"
+msgid "db%d error(%d): %s\n"
msgstr ""
-#: lib/depends.c:962
+#: lib/db1.c:387
#, c-format
-msgid "%s: %-45s YES (added files)\n"
+msgid "closed db file %s\n"
msgstr ""
-#: lib/depends.c:1021
+#: lib/db1.c:390
#, c-format
-msgid "%s: %-45s YES (added provide)\n"
+msgid "removed db file %s\n"
msgstr ""
-#: lib/depends.c:1073
+#: lib/db1.c:421
#, c-format
-msgid "%s: %-45s %-3s (cached)\n"
+msgid "bad db file %s\n"
msgstr ""
-#: lib/depends.c:1092
+#: lib/db1.c:426
#, c-format
-msgid "%s: %-45s YES (rpmrc provides)\n"
+msgid "opening db file %s mode 0x%x\n"
msgstr ""
-#: lib/depends.c:1109
+#. XXX check errno validity
+#: lib/db1.c:449
#, c-format
-msgid "%s: %-45s YES (rpmlib provides)\n"
+msgid "cannot get %s lock on database\n"
msgstr ""
-#: lib/depends.c:1131
-#, c-format
-msgid "%s: %-45s YES (db files)\n"
+#: lib/db1.c:450 lib/db2.c:786 lib/db3.c:766
+msgid "exclusive"
msgstr ""
-#: lib/depends.c:1144
-#, c-format
-msgid "%s: %-45s YES (db provides)\n"
+#: lib/db1.c:450 lib/db2.c:786 lib/db3.c:766
+msgid "shared"
msgstr ""
-#: lib/depends.c:1158
+#: lib/db2.c:145 lib/db3.c:130
#, c-format
-msgid "%s: %-45s YES (db package)\n"
+msgid "closed db environment %s/%s\n"
msgstr ""
-#: lib/depends.c:1174
+#: lib/db2.c:161 lib/db3.c:146
#, c-format
-msgid "%s: %-45s NO\n"
+msgid "removed db environment %s/%s\n"
msgstr ""
-#: lib/depends.c:1195
+#: lib/db2.c:198 lib/db3.c:183
#, c-format
-msgid "%s: (%s, %s) added to Depends cache.\n"
+msgid "opening db environment %s/%s %s\n"
msgstr ""
-#. requirements are not satisfied.
-#: lib/depends.c:1256
+#: lib/db2.c:588 lib/db3.c:569
#, c-format
-msgid "package %s-%s-%s require not satisfied: %s\n"
+msgid "closed db index %s/%s\n"
msgstr ""
-#. conflicts exist.
-#: lib/depends.c:1323
+#: lib/db2.c:678 lib/db3.c:659
#, c-format
-msgid "package %s conflicts: %s\n"
+msgid "opening db index %s/%s %s mode=0x%x\n"
msgstr ""
-#: lib/depends.c:1539
+#: lib/db2.c:784 lib/db3.c:764
#, c-format
-msgid "removing %s-%s-%s \"%s\" from tsort relations.\n"
-msgstr ""
-
-#. Record all relations.
-#: lib/depends.c:1678
-msgid "========== recording tsort relations\n"
-msgstr ""
-
-#. T4. Scan for zeroes.
-#: lib/depends.c:1725
-msgid "========== tsorting packages\n"
-msgstr ""
-
-#: lib/depends.c:1770
-msgid "========== successors only (presentation order)\n"
-msgstr ""
-
-#: lib/depends.c:1819
-msgid "LOOP:\n"
-msgstr ""
-
-#: lib/depends.c:1850
-msgid "========== continuing tsort ...\n"
+msgid "cannot get %s lock on %s/%s\n"
msgstr ""
-#: lib/db1.c:92 lib/db2.c:112 lib/db3.c:456
+#: lib/db2.c:791 lib/db3.c:771
#, c-format
-msgid "db%d error(%d) from %s: %s\n"
+msgid "locked db index %s/%s\n"
msgstr ""
-#: lib/db1.c:95 lib/db2.c:115 lib/db3.c:459
+#: lib/dbconfig.c:258
#, c-format
-msgid "db%d error(%d): %s\n"
+msgid "unrecognized db option: \"%s\" ignored\n"
msgstr ""
-#: lib/db1.c:387
+#: lib/dbconfig.c:287
#, c-format
-msgid "closed db file %s\n"
+msgid "%s has invalid numeric value, skipped\n"
msgstr ""
-#: lib/db1.c:390
+#: lib/dbconfig.c:296
#, c-format
-msgid "removed db file %s\n"
+msgid "%s has too large or too small long value, skipped\n"
msgstr ""
-#: lib/db1.c:421
+#: lib/dbconfig.c:305
#, c-format
-msgid "bad db file %s\n"
+msgid "%s has too large or too small integer value, skipped\n"
msgstr ""
-#: lib/db1.c:426
+#. XXX legacy epoch-less requires/conflicts compatibility
+#: lib/depends.c:565
#, c-format
-msgid "opening db file %s mode 0x%x\n"
+msgid ""
+"the \"B\" dependency needs an epoch (assuming same as \"A\")\n"
+"\tA %s\tB %s\n"
msgstr ""
-#. XXX check errno validity
-#: lib/db1.c:449
+#: lib/depends.c:594
#, c-format
-msgid "cannot get %s lock on database\n"
+msgid " %s A %s\tB %s\n"
msgstr ""
-#: lib/db1.c:450 lib/db3.c:1120
-msgid "exclusive"
+#: lib/depends.c:962
+#, c-format
+msgid "%s: %-45s YES (added files)\n"
msgstr ""
-#: lib/db1.c:450 lib/db3.c:1120
-msgid "shared"
+#: lib/depends.c:1021
+#, c-format
+msgid "%s: %-45s YES (added provide)\n"
msgstr ""
-#: lib/db2.c:141
+#: lib/depends.c:1073
#, c-format
-msgid "closed db environment %s/%s(%s)\n"
+msgid "%s: %-45s %-3s (cached)\n"
msgstr ""
-#: lib/db2.c:153
+#: lib/depends.c:1092
#, c-format
-msgid "removed db environment %s/%s(%s)\n"
+msgid "%s: %-45s YES (rpmrc provides)\n"
msgstr ""
-#: lib/db2.c:190
+#: lib/depends.c:1109
#, c-format
-msgid "opening db environment %s/%s(%s) %s\n"
+msgid "%s: %-45s YES (rpmlib provides)\n"
msgstr ""
-#: lib/db2.c:565
+#: lib/depends.c:1131
#, c-format
-msgid "closed db index %s/%s(%s)\n"
+msgid "%s: %-45s YES (db files)\n"
msgstr ""
-#: lib/db2.c:643
+#: lib/depends.c:1144
#, c-format
-msgid "opening db index %s/%s(%s) %s mode=0x%x\n"
+msgid "%s: %-45s YES (db provides)\n"
msgstr ""
-#: lib/db3.c:268
+#: lib/depends.c:1158
#, c-format
-msgid "unrecognized db option: \"%s\" ignored\n"
+msgid "%s: %-45s YES (db package)\n"
msgstr ""
-#: lib/db3.c:297
+#: lib/depends.c:1174
#, c-format
-msgid "%s has invalid numeric value, skipped\n"
+msgid "%s: %-45s NO\n"
msgstr ""
-#: lib/db3.c:306
+#: lib/depends.c:1195
#, c-format
-msgid "%s has too large or too small long value, skipped\n"
+msgid "%s: (%s, %s) added to Depends cache.\n"
msgstr ""
-#: lib/db3.c:315
+#. requirements are not satisfied.
+#: lib/depends.c:1256
#, c-format
-msgid "%s has too large or too small integer value, skipped\n"
+msgid "package %s-%s-%s require not satisfied: %s\n"
msgstr ""
-#: lib/db3.c:484
+#. conflicts exist.
+#: lib/depends.c:1323
#, c-format
-msgid "closed db environment %s/%s\n"
+msgid "package %s conflicts: %s\n"
msgstr ""
-#: lib/db3.c:500
+#: lib/depends.c:1539
#, c-format
-msgid "removed db environment %s/%s\n"
+msgid "removing %s-%s-%s \"%s\" from tsort relations.\n"
msgstr ""
-#: lib/db3.c:537
-#, c-format
-msgid "opening db environment %s/%s %s\n"
+#. Record all relations.
+#: lib/depends.c:1678
+msgid "========== recording tsort relations\n"
msgstr ""
-#: lib/db3.c:923
-#, c-format
-msgid "closed db index %s/%s\n"
+#. T4. Scan for zeroes.
+#: lib/depends.c:1725
+msgid "========== tsorting packages\n"
msgstr ""
-#: lib/db3.c:1013
-#, c-format
-msgid "opening db index %s/%s %s mode=0x%x\n"
+#: lib/depends.c:1770
+msgid "========== successors only (presentation order)\n"
msgstr ""
-#: lib/db3.c:1118
-#, c-format
-msgid "cannot get %s lock on %s/%s\n"
+#: lib/depends.c:1819
+msgid "LOOP:\n"
msgstr ""
-#: lib/db3.c:1125
-#, c-format
-msgid "locked db index %s/%s\n"
+#: lib/depends.c:1850
+msgid "========== continuing tsort ...\n"
msgstr ""
#: lib/falloc.c:141
msgid "cannot open file %s: %s\n"
msgstr ""
-#: lib/rpminstall.c:327 lib/rpminstall.c:632
+#: lib/rpminstall.c:327 lib/rpminstall.c:633
#, c-format
msgid "%s cannot be installed\n"
msgstr ""
msgid "removing these packages would break dependencies:\n"
msgstr ""
-#: lib/rpminstall.c:619
+#: lib/rpminstall.c:620
#, c-format
msgid "cannot open %s: %s\n"
msgstr ""
-#: lib/rpminstall.c:625
+#: lib/rpminstall.c:626
#, c-format
msgid "Installing %s\n"
msgstr ""
msgid "You must set \"%%_pgp_name\" in your macro file\n"
msgstr ""
-#: lib/transaction.c:392
+#: lib/transaction.c:403
msgid "========== relocations\n"
msgstr ""
-#: lib/transaction.c:395
+#: lib/transaction.c:406
#, c-format
msgid "%5d exclude %s\n"
msgstr ""
-#: lib/transaction.c:398
+#: lib/transaction.c:409
#, c-format
msgid "%5d relocate %s -> %s\n"
msgstr ""
-#: lib/transaction.c:472
+#: lib/transaction.c:483
#, c-format
msgid "excluding multilib path %s%s\n"
msgstr ""
-#: lib/transaction.c:521
+#: lib/transaction.c:532
#, c-format
msgid "excluding %s %s\n"
msgstr ""
-#: lib/transaction.c:528
+#: lib/transaction.c:539
#, c-format
msgid "relocating %s to %s\n"
msgstr ""
-#: lib/transaction.c:600
+#: lib/transaction.c:611
#, c-format
msgid "relocating directory %s to %s\n"
msgstr ""
-#: lib/transaction.c:605
+#: lib/transaction.c:616
#, c-format
msgid "excluding directory %s\n"
msgstr ""
-#: lib/transaction.c:729
+#: lib/transaction.c:740
#, c-format
msgid "%s skipped due to missingok flag\n"
msgstr ""
msgid "logging into %s as %s, pw %s\n"
msgstr ""
-#: rpmio/rpmlog.c:24
+#: rpmio/rpmlog.c:32
msgid "(no error)"
msgstr ""
#. !< RPMLOG_EMERG
-#: rpmio/rpmlog.c:83 rpmio/rpmlog.c:84 rpmio/rpmlog.c:85
+#: rpmio/rpmlog.c:91 rpmio/rpmlog.c:92 rpmio/rpmlog.c:93
msgid "fatal error: "
msgstr ""
#. !< RPMLOG_CRIT
-#: rpmio/rpmlog.c:86
+#: rpmio/rpmlog.c:94
msgid "error: "
msgstr ""
#. !< RPMLOG_ERR
-#: rpmio/rpmlog.c:87
+#: rpmio/rpmlog.c:95
msgid "warning: "
msgstr ""
* Retrofit rpmError() onto rpmlog sub-system.
*/
#define rpmError rpmlog
+#define rpmErrorCode() rpmlogCode()
#define rpmErrorString() rpmlogMessage()
#define rpmErrorSetCallback(_cb) rpmlogSetCallback(_cb)
typedef rpmlogCallback rpmErrorCallBackType;
return nrecs;
}
+int rpmlogCode(void)
+{
+ if (nrecs > 0)
+ return recs[nrecs-1].code;
+ return -1;
+}
+
+
const char * rpmlogMessage(void)
{
if (nrecs > 0)
int pri = RPMLOG_PRI(code);
int mask = RPMLOG_MASK(pri);
/*@unused@*/ int fac = RPMLOG_FAC(code);
- char msgbuf[BUFSIZ], *msg;
+ char *msgbuf, *msg;
+ int msgnb = BUFSIZ, nb;
FILE * msgout = stderr;
rpmlogRec rec;
if ((mask & rpmlogMask) == 0)
return;
- /*@-unrecog@*/ vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); /*@=unrecog@*/
- msgbuf[sizeof(msgbuf) - 1] = '\0';
+ msgbuf = xmalloc(msgnb);
+ *msgbuf = '\0';
+
+ /* Allocate a sufficently large buffer for output. */
+ while (1) {
+ /*@-unrecog@*/
+ nb = vsnprintf(msgbuf, msgnb, fmt, ap);
+ /*@=unrecog@*/
+ if (nb > -1 && nb < msgnb)
+ break;
+ if (nb > -1) /* glibc 2.1 */
+ msgnb = nb+1;
+ else /* glibc 2.0 */
+ msgnb *= 2;
+ msgbuf = xrealloc(msgbuf, msgnb);
+ }
+ msgbuf[msgnb - 1] = '\0';
msg = msgbuf;
/* Save copy of all messages at warning (or below == "more important"). */
++nrecs;
rec->code = code;
- rec->message = xstrdup(msg);
+ rec->message = msgbuf;
+ msgbuf = NULL;
if (_rpmlogCallback) {
_rpmlogCallback();
+ if (msgbuf)
+ free(msgbuf);
return; /* XXX Preserve legacy rpmError behavior. */
}
}
fputs(msg, msgout);
fflush(msgout);
+ if (msgbuf)
+ free(msgbuf);
if (pri <= RPMLOG_CRIT)
exit(EXIT_FAILURE);
}
va_end(ap);
}
+int rpmErrorCode(void)
+{
+ return rpmlogCode();
+}
+
const char * rpmErrorString(void)
{
return rpmlogMessage();
/*@observer@*/ const char * rpmlogMessage(void);
/**
+ * Return error code from last rpmError() message.
+ * @deprecated Perl-RPM needs, what's really needed is predictable, non-i18n
+ * encumbered, error text that can be retrieved through rpmlogMessage()
+ * and parsed IMHO.
+ * @return code from last message
+ */
+int rpmlogCode(void);
+
+/**
* Print all rpmError() messages.
* @param f file handle (NULL uses stderr)
*/
rpmlogCallback rpmErrorSetCallback(rpmlogCallback cb);
/**
+ * Return error code from last rpmError() message.
+ * @deprecated Perl-RPM needs, use rpmlogCode() instead.
+ * @return code from last message
+ */
+int rpmErrorCode(void);
+
+/**
* Return text of last rpmError() message.
* @deprecated gnorpm needs, use rpmlogMessage() instead.
* @return text of last message