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 
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   // Content file first to get the repoindex
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   // Prepare parsing
00090   descr_dir = _repoindex->descrdir; // path below reporoot
00091   //_datadir  = _repoIndex->datadir;  // path below reporoot
00092   
00093   for ( RepoIndex::FileChecksumMap::const_iterator it = _repoindex->metaFileChecksums.begin();
00094         it != _repoindex->metaFileChecksums.end();
00095         ++it )
00096   {
00097     // omit unwanted translations
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         // Not 100% correct as we take each fallback of textLocale
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           // discard
00119           continue;
00120         }
00121       }
00122     }
00123     else if ( str::endsWith( it->first, ".pat" ) 
00124               || str::endsWith( it->first, ".pat.gz" ) )
00125     {
00126 
00127       // *** see also zypp/parser/susetags/RepoParser.cc ***
00128 
00129       // omit unwanted patterns, see https://bugzilla.novell.com/show_bug.cgi?id=298716
00130       // expect "<name>.<arch>.pat[.gz]", <name> might contain additional dots
00131       // split at dots, take .pat or .pat.gz into account
00132 
00133       std::vector<std::string> patparts;
00134       unsigned archpos = 2;
00135       // expect "<name>.<arch>.pat[.gz]", <name> might contain additional dots
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                             // might by an invalid architecture
00143         {
00144           Arch patarch( patparts[count-archpos] );
00145           if ( !patarch.compatibleWith( ZConfig::instance().systemArchitecture() ) )
00146           {
00147             // discard, if not compatible
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           // keep .pat file if it doesn't contain an recognizable arch
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 }// ns susetags
00184 }// ns source
00185 } // ns zypp

Generated on Tue Sep 25 19:23:05 2007 for libzypp by  doxygen 1.5.3