librpmDb.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include "librpm.h"
00013 
00014 #include <iostream>
00015 
00016 #include "zypp/base/Logger.h"
00017 #include "zypp/target/rpm/librpmDb.h"
00018 #include "zypp/target/rpm/RpmHeader.h"
00019 #include "zypp/target/rpm/RpmException.h"
00020 
00021 using namespace std;
00022 
00023 namespace zypp {
00024   namespace target {
00025     namespace rpm {
00027 //
00028 //      CLASS NAME : librpmDb::D
00032 class librpmDb::D {
00033   D & operator=( const D & ); // NO ASSIGNMENT!
00034   D ( const D & );            // NO COPY!
00035   public:
00036 
00037     const Pathname _root;   // root directory for all operations
00038     const Pathname _dbPath; // directory (below root) that contains the rpmdb
00039     rpmdb          _db;     // database handle
00040     shared_ptr<RpmException> _error;  // database error
00041 
00042     friend ostream & operator<<( ostream & str, const D & obj ) {
00043       str << "{" << obj._error  << "(" << obj._root << ")" << obj._dbPath << "}";
00044       return str;
00045     }
00046 
00047     D( const Pathname & root_r, const Pathname & dbPath_r, bool readonly_r )
00048       : _root  ( root_r )
00049       , _dbPath( dbPath_r )
00050       , _db    ( 0 )
00051     {
00052       _error.reset();
00053       // set %_dbpath macro
00054       ::addMacro( NULL, "_dbpath", NULL, _dbPath.asString().c_str(), RMIL_CMDLINE );
00055       const char * root = ( _root == "/" ? NULL : _root.asString().c_str() );
00056       int          perms = 0644;
00057 
00058       // check whether to create a new db
00059       PathInfo master( _root + _dbPath + "Packages" );
00060       if ( ! master.isFile() ) {
00061         // init database
00062         int res = ::rpmdbInit( root, perms );
00063         if ( res ) {
00064           ERR << "rpmdbInit error(" << res << "): " << *this << endl;
00065           _error = shared_ptr<RpmInitException>(new RpmInitException(_root, _dbPath));
00066           ZYPP_THROW(*_error);
00067         }
00068       }
00069 
00070       // open database
00071       int res = ::rpmdbOpen( root, &_db, (readonly_r ? O_RDONLY : O_RDWR ), perms );
00072       if ( res || !_db ) {
00073         if ( _db ) {
00074           ::rpmdbClose( _db );
00075           _db = 0;
00076         }
00077         ERR << "rpmdbOpen error(" << res << "): " << *this << endl;
00078         _error = shared_ptr<RpmDbOpenException>(new RpmDbOpenException(_root, _dbPath));
00079         ZYPP_THROW(*_error);
00080         return;
00081       }
00082 
00083       DBG << "DBACCESS " << *this << endl;
00084     }
00085 
00086     ~D() {
00087       if ( _db ) {
00088 #if 0
00089         // login here may cause a SEGV, if call is caused by
00090         // static variables being deleted. Might be that PMError
00091         // static strings or logstreams are already destructed.
00092         int res = ::rpmdbClose( _db );
00093         if ( res ) {
00094           WAR << "::rpmdbClose error(" << res << ")" << endl;
00095         }
00096         DBG << "DBCLOSE " << *this << endl;
00097 #else
00098       ::rpmdbClose( _db );
00099 #endif
00100       }
00101     }
00102 };
00103 
00105 
00107 //
00108 //      CLASS NAME : librpmDb (ststic interface)
00109 //
00111 
00112 Pathname         librpmDb::_defaultRoot  ( "/" );
00113 Pathname         librpmDb::_defaultDbPath( "/var/lib/rpm" );
00114 librpmDb::constPtr librpmDb::_defaultDb;
00115 bool             librpmDb::_dbBlocked    ( true );
00116 
00118 //
00119 //
00120 //      METHOD NAME : librpmDb::globalInit
00121 //      METHOD TYPE : bool
00122 //
00123 bool librpmDb::globalInit()
00124 {
00125   static bool initialized = false;
00126 
00127   if ( initialized )
00128     return true;
00129 
00130   int rc = ::rpmReadConfigFiles( NULL, NULL );
00131   if ( rc ) {
00132     ERR << "rpmReadConfigFiles returned " << rc << endl;
00133     return false;
00134   }
00135 
00136   // should speed up convertdb and rebuilddb.
00137   ::addMacro( NULL, "_rpmdb_rebuild", NULL, "%{nil}", RMIL_CMDLINE );
00138 
00139   initialized = true; // Necessary to be able to use exand().
00140 
00141 #define OUTVAL(n) << " (" #n ":" << expand( "%{" #n "}" ) << ")"
00142   MIL << "librpm init done:"
00143     OUTVAL(_target)
00144     OUTVAL(_dbpath)
00145       << endl;
00146 #undef OUTVAL
00147   return initialized;
00148 }
00149 
00151 //
00152 //
00153 //      METHOD NAME : librpmDb::expand
00154 //      METHOD TYPE : std::string
00155 //
00156 std::string librpmDb::expand( const std::string & macro_r )
00157 {
00158   if ( ! globalInit() )
00159     return macro_r;  // unexpanded
00160 
00161   char * val = ::rpmExpand( macro_r.c_str(), NULL );
00162   if ( !val )
00163     return "";
00164 
00165   string ret( val );
00166   free( val );
00167   return ret;
00168 }
00169 
00171 //
00172 //
00173 //      METHOD NAME : librpmDb::newLibrpmDb
00174 //      METHOD TYPE : librpmDb *
00175 //
00176 librpmDb * librpmDb::newLibrpmDb( Pathname root_r, Pathname dbPath_r, bool readonly_r )
00177 {
00178   // check arguments
00179   if ( ! (root_r.absolute() && dbPath_r.absolute()) ) {
00180     ZYPP_THROW(RpmInvalidRootException(root_r, dbPath_r));
00181   }
00182 
00183   // initialize librpm
00184   if ( ! globalInit() ) {
00185     ZYPP_THROW(GlobalRpmInitException());
00186   }
00187 
00188   // open rpmdb
00189   librpmDb * ret = 0;
00190   try {
00191     ret = new librpmDb( root_r, dbPath_r, readonly_r );
00192   }
00193   catch (const RpmException & excpt_r)
00194   {
00195     ZYPP_CAUGHT(excpt_r);
00196     delete ret;
00197     ret = 0;
00198     ZYPP_RETHROW(excpt_r);
00199   }
00200   return ret;
00201 }
00202 
00204 //
00205 //
00206 //      METHOD NAME : librpmDb::dbAccess
00207 //      METHOD TYPE : PMError
00208 //
00209 void librpmDb::dbAccess( const Pathname & root_r, const Pathname & dbPath_r )
00210 {
00211   // check arguments
00212   if ( ! (root_r.absolute() && dbPath_r.absolute()) ) {
00213     ZYPP_THROW(RpmInvalidRootException(root_r, dbPath_r));
00214   }
00215 
00216   if ( _defaultDb ) {
00217     // already accessing a database: switching is not allowed.
00218     if ( _defaultRoot == root_r && _defaultDbPath == dbPath_r )
00219       return;
00220     else {
00221       ZYPP_THROW(RpmDbAlreadyOpenException(_defaultRoot, _defaultDbPath, root_r, dbPath_r));
00222     }
00223   }
00224 
00225   // got no database: we could switch to a new one (even if blocked!)
00226   _defaultRoot = root_r;
00227   _defaultDbPath = dbPath_r;
00228   MIL << "Set new database location: " << stringPath( _defaultRoot, _defaultDbPath ) << endl;
00229 
00230   return dbAccess();
00231 }
00232 
00234 //
00235 //
00236 //      METHOD NAME : librpmDb::dbAccess
00237 //      METHOD TYPE : PMError
00238 //
00239 void librpmDb::dbAccess()
00240 {
00241   if ( _dbBlocked ) {
00242     ZYPP_THROW(RpmAccessBlockedException(_defaultRoot, _defaultDbPath));
00243   }
00244 
00245   if ( !_defaultDb ) {
00246     // get access
00247     _defaultDb = newLibrpmDb( _defaultRoot, _defaultDbPath, /*readonly*/true );
00248   }
00249 }
00250 
00252 //
00253 //
00254 //      METHOD NAME : librpmDb::dbAccess
00255 //      METHOD TYPE : PMError
00256 //
00257 void librpmDb::dbAccess( librpmDb::constPtr & ptr_r )
00258 {
00259   try {
00260     dbAccess();
00261   }
00262   catch (const RpmException & excpt_r)
00263   {
00264     ZYPP_CAUGHT(excpt_r);
00265     ptr_r = 0;
00266     ZYPP_RETHROW(excpt_r);
00267   }
00268   ptr_r = _defaultDb;
00269 }
00270 
00272 //
00273 //
00274 //      METHOD NAME : librpmDb::dbRelease
00275 //      METHOD TYPE : unsigned
00276 //
00277 unsigned librpmDb::dbRelease( bool force_r )
00278 {
00279   if ( !_defaultDb ) {
00280     return 0;
00281   }
00282 
00283   unsigned outstanding = _defaultDb->refCount() - 1; // refCount can't be 0
00284 
00285   switch ( outstanding ) {
00286   default:
00287     if ( !force_r ) {
00288       DBG << "dbRelease: keep access, outstanding " << outstanding << endl;
00289       break;
00290     }
00291     // else fall through:
00292   case 0:
00293     DBG << "dbRelease: release" << (force_r && outstanding ? "(forced)" : "")
00294       << ", outstanding " << outstanding << endl;
00295 
00296     _defaultDb->_d._error = shared_ptr<RpmAccessBlockedException>(new RpmAccessBlockedException(_defaultDb->_d._root, _defaultDb->_d._dbPath));
00297     // tag handle invalid
00298     _defaultDb = 0;
00299     break;
00300   }
00301 
00302   return outstanding;
00303 }
00304 
00306 //
00307 //
00308 //      METHOD NAME : librpmDb::blockAccess
00309 //      METHOD TYPE : unsigned
00310 //
00311 unsigned librpmDb::blockAccess()
00312 {
00313   MIL << "Block access" << endl;
00314   _dbBlocked = true;
00315   return dbRelease( /*force*/true );
00316 }
00317 
00319 //
00320 //
00321 //      METHOD NAME : librpmDb::unblockAccess
00322 //      METHOD TYPE : void
00323 //
00324 void librpmDb::unblockAccess()
00325 {
00326   MIL << "Unblock access" << endl;
00327   _dbBlocked = false;
00328 }
00329 
00331 //
00332 //
00333 //      METHOD NAME : librpmDb::dumpState
00334 //      METHOD TYPE : ostream &
00335 //
00336 ostream & librpmDb::dumpState( ostream & str )
00337 {
00338   if ( !_defaultDb ) {
00339     return str << "[librpmDb " << (_dbBlocked?"BLOCKED":"CLOSED") << " " << stringPath( _defaultRoot, _defaultDbPath ) << "]";
00340   }
00341   return str << "[" << _defaultDb << "]";
00342 }
00343 
00345 //
00346 //      CLASS NAME : librpmDb (internal database handle interface (nonstatic))
00347 //
00349 
00351 //
00352 //
00353 //      METHOD NAME : librpmDb::librpmDb
00354 //      METHOD TYPE : Constructor
00355 //
00356 //      DESCRIPTION :
00357 //
00358 librpmDb::librpmDb( const Pathname & root_r, const Pathname & dbPath_r, bool readonly_r )
00359     : _d( * new D( root_r, dbPath_r, readonly_r ) )
00360 {
00361 }
00362 
00364 //
00365 //
00366 //      METHOD NAME : librpmDb::~librpmDb
00367 //      METHOD TYPE : Destructor
00368 //
00369 //      DESCRIPTION :
00370 //
00371 librpmDb::~librpmDb()
00372 {
00373   delete &_d;
00374 }
00375 
00377 //
00378 //
00379 //      METHOD NAME : librpmDb::unref_to
00380 //      METHOD TYPE : void
00381 //
00382 void librpmDb::unref_to( unsigned refCount_r ) const
00383 {
00384   if ( refCount_r == 1 ) {
00385     dbRelease();
00386   }
00387 }
00388 
00390 //
00391 //
00392 //      METHOD NAME : librpmDb::root
00393 //      METHOD TYPE : const Pathname &
00394 //
00395 const Pathname & librpmDb::root() const
00396 {
00397   return _d._root;
00398 }
00399 
00401 //
00402 //
00403 //      METHOD NAME : librpmDb::dbPath
00404 //      METHOD TYPE : const Pathname &
00405 //
00406 const Pathname & librpmDb::dbPath() const
00407 {
00408   return _d._dbPath;
00409 }
00410 
00412 //
00413 //
00414 //      METHOD NAME : librpmDb::error
00415 //      METHOD TYPE : PMError
00416 //
00417 shared_ptr<RpmException> librpmDb::error() const
00418 {
00419   return _d._error;
00420 }
00421 
00423 //
00424 //
00425 //      METHOD NAME : librpmDb::empty
00426 //      METHOD TYPE : bool
00427 //
00428 bool librpmDb::empty() const
00429 {
00430   return( valid() && ! *db_const_iterator( this ) );
00431 }
00432 
00434 //
00435 //
00436 //      METHOD NAME : librpmDb::dont_call_it
00437 //      METHOD TYPE : void *
00438 //
00439 void * librpmDb::dont_call_it() const
00440 {
00441   return _d._db;
00442 }
00443 
00445 //
00446 //
00447 //      METHOD NAME : librpmDb::dumpOn
00448 //      METHOD TYPE : ostream &
00449 //
00450 //      DESCRIPTION :
00451 //
00452 ostream & librpmDb::dumpOn( ostream & str ) const
00453 {
00454   ReferenceCounted::dumpOn( str ) << _d;
00455   return str;
00456 }
00457 
00459 //
00460 //      CLASS NAME : librpmDb::DbDirInfo
00461 //
00463 
00465 //
00466 //
00467 //      METHOD NAME : librpmDb::DbDirInfo::DbDirInfo
00468 //      METHOD TYPE : Constructor
00469 //
00470 librpmDb::DbDirInfo::DbDirInfo( const Pathname & root_r, const Pathname & dbPath_r )
00471     : _root( root_r )
00472     , _dbPath( dbPath_r )
00473 {
00474   // check and adjust arguments
00475   if ( ! (root_r.absolute() && dbPath_r.absolute()) ) {
00476     ERR << "Relative path for root(" << _root << ") or dbPath(" << _dbPath << ")" << endl;
00477   } else {
00478     _dbDir   ( _root + _dbPath );
00479     _dbV4    ( _dbDir.path() + "Packages" );
00480     _dbV3    ( _dbDir.path() + "packages.rpm" );
00481     _dbV3ToV4( _dbDir.path() + "packages.rpm3" );
00482     DBG << *this << endl;
00483   }
00484 }
00485 
00487 //
00488 //
00489 //      METHOD NAME : librpmDb::DbDirInfo::update
00490 //      METHOD TYPE : void
00491 //
00492 void librpmDb::DbDirInfo::restat()
00493 {
00494   _dbDir();
00495   _dbV4();
00496   _dbV3();
00497   _dbV3ToV4();
00498   DBG << *this << endl;
00499 }
00500 
00501 /******************************************************************
00502 **
00503 **
00504 **      FUNCTION NAME : operator<<
00505 **      FUNCTION TYPE : std::ostream &
00506 */
00507 std::ostream & operator<<( std::ostream & str, const librpmDb::DbDirInfo & obj )
00508 {
00509   if ( obj.illegalArgs() ) {
00510     str << "ILLEGAL: '(" << obj.root() << ")" << obj.dbPath() << "'";
00511   } else {
00512     str << "'(" << obj.root() << ")" << obj.dbPath() << "':" << endl;
00513     str << "  Dir:    " << obj._dbDir << endl;
00514     str << "  V4:     " << obj._dbV4 << endl;
00515     str << "  V3:     " << obj._dbV3 << endl;
00516     str << "  V3ToV4: " << obj._dbV3ToV4;
00517   }
00518   return str;
00519 }
00520 
00522 //
00523 //      CLASS NAME : librpmDb::db_const_iterator::D
00527 class librpmDb::db_const_iterator::D {
00528   D & operator=( const D & ); // NO ASSIGNMENT!
00529   D ( const D & );            // NO COPY!
00530   public:
00531 
00532     librpmDb::constPtr     _dbptr;
00533     shared_ptr<RpmException> _dberr;
00534 
00535     RpmHeader::constPtr _hptr;
00536     rpmdbMatchIterator   _mi;
00537 
00538     D( librpmDb::constPtr dbptr_r )
00539       : _dbptr( dbptr_r )
00540       , _mi( 0 )
00541     {
00542       if ( !_dbptr ) {
00543         try {
00544           librpmDb::dbAccess( _dbptr );
00545         }
00546         catch (const RpmException & excpt_r)
00547         {
00548           ZYPP_CAUGHT(excpt_r);
00549         }
00550         if ( !_dbptr ) {
00551           WAR << "No database access: " << _dberr << endl;
00552         }
00553       } else {
00554         destroy(); // Checks whether _dbptr still valid
00555       }
00556     }
00557 
00558     ~D() {
00559       if ( _mi ) {
00560         ::rpmdbFreeIterator( _mi );
00561       }
00562     }
00563 
00568     bool create( int rpmtag, const void * keyp = NULL, size_t keylen = 0 ) {
00569       destroy();
00570       if ( ! _dbptr )
00571         return false;
00572       _mi = ::rpmdbInitIterator( _dbptr->_d._db, rpmTag(rpmtag), keyp, keylen );
00573       return _mi;
00574     }
00575 
00580     bool destroy() {
00581       if ( _mi ) {
00582         _mi = ::rpmdbFreeIterator( _mi );
00583         _hptr = 0;
00584       }
00585       if ( _dbptr && _dbptr->error() ) {
00586         _dberr = _dbptr->error();
00587         WAR << "Lost database access: " << _dberr << endl;
00588         _dbptr = 0;
00589       }
00590       return false;
00591     }
00592 
00597     bool advance() {
00598       if ( !_mi )
00599         return false;
00600       Header h = ::rpmdbNextIterator( _mi );
00601       if ( ! h ) {
00602         destroy();
00603         return false;
00604       }
00605       _hptr = new RpmHeader( h );
00606       return true;
00607     }
00608 
00612     bool init( int rpmtag, const void * keyp = NULL, size_t keylen = 0 ) {
00613       if ( ! create( rpmtag, keyp, keylen ) )
00614         return false;
00615       return advance();
00616     }
00617 
00622     bool set( int off_r ) {
00623       if ( ! create( RPMDBI_PACKAGES ) )
00624         return false;
00625 #warning TESTCASE: rpmdbAppendIterator and (non)sequential access?
00626       ::rpmdbAppendIterator( _mi, &off_r, 1 );
00627       return advance();
00628     }
00629 
00630     unsigned offset() {
00631       return( _mi ? ::rpmdbGetIteratorOffset( _mi ) : 0 );
00632     }
00633 
00634     int size() {
00635       if ( !_mi )
00636         return 0;
00637       int ret = ::rpmdbGetIteratorCount( _mi );
00638 #warning TESTCASE: rpmdbGetIteratorCount returns 0 on sequential access?
00639       return( ret ? ret : -1 ); // -1: sequential access
00640     }
00641 };
00642 
00644 
00646 //
00647 //      CLASS NAME : librpmDb::Ptr::db_const_iterator
00648 //
00650 
00652 //
00653 //
00654 //      METHOD NAME : librpmDb::db_const_iterator::db_iterator
00655 //      METHOD TYPE : Constructor
00656 //
00657 librpmDb::db_const_iterator::db_const_iterator( librpmDb::constPtr dbptr_r )
00658     : _d( * new D( dbptr_r ) )
00659 {
00660   findAll();
00661 }
00662 
00664 //
00665 //
00666 //      METHOD NAME : librpmDb::db_const_iterator::~db_const_iterator
00667 //      METHOD TYPE : Destructor
00668 //
00669 librpmDb::db_const_iterator::~db_const_iterator()
00670 {
00671   delete &_d;
00672 }
00673 
00675 //
00676 //
00677 //      METHOD NAME : librpmDb::db_const_iterator::operator++
00678 //      METHOD TYPE : void
00679 //
00680 void librpmDb::db_const_iterator::operator++()
00681 {
00682   _d.advance();
00683 }
00684 
00686 //
00687 //
00688 //      METHOD NAME : librpmDb::db_const_iterator::dbHdrNum
00689 //      METHOD TYPE : unsigned
00690 //
00691 unsigned librpmDb::db_const_iterator::dbHdrNum() const
00692 {
00693   return _d.offset();
00694 }
00695 
00697 //
00698 //
00699 //      METHOD NAME : librpmDb::db_const_iterator::operator*
00700 //      METHOD TYPE : const RpmHeader::constPtr &
00701 //
00702 const RpmHeader::constPtr & librpmDb::db_const_iterator::operator*() const
00703 {
00704   return _d._hptr;
00705 }
00706 
00708 //
00709 //
00710 //      METHOD NAME : librpmDb::db_const_iterator::dbError
00711 //      METHOD TYPE : PMError
00712 //
00713 shared_ptr<RpmException> librpmDb::db_const_iterator::dbError() const
00714 {
00715   if ( _d._dbptr )
00716     return _d._dbptr->error();
00717 
00718   return _d._dberr;
00719 }
00720 
00721 /******************************************************************
00722 **
00723 **
00724 **      FUNCTION NAME : operator<<
00725 **      FUNCTION TYPE : ostream &
00726 */
00727 ostream & operator<<( ostream & str, const librpmDb::db_const_iterator & obj )
00728 {
00729   str << "db_const_iterator(" << obj._d._dbptr
00730     << " Size:" << obj._d.size()
00731       << " HdrNum:" << obj._d.offset()
00732         << ")";
00733   return str;
00734 }
00735 
00737 //
00738 //
00739 //      METHOD NAME : librpmDb::db_const_iterator::findAll
00740 //      METHOD TYPE : bool
00741 //
00742 bool librpmDb::db_const_iterator::findAll()
00743 {
00744   return _d.init( RPMDBI_PACKAGES );
00745 }
00746 
00748 //
00749 //
00750 //      METHOD NAME : librpmDb::db_const_iterator::findByFile
00751 //      METHOD TYPE : bool
00752 //
00753 bool librpmDb::db_const_iterator::findByFile( const std::string & file_r )
00754 {
00755   return _d.init( RPMTAG_BASENAMES, file_r.c_str() );
00756 }
00757 
00759 //
00760 //
00761 //      METHOD NAME : librpmDb::db_const_iterator::findByProvides
00762 //      METHOD TYPE : bool
00763 //
00764 bool librpmDb::db_const_iterator::findByProvides( const std::string & tag_r )
00765 {
00766   return _d.init( RPMTAG_PROVIDENAME, tag_r.c_str() );
00767 }
00768 
00770 //
00771 //
00772 //      METHOD NAME : librpmDb::db_const_iterator::findByRequiredBy
00773 //      METHOD TYPE : bool
00774 //
00775 bool librpmDb::db_const_iterator::findByRequiredBy( const std::string & tag_r )
00776 {
00777   return _d.init( RPMTAG_REQUIRENAME, tag_r.c_str() );
00778 }
00779 
00781 //
00782 //
00783 //      METHOD NAME : librpmDb::db_const_iterator::findByConflicts
00784 //      METHOD TYPE : bool
00785 //
00786 bool librpmDb::db_const_iterator::findByConflicts( const std::string & tag_r )
00787 {
00788   return _d.init( RPMTAG_CONFLICTNAME, tag_r.c_str() );
00789 }
00790 
00792 //
00793 //
00794 //      METHOD NAME : librpmDb::findByName
00795 //      METHOD TYPE : bool
00796 //
00797 bool librpmDb::db_const_iterator::findByName( const string & name_r )
00798 {
00799   return _d.init( RPMTAG_NAME, name_r.c_str() );
00800 }
00801 
00803 //
00804 //
00805 //      METHOD NAME : librpmDb::db_const_iterator::findPackage
00806 //      METHOD TYPE : bool
00807 //
00808 bool librpmDb::db_const_iterator::findPackage( const string & name_r )
00809 {
00810   if ( ! _d.init( RPMTAG_NAME, name_r.c_str() ) )
00811     return false;
00812 
00813   if ( _d.size() == 1 )
00814     return true;
00815 
00816   // check installtime on multiple entries
00817   int match    = 0;
00818   time_t itime = 0;
00819   for ( ; operator*(); operator++() ) {
00820     if ( operator*()->tag_installtime() > itime ) {
00821       match = _d.offset();
00822       itime = operator*()->tag_installtime();
00823     }
00824   }
00825 
00826   return _d.set( match );
00827 }
00828 
00830 //
00831 //
00832 //      METHOD NAME : librpmDb::db_const_iterator::findPackage
00833 //      METHOD TYPE : bool
00834 //
00835 bool librpmDb::db_const_iterator::findPackage( const std::string & name_r, const Edition & ed_r )
00836 {
00837   if ( ! _d.init( RPMTAG_NAME, name_r.c_str() ) )
00838     return false;
00839 
00840   for ( ; operator*(); operator++() ) {
00841     if ( ed_r == operator*()->tag_edition() ) {
00842       int match = _d.offset();
00843       return _d.set( match );
00844     }
00845   }
00846 
00847   return _d.destroy();
00848 }
00849 
00851 //
00852 //
00853 //      METHOD NAME : librpmDb::db_const_iterator::findPackage
00854 //      METHOD TYPE : bool
00855 //
00856 bool librpmDb::db_const_iterator::findPackage( const Package::constPtr & which_r )
00857 {
00858   if ( ! which_r )
00859     return _d.destroy();
00860 
00861   return findPackage( which_r->name(), which_r->edition() );
00862 }
00863 
00864     } // namespace rpm
00865   } // namespace target
00866 } // namespace zypp

Generated on Thu Jul 6 00:07:26 2006 for zypp by  doxygen 1.4.6