Downloader.cc
Go to the documentation of this file.00001
00002 #include <iostream>
00003 #include <fstream>
00004
00005 #include "zypp/base/Logger.h"
00006 #include "zypp/base/String.h"
00007 #include "zypp/OnMediaLocation.h"
00008 #include "zypp/MediaSetAccess.h"
00009 #include "zypp/Fetcher.h"
00010 #include "zypp/Locale.h"
00011 #include "zypp/ZConfig.h"
00012 #include "zypp/repo/MediaInfoDownloader.h"
00013 #include "zypp/repo/susetags/Downloader.h"
00014 #include "zypp/parser/ParseException.h"
00015 #include "zypp/parser/susetags/RepoIndex.h"
00016 #include "zypp/base/UserRequestException.h"
00017 #include "zypp/KeyContext.h"
00018
00019 using namespace std;
00020 using namespace zypp::parser;
00021 using namespace zypp::parser::susetags;
00022
00023 namespace zypp
00024 {
00025 namespace repo
00026 {
00027 namespace susetags
00028 {
00029
00030 Downloader::Downloader( const RepoInfo &repoinfo )
00031 : repo::Downloader(repoinfo)
00032 {
00033 }
00034
00035 RepoStatus Downloader::status( MediaSetAccess &media )
00036 {
00037 Pathname content = media.provideFile( repoInfo().path() + "/content");
00038
00039
00040 Pathname mediafile = media.provideFile( "/media.1/media" );
00041
00042 return RepoStatus(content) && RepoStatus(mediafile);
00043 }
00044
00045 void Downloader::download( MediaSetAccess &media,
00046 const Pathname &dest_dir,
00047 const ProgressData::ReceiverFnc & progress )
00048 {
00049 downloadMediaInfo( dest_dir, media );
00050
00051 SignatureFileChecker sigchecker;
00052
00053 Pathname sig = repoInfo().path() + "/content.asc";
00054
00055 this->enqueue( OnMediaLocation( sig, 1 ).setOptional(true) );
00056 this->start( dest_dir, media );
00057
00058 if ( PathInfo(dest_dir / sig ).isExist() )
00059 sigchecker = SignatureFileChecker( dest_dir + sig);
00060 this->reset();
00061
00062 Pathname key = repoInfo().path() + "/content.key";
00063
00064 this->enqueue( OnMediaLocation( key, 1 ).setOptional(true) );
00065 this->start( dest_dir, media );
00066
00067 KeyContext context;
00068 context.setRepoInfo(repoInfo());
00069
00070 if ( PathInfo(dest_dir / key).isExist() )
00071 sigchecker.addPublicKey(dest_dir + key, context);
00072
00073
00074 else
00075 sigchecker.setKeyContext(context);
00076
00077 this->reset();
00078
00079 if ( ! repoInfo().gpgCheck() )
00080 {
00081 WAR << "Signature checking disabled in config of repository " << repoInfo().alias() << endl;
00082 }
00083 this->enqueue( OnMediaLocation( repoInfo().path() + "/content", 1 ),
00084 repoInfo().gpgCheck() ? FileChecker(sigchecker) : FileChecker(NullFileChecker()) );
00085 this->start( dest_dir, media );
00086 this->reset();
00087
00088 Pathname descr_dir;
00089
00090
00091 {
00092 Pathname inputfile( dest_dir + repoInfo().path() + "/content" );
00093 ContentFileReader content;
00094 content.setRepoIndexConsumer( bind( &Downloader::consumeIndex, this, _1 ) );
00095 content.parse( inputfile );
00096 }
00097 if ( ! _repoindex )
00098 {
00099 ZYPP_THROW( ParseException( (dest_dir+repoInfo().path()).asString() + ": " + "No repository index in content file." ) );
00100 }
00101 MIL << "RepoIndex: " << _repoindex << endl;
00102 if ( _repoindex->metaFileChecksums.empty() )
00103 {
00104 ZYPP_THROW( ParseException( (dest_dir+repoInfo().path()).asString() + ": " + "No metadata checksums in content file." ) );
00105 }
00106 if ( _repoindex->signingKeys.empty() )
00107 {
00108 WAR << "No signing keys defined." << endl;
00109 }
00110
00111
00112 descr_dir = _repoindex->descrdir;
00113
00114
00115
00116 for_( it, _repoindex->metaFileChecksums.begin(), _repoindex->metaFileChecksums.end() )
00117 {
00118
00119 if ( str::hasPrefix( it->first, "packages" ) )
00120 {
00121 std::string rest( str::stripPrefix( it->first, "packages" ) );
00122 if ( ! ( rest.empty()
00123 || rest == ".DU"
00124 || rest == ".en"
00125 || rest == ".gz"
00126 || rest == ".DU.gz"
00127 || rest == ".en.gz" ) )
00128 {
00129
00130 Locale toParse( ZConfig::instance().textLocale() );
00131 while ( toParse != Locale::noCode )
00132 {
00133 if ( rest == ("."+toParse.code()) || (rest == ("."+toParse.code()+".gz")) )
00134 break;
00135 toParse = toParse.fallback();
00136 }
00137 if ( toParse == Locale::noCode )
00138 {
00139
00140 continue;
00141 }
00142 }
00143 }
00144 else if ( it->first == "patterns.pat"
00145 || it->first == "patterns.pat.gz" )
00146 {
00147
00148 }
00149 else if ( str::endsWith( it->first, ".pat" )
00150 || str::endsWith( it->first, ".pat.gz" ) )
00151 {
00152
00153
00154
00155
00156
00157
00158
00159 std::vector<std::string> patparts;
00160 unsigned archpos = 2;
00161
00162 unsigned count = str::split( it->first, std::back_inserter(patparts), "." );
00163 if ( patparts[count-1] == "gz" )
00164 archpos++;
00165
00166 if ( count > archpos )
00167 {
00168 try
00169 {
00170 Arch patarch( patparts[count-archpos] );
00171 if ( !patarch.compatibleWith( ZConfig::instance().systemArchitecture() ) )
00172 {
00173
00174 MIL << "Discarding pattern " << it->first << endl;
00175 continue;
00176 }
00177 }
00178 catch ( const Exception & excpt )
00179 {
00180 WAR << "Pattern file name does not contain recognizable architecture: " << it->first << endl;
00181
00182 }
00183 }
00184 }
00185 MIL << "adding job " << it->first << endl;
00186 OnMediaLocation location( repoInfo().path() + descr_dir + it->first, 1 );
00187 location.setChecksum( it->second );
00188 this->enqueueDigested(location);
00189 }
00190
00191 for_( it, _repoindex->mediaFileChecksums.begin(), _repoindex->mediaFileChecksums.end() )
00192 {
00193
00194 if ( it->first != "license.tar.gz" )
00195 continue;
00196
00197 MIL << "adding job " << it->first << endl;
00198 OnMediaLocation location( repoInfo().path() + it->first, 1 );
00199 location.setChecksum( it->second );
00200 this->enqueueDigested(location);
00201 }
00202
00203 for_( it, _repoindex->signingKeys.begin(),_repoindex->signingKeys.end() )
00204 {
00205 MIL << "adding job " << it->first << endl;
00206 OnMediaLocation location( repoInfo().path() + it->first, 1 );
00207 location.setChecksum( it->second );
00208 this->enqueueDigested(location);
00209 }
00210
00211 this->start( dest_dir, media );
00212 }
00213
00214 void Downloader::consumeIndex( const RepoIndex_Ptr & data_r )
00215 {
00216 MIL << "Consuming repo index" << endl;
00217 _repoindex = data_r;
00218 }
00219
00220 }
00221 }
00222 }