00001
00002
00003
00004
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
00032
00034
00036 namespace
00037 {
00038
00039 bool yes() { return true; }
00040 bool no() { return false; }
00041
00043 }
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
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 }
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
00101
00102
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
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
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 }
00149 }