typos (#301331)
[platform/upstream/libzypp.git] / zypp / repo / susetags / Downloader.cc
1
2 #include <iostream>
3 #include <fstream>
4
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"
17
18 using namespace std;
19 using namespace zypp::parser;
20 using namespace zypp::parser::susetags;
21
22 namespace zypp
23 {
24 namespace repo
25 {
26 namespace susetags
27 {
28
29 Downloader::Downloader(const Pathname &path )
30     : _path(path)
31 {
32
33 }
34
35 RepoStatus Downloader::status( MediaSetAccess &media )
36 {
37   Pathname content = media.provideFile( _path + "/content");
38   return RepoStatus(content);
39 }
40
41 void Downloader::download( MediaSetAccess &media,
42                            const Pathname &dest_dir,
43                            const ProgressData::ReceiverFnc & progress )
44 {
45   downloadMediaInfo( dest_dir, media );
46
47   SignatureFileChecker sigchecker;
48
49   Pathname sig = _path + "/content.asc";
50   if ( media.doesFileExist(sig) )
51   {
52     this->enqueue( OnMediaLocation( sig, 1 ) );
53     this->start( dest_dir, media );
54     this->reset();
55
56     sigchecker = SignatureFileChecker( dest_dir + sig );
57   }
58
59   Pathname key = _path + "/content.key";
60   if ( media.doesFileExist(key) )
61   {
62     this->enqueue( OnMediaLocation( key, 1 ) );
63     this->start( dest_dir, media );
64     this->reset();
65     sigchecker.addPublicKey(dest_dir + key);
66   }
67
68
69   this->enqueue( OnMediaLocation( _path + "/content", 1 ), sigchecker );
70   this->start( dest_dir, media );
71   this->reset();
72
73   Pathname descr_dir;
74
75   // Content file first to get the repoindex
76   {
77     Pathname inputfile( dest_dir +  _path + "/content" );
78     ContentFileReader content;
79     content.setRepoIndexConsumer( bind( &Downloader::consumeIndex, this, _1 ) );
80     content.parse( inputfile );
81   }
82   if ( ! _repoindex )
83   {
84     ZYPP_THROW( ParseException( (dest_dir+_path).asString() + ": " + "No repository index in content file." ) );
85   }
86   
87   // Prepare parsing
88   descr_dir = _repoindex->descrdir; // path below reporoot
89   //_datadir  = _repoIndex->datadir;  // path below reporoot
90   
91   for ( RepoIndex::FileChecksumMap::const_iterator it = _repoindex->metaFileChecksums.begin();
92         it != _repoindex->metaFileChecksums.end();
93         ++it )
94   {
95     // omit unwanted translations
96     if ( str::hasPrefix( it->first, "packages" ) )
97     {
98       std::string rest( str::stripPrefix( it->first, "packages" ) );
99       if ( ! (   rest.empty()
100               || rest == ".DU"
101               || rest == ".en"
102               || rest == ".gz"
103               || rest == ".DU.gz"
104               || rest == ".en.gz" ) )
105       {
106         // Not 100% correct as we take each fallback of textLocale
107         Locale toParse( ZConfig::instance().textLocale() );
108         while ( toParse != Locale::noCode )
109         {
110           if ( rest == ("."+toParse.code()) || (rest == ("."+toParse.code()+".gz")) )
111             break;
112           toParse = toParse.fallback();
113         }
114         if ( toParse == Locale::noCode )
115         {
116           // discard
117           continue;
118         }
119       }
120     }
121     else if ( str::endsWith( it->first, ".pat" ) 
122               || str::endsWith( it->first, ".pat.gz" ) )
123     {
124
125       // *** see also zypp/parser/susetags/RepoParser.cc ***
126
127       // omit unwanted patterns, see https://bugzilla.novell.com/show_bug.cgi?id=298716
128       // expect "<name>.<arch>.pat[.gz]", <name> might contain additional dots
129       // split at dots, take .pat or .pat.gz into account
130
131       std::vector<std::string> patparts;
132       unsigned archpos = 2;
133       // expect "<name>.<arch>.pat[.gz]", <name> might contain additional dots
134       unsigned count = str::split( it->first, std::back_inserter(patparts), "." );
135       if ( patparts[count-1] == "gz" )
136           archpos++;
137
138       if ( count > archpos )
139       {
140         try                             // might by an invalid architecture
141         {
142           Arch patarch( patparts[count-archpos] );
143           if ( !patarch.compatibleWith( ZConfig::instance().systemArchitecture() ) )
144           {
145             // discard, if not compatible
146             MIL << "Discarding pattern " << it->first << endl;
147             continue;
148           }
149         }
150         catch ( const Exception & excpt )
151         {
152           WAR << "Pattern file name does not contain recognizable architecture: " << it->first << endl;
153           // keep .pat file if it doesn't contain an recognizable arch
154         }
155       }
156     }
157     MIL << "adding job " << it->first << endl;
158     OnMediaLocation location( _path + descr_dir + it->first, 1 );
159     location.setChecksum( it->second );
160     this->enqueueDigested(location);
161   }
162   
163   for ( RepoIndex::FileChecksumMap::const_iterator it = _repoindex->signingKeys.begin();
164         it != _repoindex->signingKeys.end();
165         ++it )
166   {
167     OnMediaLocation location( _path + it->first, 1 );
168     location.setChecksum( it->second );
169     this->enqueueDigested(location);
170   }
171   
172   // add hashed media files
173   
174   for ( RepoIndex::FileChecksumMap::const_iterator it = _repoindex->mediaFileChecksums.begin();
175         it != _repoindex->mediaFileChecksums.end();
176         ++it )
177   {
178     OnMediaLocation location( _path + it->first, 1 );
179     location.setChecksum( it->second );
180     this->enqueueDigested(location);
181   }
182
183   this->start( dest_dir, media );
184 }
185
186 void Downloader::consumeIndex( const RepoIndex_Ptr & data_r )
187 {
188   MIL << "Consuming repo index" << endl;
189   _repoindex = data_r;
190 }
191
192 }// ns susetags
193 }// ns source
194 } // ns zypp