Merge changes from rpm-4.0.2.

Add iterators and reverse flag so that erase transactions can run backwards.

CVS patchset: 4556
CVS date: 2001/02/17 17:53:21
This commit is contained in:
jbj 2001-02-17 17:53:21 +00:00
parent e89f3d1791
commit 8f99e61fc7
15 changed files with 547 additions and 632 deletions

View File

@ -308,6 +308,7 @@ DBLIBSRCS=""
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"],
@ -320,10 +321,14 @@ AC_CHECK_FUNC(db_create, [DBLIBSRCS="$DBLIBSRCS db3.c"],
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 )

View File

@ -22,7 +22,7 @@ LIBS =
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 \

309
lib/db2.c
View File

@ -4,8 +4,19 @@
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 */
@ -13,16 +24,15 @@ static int _debug = 1; /* XXX if < 0 debugging, > 0 unusual error returns */
#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;
@ -100,12 +110,7 @@ static int db_env_create(DB_ENV **dbenvp, int foo)
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)
@ -120,14 +125,13 @@ static int cvtdberr(dbiIndex dbi, const char * msg, int error, int printit) {
}
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;
@ -138,20 +142,24 @@ static int db_fini(dbiIndex dbi, const char * dbhome, const char * dbfile,
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);
}
@ -164,12 +172,12 @@ static int db_fini(dbiIndex dbi, const char * dbhome, const char * 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;
@ -187,8 +195,8 @@ static int db_init(dbiIndex dbi, const char *dbhome, const char *dbfile,
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);
@ -220,8 +228,12 @@ static int db_init(dbiIndex dbi, const char *dbhome, const char *dbfile,
/* 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 */
@ -234,7 +246,11 @@ static int db_init(dbiIndex dbi, const char *dbhome, const char *dbfile,
#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;
@ -272,6 +288,7 @@ static int db2sync(dbiIndex dbi, unsigned int flags)
#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);
@ -292,12 +309,15 @@ static int db2c_del(dbiIndex dbi, DBC * dbcursor, u_int32_t flags)
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;
}
@ -309,9 +329,7 @@ static int db2c_get(dbiIndex dbi, DBC * dbcursor,
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
@ -319,12 +337,13 @@ static int db2c_get(dbiIndex dbi, DBC * dbcursor,
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;
@ -335,7 +354,7 @@ static int db2c_put(dbiIndex dbi, DBC * dbcursor,
return rc;
}
static inline int db2c_close(dbiIndex dbi, DBC * dbcursor)
static INLINE int db2c_close(dbiIndex dbi, DBC * dbcursor)
{
int rc;
@ -344,17 +363,16 @@ static inline int db2c_close(dbiIndex dbi, DBC * dbcursor)
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;
@ -362,45 +380,62 @@ static inline int db2c_open(dbiIndex dbi, DBC ** dbcp)
#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;
@ -414,24 +449,21 @@ static int db2cput(dbiIndex dbi, const void * keyp, size_t keylen,
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;
@ -444,14 +476,10 @@ static int db2cdel(dbiIndex dbi, const void * keyp, size_t keylen, unsigned int
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);
@ -460,15 +488,15 @@ static int db2cdel(dbiIndex dbi, const void * keyp, size_t keylen, unsigned int
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;
@ -482,23 +510,18 @@ static int db2cget(dbiIndex dbi, void ** keyp, size_t * keylen,
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) {
@ -513,17 +536,18 @@ static int db2cget(dbiIndex dbi, void ** keyp, size_t * keylen,
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;
@ -561,9 +585,8 @@ static int db2close(dbiIndex dbi, unsigned int flags)
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)));
}
@ -572,7 +595,8 @@ static int db2close(dbiIndex dbi, unsigned int flags)
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 */
@ -584,7 +608,7 @@ static int db2close(dbiIndex dbi, unsigned int flags)
if (urlfn)
free((void *)urlfn);
db2Free(dbi);
db3Free(dbi);
return rc;
}
@ -595,14 +619,16 @@ static int db2open(rpmdb rpmdb, int rpmtag, dbiIndex * dbip)
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;
@ -629,19 +655,29 @@ static int db2open(rpmdb rpmdb, int rpmtag, dbiIndex * dbip)
}
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)
@ -697,21 +733,69 @@ static int db2open(rpmdb rpmdb, int rpmtag, dbiIndex * dbip)
}
dbi->dbi_dbinfo = NULL;
rc = db->open(db, dbfile, dbsubfile,
dbi->dbi_type, oflags, dbi->dbi_perms);
rc = cvtdberr(dbi, "db->open", rc, _debug);
{ const char * dbfullpath;
const char * dbpath;
char * t;
int nb;
if (dbi->dbi_get_rmw_cursor) {
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);
}
/* XXX return rc == errno without printing */
_printit = (rc > 0 ? 0 : _debug);
xx = cvtdberr(dbi, "db->open", rc, _printit);
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;
@ -729,9 +813,29 @@ static int db2open(rpmdb rpmdb, int rpmtag, dbiIndex * dbip)
}
}
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 */
}
@ -744,20 +848,21 @@ static int db2open(rpmdb rpmdb, int rpmtag, dbiIndex * dbip)
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);
@ -765,6 +870,8 @@ static int db2open(rpmdb rpmdb, int rpmtag, dbiIndex * dbip)
return rc;
}
/** \ingroup db2
*/
struct _dbiVec db2vec = {
DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH,
db2open, db2close, db2sync, db2copen, db2cclose, db2cdel, db2cget, db2cput,

358
lib/db3.c
View File

@ -29,360 +29,6 @@ typedef int int32_t;
#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)
@ -481,7 +127,7 @@ static int db_fini(dbiIndex dbi, const char * dbhome, const char * dbfile,
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) {
@ -716,7 +362,7 @@ static inline int db3c_open(dbiIndex dbi, /*@out@*/ DBC ** dbcp)
#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;
}

View File

@ -141,6 +141,8 @@ struct rpmTransactionSet_s {
/*!< 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. */

View File

@ -289,6 +289,15 @@ extern "C" {
*/
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

View File

@ -598,6 +598,7 @@ int rpmErase(const char * rootdir, const char ** argv,
}
if (!stopUninstall) {
transFlags |= RPMTRANS_FLAG_REVERSE;
numFailed += rpmRunTransactions(ts, NULL, NULL, NULL, &probs,
transFlags, 0);
}

View File

@ -1077,6 +1077,7 @@ typedef enum rpmtransFlags_e {
RPMTRANS_FLAG_PKGUNDO = (1 << 12),
RPMTRANS_FLAG_COMMIT = (1 << 13),
RPMTRANS_FLAG_UNDO = (1 << 14),
RPMTRANS_FLAG_REVERSE = (1 << 15),
} rpmtransFlags;
/** \ingroup rpmtrans

View File

@ -15,21 +15,22 @@ static struct rpmlibProvides {
} 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 }
};

View File

@ -61,6 +61,17 @@ struct diskspaceInfo {
#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;
@ -1261,6 +1272,90 @@ static void skipFiles(const rpmTransactionSet ts, 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,
@ -1269,20 +1364,20 @@ 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? */
@ -1425,15 +1520,15 @@ int rpmRunTransactions( rpmTransactionSet ts,
/* ===============================================
* 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;
@ -1501,7 +1596,7 @@ int rpmRunTransactions( rpmTransactionSet ts,
/* ===============================================
* 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]))
@ -1510,18 +1605,18 @@ int rpmRunTransactions( rpmTransactionSet ts,
}
}
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;
@ -1645,7 +1740,7 @@ int rpmRunTransactions( rpmTransactionSet ts,
}
}
NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_STOP, 6, flEntries,
NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_STOP, 6, ts->flEntries,
NULL, ts->notifyData));
if (ts->chrootDone) {
@ -1658,7 +1753,7 @@ int rpmRunTransactions( rpmTransactionSet ts,
* 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) {
@ -1676,13 +1771,13 @@ int rpmRunTransactions( rpmTransactionSet ts,
(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;
}
@ -1690,7 +1785,7 @@ int rpmRunTransactions( rpmTransactionSet ts,
* 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;
@ -1707,14 +1802,31 @@ int rpmRunTransactions( rpmTransactionSet ts,
*/
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,
@ -1775,6 +1887,7 @@ if (fi->ap == NULL) fi->ap = alp; /* XXX WTFO? */
}
break;
case TR_REMOVED:
oc = tsGetOc(tsi);
/* If install failed, then we shouldn't erase. */
if (ts->order[oc].u.removed.dependsOnIndex == lastFailed)
break;
@ -1786,8 +1899,11 @@ if (fi->ap == NULL) fi->ap = alp; /* XXX WTFO? */
}
(void) rpmdbSync(ts->rpmdb);
}
#ifndef DYING
tsi = tsFreeIterator(tsi);
#endif
freeFl(ts, flList);
freeFl(ts, ts->flList);
if (ourrc)
return -1;

View File

@ -25,10 +25,11 @@ build/parseSpec.c
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

View File

@ -6,7 +6,7 @@
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"
@ -2222,6 +2222,105 @@ msgstr ""
msgid " failed - "
msgstr ""
#: lib/db1.c:92 lib/db2.c:117 lib/db3.c:102
#, c-format
msgid "db%d error(%d) from %s: %s\n"
msgstr ""
#: lib/db1.c:95 lib/db2.c:120 lib/db3.c:105
#, c-format
msgid "db%d error(%d): %s\n"
msgstr ""
#: lib/db1.c:387
#, c-format
msgid "closed db file %s\n"
msgstr ""
#: lib/db1.c:390
#, c-format
msgid "removed db file %s\n"
msgstr ""
#: lib/db1.c:421
#, c-format
msgid "bad db file %s\n"
msgstr ""
#: lib/db1.c:426
#, c-format
msgid "opening db file %s mode 0x%x\n"
msgstr ""
#. XXX check errno validity
#: lib/db1.c:449
#, c-format
msgid "cannot get %s lock on database\n"
msgstr ""
#: lib/db1.c:450 lib/db2.c:786 lib/db3.c:766
msgid "exclusive"
msgstr ""
#: lib/db1.c:450 lib/db2.c:786 lib/db3.c:766
msgid "shared"
msgstr ""
#: lib/db2.c:145 lib/db3.c:130
#, c-format
msgid "closed db environment %s/%s\n"
msgstr ""
#: lib/db2.c:161 lib/db3.c:146
#, c-format
msgid "removed db environment %s/%s\n"
msgstr ""
#: lib/db2.c:198 lib/db3.c:183
#, c-format
msgid "opening db environment %s/%s %s\n"
msgstr ""
#: lib/db2.c:588 lib/db3.c:569
#, c-format
msgid "closed db index %s/%s\n"
msgstr ""
#: lib/db2.c:678 lib/db3.c:659
#, c-format
msgid "opening db index %s/%s %s mode=0x%x\n"
msgstr ""
#: lib/db2.c:784 lib/db3.c:764
#, c-format
msgid "cannot get %s lock on %s/%s\n"
msgstr ""
#: lib/db2.c:791 lib/db3.c:771
#, c-format
msgid "locked db index %s/%s\n"
msgstr ""
#: lib/dbconfig.c:258
#, c-format
msgid "unrecognized db option: \"%s\" ignored\n"
msgstr ""
#: lib/dbconfig.c:287
#, c-format
msgid "%s has invalid numeric value, skipped\n"
msgstr ""
#: lib/dbconfig.c:296
#, c-format
msgid "%s has too large or too small long value, skipped\n"
msgstr ""
#: lib/dbconfig.c:305
#, c-format
msgid "%s has too large or too small integer value, skipped\n"
msgstr ""
#. XXX legacy epoch-less requires/conflicts compatibility
#: lib/depends.c:565
#, c-format
@ -2324,130 +2423,6 @@ msgstr ""
msgid "========== continuing tsort ...\n"
msgstr ""
#: lib/db1.c:92 lib/db2.c:112 lib/db3.c:456
#, c-format
msgid "db%d error(%d) from %s: %s\n"
msgstr ""
#: lib/db1.c:95 lib/db2.c:115 lib/db3.c:459
#, c-format
msgid "db%d error(%d): %s\n"
msgstr ""
#: lib/db1.c:387
#, c-format
msgid "closed db file %s\n"
msgstr ""
#: lib/db1.c:390
#, c-format
msgid "removed db file %s\n"
msgstr ""
#: lib/db1.c:421
#, c-format
msgid "bad db file %s\n"
msgstr ""
#: lib/db1.c:426
#, c-format
msgid "opening db file %s mode 0x%x\n"
msgstr ""
#. XXX check errno validity
#: lib/db1.c:449
#, c-format
msgid "cannot get %s lock on database\n"
msgstr ""
#: lib/db1.c:450 lib/db3.c:1120
msgid "exclusive"
msgstr ""
#: lib/db1.c:450 lib/db3.c:1120
msgid "shared"
msgstr ""
#: lib/db2.c:141
#, c-format
msgid "closed db environment %s/%s(%s)\n"
msgstr ""
#: lib/db2.c:153
#, c-format
msgid "removed db environment %s/%s(%s)\n"
msgstr ""
#: lib/db2.c:190
#, c-format
msgid "opening db environment %s/%s(%s) %s\n"
msgstr ""
#: lib/db2.c:565
#, c-format
msgid "closed db index %s/%s(%s)\n"
msgstr ""
#: lib/db2.c:643
#, c-format
msgid "opening db index %s/%s(%s) %s mode=0x%x\n"
msgstr ""
#: lib/db3.c:268
#, c-format
msgid "unrecognized db option: \"%s\" ignored\n"
msgstr ""
#: lib/db3.c:297
#, c-format
msgid "%s has invalid numeric value, skipped\n"
msgstr ""
#: lib/db3.c:306
#, c-format
msgid "%s has too large or too small long value, skipped\n"
msgstr ""
#: lib/db3.c:315
#, c-format
msgid "%s has too large or too small integer value, skipped\n"
msgstr ""
#: lib/db3.c:484
#, c-format
msgid "closed db environment %s/%s\n"
msgstr ""
#: lib/db3.c:500
#, c-format
msgid "removed db environment %s/%s\n"
msgstr ""
#: lib/db3.c:537
#, c-format
msgid "opening db environment %s/%s %s\n"
msgstr ""
#: lib/db3.c:923
#, c-format
msgid "closed db index %s/%s\n"
msgstr ""
#: lib/db3.c:1013
#, c-format
msgid "opening db index %s/%s %s mode=0x%x\n"
msgstr ""
#: lib/db3.c:1118
#, c-format
msgid "cannot get %s lock on %s/%s\n"
msgstr ""
#: lib/db3.c:1125
#, c-format
msgid "locked db index %s/%s\n"
msgstr ""
#: lib/falloc.c:141
#, c-format
msgid ""
@ -3371,7 +3346,7 @@ msgstr ""
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 ""
@ -3423,12 +3398,12 @@ 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 ""
@ -3661,46 +3636,46 @@ 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 ""
@ -3870,22 +3845,22 @@ 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 ""

View File

@ -98,6 +98,7 @@ typedef enum rpmerrCode_e {
* Retrofit rpmError() onto rpmlog sub-system.
*/
#define rpmError rpmlog
#define rpmErrorCode() rpmlogCode()
#define rpmErrorString() rpmlogMessage()
#define rpmErrorSetCallback(_cb) rpmlogSetCallback(_cb)
typedef rpmlogCallback rpmErrorCallBackType;

View File

@ -17,6 +17,14 @@ int rpmlogGetNrecs(void)
return nrecs;
}
int rpmlogCode(void)
{
if (nrecs > 0)
return recs[nrecs-1].code;
return -1;
}
const char * rpmlogMessage(void)
{
if (nrecs > 0)
@ -95,15 +103,31 @@ static void vrpmlog (unsigned code, const char *fmt, va_list ap)
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"). */
@ -119,10 +143,13 @@ static void vrpmlog (unsigned code, const char *fmt, va_list ap)
++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. */
}
}
@ -152,6 +179,8 @@ static void vrpmlog (unsigned code, const char *fmt, va_list ap)
fputs(msg, msgout);
fflush(msgout);
if (msgbuf)
free(msgbuf);
if (pri <= RPMLOG_CRIT)
exit(EXIT_FAILURE);
}
@ -165,6 +194,11 @@ void rpmlog (int code, const char *fmt, ...)
va_end(ap);
}
int rpmErrorCode(void)
{
return rpmlogCode();
}
const char * rpmErrorString(void)
{
return rpmlogMessage();

View File

@ -173,6 +173,15 @@ int rpmlogGetNrecs(void);
*/
/*@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)
@ -212,6 +221,13 @@ rpmlogCallback rpmlogSetCallback(rpmlogCallback cb);
*/
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.