|
libzypp
9.1.2
|
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 { 00025 namespace target 00026 { 00027 namespace rpm 00028 { 00030 // 00031 // CLASS NAME : librpmDb::D 00035 class librpmDb::D 00036 { 00037 D & operator=( const D & ); // NO ASSIGNMENT! 00038 D ( const D & ); // NO COPY! 00039 public: 00040 00041 const Pathname _root; // root directory for all operations 00042 const Pathname _dbPath; // directory (below root) that contains the rpmdb 00043 rpmts _ts; // transaction handle, includes database 00044 shared_ptr<RpmException> _error; // database error 00045 00046 friend ostream & operator<<( ostream & str, const D & obj ) 00047 { 00048 str << "{" << obj._error << "(" << obj._root << ")" << obj._dbPath << "}"; 00049 return str; 00050 } 00051 00052 D( const Pathname & root_r, const Pathname & dbPath_r, bool readonly_r ) 00053 : _root ( root_r ) 00054 , _dbPath( dbPath_r ) 00055 , _ts ( 0 ) 00056 { 00057 _error.reset(); 00058 // set %_dbpath macro 00059 ::addMacro( NULL, "_dbpath", NULL, _dbPath.asString().c_str(), RMIL_CMDLINE ); 00060 const char * root = ( _root == "/" ? NULL : _root.asString().c_str() ); 00061 int perms = 0644; 00062 00063 _ts = ::rpmtsCreate(); 00064 ::rpmtsSetRootDir( _ts, _root.c_str() ); 00065 00066 // check whether to create a new db 00067 PathInfo master( _root + _dbPath + "Packages" ); 00068 if ( ! master.isFile() ) 00069 { 00070 // init database 00071 int res = ::rpmtsInitDB( _ts, perms ); 00072 if ( res ) 00073 { 00074 ERR << "rpmdbInit error(" << res << "): " << *this << endl; 00075 _error = shared_ptr<RpmInitException>(new RpmInitException(_root, _dbPath)); 00076 rpmtsFree(_ts); 00077 ZYPP_THROW(*_error); 00078 } 00079 } 00080 00081 // open database 00082 int res = ::rpmtsOpenDB( _ts, (readonly_r ? O_RDONLY : O_RDWR )); 00083 if ( res ) 00084 { 00085 ERR << "rpmdbOpen error(" << res << "): " << *this << endl; 00086 _error = shared_ptr<RpmDbOpenException>(new RpmDbOpenException(_root, _dbPath)); 00087 rpmtsFree(_ts); 00088 ZYPP_THROW(*_error); 00089 return; 00090 } 00091 00092 DBG << "DBACCESS " << *this << endl; 00093 } 00094 00095 ~D() 00096 { 00097 if ( _ts ) 00098 { 00099 ::rpmtsFree(_ts); 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 { 00133 ERR << "rpmReadConfigFiles returned " << rc << endl; 00134 return false; 00135 } 00136 00137 initialized = true; // Necessary to be able to use exand(). 00138 00139 #define OUTVAL(n) << " (" #n ":" << expand( "%{" #n "}" ) << ")" 00140 MIL << "librpm init done:" 00141 OUTVAL(_target) 00142 OUTVAL(_dbpath) 00143 << endl; 00144 #undef OUTVAL 00145 return initialized; 00146 } 00147 00149 // 00150 // 00151 // METHOD NAME : librpmDb::expand 00152 // METHOD TYPE : std::string 00153 // 00154 std::string librpmDb::expand( const std::string & macro_r ) 00155 { 00156 if ( ! globalInit() ) 00157 return macro_r; // unexpanded 00158 00159 char * val = ::rpmExpand( macro_r.c_str(), NULL ); 00160 if ( !val ) 00161 return ""; 00162 00163 string ret( val ); 00164 free( val ); 00165 return ret; 00166 } 00167 00169 // 00170 // 00171 // METHOD NAME : librpmDb::newLibrpmDb 00172 // METHOD TYPE : librpmDb * 00173 // 00174 librpmDb * librpmDb::newLibrpmDb( Pathname root_r, Pathname dbPath_r, bool readonly_r ) 00175 { 00176 // check arguments 00177 if ( ! (root_r.absolute() && dbPath_r.absolute()) ) 00178 { 00179 ZYPP_THROW(RpmInvalidRootException(root_r, dbPath_r)); 00180 } 00181 00182 // initialize librpm 00183 if ( ! globalInit() ) 00184 { 00185 ZYPP_THROW(GlobalRpmInitException()); 00186 } 00187 00188 // open rpmdb 00189 librpmDb * ret = 0; 00190 try 00191 { 00192 ret = new librpmDb( root_r, dbPath_r, readonly_r ); 00193 } 00194 catch (const RpmException & excpt_r) 00195 { 00196 ZYPP_CAUGHT(excpt_r); 00197 delete ret; 00198 ret = 0; 00199 ZYPP_RETHROW(excpt_r); 00200 } 00201 return ret; 00202 } 00203 00205 // 00206 // 00207 // METHOD NAME : librpmDb::dbAccess 00208 // METHOD TYPE : PMError 00209 // 00210 void librpmDb::dbAccess( const Pathname & root_r, const Pathname & dbPath_r ) 00211 { 00212 // check arguments 00213 if ( ! (root_r.absolute() && dbPath_r.absolute()) ) 00214 { 00215 ZYPP_THROW(RpmInvalidRootException(root_r, dbPath_r)); 00216 } 00217 00218 if ( _defaultDb ) 00219 { 00220 // already accessing a database: switching is not allowed. 00221 if ( _defaultRoot == root_r && _defaultDbPath == dbPath_r ) 00222 return; 00223 else 00224 { 00225 ZYPP_THROW(RpmDbAlreadyOpenException(_defaultRoot, _defaultDbPath, root_r, dbPath_r)); 00226 } 00227 } 00228 00229 // got no database: we could switch to a new one (even if blocked!) 00230 _defaultRoot = root_r; 00231 _defaultDbPath = dbPath_r; 00232 MIL << "Set new database location: " << stringPath( _defaultRoot, _defaultDbPath ) << endl; 00233 00234 return dbAccess(); 00235 } 00236 00238 // 00239 // 00240 // METHOD NAME : librpmDb::dbAccess 00241 // METHOD TYPE : PMError 00242 // 00243 void librpmDb::dbAccess() 00244 { 00245 if ( _dbBlocked ) 00246 { 00247 ZYPP_THROW(RpmAccessBlockedException(_defaultRoot, _defaultDbPath)); 00248 } 00249 00250 if ( !_defaultDb ) 00251 { 00252 // get access 00253 _defaultDb = newLibrpmDb( _defaultRoot, _defaultDbPath, /*readonly*/true ); 00254 } 00255 } 00256 00258 // 00259 // 00260 // METHOD NAME : librpmDb::dbAccess 00261 // METHOD TYPE : PMError 00262 // 00263 void librpmDb::dbAccess( librpmDb::constPtr & ptr_r ) 00264 { 00265 try 00266 { 00267 dbAccess(); 00268 } 00269 catch (const RpmException & excpt_r) 00270 { 00271 ZYPP_CAUGHT(excpt_r); 00272 ptr_r = 0; 00273 ZYPP_RETHROW(excpt_r); 00274 } 00275 ptr_r = _defaultDb; 00276 } 00277 00279 // 00280 // 00281 // METHOD NAME : librpmDb::dbRelease 00282 // METHOD TYPE : unsigned 00283 // 00284 unsigned librpmDb::dbRelease( bool force_r ) 00285 { 00286 if ( !_defaultDb ) 00287 { 00288 return 0; 00289 } 00290 00291 unsigned outstanding = _defaultDb->refCount() - 1; // refCount can't be 0 00292 00293 switch ( outstanding ) 00294 { 00295 default: 00296 if ( !force_r ) 00297 { 00298 DBG << "dbRelease: keep access, outstanding " << outstanding << endl; 00299 break; 00300 } 00301 // else fall through: 00302 case 0: 00303 DBG << "dbRelease: release" << (force_r && outstanding ? "(forced)" : "") 00304 << ", outstanding " << outstanding << endl; 00305 00306 _defaultDb->_d._error = shared_ptr<RpmAccessBlockedException>(new RpmAccessBlockedException(_defaultDb->_d._root, _defaultDb->_d._dbPath)); 00307 // tag handle invalid 00308 _defaultDb = 0; 00309 break; 00310 } 00311 00312 return outstanding; 00313 } 00314 00316 // 00317 // 00318 // METHOD NAME : librpmDb::blockAccess 00319 // METHOD TYPE : unsigned 00320 // 00321 unsigned librpmDb::blockAccess() 00322 { 00323 MIL << "Block access" << endl; 00324 _dbBlocked = true; 00325 return dbRelease( /*force*/true ); 00326 } 00327 00329 // 00330 // 00331 // METHOD NAME : librpmDb::unblockAccess 00332 // METHOD TYPE : void 00333 // 00334 void librpmDb::unblockAccess() 00335 { 00336 MIL << "Unblock access" << endl; 00337 _dbBlocked = false; 00338 } 00339 00341 // 00342 // 00343 // METHOD NAME : librpmDb::dumpState 00344 // METHOD TYPE : ostream & 00345 // 00346 ostream & librpmDb::dumpState( ostream & str ) 00347 { 00348 if ( !_defaultDb ) 00349 { 00350 return str << "[librpmDb " << (_dbBlocked?"BLOCKED":"CLOSED") << " " << stringPath( _defaultRoot, _defaultDbPath ) << "]"; 00351 } 00352 return str << "[" << _defaultDb << "]"; 00353 } 00354 00356 // 00357 // CLASS NAME : librpmDb (internal database handle interface (nonstatic)) 00358 // 00360 00362 // 00363 // 00364 // METHOD NAME : librpmDb::librpmDb 00365 // METHOD TYPE : Constructor 00366 // 00367 // DESCRIPTION : 00368 // 00369 librpmDb::librpmDb( const Pathname & root_r, const Pathname & dbPath_r, bool readonly_r ) 00370 : _d( * new D( root_r, dbPath_r, readonly_r ) ) 00371 {} 00372 00374 // 00375 // 00376 // METHOD NAME : librpmDb::~librpmDb 00377 // METHOD TYPE : Destructor 00378 // 00379 // DESCRIPTION : 00380 // 00381 librpmDb::~librpmDb() 00382 { 00383 delete &_d; 00384 } 00385 00387 // 00388 // 00389 // METHOD NAME : librpmDb::unref_to 00390 // METHOD TYPE : void 00391 // 00392 void librpmDb::unref_to( unsigned refCount_r ) const 00393 { 00394 if ( refCount_r == 1 ) 00395 { 00396 dbRelease(); 00397 } 00398 } 00399 00401 // 00402 // 00403 // METHOD NAME : librpmDb::root 00404 // METHOD TYPE : const Pathname & 00405 // 00406 const Pathname & librpmDb::root() const 00407 { 00408 return _d._root; 00409 } 00410 00412 // 00413 // 00414 // METHOD NAME : librpmDb::dbPath 00415 // METHOD TYPE : const Pathname & 00416 // 00417 const Pathname & librpmDb::dbPath() const 00418 { 00419 return _d._dbPath; 00420 } 00421 00423 // 00424 // 00425 // METHOD NAME : librpmDb::error 00426 // METHOD TYPE : PMError 00427 // 00428 shared_ptr<RpmException> librpmDb::error() const 00429 { 00430 return _d._error; 00431 } 00432 00434 // 00435 // 00436 // METHOD NAME : librpmDb::empty 00437 // METHOD TYPE : bool 00438 // 00439 bool librpmDb::empty() const 00440 { 00441 return( valid() && ! *db_const_iterator( this ) ); 00442 } 00443 00445 // 00446 // 00447 // METHOD NAME : librpmDb::size 00448 // METHOD TYPE : unsigned 00449 // 00450 unsigned librpmDb::size() const 00451 { 00452 unsigned count = 0; 00453 if ( valid() ) 00454 { 00455 db_const_iterator it( this ); 00456 for ( db_const_iterator it( this ); *it; ++it ) 00457 ++count; 00458 } 00459 return count; 00460 } 00461 00463 // 00464 // 00465 // METHOD NAME : librpmDb::dont_call_it 00466 // METHOD TYPE : void * 00467 // 00468 void * librpmDb::dont_call_it() const 00469 { 00470 return rpmtsGetRdb(_d._ts); 00471 } 00472 00474 // 00475 // 00476 // METHOD NAME : librpmDb::dumpOn 00477 // METHOD TYPE : ostream & 00478 // 00479 // DESCRIPTION : 00480 // 00481 ostream & librpmDb::dumpOn( ostream & str ) const 00482 { 00483 ReferenceCounted::dumpOn( str ) << _d; 00484 return str; 00485 } 00486 00488 // 00489 // CLASS NAME : librpmDb::DbDirInfo 00490 // 00492 00494 // 00495 // 00496 // METHOD NAME : librpmDb::DbDirInfo::DbDirInfo 00497 // METHOD TYPE : Constructor 00498 // 00499 librpmDb::DbDirInfo::DbDirInfo( const Pathname & root_r, const Pathname & dbPath_r ) 00500 : _root( root_r ) 00501 , _dbPath( dbPath_r ) 00502 { 00503 // check and adjust arguments 00504 if ( ! (root_r.absolute() && dbPath_r.absolute()) ) 00505 { 00506 ERR << "Relative path for root(" << _root << ") or dbPath(" << _dbPath << ")" << endl; 00507 } 00508 else 00509 { 00510 _dbDir ( _root + _dbPath ); 00511 _dbV4 ( _dbDir.path() + "Packages" ); 00512 _dbV3 ( _dbDir.path() + "packages.rpm" ); 00513 _dbV3ToV4( _dbDir.path() + "packages.rpm3" ); 00514 DBG << *this << endl; 00515 } 00516 } 00517 00519 // 00520 // 00521 // METHOD NAME : librpmDb::DbDirInfo::update 00522 // METHOD TYPE : void 00523 // 00524 void librpmDb::DbDirInfo::restat() 00525 { 00526 _dbDir(); 00527 _dbV4(); 00528 _dbV3(); 00529 _dbV3ToV4(); 00530 DBG << *this << endl; 00531 } 00532 00533 /****************************************************************** 00534 ** 00535 ** 00536 ** FUNCTION NAME : operator<< 00537 ** FUNCTION TYPE : std::ostream & 00538 */ 00539 std::ostream & operator<<( std::ostream & str, const librpmDb::DbDirInfo & obj ) 00540 { 00541 if ( obj.illegalArgs() ) 00542 { 00543 str << "ILLEGAL: '(" << obj.root() << ")" << obj.dbPath() << "'"; 00544 } 00545 else 00546 { 00547 str << "'(" << obj.root() << ")" << obj.dbPath() << "':" << endl; 00548 str << " Dir: " << obj._dbDir << endl; 00549 str << " V4: " << obj._dbV4 << endl; 00550 str << " V3: " << obj._dbV3 << endl; 00551 str << " V3ToV4: " << obj._dbV3ToV4; 00552 } 00553 return str; 00554 } 00555 00557 // 00558 // CLASS NAME : librpmDb::db_const_iterator::D 00562 class librpmDb::db_const_iterator::D 00563 { 00564 D & operator=( const D & ); // NO ASSIGNMENT! 00565 D ( const D & ); // NO COPY! 00566 public: 00567 00568 librpmDb::constPtr _dbptr; 00569 shared_ptr<RpmException> _dberr; 00570 00571 RpmHeader::constPtr _hptr; 00572 rpmdbMatchIterator _mi; 00573 00574 D( librpmDb::constPtr dbptr_r ) 00575 : _dbptr( dbptr_r ) 00576 , _mi( 0 ) 00577 { 00578 if ( !_dbptr ) 00579 { 00580 try 00581 { 00582 librpmDb::dbAccess( _dbptr ); 00583 } 00584 catch (const RpmException & excpt_r) 00585 { 00586 ZYPP_CAUGHT(excpt_r); 00587 } 00588 if ( !_dbptr ) 00589 { 00590 WAR << "No database access: " << _dberr << endl; 00591 } 00592 } 00593 else 00594 { 00595 destroy(); // Checks whether _dbptr still valid 00596 } 00597 } 00598 00599 ~D() 00600 { 00601 if ( _mi ) 00602 { 00603 ::rpmdbFreeIterator( _mi ); 00604 } 00605 } 00606 00611 bool create( int rpmtag, const void * keyp = NULL, size_t keylen = 0 ) 00612 { 00613 destroy(); 00614 if ( ! _dbptr ) 00615 return false; 00616 _mi = ::rpmtsInitIterator( _dbptr->_d._ts, rpmTag(rpmtag), keyp, keylen ); 00617 return _mi; 00618 } 00619 00624 bool destroy() 00625 { 00626 if ( _mi ) 00627 { 00628 _mi = ::rpmdbFreeIterator( _mi ); 00629 _hptr = 0; 00630 } 00631 if ( _dbptr && _dbptr->error() ) 00632 { 00633 _dberr = _dbptr->error(); 00634 WAR << "Lost database access: " << _dberr << endl; 00635 _dbptr = 0; 00636 } 00637 return false; 00638 } 00639 00644 bool advance() 00645 { 00646 if ( !_mi ) 00647 return false; 00648 Header h = ::rpmdbNextIterator( _mi ); 00649 if ( ! h ) 00650 { 00651 destroy(); 00652 return false; 00653 } 00654 _hptr = new RpmHeader( h ); 00655 return true; 00656 } 00657 00661 bool init( int rpmtag, const void * keyp = NULL, size_t keylen = 0 ) 00662 { 00663 if ( ! create( rpmtag, keyp, keylen ) ) 00664 return false; 00665 return advance(); 00666 } 00667 00672 bool set( int off_r ) 00673 { 00674 if ( ! create( RPMDBI_PACKAGES ) ) 00675 return false; 00676 #warning TESTCASE: rpmdbAppendIterator and (non)sequential access? 00677 ::rpmdbAppendIterator( _mi, &off_r, 1 ); 00678 return advance(); 00679 } 00680 00681 unsigned offset() 00682 { 00683 return( _mi ? ::rpmdbGetIteratorOffset( _mi ) : 0 ); 00684 } 00685 00686 int size() 00687 { 00688 if ( !_mi ) 00689 return 0; 00690 int ret = ::rpmdbGetIteratorCount( _mi ); 00691 #warning TESTCASE: rpmdbGetIteratorCount returns 0 on sequential access? 00692 return( ret ? ret : -1 ); // -1: sequential access 00693 } 00694 }; 00695 00697 00699 // 00700 // CLASS NAME : librpmDb::Ptr::db_const_iterator 00701 // 00703 00705 // 00706 // 00707 // METHOD NAME : librpmDb::db_const_iterator::db_iterator 00708 // METHOD TYPE : Constructor 00709 // 00710 librpmDb::db_const_iterator::db_const_iterator( librpmDb::constPtr dbptr_r ) 00711 : _d( * new D( dbptr_r ) ) 00712 { 00713 findAll(); 00714 } 00715 00717 // 00718 // 00719 // METHOD NAME : librpmDb::db_const_iterator::~db_const_iterator 00720 // METHOD TYPE : Destructor 00721 // 00722 librpmDb::db_const_iterator::~db_const_iterator() 00723 { 00724 delete &_d; 00725 } 00726 00728 // 00729 // 00730 // METHOD NAME : librpmDb::db_const_iterator::operator++ 00731 // METHOD TYPE : void 00732 // 00733 void librpmDb::db_const_iterator::operator++() 00734 { 00735 _d.advance(); 00736 } 00737 00739 // 00740 // 00741 // METHOD NAME : librpmDb::db_const_iterator::dbHdrNum 00742 // METHOD TYPE : unsigned 00743 // 00744 unsigned librpmDb::db_const_iterator::dbHdrNum() const 00745 { 00746 return _d.offset(); 00747 } 00748 00750 // 00751 // 00752 // METHOD NAME : librpmDb::db_const_iterator::operator* 00753 // METHOD TYPE : const RpmHeader::constPtr & 00754 // 00755 const RpmHeader::constPtr & librpmDb::db_const_iterator::operator*() const 00756 { 00757 return _d._hptr; 00758 } 00759 00761 // 00762 // 00763 // METHOD NAME : librpmDb::db_const_iterator::dbError 00764 // METHOD TYPE : PMError 00765 // 00766 shared_ptr<RpmException> librpmDb::db_const_iterator::dbError() const 00767 { 00768 if ( _d._dbptr ) 00769 return _d._dbptr->error(); 00770 00771 return _d._dberr; 00772 } 00773 00774 /****************************************************************** 00775 ** 00776 ** 00777 ** FUNCTION NAME : operator<< 00778 ** FUNCTION TYPE : ostream & 00779 */ 00780 ostream & operator<<( ostream & str, const librpmDb::db_const_iterator & obj ) 00781 { 00782 str << "db_const_iterator(" << obj._d._dbptr 00783 << " Size:" << obj._d.size() 00784 << " HdrNum:" << obj._d.offset() 00785 << ")"; 00786 return str; 00787 } 00788 00790 // 00791 // 00792 // METHOD NAME : librpmDb::db_const_iterator::findAll 00793 // METHOD TYPE : bool 00794 // 00795 bool librpmDb::db_const_iterator::findAll() 00796 { 00797 return _d.init( RPMDBI_PACKAGES ); 00798 } 00799 00801 // 00802 // 00803 // METHOD NAME : librpmDb::db_const_iterator::findByFile 00804 // METHOD TYPE : bool 00805 // 00806 bool librpmDb::db_const_iterator::findByFile( const std::string & file_r ) 00807 { 00808 return _d.init( RPMTAG_BASENAMES, file_r.c_str() ); 00809 } 00810 00812 // 00813 // 00814 // METHOD NAME : librpmDb::db_const_iterator::findByProvides 00815 // METHOD TYPE : bool 00816 // 00817 bool librpmDb::db_const_iterator::findByProvides( const std::string & tag_r ) 00818 { 00819 return _d.init( RPMTAG_PROVIDENAME, tag_r.c_str() ); 00820 } 00821 00823 // 00824 // 00825 // METHOD NAME : librpmDb::db_const_iterator::findByRequiredBy 00826 // METHOD TYPE : bool 00827 // 00828 bool librpmDb::db_const_iterator::findByRequiredBy( const std::string & tag_r ) 00829 { 00830 return _d.init( RPMTAG_REQUIRENAME, tag_r.c_str() ); 00831 } 00832 00834 // 00835 // 00836 // METHOD NAME : librpmDb::db_const_iterator::findByConflicts 00837 // METHOD TYPE : bool 00838 // 00839 bool librpmDb::db_const_iterator::findByConflicts( const std::string & tag_r ) 00840 { 00841 return _d.init( RPMTAG_CONFLICTNAME, tag_r.c_str() ); 00842 } 00843 00845 // 00846 // 00847 // METHOD NAME : librpmDb::findByName 00848 // METHOD TYPE : bool 00849 // 00850 bool librpmDb::db_const_iterator::findByName( const string & name_r ) 00851 { 00852 return _d.init( RPMTAG_NAME, name_r.c_str() ); 00853 } 00854 00856 // 00857 // 00858 // METHOD NAME : librpmDb::db_const_iterator::findPackage 00859 // METHOD TYPE : bool 00860 // 00861 bool librpmDb::db_const_iterator::findPackage( const string & name_r ) 00862 { 00863 if ( ! _d.init( RPMTAG_NAME, name_r.c_str() ) ) 00864 return false; 00865 00866 if ( _d.size() == 1 ) 00867 return true; 00868 00869 // check installtime on multiple entries 00870 int match = 0; 00871 time_t itime = 0; 00872 for ( ; operator*(); operator++() ) 00873 { 00874 if ( operator*()->tag_installtime() > itime ) 00875 { 00876 match = _d.offset(); 00877 itime = operator*()->tag_installtime(); 00878 } 00879 } 00880 00881 return _d.set( match ); 00882 } 00883 00885 // 00886 // 00887 // METHOD NAME : librpmDb::db_const_iterator::findPackage 00888 // METHOD TYPE : bool 00889 // 00890 bool librpmDb::db_const_iterator::findPackage( const std::string & name_r, const Edition & ed_r ) 00891 { 00892 if ( ! _d.init( RPMTAG_NAME, name_r.c_str() ) ) 00893 return false; 00894 00895 for ( ; operator*(); operator++() ) 00896 { 00897 if ( ed_r == operator*()->tag_edition() ) 00898 { 00899 int match = _d.offset(); 00900 return _d.set( match ); 00901 } 00902 } 00903 00904 return _d.destroy(); 00905 } 00906 00908 // 00909 // 00910 // METHOD NAME : librpmDb::db_const_iterator::findPackage 00911 // METHOD TYPE : bool 00912 // 00913 bool librpmDb::db_const_iterator::findPackage( const Package::constPtr & which_r ) 00914 { 00915 if ( ! which_r ) 00916 return _d.destroy(); 00917 00918 return findPackage( which_r->name(), which_r->edition() ); 00919 } 00920 00921 } // namespace rpm 00922 } // namespace target 00923 } // namespace zypp
1.7.6.1