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