5 #include "zypp/base/Logger.h"
6 #include "zypp/base/String.h"
7 #include "zypp/OnMediaLocation.h"
8 #include "zypp/MediaSetAccess.h"
9 #include "zypp/Fetcher.h"
10 #include "zypp/Locale.h"
11 #include "zypp/ZConfig.h"
12 #include "zypp/repo/MediaInfoDownloader.h"
13 #include "zypp/repo/susetags/Downloader.h"
14 #include "zypp/parser/ParseException.h"
15 #include "zypp/parser/susetags/RepoIndex.h"
16 #include "zypp/base/UserRequestException.h"
19 using namespace zypp::parser;
20 using namespace zypp::parser::susetags;
29 Downloader::Downloader(const RepoInfo &info )
35 Downloader::Downloader(const Pathname &path )
42 RepoStatus Downloader::status( MediaSetAccess &media )
44 Pathname content = media.provideFile( _info.path() + "/content");
45 Pathname mediafile = media.provideFile( _info.path() + "/media.1/media" );
47 return RepoStatus(content) && RepoStatus(mediafile);
50 void Downloader::download( MediaSetAccess &media,
51 const Pathname &dest_dir,
52 const ProgressData::ReceiverFnc & progress )
54 downloadMediaInfo( dest_dir, media );
56 SignatureFileChecker sigchecker(_info.name());
58 Pathname sig = _info.path() + "/content.asc";
59 if ( media.doesFileExist(sig) )
61 this->enqueue( OnMediaLocation( sig, 1 ) );
62 this->start( dest_dir, media );
65 sigchecker = SignatureFileChecker( dest_dir + sig, _info.name() );
68 Pathname key = _info.path() + "/content.key";
69 if ( media.doesFileExist(key) )
71 this->enqueue( OnMediaLocation( key, 1 ) );
72 this->start( dest_dir, media );
74 sigchecker.addPublicKey(dest_dir + key);
77 if ( ! _info.gpgCheck() )
79 WAR << "Signature checking disabled in config of repository " << _info.alias() << endl;
81 this->enqueue( OnMediaLocation( _info.path() + "/content", 1 ),
82 _info.gpgCheck() ? FileChecker(sigchecker) : FileChecker(NullFileChecker()) );
83 this->start( dest_dir, media );
88 // Content file first to get the repoindex
90 Pathname inputfile( dest_dir + _info.path() + "/content" );
91 ContentFileReader content;
92 content.setRepoIndexConsumer( bind( &Downloader::consumeIndex, this, _1 ) );
93 content.parse( inputfile );
97 ZYPP_THROW( ParseException( (dest_dir+_info.path()).asString() + ": " + "No repository index in content file." ) );
99 MIL << "RepoIndex: " << _repoindex << endl;
100 if ( _repoindex->metaFileChecksums.empty() )
102 ZYPP_THROW( ParseException( (dest_dir+_info.path()).asString() + ": " + "No metadata checksums in content file." ) );
104 if ( _repoindex->signingKeys.empty() )
106 WAR << "No signing keys defined." << endl;
110 descr_dir = _repoindex->descrdir; // path below reporoot
111 //_datadir = _repoIndex->datadir; // path below reporoot
114 for ( RepoIndex::FileChecksumMap::const_iterator it = _repoindex->metaFileChecksums.begin();
115 it != _repoindex->metaFileChecksums.end();
118 // omit unwanted translations
119 if ( str::hasPrefix( it->first, "packages" ) )
121 std::string rest( str::stripPrefix( it->first, "packages" ) );
122 if ( ! ( rest.empty()
127 || rest == ".en.gz" ) )
129 // Not 100% correct as we take each fallback of textLocale
130 Locale toParse( ZConfig::instance().textLocale() );
131 while ( toParse != Locale::noCode )
133 if ( rest == ("."+toParse.code()) || (rest == ("."+toParse.code()+".gz")) )
135 toParse = toParse.fallback();
137 if ( toParse == Locale::noCode )
144 else if ( it->first == "patterns.pat"
145 || it->first == "patterns.pat.gz" )
147 // take all patterns in one go
149 else if ( str::endsWith( it->first, ".pat" )
150 || str::endsWith( it->first, ".pat.gz" ) )
153 // *** see also zypp/parser/susetags/RepoParser.cc ***
155 // omit unwanted patterns, see https://bugzilla.novell.com/show_bug.cgi?id=298716
156 // expect "<name>.<arch>.pat[.gz]", <name> might contain additional dots
157 // split at dots, take .pat or .pat.gz into account
159 std::vector<std::string> patparts;
160 unsigned archpos = 2;
161 // expect "<name>.<arch>.pat[.gz]", <name> might contain additional dots
162 unsigned count = str::split( it->first, std::back_inserter(patparts), "." );
163 if ( patparts[count-1] == "gz" )
166 if ( count > archpos )
168 try // might by an invalid architecture
170 Arch patarch( patparts[count-archpos] );
171 if ( !patarch.compatibleWith( ZConfig::instance().systemArchitecture() ) )
173 // discard, if not compatible
174 MIL << "Discarding pattern " << it->first << endl;
178 catch ( const Exception & excpt )
180 WAR << "Pattern file name does not contain recognizable architecture: " << it->first << endl;
181 // keep .pat file if it doesn't contain an recognizable arch
185 MIL << "adding job " << it->first << endl;
186 OnMediaLocation location( _info.path() + descr_dir + it->first, 1 );
187 location.setChecksum( it->second );
188 this->enqueueDigested(location);
191 for ( RepoIndex::FileChecksumMap::const_iterator it = _repoindex->signingKeys.begin();
192 it != _repoindex->signingKeys.end();
195 OnMediaLocation location( _info.path() + it->first, 1 );
196 location.setChecksum( it->second );
197 this->enqueueDigested(location);
200 this->start( dest_dir, media );
203 void Downloader::consumeIndex( const RepoIndex_Ptr & data_r )
205 MIL << "Consuming repo index" << endl;