using namespace std;
-namespace zypp {
- namespace target {
- namespace rpm {
+namespace zypp
+{
+namespace target
+{
+namespace rpm
+{
///////////////////////////////////////////////////////////////////
//
// CLASS NAME : librpmDb::D
/**
* @short librpmDb internal database handle
**/
-class librpmDb::D {
+class librpmDb::D
+{
D & operator=( const D & ); // NO ASSIGNMENT!
D ( const D & ); // NO COPY!
- public:
+public:
- const Pathname _root; // root directory for all operations
- const Pathname _dbPath; // directory (below root) that contains the rpmdb
- rpmdb _db; // database handle
- shared_ptr<RpmException> _error; // database error
+ const Pathname _root; // root directory for all operations
+ const Pathname _dbPath; // directory (below root) that contains the rpmdb
+ rpmdb _db; // database handle
+ shared_ptr<RpmException> _error; // database error
- friend ostream & operator<<( ostream & str, const D & obj ) {
- str << "{" << obj._error << "(" << obj._root << ")" << obj._dbPath << "}";
- return str;
- }
+ friend ostream & operator<<( ostream & str, const D & obj )
+ {
+ str << "{" << obj._error << "(" << obj._root << ")" << obj._dbPath << "}";
+ return str;
+ }
- D( const Pathname & root_r, const Pathname & dbPath_r, bool readonly_r )
+ D( const Pathname & root_r, const Pathname & dbPath_r, bool readonly_r )
: _root ( root_r )
, _dbPath( dbPath_r )
, _db ( 0 )
+ {
+ _error.reset();
+ // set %_dbpath macro
+ ::addMacro( NULL, "_dbpath", NULL, _dbPath.asString().c_str(), RMIL_CMDLINE );
+ const char * root = ( _root == "/" ? NULL : _root.asString().c_str() );
+ int perms = 0644;
+
+ // check whether to create a new db
+ PathInfo master( _root + _dbPath + "Packages" );
+ if ( ! master.isFile() )
{
- _error.reset();
- // set %_dbpath macro
- ::addMacro( NULL, "_dbpath", NULL, _dbPath.asString().c_str(), RMIL_CMDLINE );
- const char * root = ( _root == "/" ? NULL : _root.asString().c_str() );
- int perms = 0644;
-
- // check whether to create a new db
- PathInfo master( _root + _dbPath + "Packages" );
- if ( ! master.isFile() ) {
- // init database
- int res = ::rpmdbInit( root, perms );
- if ( res ) {
- ERR << "rpmdbInit error(" << res << "): " << *this << endl;
- _error = shared_ptr<RpmInitException>(new RpmInitException(_root, _dbPath));
- ZYPP_THROW(*_error);
- }
+ // init database
+ int res = ::rpmdbInit( root, perms );
+ if ( res )
+ {
+ ERR << "rpmdbInit error(" << res << "): " << *this << endl;
+ _error = shared_ptr<RpmInitException>(new RpmInitException(_root, _dbPath));
+ ZYPP_THROW(*_error);
}
+ }
- // open database
- int res = ::rpmdbOpen( root, &_db, (readonly_r ? O_RDONLY : O_RDWR ), perms );
- if ( res || !_db ) {
- if ( _db ) {
- ::rpmdbClose( _db );
- _db = 0;
- }
- ERR << "rpmdbOpen error(" << res << "): " << *this << endl;
- _error = shared_ptr<RpmDbOpenException>(new RpmDbOpenException(_root, _dbPath));
- ZYPP_THROW(*_error);
- return;
+ // open database
+ int res = ::rpmdbOpen( root, &_db, (readonly_r ? O_RDONLY : O_RDWR ), perms );
+ if ( res || !_db )
+ {
+ if ( _db )
+ {
+ ::rpmdbClose( _db );
+ _db = 0;
}
-
- DBG << "DBACCESS " << *this << endl;
+ ERR << "rpmdbOpen error(" << res << "): " << *this << endl;
+ _error = shared_ptr<RpmDbOpenException>(new RpmDbOpenException(_root, _dbPath));
+ ZYPP_THROW(*_error);
+ return;
}
- ~D() {
- if ( _db ) {
+ DBG << "DBACCESS " << *this << endl;
+ }
+
+ ~D()
+ {
+ if ( _db )
+ {
::rpmdbClose( _db );
- }
}
+ }
};
///////////////////////////////////////////////////////////////////
return true;
int rc = ::rpmReadConfigFiles( NULL, NULL );
- if ( rc ) {
+ if ( rc )
+ {
ERR << "rpmReadConfigFiles returned " << rc << endl;
return false;
}
#define OUTVAL(n) << " (" #n ":" << expand( "%{" #n "}" ) << ")"
MIL << "librpm init done:"
- OUTVAL(_target)
- OUTVAL(_dbpath)
- << endl;
+ OUTVAL(_target)
+ OUTVAL(_dbpath)
+ << endl;
#undef OUTVAL
return initialized;
}
librpmDb * librpmDb::newLibrpmDb( Pathname root_r, Pathname dbPath_r, bool readonly_r )
{
// check arguments
- if ( ! (root_r.absolute() && dbPath_r.absolute()) ) {
+ if ( ! (root_r.absolute() && dbPath_r.absolute()) )
+ {
ZYPP_THROW(RpmInvalidRootException(root_r, dbPath_r));
}
// initialize librpm
- if ( ! globalInit() ) {
+ if ( ! globalInit() )
+ {
ZYPP_THROW(GlobalRpmInitException());
}
// open rpmdb
librpmDb * ret = 0;
- try {
+ try
+ {
ret = new librpmDb( root_r, dbPath_r, readonly_r );
}
catch (const RpmException & excpt_r)
void librpmDb::dbAccess( const Pathname & root_r, const Pathname & dbPath_r )
{
// check arguments
- if ( ! (root_r.absolute() && dbPath_r.absolute()) ) {
+ if ( ! (root_r.absolute() && dbPath_r.absolute()) )
+ {
ZYPP_THROW(RpmInvalidRootException(root_r, dbPath_r));
}
- if ( _defaultDb ) {
+ if ( _defaultDb )
+ {
// already accessing a database: switching is not allowed.
if ( _defaultRoot == root_r && _defaultDbPath == dbPath_r )
return;
- else {
+ else
+ {
ZYPP_THROW(RpmDbAlreadyOpenException(_defaultRoot, _defaultDbPath, root_r, dbPath_r));
}
}
//
void librpmDb::dbAccess()
{
- if ( _dbBlocked ) {
+ if ( _dbBlocked )
+ {
ZYPP_THROW(RpmAccessBlockedException(_defaultRoot, _defaultDbPath));
}
- if ( !_defaultDb ) {
+ if ( !_defaultDb )
+ {
// get access
_defaultDb = newLibrpmDb( _defaultRoot, _defaultDbPath, /*readonly*/true );
}
//
void librpmDb::dbAccess( librpmDb::constPtr & ptr_r )
{
- try {
+ try
+ {
dbAccess();
}
catch (const RpmException & excpt_r)
//
unsigned librpmDb::dbRelease( bool force_r )
{
- if ( !_defaultDb ) {
+ if ( !_defaultDb )
+ {
return 0;
}
unsigned outstanding = _defaultDb->refCount() - 1; // refCount can't be 0
- switch ( outstanding ) {
+ switch ( outstanding )
+ {
default:
- if ( !force_r ) {
+ if ( !force_r )
+ {
DBG << "dbRelease: keep access, outstanding " << outstanding << endl;
break;
}
// else fall through:
case 0:
DBG << "dbRelease: release" << (force_r && outstanding ? "(forced)" : "")
- << ", outstanding " << outstanding << endl;
+ << ", outstanding " << outstanding << endl;
_defaultDb->_d._error = shared_ptr<RpmAccessBlockedException>(new RpmAccessBlockedException(_defaultDb->_d._root, _defaultDb->_d._dbPath));
// tag handle invalid
//
ostream & librpmDb::dumpState( ostream & str )
{
- if ( !_defaultDb ) {
+ if ( !_defaultDb )
+ {
return str << "[librpmDb " << (_dbBlocked?"BLOCKED":"CLOSED") << " " << stringPath( _defaultRoot, _defaultDbPath ) << "]";
}
return str << "[" << _defaultDb << "]";
//
librpmDb::librpmDb( const Pathname & root_r, const Pathname & dbPath_r, bool readonly_r )
: _d( * new D( root_r, dbPath_r, readonly_r ) )
-{
-}
+{}
///////////////////////////////////////////////////////////////////
//
//
void librpmDb::unref_to( unsigned refCount_r ) const
{
- if ( refCount_r == 1 ) {
+ if ( refCount_r == 1 )
+ {
dbRelease();
}
}
{
unsigned count = 0;
if ( valid() )
- {
- dbiIndex dbi = dbiOpen( _d._db, RPMTAG_NAME, 0 );
- if ( dbi )
- {
- DBC * dbcursor = 0;
- dbiCopen( dbi, dbi->dbi_txnid, &dbcursor, 0 );
-
- DBT key, data;
- memset( &key, 0, sizeof(key) );
- memset( &data, 0, sizeof(data) );
- while ( dbiGet( dbi, dbcursor, &key, &data, DB_NEXT ) == 0 )
- count += data.size / dbi->dbi_jlen;
-
- dbiCclose( dbi, dbcursor, 0 );
- /* no need to close dbi */
+ {
+#if defined(_RPM_4_4_COMPAT) || defined(_RPM_5)
+ // looks like rpm-4.7 has no public dbi interface anymore
+ int dbi = ::rpmdbOpen("/", &_d._db, O_RDONLY, 0);
+ if (dbi == 0) {
+ rpmdbMatchIterator mi = ::rpmdbInitIterator(_d._db, RPMTAG_NAME, NULL, 0);
+ if (mi != NULL) {
+ for (;;) {
+ Header rpmHeader = ::rpmdbNextIterator(mi);
+ if (rpmHeader != NULL)
+ ++count;
+ }
}
+ ::rpmdbClose(_d._db);
+ }
+#else
+ dbiIndex dbi = dbiOpen( _d._db, RPMTAG_NAME, 0 );
+ if ( dbi )
+ {
+ DBC * dbcursor = 0;
+ dbiCopen( dbi, dbi->dbi_txnid, &dbcursor, 0 );
+
+ DBT key, data;
+ memset( &key, 0, sizeof(key) );
+ memset( &data, 0, sizeof(data) );
+ while ( dbiGet( dbi, dbcursor, &key, &data, DB_NEXT ) == 0 )
+ count += data.size / dbi->dbi_jlen;
+
+ dbiCclose( dbi, dbcursor, 0 );
+ /* no need to close dbi */
}
+#endif
+ }
return count;
}
, _dbPath( dbPath_r )
{
// check and adjust arguments
- if ( ! (root_r.absolute() && dbPath_r.absolute()) ) {
+ if ( ! (root_r.absolute() && dbPath_r.absolute()) )
+ {
ERR << "Relative path for root(" << _root << ") or dbPath(" << _dbPath << ")" << endl;
- } else {
+ }
+ else
+ {
_dbDir ( _root + _dbPath );
_dbV4 ( _dbDir.path() + "Packages" );
_dbV3 ( _dbDir.path() + "packages.rpm" );
*/
std::ostream & operator<<( std::ostream & str, const librpmDb::DbDirInfo & obj )
{
- if ( obj.illegalArgs() ) {
+ if ( obj.illegalArgs() )
+ {
str << "ILLEGAL: '(" << obj.root() << ")" << obj.dbPath() << "'";
- } else {
+ }
+ else
+ {
str << "'(" << obj.root() << ")" << obj.dbPath() << "':" << endl;
str << " Dir: " << obj._dbDir << endl;
str << " V4: " << obj._dbV4 << endl;
/**
*
**/
-class librpmDb::db_const_iterator::D {
+class librpmDb::db_const_iterator::D
+{
D & operator=( const D & ); // NO ASSIGNMENT!
D ( const D & ); // NO COPY!
- public:
+public:
- librpmDb::constPtr _dbptr;
- shared_ptr<RpmException> _dberr;
+ librpmDb::constPtr _dbptr;
+ shared_ptr<RpmException> _dberr;
- RpmHeader::constPtr _hptr;
- rpmdbMatchIterator _mi;
+ RpmHeader::constPtr _hptr;
+ rpmdbMatchIterator _mi;
- D( librpmDb::constPtr dbptr_r )
+ D( librpmDb::constPtr dbptr_r )
: _dbptr( dbptr_r )
, _mi( 0 )
+ {
+ if ( !_dbptr )
{
- if ( !_dbptr ) {
- try {
- librpmDb::dbAccess( _dbptr );
- }
- catch (const RpmException & excpt_r)
- {
- ZYPP_CAUGHT(excpt_r);
- }
- if ( !_dbptr ) {
- WAR << "No database access: " << _dberr << endl;
- }
- } else {
- destroy(); // Checks whether _dbptr still valid
+ try
+ {
+ librpmDb::dbAccess( _dbptr );
}
- }
-
- ~D() {
- if ( _mi ) {
- ::rpmdbFreeIterator( _mi );
+ catch (const RpmException & excpt_r)
+ {
+ ZYPP_CAUGHT(excpt_r);
}
+ if ( !_dbptr )
+ {
+ WAR << "No database access: " << _dberr << endl;
+ }
+ }
+ else
+ {
+ destroy(); // Checks whether _dbptr still valid
}
+ }
- /**
- * Let iterator access a dbindex file. Call @ref advance to access the
- * 1st element (if present).
- **/
- bool create( int rpmtag, const void * keyp = NULL, size_t keylen = 0 ) {
- destroy();
- if ( ! _dbptr )
- return false;
- _mi = ::rpmdbInitIterator( _dbptr->_d._db, rpmTag(rpmtag), keyp, keylen );
- return _mi;
+ ~D()
+ {
+ if ( _mi )
+ {
+ ::rpmdbFreeIterator( _mi );
}
+ }
- /**
- * Destroy iterator. Invalidates _dbptr, if database was blocked meanwile.
- * Always returns false.
- **/
- bool destroy() {
- if ( _mi ) {
- _mi = ::rpmdbFreeIterator( _mi );
- _hptr = 0;
- }
- if ( _dbptr && _dbptr->error() ) {
- _dberr = _dbptr->error();
- WAR << "Lost database access: " << _dberr << endl;
- _dbptr = 0;
- }
+ /**
+ * Let iterator access a dbindex file. Call @ref advance to access the
+ * 1st element (if present).
+ **/
+ bool create( int rpmtag, const void * keyp = NULL, size_t keylen = 0 )
+ {
+ destroy();
+ if ( ! _dbptr )
return false;
- }
+ _mi = ::rpmdbInitIterator( _dbptr->_d._db, rpmTag(rpmtag), keyp, keylen );
+ return _mi;
+ }
- /**
- * Advance to the first/next header in iterator. Destroys iterator if
- * no more headers available.
- **/
- bool advance() {
- if ( !_mi )
- return false;
- Header h = ::rpmdbNextIterator( _mi );
- if ( ! h ) {
- destroy();
- return false;
- }
- _hptr = new RpmHeader( h );
- return true;
+ /**
+ * Destroy iterator. Invalidates _dbptr, if database was blocked meanwile.
+ * Always returns false.
+ **/
+ bool destroy()
+ {
+ if ( _mi )
+ {
+ _mi = ::rpmdbFreeIterator( _mi );
+ _hptr = 0;
+ }
+ if ( _dbptr && _dbptr->error() )
+ {
+ _dberr = _dbptr->error();
+ WAR << "Lost database access: " << _dberr << endl;
+ _dbptr = 0;
}
+ return false;
+ }
- /**
- * Access a dbindex file and advance to the 1st header.
- **/
- bool init( int rpmtag, const void * keyp = NULL, size_t keylen = 0 ) {
- if ( ! create( rpmtag, keyp, keylen ) )
- return false;
- return advance();
+ /**
+ * Advance to the first/next header in iterator. Destroys iterator if
+ * no more headers available.
+ **/
+ bool advance()
+ {
+ if ( !_mi )
+ return false;
+ Header h = ::rpmdbNextIterator( _mi );
+ if ( ! h )
+ {
+ destroy();
+ return false;
}
+ _hptr = new RpmHeader( h );
+ return true;
+ }
- /**
- * Create an itertator that contains the database entry located at
- * off_r, and advance to the 1st header.
- **/
- bool set( int off_r ) {
- if ( ! create( RPMDBI_PACKAGES ) )
- return false;
+ /**
+ * Access a dbindex file and advance to the 1st header.
+ **/
+ bool init( int rpmtag, const void * keyp = NULL, size_t keylen = 0 )
+ {
+ if ( ! create( rpmtag, keyp, keylen ) )
+ return false;
+ return advance();
+ }
+
+ /**
+ * Create an itertator that contains the database entry located at
+ * off_r, and advance to the 1st header.
+ **/
+ bool set( int off_r )
+ {
+ if ( ! create( RPMDBI_PACKAGES ) )
+ return false;
#warning TESTCASE: rpmdbAppendIterator and (non)sequential access?
- ::rpmdbAppendIterator( _mi, &off_r, 1 );
- return advance();
- }
+ ::rpmdbAppendIterator( _mi, &off_r, 1 );
+ return advance();
+ }
- unsigned offset() {
- return( _mi ? ::rpmdbGetIteratorOffset( _mi ) : 0 );
- }
+ unsigned offset()
+ {
+ return( _mi ? ::rpmdbGetIteratorOffset( _mi ) : 0 );
+ }
- int size() {
- if ( !_mi )
- return 0;
- int ret = ::rpmdbGetIteratorCount( _mi );
+ int size()
+ {
+ if ( !_mi )
+ return 0;
+ int ret = ::rpmdbGetIteratorCount( _mi );
#warning TESTCASE: rpmdbGetIteratorCount returns 0 on sequential access?
- return( ret ? ret : -1 ); // -1: sequential access
- }
+ return( ret ? ret : -1 ); // -1: sequential access
+ }
};
///////////////////////////////////////////////////////////////////
ostream & operator<<( ostream & str, const librpmDb::db_const_iterator & obj )
{
str << "db_const_iterator(" << obj._d._dbptr
- << " Size:" << obj._d.size()
- << " HdrNum:" << obj._d.offset()
- << ")";
+ << " Size:" << obj._d.size()
+ << " HdrNum:" << obj._d.offset()
+ << ")";
return str;
}
// check installtime on multiple entries
int match = 0;
time_t itime = 0;
- for ( ; operator*(); operator++() ) {
- if ( operator*()->tag_installtime() > itime ) {
+ for ( ; operator*(); operator++() )
+ {
+ if ( operator*()->tag_installtime() > itime )
+ {
match = _d.offset();
itime = operator*()->tag_installtime();
}
if ( ! _d.init( RPMTAG_NAME, name_r.c_str() ) )
return false;
- for ( ; operator*(); operator++() ) {
- if ( ed_r == operator*()->tag_edition() ) {
+ for ( ; operator*(); operator++() )
+ {
+ if ( ed_r == operator*()->tag_edition() )
+ {
int match = _d.offset();
return _d.set( match );
}
return findPackage( which_r->name(), which_r->edition() );
}
- } // namespace rpm
- } // namespace target
+} // namespace rpm
+} // namespace target
} // namespace zypp