SourceProvideFile.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 <sstream>
00015 #include "zypp/base/Logger.h"
00016 
00017 #include "zypp/source/SourceProvideFile.h"
00018 #include "zypp/ZYppCallbacks.h"
00019 
00020 using std::endl;
00021 
00023 namespace zypp
00024 { 
00025 
00026   namespace source
00027   { 
00028 
00030     //
00031     //  CLASS NAME : ProvideFilePolicy
00032     //
00034 
00036     namespace
00037     { 
00038 
00039       bool yes() { return true; }
00040       bool no()  { return false; }
00041 
00043     } // namespace
00045 
00046     ProvideFilePolicy & ProvideFilePolicy::failOnChecksumErrorCB( bool yesno_r )
00047     {
00048       _failOnChecksumErrorCB = (yesno_r ? &yes : &no);
00049       return *this;
00050     }
00051 
00052     bool ProvideFilePolicy::progress( int value ) const
00053     {
00054       if ( _progressCB )
00055         return _progressCB( value );
00056       return true;
00057     }
00058 
00059     bool ProvideFilePolicy::failOnChecksumError() const
00060     {
00061       if ( _failOnChecksumErrorCB )
00062         return _failOnChecksumErrorCB();
00063       return true;
00064     }
00065 
00067     //
00068     //  provideFile
00069     //
00071 
00073     namespace
00074     { 
00075 
00080       struct DownloadFileReportHack : public callback::ReceiveReport<source::SourceReport>
00081       {
00082         virtual bool progress( int value )
00083         {
00084           if ( _redirect )
00085             return _redirect( value );
00086           return true;
00087         }
00088         function<bool ( int )> _redirect;
00089       };
00090 
00092     } // namespace
00094 
00095     ManagedFile provideFile( Source_Ref source_r,
00096                              const source::OnMediaLocation & loc_r,
00097                              const ProvideFilePolicy & policy_r )
00098     {
00099       MIL << "sourceProvideFile " << loc_r << endl;
00100       // Arrange DownloadFileReportHack to recieve the source::DownloadFileReport
00101       // and redirect download progress triggers to call the ProvideFilePolicy
00102       // callback.
00103       DownloadFileReportHack dumb;
00104       dumb._redirect = bind( mem_fun_ref( &ProvideFilePolicy::progress ),
00105                              ref( policy_r ), _1 );
00106       callback::TempConnect<source::SourceReport> temp( dumb );
00107 
00108 
00109       ManagedFile ret( source_r.provideFile( loc_r.filename(), loc_r.medianr() ),
00110                        bind( &Source_Ref::releaseFile, source_r, _1, loc_r.medianr() ) );
00111 
00112       if ( loc_r.checksum().empty() )
00113         {
00114           // no checksum in metadata
00115           WAR << "No checksum in metadata " << loc_r << endl;
00116         }
00117       else
00118         {
00119           std::ifstream input( ret->asString().c_str() );
00120           CheckSum retChecksum( loc_r.checksum().type(), input );
00121           input.close();
00122 
00123           if ( loc_r.checksum() != retChecksum )
00124             {
00125               // failed integity check
00126               std::ostringstream err;
00127               err << "File " << ret << " fails integrity check. Expected: [" << loc_r.checksum() << "] Got: [";
00128               if ( retChecksum.empty() )
00129                 err << "Failed to compute checksum";
00130               else
00131                 err << retChecksum;
00132               err << "]";
00133 
00134               if ( policy_r.failOnChecksumError() )
00135                 ZYPP_THROW( Exception( err.str() ) );
00136               else
00137                 WAR << "NO failOnChecksumError: " << err.str() << endl;
00138             }
00139         }
00140 
00141       MIL << "sourceProvideFile at " << ret << endl;
00142       return ret;
00143     }
00144 
00146   } // namespace source
00149 } // namespace zypp

Generated on Tue Nov 28 16:49:32 2006 for zypp by  doxygen 1.5.0