libzypp  17.38.13
RepoFileReader.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 #include <zypp/ZYppCallbacks.h>
15 #include <zypp-core/base/String.h>
16 #include <zypp-core/base/StringV.h>
17 #include <utility>
18 #include <zypp-core/base/InputStream>
19 #include <zypp-core/base/UserRequestException>
20 
21 #include <zypp-core/parser/IniDict>
23 
24 using std::endl;
25 
27 namespace zypp
28 {
30  namespace parser
31  {
33  namespace {
34 
39  class RepoFileParser : public IniDict
40  {
41  public:
42  RepoFileParser( const InputStream & is_r )
43  { read( is_r ); }
44 
45  using IniDict::consume; // don't hide overloads we don't redefine here
46 
47  void consume( const std::string & section_r, const std::string & key_r, const std::string & value_r ) override
48  {
49  if ( key_r == "baseurl" )
50  {
51  _inMultiline = MultiLine::baseurl;
52  storeUrl( _baseurls[section_r], value_r );
53  }
54  else if ( key_r == "gpgkey" )
55  {
56  _inMultiline = MultiLine::gpgkey;
57  storeUrl( _gpgkeys[section_r], value_r );
58  }
59  else if ( key_r == "mirrorlist" )
60  {
61  _inMultiline = MultiLine::mirrorlist;
62  storeUrl( _mirrorlist[section_r], value_r );
63  }
64  else if ( key_r == "metalink" )
65  {
66  _inMultiline = MultiLine::metalink;
67  storeUrl( _metalink[section_r], value_r );
68  }
69  else
70  {
72  IniDict::consume( section_r, key_r, value_r );
73  }
74  }
75 
76  void garbageLine( const std::string & section_r, const std::string & line_r ) override
77  {
78  switch ( _inMultiline )
79  {
80  case MultiLine::baseurl:
81  storeUrl( _baseurls[section_r], line_r );
82  break;
83 
84  case MultiLine::gpgkey:
85  storeUrl( _gpgkeys[section_r], line_r );
86  break;
87 
88  case MultiLine::mirrorlist:
89  storeUrl( _mirrorlist[section_r], line_r );
90  break;
91 
92  case MultiLine::metalink:
93  storeUrl( _metalink[section_r], line_r );
94  break;
95 
96  case MultiLine::none:
97  IniDict::garbageLine( section_r, line_r ); // throw
98  break;
99  }
100  }
101 
102  std::list<Url> & baseurls( const std::string & section_r )
103  { return _baseurls[section_r]; }
104 
105  std::list<Url> & gpgkeys( const std::string & section_r )
106  { return _gpgkeys[section_r]; }
107 
108  std::list<Url> & mirrorlist( const std::string & section_r )
109  { return _mirrorlist[section_r]; }
110 
111  std::list<Url> & metalink( const std::string & section_r )
112  { return _metalink[section_r]; }
113 
114  private:
115  void storeUrl( std::list<Url> & store_r, const std::string & line_r )
116  {
117  // #285: Fedora/dnf allows WS separated urls (and an optional comma)
118  strv::splitRx( line_r, "[,[:blank:]]*[[:blank:]][,[:blank:]]*", [&store_r]( std::string_view w ) {
119  if ( ! w.empty() )
120  store_r.push_back( Url(std::string(w)) );
121  });
122  }
123 
124  enum class MultiLine { none, baseurl, gpgkey, mirrorlist, metalink };
126 
127  std::map<std::string,std::list<Url>> _baseurls;
128  std::map<std::string,std::list<Url>> _gpgkeys;
129  std::map<std::string,std::list<Url>> _mirrorlist;
130  std::map<std::string,std::list<Url>> _metalink;
131  };
132 
133  } //namespace
135 
140  static void repositories_in_stream( const InputStream &is,
141  const RepoFileReader::ProcessRepo &callback,
142  const ProgressData::ReceiverFnc &progress )
143  try {
144  RepoFileParser dict(is);
145  for_( its, dict.sectionsBegin(), dict.sectionsEnd() )
146  {
147  RepoInfo info;
148  info.setAlias(*its);
149  std::string proxy;
150  std::string proxyport;
151 
152  for_( it, dict.entriesBegin(*its), dict.entriesEnd(*its) )
153  {
154  //MIL << (*it).first << endl;
155  if (it->first == "name" )
156  info.setName(it-> second);
157  else if ( it->first == "enabled" )
158  info.setEnabled( str::strToTrue( it->second ) );
159  else if ( it->first == "priority" )
160  info.setPriority( str::strtonum<unsigned>( it->second ) );
161  else if ( it->first == "path" ) {
162  Pathname location { it->second };
163  if ( location.relativeDotDot() ) {
164  // Don't accept downloadable data outside repo root
165  JobReport::warning( str::sconcat( *its,": hostile path=",location," => ", location.absolutename() ) );
166  pWAR( "Hostile path=", location, "=>", location.absolutename() );
167  location = location.absolutename();
168  }
169  info.setPath( location );
170  }
171  else if ( it->first == "type" )
172  ; // bsc#1177427 et.al.: type in a .repo file is legacy - ignore it and let RepoManager probe
173  else if ( it->first == "autorefresh" )
174  info.setAutorefresh( str::strToTrue( it->second ) );
175  else if ( it->first == "gpgcheck" )
176  info.setGpgCheck( str::strToTriBool( it->second ) );
177  else if ( it->first == "repo_gpgcheck" )
178  info.setRepoGpgCheck( str::strToTrue( it->second ) );
179  else if ( it->first == "pkg_gpgcheck" )
180  info.setPkgGpgCheck( str::strToTrue( it->second ) );
181  else if ( it->first == "keeppackages" )
182  info.setKeepPackages( str::strToTrue( it->second ) );
183  else if ( it->first == "service" )
184  info.setService( it->second );
185  else if ( it->first == "proxy" )
186  {
187  // Translate it into baseurl queryparams
188  // NOTE: The hack here does not add proxy to mirrorlist urls but the
189  // original code worked without complains, so keep it for now.
190  static const str::regex ex( ":[0-9]+$" ); // portspec
191  str::smatch what;
192  if ( str::regex_match( it->second, what, ex ) )
193  {
194  proxy = it->second.substr( 0, it->second.size() - what[0].size() );
195  proxyport = what[0].substr( 1 );
196  }
197  else
198  {
199  proxy = it->second;
200  }
201  }
202  else
203  {
204  // Extra tags are directly forwarded to the RepoInfo.
205  if ( not info.setExtraValue( it->first, it->second ) ) {
206  WAR << "Unknown attribute in [" << *its << "]: " << it->first << "=" << it->second << " not interpreted; preserved as an extra value" << endl;
207  }
208  }
209  }
210 
211  for ( auto & url : dict.baseurls( *its ) )
212  {
213  if ( ! proxy.empty() && url.getQueryParam( "proxy" ).empty() )
214  {
215  url.setQueryParam( "proxy", proxy );
216  url.setQueryParam( "proxyport", proxyport );
217  }
218  info.addBaseUrl( url );
219  }
220 
221  if ( ! dict.gpgkeys( *its ).empty() )
222  info.setGpgKeyUrls( std::move(dict.gpgkeys( *its )) );
223 
224  if ( ! dict.mirrorlist( *its ).empty() ) // parser tolerates multiple definitions, but 1st one wins
225  info.setMirrorlistUrl( dict.mirrorlist( *its ).front() );
226 
227  if ( ! dict.metalink( *its ).empty() ) // parser tolerates multiple definitions, but 1st one wins
228  info.setMetalinkUrl( dict.metalink( *its ).front() );
229 
230  info.setFilepath(is.path());
231  MIL << info << endl;
232  // add it to the list.
233  callback(info);
234  //if (!progress.tick())
235  // ZYPP_THROW(AbortRequestException());
236  }
237  }
238  catch ( Exception & ex ) {
239  ex.addHistory( "Parsing .repo file "+is.name() );
240  ZYPP_RETHROW( ex );
241  }
242 
244  //
245  // CLASS NAME : RepoFileReader
246  //
248 
250  ProcessRepo callback,
251  const ProgressData::ReceiverFnc &progress )
252  : _callback(std::move(callback))
253  {
254  repositories_in_stream(InputStream(repo_file), _callback, progress);
255  }
256 
258  ProcessRepo callback,
259  const ProgressData::ReceiverFnc &progress )
260  : _callback(std::move(callback))
261  {
262  repositories_in_stream(is, _callback, progress);
263  }
264 
266  {}
267 
268 
269  std::ostream & operator<<( std::ostream & str, const RepoFileReader & obj )
270  {
271  return str;
272  }
273 
274  } // namespace parser
276 } // namespace zypp
MultiLine _inMultiline
#define MIL
Definition: Logger.h:103
unsigned size() const
Definition: Regex.cc:106
void setAutorefresh(bool autorefresh)
enable or disable autorefresh
Definition: RepoInfoBase.cc:92
Regular expression.
Definition: Regex.h:94
void setPriority(unsigned newval_r)
Set repository priority for solver.
Definition: RepoInfo.cc:619
std::map< std::string, std::list< Url > > _gpgkeys
std::map< std::string, std::list< Url > > _mirrorlist
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
Definition: progressdata.h:140
void setEnabled(bool enabled)
enable or disable the repository
Definition: RepoInfoBase.cc:89
std::map< std::string, std::list< Url > > _baseurls
void addHistory(const std::string &msg_r)
Add some message text to the history.
Definition: Exception.cc:189
void setAlias(const std::string &alias)
set the repository alias
Definition: RepoInfoBase.cc:95
String related utilities and Regular expression matching.
void setFilepath(const Pathname &filename)
set the path to the .repo file
Definition: ansi.h:854
What is known about a repository.
Definition: RepoInfo.h:71
static bool warning(const std::string &msg_r, const UserData &userData_r=UserData())
send warning text
void setGpgCheck(TriBool value_r)
Set the value for gpgCheck (or indeterminate to use the default).
Definition: RepoInfo.cc:626
Helper to create and pass std::istream.
Definition: inputstream.h:56
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:27
RepoFileReader(const Pathname &repo_file, ProcessRepo callback, const ProgressData::ReceiverFnc &progress=ProgressData::ReceiverFnc())
Constructor.
TriBool strToTriBool(const C_Str &str)
Parse str into a bool if it&#39;s a legal true or false string; else indeterminate.
Definition: String.cc:96
void setMirrorlistUrl(const Url &url)
Set the raw mirrorlist url.
Definition: RepoInfo.cc:734
static void repositories_in_stream(const InputStream &is, const RepoFileReader::ProcessRepo &callback, const ProgressData::ReceiverFnc &progress)
List of RepoInfo&#39;s from a file.
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
Definition: Exception.h:479
std::map< std::string, std::list< Url > > _metalink
void setRepoGpgCheck(TriBool value_r)
Set the value for repoGpgCheck (or indeterminate to use the default).
Definition: RepoInfo.cc:644
void setPath(const Pathname &path)
set the product path.
Definition: RepoInfo.cc:800
void setService(const std::string &name)
sets service which added this repository
Definition: RepoInfo.cc:822
#define WAR
Definition: Logger.h:104
#define pWAR
Definition: LogTools.h:316
void setKeepPackages(bool keep)
Set if packaqes downloaded from this repository will be kept in local cache.
Definition: RepoInfo.cc:819
std::string sconcat(Args &&... args)
Concat words as string.
Definition: LogTools.h:276
Read repository data from a .repo file.
const Pathname & path() const
Path to the input file or empty if no file.
Definition: inputstream.h:111
virtual void garbageLine(const std::string &section, const std::string &line)
Called whenever a garbage line is found.
Definition: iniparser.cc:78
function< bool(const RepoInfo &)> ProcessRepo
Callback definition.
zypp::Url Url
Definition: url.h:15
const ProcessCredentials & _callback
void consume(const std::string &section) override
Called when a section is found.
Definition: inidict.cc:64
void setMetalinkUrl(const Url &url)
Set the raw metalink url.
Definition: RepoInfo.cc:737
void setGpgKeyUrls(url_set urls)
Set a list of gpgkey URLs defined for this repo.
Definition: RepoInfo.cc:755
Regular expression match result.
Definition: Regex.h:167
Base class for Exception.
Definition: Exception.h:152
void addBaseUrl(Url url)
Add a base url.
Definition: RepoInfo.cc:767
std::map< std::string, std::string > read(const Pathname &_path)
Read sysconfig file path_r and return (key,valye) pairs.
Definition: sysconfig.cc:34
bool regex_match(const char *s, smatch &matches, const regex &regex) ZYPP_API
Regular expression matching.
Definition: Regex.cc:80
void setName(const std::string &name)
set the repository name
Definition: RepoInfoBase.cc:98
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
void setPkgGpgCheck(TriBool value_r)
Set the value for pkgGpgCheck (or indeterminate to use the default).
Definition: RepoInfo.cc:654
bool setExtraValue(const std::string &key_r, std::string value_r)
Remember extra value_r for key_r.
Definition: RepoInfo.cc:1269
bool strToTrue(const C_Str &str)
Parsing boolean from string.
Definition: String.cc:66
std::ostream & operator<<(std::ostream &str, const ProductFileData &obj)
relates: ProductFileData Stream output