SourceImpl.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 #include <fstream>
00014 #include "zypp/base/Logger.h"
00015 #include "zypp/Digest.h"
00016 #include "zypp/SourceFactory.h"
00017 #include "zypp/source/SourceImpl.h"
00018 #include "zypp/ZYppCallbacks.h"
00019 #include "zypp/SourceManager.h"
00020 
00021 #include <fstream>
00022 
00023 using std::endl;
00024 
00026 namespace zypp
00027 { 
00028 
00029   namespace source
00030   { 
00031 
00032     IMPL_PTR_TYPE(SourceImpl);
00033 
00034 
00035     class DownloadProgressPackageReceiver
00036         : public callback::ReceiveReport<media::DownloadProgressReport>
00037     {
00038         callback::SendReport <DownloadResolvableReport> & _report;
00039         Resolvable::constPtr _resolvable;
00040 
00041       public:
00042 
00043         DownloadProgressPackageReceiver (
00044             callback::SendReport <DownloadResolvableReport> & report_r,
00045             Resolvable::constPtr resolvable_r
00046         )
00047         : _report (report_r)
00048         , _resolvable (resolvable_r)
00049         {}
00050 
00051         virtual ~DownloadProgressPackageReceiver () {}
00052 
00053         virtual void reportbegin() {}
00054 
00055         virtual void reportend() {}
00056 
00061         virtual bool progress( int percent, Url )
00062         {
00063             return _report->progress( percent, _resolvable );
00064         }
00065     };
00066 
00067 
00068     class DownloadProgressFileReceiver
00069         : public callback::ReceiveReport<media::DownloadProgressReport>
00070     {
00071         callback::SendReport <DownloadFileReport> & _report;
00072 
00073       public:
00074 
00075         DownloadProgressFileReceiver (
00076             callback::SendReport <DownloadFileReport> & report_r
00077         )
00078         : _report (report_r)
00079         {}
00080 
00081         virtual ~DownloadProgressFileReceiver () {}
00082 
00083         virtual void reportbegin() {}
00084 
00085         virtual void reportend() {}
00086 
00091         virtual bool progress( int percent, Url url )
00092         {
00093             return _report->progress( percent, url );
00094         }
00095     };
00096 
00098     //
00099     //  METHOD NAME : SourceImpl::SourceImpl
00100     //  METHOD TYPE : Ctor
00101     //
00102     SourceImpl::SourceImpl()
00103     : _enabled(true)
00104     , _autorefresh(true)
00105     , _priority (0)
00106     , _priority_unsubscribed (0)
00107     , _subscribed(false)
00108     , _res_store_initialized(false)
00109     , _base_source(false)
00110     {
00111     }
00112 
00114     //
00115     //  METHOD NAME : SourceImpl::factoryCtor
00116     //  METHOD TYPE : void
00117     //
00118     void SourceImpl::factoryCtor( const media::MediaId & media_r,
00119                                   const Pathname & path_r,
00120                                   const std::string & alias_r,
00121                                   const Pathname cache_dir_r,
00122                                   const bool base_source)
00123     {
00124       _media_set = new MediaSet( selfSourceRef() );
00125       _url = media_mgr.url( media_r );
00126       _media_set->redirect( 1, media_r );
00127       _path      = path_r;
00128       _alias     = alias_r;
00129       _cache_dir = cache_dir_r;
00130       _subscribed = true;
00131       _base_source = base_source;
00132 
00133       // for sources which are neither CD nor DVD we enable autorefresh by default
00134       _autorefresh = media::MediaAccess::canBeVolatile( _url );
00135 
00136       try
00137         {
00138           factoryInit();
00139         }
00140       catch ( Exception & excpt )
00141         {
00142           _store.clear();
00143           ZYPP_RETHROW( excpt );
00144         }
00145     }
00146 
00148     //
00149     //  METHOD NAME : SourceImpl::factoryInit
00150     //  METHOD TYPE : void
00151     //
00152     void SourceImpl::factoryInit()
00153     {
00154       ZYPP_THROW( Exception( "FactoryInit not implemented!" ) );
00155     }
00156 
00158     //
00159     //  METHOD NAME : SourceImpl::~SourceImpl
00160     //  METHOD TYPE : Dtor
00161     //
00162     SourceImpl::~SourceImpl()
00163     {
00164       if (_media_set) {
00165         media::MediaAccessId _media = _media_set->getMediaAccessId( 1 );
00166         media_mgr.release (_media, false);
00167       }
00168     }
00169 
00170     const ResStore & SourceImpl::resolvables() const
00171     {
00172       if ( !_res_store_initialized )
00173       {
00174         // cast away const to allow late init
00175         Source_Ref self( const_cast<SourceImpl*>(this)->selfSourceRef() );
00176         const_cast<SourceImpl*>(this)->createResolvables(self);
00177         const_cast<SourceImpl*>(this)->_res_store_initialized = true;
00178       }
00179       return _store;
00180      }
00181 
00182     const ResStore SourceImpl::resolvables(zypp::Resolvable::Kind kind) const
00183     {
00184       Source_Ref self( const_cast<SourceImpl*>(this)->selfSourceRef() );
00185       return const_cast<SourceImpl*>(this)->provideResolvables(self, kind);
00186     }
00187 
00188     Date SourceImpl::timestamp() const
00189     {
00190       return Date::now();
00191     }
00192     
00193     void SourceImpl::dirInfo(const unsigned media_nr,
00194                              std::list<std::string> &retlist,
00195                              const Pathname         &path_r,
00196                              bool                    dots ) const
00197     {
00198       DBG << "reading " << path_r << " file list" << endl;
00199       media::MediaAccessId _media = _media_set->getMediaAccessId( media_nr );
00200       media_mgr.dirInfo( _media, retlist, path_r, dots );
00201     }
00202 
00203     const Pathname SourceImpl::providePackage( Package::constPtr package )
00204     {
00205       bool retry = true;
00206       bool digest_ok = false;
00207       Pathname file;
00208       callback::SendReport<source::DownloadResolvableReport> report;
00209       DownloadProgressPackageReceiver download_report( report, package );
00210 
00211       while (retry)
00212       {
00213         report->start( package, package->source().url() );
00214 
00215         callback::TempConnect<media::DownloadProgressReport> tmp_download( download_report );
00216 
00217         file = provideJustFile( package->location(), package->sourceMediaNr());
00218 
00219         report->finish( package, source::DownloadResolvableReport::NO_ERROR, "" );
00220 
00221         CheckSum checksum = package->checksum();
00222         std::string calculated_digest;
00223 
00224         // check digest
00225         try
00226         {
00227           std::ifstream is(file.asString().c_str(), std::ifstream::binary);
00228           calculated_digest = Digest::digest(checksum.type(), is);
00229           is.close();
00230         }
00231         catch (std::exception &e)
00232         {
00233           ERR << "Can't open " << file << " for integrity check." << std::endl;
00234         }
00235 
00236         if ( checksum.checksum() == calculated_digest )
00237         {
00238           MIL << package->location() << " ok. [" << calculated_digest << "]" << std::endl;
00239           digest_ok = true;
00240           retry = false;
00241         }
00242 
00243         if (!digest_ok)
00244         {
00245           std::string  package_str = package->name() + "-" + package->edition().asString();
00246           source::DownloadResolvableReport::Action useraction = report->problem(package, source::DownloadResolvableReport::INVALID, "Package " + package_str + " fails integrity check. Do you want to retry downloading it, or abort installation?");
00247 
00248           if( useraction == source::DownloadResolvableReport::ABORT )
00249           {
00250             ZYPP_THROW(Exception("Package " + package->location().asString() + " fails integrity check. Expected: [" + checksum.checksum() + "] Read: [" + calculated_digest + "] (" + checksum.type() + ")"));
00251           }
00252           else if ( useraction == source::DownloadResolvableReport::RETRY )
00253           {
00254             retry = true;
00255           }
00256         }
00257       }
00258       return file;
00259     }
00260 
00261     const Pathname SourceImpl::provideFile(const Pathname & file_r,
00262                                            const unsigned media_nr,
00263                                            bool cached,
00264                                            bool checkonly )
00265     {
00266       callback::SendReport<source::DownloadFileReport> report;
00267       DownloadProgressFileReceiver download_report( report );
00268 
00269       SourceFactory source_factory;
00270 
00271       Url file_url( url().asString() + file_r.asString() );
00272 
00273       report->start( source_factory.createFrom(this), file_url );
00274 
00275       callback::TempConnect<media::DownloadProgressReport> tmp_download( download_report );
00276 
00277       Pathname file = provideJustFile( file_r, media_nr, cached, checkonly );
00278 
00279       report->finish( file_url, source::DownloadFileReport::NO_ERROR, "" );
00280 
00281       return file;
00282     }
00283 
00284     const Pathname SourceImpl::tryToProvideFile( const Pathname & file, const unsigned media_nr )
00285     {
00286       media::MediaAccessId _media = _media_set->getMediaAccessId( media_nr);
00287       media_mgr.provideFile (_media, file, false, false);
00288       return media_mgr.localPath( _media, file );
00289     }
00290 
00291     void SourceImpl::copyLocalMetadata(const Pathname &src, const Pathname &dst) const
00292     {
00293       // refuse to use stupid paths as cache dir
00294       if (dst == Pathname("/") )
00295         ZYPP_THROW(Exception("I refuse to use / as local dir"));
00296 
00297       if (0 != assert_dir(dst, 0755))
00298         ZYPP_THROW(Exception("Cannot create local directory" + dst.asString()));
00299 
00300       MIL << "Cleaning up local dir" << std::endl;
00301       filesystem::clean_dir(dst);
00302       MIL << "Copying " << src << " content to local : " << dst << std::endl;
00303        
00304       if ( copy_dir_content( src, dst) != 0)
00305       {
00306         filesystem::clean_dir(dst);
00307         ZYPP_THROW(Exception( "Can't copy downloaded data to local dir. local dir cleaned."));
00308       }
00309     }
00310     
00311     const Pathname SourceImpl::provideJustFile(const Pathname & file_r,
00312                                            const unsigned media_nr,
00313                                            bool cached,
00314                                            bool checkonly )
00315     {
00316       callback::SendReport<media::MediaChangeReport> report;
00317 
00318       SourceFactory source_factory;
00319 
00320       // get the mediaId, but don't try to attach it here
00321       media::MediaAccessId _media = _media_set->getMediaAccessId( media_nr, true );
00322       do {
00323         try {
00324           DBG << "Going to try provide file " << file_r << " from " << media_nr << endl;
00325 
00326           // try to attach the media
00327           _media = _media_set->getMediaAccessId( media_nr ); // in case of redirect
00328           media_mgr.provideFile (_media, file_r, cached, checkonly);
00329           break;
00330         }
00331         catch ( Exception & excp )
00332         {
00333           ZYPP_CAUGHT(excp);
00334             media::MediaChangeReport::Action user;
00335 
00336           do {
00337 
00338             DBG << "Media couldn't provide file " << file_r << " , releasing." << endl;
00339             try {
00340                 media_mgr.release (_media, false);
00341             }
00342             catch (const Exception & excpt_r)
00343             {
00344                 ZYPP_CAUGHT(excpt_r);
00345                 MIL << "Failed to release media " << _media << endl;
00346             }
00347             MIL << "Releasing all medias of all sources" << endl;
00348             try {
00349                 zypp::SourceManager::sourceManager()->releaseAllSources();
00350             }
00351             catch (const zypp::Exception& excpt_r)
00352             {
00353                 ZYPP_CAUGHT(excpt_r);
00354                 ERR << "Failed to release all sources" << endl;
00355             }
00356 
00357             // set up the reason
00358             media::MediaChangeReport::Error reason
00359                 = media::MediaChangeReport::INVALID;
00360 
00361             if( typeid(excp) == typeid( media::MediaFileNotFoundException )  ||
00362               typeid(excp) == typeid( media::MediaNotAFileException ) )
00363             {
00364                 reason = media::MediaChangeReport::NOT_FOUND;
00365             } else if( typeid(excp) == typeid( media::MediaNotDesiredException)  ||
00366               typeid(excp) == typeid( media::MediaNotAttachedException) )
00367             {
00368                 reason = media::MediaChangeReport::WRONG;
00369             }
00370 
00371             user  = checkonly ? media::MediaChangeReport::ABORT :
00372               report->requestMedia (
00373                 source_factory.createFrom( this ),
00374                 media_nr,
00375                 reason,
00376                 excp.asUserString()
00377               );
00378 
00379             DBG << "ProvideFile exception caught, callback answer: " << user << endl;
00380 
00381             if( user == media::MediaChangeReport::ABORT )
00382             {
00383               DBG << "Aborting" << endl;
00384               ZYPP_RETHROW ( excp );
00385             }
00386             else if ( user == media::MediaChangeReport::IGNORE )
00387             {
00388               DBG << "Skipping" << endl;
00389               ZYPP_THROW ( SkipRequestedException("User-requested skipping of a file") );
00390             }
00391             else if ( user == media::MediaChangeReport::EJECT )
00392             {
00393               DBG << "Eject: try to release" << endl;
00394               try {
00395                 zypp::SourceManager::sourceManager()->releaseAllSources();
00396               }
00397               catch (const zypp::Exception& excpt_r)
00398               {
00399                 ZYPP_CAUGHT(excpt_r);
00400                 ERR << "Failed to release all sources" << endl;
00401               }
00402               media_mgr.release (_media, true); // one more release needed for eject
00403               // FIXME: this will not work, probably
00404             }
00405             else if ( user == media::MediaChangeReport::RETRY  ||
00406             user == media::MediaChangeReport::CHANGE_URL )
00407             {
00408               // retry
00409               DBG << "Going to try again" << endl;
00410 
00411               // not attaching, media set will do that for us
00412               // this could generate uncaught exception (#158620)
00413 
00414               break;
00415             }
00416             else {
00417               DBG << "Don't know, let's ABORT" << endl;
00418 
00419               ZYPP_RETHROW ( excp );
00420             }
00421           } while( user == media::MediaChangeReport::EJECT );
00422         }
00423 
00424         // retry or change URL
00425       } while( true );
00426 
00427       return media_mgr.localPath( _media, file_r );
00428     }
00429 
00430     const Pathname SourceImpl::provideDirTree(const Pathname & path_r, const unsigned media_nr)
00431     {
00432       callback::SendReport<media::MediaChangeReport> report;
00433       SourceFactory source_factory;
00434       // get the mediaId, but don't try to attach it here
00435       media::MediaAccessId _media = _media_set->getMediaAccessId( media_nr, true );
00436       do
00437       {
00438         try
00439         {
00440           DBG << "Going to try provide tree " << path_r << " from " << media_nr << endl;
00441           // try to attach the media
00442           _media = _media_set->getMediaAccessId( media_nr ); // in case of redirect
00443           media_mgr.provideDirTree (_media, path_r);
00444           break;
00445         }
00446         catch ( Exception & excp )
00447         {
00448           ZYPP_CAUGHT(excp);
00449           media::MediaChangeReport::Action user;
00450 
00451           do
00452           {
00453             DBG << "Media couldn't provide tree " << path_r << " , releasing." << endl;
00454             try
00455             {
00456               media_mgr.release (_media, false);
00457             }
00458             catch (const Exception & excpt_r)
00459             {
00460               ZYPP_CAUGHT(excpt_r);
00461               MIL << "Failed to release media " << _media << endl;
00462             }
00463             MIL << "Releasing all medias of all sources" << endl;
00464             try
00465             {
00466               zypp::SourceManager::sourceManager()->releaseAllSources();
00467             }
00468             catch (const zypp::Exception& excpt_r)
00469             {
00470               ZYPP_CAUGHT(excpt_r);
00471               ERR << "Failed to release all sources" << endl;
00472             }
00473             // set up the reason
00474             media::MediaChangeReport::Error reason = media::MediaChangeReport::INVALID;
00475 
00476             if( typeid(excp) == typeid( media::MediaFileNotFoundException )  || typeid(excp) == typeid( media::MediaNotAFileException ) )
00477             {
00478               reason = media::MediaChangeReport::NOT_FOUND;
00479             }
00480             else if( typeid(excp) == typeid( media::MediaNotDesiredException)  || typeid(excp) == typeid( media::MediaNotAttachedException) )
00481             {
00482               reason = media::MediaChangeReport::WRONG;
00483             }
00484             user  = report->requestMedia ( source_factory.createFrom( this ), media_nr, reason, excp.asUserString() );
00485 
00486             DBG << "ProvideFile exception caught, callback answer: " << user << endl;
00487 
00488             if( user == media::MediaChangeReport::ABORT )
00489             {
00490               DBG << "Aborting" << endl;
00491               ZYPP_RETHROW ( excp );
00492             }
00493             else if ( user == media::MediaChangeReport::EJECT )
00494             {
00495               DBG << "Eject: try to release" << endl;
00496               try {
00497                 zypp::SourceManager::sourceManager()->releaseAllSources();
00498               }
00499               catch (const zypp::Exception& excpt_r)
00500               {
00501                 ZYPP_CAUGHT(excpt_r);
00502                 ERR << "Failed to release all sources" << endl;
00503               }
00504               media_mgr.release (_media, true); // one more release needed for eject
00505               // FIXME: this will not work, probably
00506             }
00507             else if ( user == media::MediaChangeReport::RETRY  ||
00508                       user == media::MediaChangeReport::CHANGE_URL )
00509             {
00510               // retry
00511               DBG << "Going to try again" << endl;
00512 
00513               // not attaching, media set will do that for us
00514               // this could generate uncaught exception (#158620)
00515 
00516               break;
00517             }
00518             else
00519             {
00520               DBG << "Don't know, let's ABORT" << endl;
00521 
00522               ZYPP_RETHROW ( excp );
00523             }
00524           } while( user == media::MediaChangeReport::EJECT );
00525         }
00526       // retry or change URL
00527       } while( true );
00528       return media_mgr.localPath( _media, path_r );
00529     }
00530 
00531     const void SourceImpl::releaseFile(const Pathname & file_r,
00532                                        const unsigned media_nr)
00533     {
00534       DBG << "releaseFile(" << file_r << ", " << media_nr << ")" << endl;
00535       media::MediaAccessId _media = _media_set->getMediaAccessId( media_nr );
00536       media_mgr.releaseFile(_media, file_r);
00537     }
00538 
00539     const void SourceImpl::releaseDir(const Pathname & path_r,
00540                                       const unsigned media_nr,
00541                                       const bool recursive)
00542     {
00543       DBG << "releaseDir(" << path_r << ", " << media_nr << (recursive?", recursive":"") << ")" << endl;
00544       media::MediaAccessId _media = _media_set->getMediaAccessId( media_nr );
00545       if (recursive)
00546         media_mgr.releasePath(_media, path_r);
00547       else
00548         media_mgr.releaseDir(_media, path_r);
00549     }
00550 
00551     void SourceImpl::changeMedia( const media::MediaId & media_r, const Pathname & path_r )
00552     {
00553       DBG << "changeMedia(" << path_r << ")" << endl;
00554       _url = media_mgr.url( media_r );
00555       _media_set->reset();
00556       _media_set->redirect( 1, media_r );
00557       _path = path_r;
00558     }
00559 
00560     void SourceImpl::enable()
00561     {
00562 //      if (autorefresh())
00563 //      refresh();
00564       _enabled = true;
00565     }
00566 
00567     void SourceImpl::createResolvables(Source_Ref source_r)
00568     {}
00569 
00570     ResStore SourceImpl::provideResolvables(Source_Ref source_r, zypp::Resolvable::Kind kind)
00571     {
00572         WAR << "provideResolvables not implemented by the source" << endl;
00573         return ResStore();
00574     }
00575 
00576     void SourceImpl::storeMetadata(const Pathname & cache_dir_r)
00577     {}
00578 
00579     void SourceImpl::refresh()
00580     {
00581         // TODO: will this work in chroot?
00582         // TODO: better download somewhere else and then copy over
00583         try{
00584           storeMetadata( _cache_dir );
00585         }
00586         catch( const zypp::Exception & excpt )
00587         {
00588           ERR << "Unable to refresh the source cache" << endl;
00589           if( ! _cache_dir.empty() && _cache_dir != "/" )
00590             filesystem::clean_dir( _cache_dir );
00591 
00592           ZYPP_RETHROW( excpt );
00593         }
00594     }
00595 
00596     void SourceImpl::redirect(unsigned media_nr, const Url & new_url)
00597     {
00598       DBG << "redirect(" << new_url << ")" << endl;
00599       media::MediaAccessId id = media_mgr.open( new_url );
00600       _media_set->redirect( media_nr, id );
00601     }
00602     void SourceImpl::reattach(const Pathname &attach_point)
00603     {
00604       DBG << "reattach(" << attach_point << ")" << endl;
00605       _media_set->reattach( attach_point );
00606     }
00607 
00608     void SourceImpl::release()
00609     {
00610       if (_media_set)
00611         _media_set->release();
00612     }
00613 
00614     media::MediaVerifierRef SourceImpl::verifier(unsigned media_nr)
00615     { return media::MediaVerifierRef(new media::NoVerifier()); }
00616 
00618     // attribute accessors
00619 
00620     std::string SourceImpl::type (void) const
00621     { return "undefined"; }
00622 
00623     std::string SourceImpl::id (void) const
00624     { return _id; }
00625 
00626     void SourceImpl::setId (const std::string id_r)
00627     { _id = id_r; }
00628 
00629     unsigned SourceImpl::priority (void) const
00630     { return _priority; }
00631 
00632     void SourceImpl::setPriority (unsigned p)
00633     { _priority = p; }
00634 
00635     unsigned SourceImpl::priorityUnsubscribed (void) const
00636     { return _priority_unsubscribed; }
00637 
00638     void SourceImpl::setPriorityUnsubscribed (unsigned p)
00639     { _priority_unsubscribed = p; }
00640 
00641     bool SourceImpl::subscribed (void) const
00642     { return _subscribed; }
00643 
00644     void SourceImpl::setSubscribed (bool s)
00645     { _subscribed = s; }
00646 
00647     const Pathname & SourceImpl::cacheDir (void)
00648     { return _cache_dir; }
00649 
00650     Url SourceImpl::url (void) const
00651     { return _url; }
00652 
00653     void SourceImpl::setUrl( const Url & url )
00654     { _url = url; }
00655 
00656     bool SourceImpl::remote() const
00657     {
00658       bool downloads = false;
00659       try {
00660         downloads = media::MediaManager::downloads(_url);
00661       }
00662       catch(const zypp::Exception &e)
00663       {
00664         // should not happen, but ...
00665         ZYPP_CAUGHT(e);
00666       }
00667       return downloads;
00668     }
00669 
00670     const Pathname & SourceImpl::path (void) const
00671     { return _path; }
00672 
00673     unsigned SourceImpl::numberOfMedia(void) const
00674     { return 1; }
00675 
00676     std::string SourceImpl::vendor (void) const
00677     { return ""; }
00678 
00679     const std::list<Pathname> SourceImpl::publicKeys()
00680     { return std::list<Pathname>(); }
00681 
00682     std::string SourceImpl::unique_id (void) const
00683     { return ""; }
00684 
00686 
00690     std::string SourceImpl::zmdName (void) const
00691     { return "zmdname"; }
00692 
00693     void SourceImpl::setZmdName (const std::string name_r)
00694     { return; }
00695 
00696     std::string SourceImpl::zmdDescription (void) const
00697     { return "zmddescription"; }
00698 
00699     void SourceImpl::setZmdDescription (const std::string desc_r)
00700     { return; }
00701 
00703 
00704     std::ostream & SourceImpl::dumpOn( std::ostream & str ) const
00705     {
00706       str << "Source[" << numericId() << "|" << type();
00707       if ( !_alias.empty() )
00708         str << "|" << _alias;
00709       str << "]";
00710 
00711       str << "{"
00712           << _url << "(" << _path << ")";
00713       if ( ! _cache_dir.empty() )
00714         str << "; cache " << _cache_dir;
00715       str << "}";
00716 
00717       return str;
00718     }
00719 
00720     SourceImpl::Verifier::Verifier(const std::string & vendor_r, const std::string & id_r, const media::MediaNr media_nr)
00721     : _media_vendor(vendor_r)
00722     , _media_id(id_r)
00723     , _media_nr(media_nr)
00724     {}
00725 
00726     bool SourceImpl::Verifier::isDesiredMedia(const media::MediaAccessRef &ref)
00727     {
00728       if (_media_vendor.empty() || _media_id.empty())
00729         return true;
00730 #warning TODO define what does missing media_id/media_vendor mean
00731 
00732       Pathname media_file = "/media." + str::numstring(_media_nr) + "/media";
00733       ref->provideFile (media_file);
00734       media_file = ref->localPath(media_file);
00735       std::ifstream str(media_file.asString().c_str());
00736       std::string vendor;
00737       std::string id;
00738 
00739 #warning check the stream status
00740       getline(str, vendor);
00741       getline(str, id);
00742 
00743       return (vendor == _media_vendor && id == _media_id );
00744     }
00745 
00747   } // namespace source
00750 } // namespace zypp

Generated on Mon Jun 5 19:10:36 2006 for zypp by  doxygen 1.4.6