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
00018 using namespace std;
00019 using namespace zypp::parser;
00020 using namespace zypp::parser::susetags;
00021
00022 namespace zypp
00023 {
00024 namespace repo
00025 {
00026 namespace susetags
00027 {
00028
00029 Downloader::Downloader(const Pathname &path )
00030 : _path(path)
00031 {
00032
00033 }
00034
00035 RepoStatus Downloader::status( MediaSetAccess &media )
00036 {
00037 Pathname content = media.provideFile( _path + "/content");
00038 Pathname mediafile = media.provideFile( _path + "/media.1/media" );
00039
00040 return RepoStatus(content) && RepoStatus(mediafile);
00041 }
00042
00043 void Downloader::download( MediaSetAccess &media,
00044 const Pathname &dest_dir,
00045 const ProgressData::ReceiverFnc & progress )
00046 {
00047 downloadMediaInfo( dest_dir, media );
00048
00049 SignatureFileChecker sigchecker;
00050
00051 Pathname sig = _path + "/content.asc";
00052 if ( media.doesFileExist(sig) )
00053 {
00054 this->enqueue( OnMediaLocation( sig, 1 ) );
00055 this->start( dest_dir, media );
00056 this->reset();
00057
00058 sigchecker = SignatureFileChecker( dest_dir + sig );
00059 }
00060
00061 Pathname key = _path + "/content.key";
00062 if ( media.doesFileExist(key) )
00063 {
00064 this->enqueue( OnMediaLocation( key, 1 ) );
00065 this->start( dest_dir, media );
00066 this->reset();
00067 sigchecker.addPublicKey(dest_dir + key);
00068 }
00069
00070
00071 this->enqueue( OnMediaLocation( _path + "/content", 1 ), sigchecker );
00072 this->start( dest_dir, media );
00073 this->reset();
00074
00075 Pathname descr_dir;
00076
00077
00078 {
00079 Pathname inputfile( dest_dir + _path + "/content" );
00080 ContentFileReader content;
00081 content.setRepoIndexConsumer( bind( &Downloader::consumeIndex, this, _1 ) );
00082 content.parse( inputfile );
00083 }
00084 if ( ! _repoindex )
00085 {
00086 ZYPP_THROW( ParseException( (dest_dir+_path).asString() + ": " + "No repository index in content file." ) );
00087 }
00088
00089
00090 descr_dir = _repoindex->descrdir;
00091
00092
00093 for ( RepoIndex::FileChecksumMap::const_iterator it = _repoindex->metaFileChecksums.begin();
00094 it != _repoindex->metaFileChecksums.end();
00095 ++it )
00096 {
00097
00098 if ( str::hasPrefix( it->first, "packages" ) )
00099 {
00100 std::string rest( str::stripPrefix( it->first, "packages" ) );
00101 if ( ! ( rest.empty()
00102 || rest == ".DU"
00103 || rest == ".en"
00104 || rest == ".gz"
00105 || rest == ".DU.gz"
00106 || rest == ".en.gz" ) )
00107 {
00108
00109 Locale toParse( ZConfig::instance().textLocale() );
00110 while ( toParse != Locale::noCode )
00111 {
00112 if ( rest == ("."+toParse.code()) || (rest == ("."+toParse.code()+".gz")) )
00113 break;
00114 toParse = toParse.fallback();
00115 }
00116 if ( toParse == Locale::noCode )
00117 {
00118
00119 continue;
00120 }
00121 }
00122 }
00123 else if ( str::endsWith( it->first, ".pat" )
00124 || str::endsWith( it->first, ".pat.gz" ) )
00125 {
00126
00127
00128
00129
00130
00131
00132
00133 std::vector<std::string> patparts;
00134 unsigned archpos = 2;
00135
00136 unsigned count = str::split( it->first, std::back_inserter(patparts), "." );
00137 if ( patparts[count-1] == "gz" )
00138 archpos++;
00139
00140 if ( count > archpos )
00141 {
00142 try
00143 {
00144 Arch patarch( patparts[count-archpos] );
00145 if ( !patarch.compatibleWith( ZConfig::instance().systemArchitecture() ) )
00146 {
00147
00148 MIL << "Discarding pattern " << it->first << endl;
00149 continue;
00150 }
00151 }
00152 catch ( const Exception & excpt )
00153 {
00154 WAR << "Pattern file name does not contain recognizable architecture: " << it->first << endl;
00155
00156 }
00157 }
00158 }
00159 MIL << "adding job " << it->first << endl;
00160 OnMediaLocation location( _path + descr_dir + it->first, 1 );
00161 location.setChecksum( it->second );
00162 this->enqueueDigested(location);
00163 }
00164
00165 for ( RepoIndex::FileChecksumMap::const_iterator it = _repoindex->signingKeys.begin();
00166 it != _repoindex->signingKeys.end();
00167 ++it )
00168 {
00169 OnMediaLocation location( _path + it->first, 1 );
00170 location.setChecksum( it->second );
00171 this->enqueueDigested(location);
00172 }
00173
00174 this->start( dest_dir, media );
00175 }
00176
00177 void Downloader::consumeIndex( const RepoIndex_Ptr & data_r )
00178 {
00179 MIL << "Consuming repo index" << endl;
00180 _repoindex = data_r;
00181 }
00182
00183 }
00184 }
00185 }