libzypp  17.28.4
RepoFileReader.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 #include <zypp/base/LogTools.h>
14 #include <zypp/base/String.h>
15 #include <zypp/base/StringV.h>
16 #include <zypp/base/InputStream.h>
18 
19 #include <zypp/parser/IniDict.h>
21 
22 using std::endl;
23 
25 namespace zypp
26 {
28  namespace parser
29  {
31  namespace {
32 
37  class RepoFileParser : public IniDict
38  {
39  public:
40  RepoFileParser( const InputStream & is_r )
41  { read( is_r ); }
42 
43  using IniDict::consume; // don't hide overloads we don't redefine here
44 
45  virtual void consume( const std::string & section_r, const std::string & key_r, const std::string & value_r )
46  {
47  if ( key_r == "baseurl" )
48  {
49  _inMultiline = MultiLine::baseurl;
50  storeUrl( _baseurls[section_r], value_r );
51  }
52  else if ( key_r == "gpgkey" )
53  {
54  _inMultiline = MultiLine::gpgkey;
55  storeUrl( _gpgkeys[section_r], value_r );
56  }
57  else if ( key_r == "mirrorlist" )
58  {
59  _inMultiline = MultiLine::mirrorlist;
60  storeUrl( _mirrorlist[section_r], value_r );
61  }
62  else if ( key_r == "metalink" )
63  {
64  _inMultiline = MultiLine::metalink;
65  storeUrl( _metalink[section_r], value_r );
66  }
67  else
68  {
69  _inMultiline = MultiLine::none;
70  IniDict::consume( section_r, key_r, value_r );
71  }
72  }
73 
74  virtual void garbageLine( const std::string & section_r, const std::string & line_r )
75  {
76  switch ( _inMultiline )
77  {
78  case MultiLine::baseurl:
79  storeUrl( _baseurls[section_r], line_r );
80  break;
81 
82  case MultiLine::gpgkey:
83  storeUrl( _gpgkeys[section_r], line_r );
84  break;
85 
86  case MultiLine::mirrorlist:
87  storeUrl( _mirrorlist[section_r], line_r );
88  break;
89 
90  case MultiLine::metalink:
91  storeUrl( _metalink[section_r], line_r );
92  break;
93 
94  case MultiLine::none:
95  IniDict::garbageLine( section_r, line_r ); // throw
96  break;
97  }
98  }
99 
100  std::list<Url> & baseurls( const std::string & section_r )
101  { return _baseurls[section_r]; }
102 
103  std::list<Url> & gpgkeys( const std::string & section_r )
104  { return _gpgkeys[section_r]; }
105 
106  std::list<Url> & mirrorlist( const std::string & section_r )
107  { return _mirrorlist[section_r]; }
108 
109  std::list<Url> & metalink( const std::string & section_r )
110  { return _metalink[section_r]; }
111 
112  private:
113  void storeUrl( std::list<Url> & store_r, const std::string & line_r )
114  {
115  // #285: Fedora/dnf allows WS separated urls (and an optional comma)
116  strv::splitRx( line_r, "[,[:blank:]]*[[:blank:]][,[:blank:]]*", [&store_r]( std::string_view w ) {
117  if ( ! w.empty() )
118  store_r.push_back( Url(std::string(w)) );
119  });
120  }
121 
122  enum class MultiLine { none, baseurl, gpgkey, mirrorlist, metalink };
123  MultiLine _inMultiline = MultiLine::none;
124 
125  std::map<std::string,std::list<Url>> _baseurls;
126  std::map<std::string,std::list<Url>> _gpgkeys;
127  std::map<std::string,std::list<Url>> _mirrorlist;
128  std::map<std::string,std::list<Url>> _metalink;
129  };
130 
131  } //namespace
133 
138  static void repositories_in_stream( const InputStream &is,
139  const RepoFileReader::ProcessRepo &callback,
140  const ProgressData::ReceiverFnc &progress )
141  {
142  RepoFileParser dict(is);
143  for_( its, dict.sectionsBegin(), dict.sectionsEnd() )
144  {
145  RepoInfo info;
146  info.setAlias(*its);
147  std::string proxy;
148  std::string proxyport;
149 
150  for_( it, dict.entriesBegin(*its), dict.entriesEnd(*its) )
151  {
152  //MIL << (*it).first << endl;
153  if (it->first == "name" )
154  info.setName(it-> second);
155  else if ( it->first == "enabled" )
156  info.setEnabled( str::strToTrue( it->second ) );
157  else if ( it->first == "priority" )
158  info.setPriority( str::strtonum<unsigned>( it->second ) );
159  else if ( it->first == "path" )
160  info.setPath( Pathname(it->second) );
161  else if ( it->first == "type" )
162  ; // bsc#1177427 et.al.: type in a .repo file is legacy - ignore it and let RepoManager probe
163  else if ( it->first == "autorefresh" )
164  info.setAutorefresh( str::strToTrue( it->second ) );
165  else if ( it->first == "gpgcheck" )
166  info.setGpgCheck( str::strToTriBool( it->second ) );
167  else if ( it->first == "repo_gpgcheck" )
168  info.setRepoGpgCheck( str::strToTrue( it->second ) );
169  else if ( it->first == "pkg_gpgcheck" )
170  info.setPkgGpgCheck( str::strToTrue( it->second ) );
171  else if ( it->first == "keeppackages" )
172  info.setKeepPackages( str::strToTrue( it->second ) );
173  else if ( it->first == "service" )
174  info.setService( it->second );
175  else if ( it->first == "proxy" )
176  {
177  // Translate it into baseurl queryparams
178  // NOTE: The hack here does not add proxy to mirrorlist urls but the
179  // original code worked without complains, so keep it for now.
180  static const str::regex ex( ":[0-9]+$" ); // portspec
181  str::smatch what;
182  if ( str::regex_match( it->second, what, ex ) )
183  {
184  proxy = it->second.substr( 0, it->second.size() - what[0].size() );
185  proxyport = what[0].substr( 1 );
186  }
187  else
188  {
189  proxy = it->second;
190  }
191  }
192  else
193  ERR << "Unknown attribute in [" << *its << "]: " << it->first << "=" << it->second << " ignored" << endl;
194  }
195 
196  for ( auto & url : dict.baseurls( *its ) )
197  {
198  if ( ! proxy.empty() && url.getQueryParam( "proxy" ).empty() )
199  {
200  url.setQueryParam( "proxy", proxy );
201  url.setQueryParam( "proxyport", proxyport );
202  }
203  info.addBaseUrl( url );
204  }
205 
206  if ( ! dict.gpgkeys( *its ).empty() )
207  info.setGpgKeyUrls( std::move(dict.gpgkeys( *its )) );
208 
209  if ( ! dict.mirrorlist( *its ).empty() )
210  info.setMirrorListUrls( std::move(dict.mirrorlist( *its )) );
211 
212  if ( ! dict.metalink( *its ).empty() )
213  info.setMetalinkUrls( std::move(dict.metalink( *its )) );
214 
215 
216  info.setFilepath(is.path());
217  MIL << info << endl;
218  // add it to the list.
219  callback(info);
220  //if (!progress.tick())
221  // ZYPP_THROW(AbortRequestException());
222  }
223  }
224 
226  //
227  // CLASS NAME : RepoFileReader
228  //
230 
232  const ProcessRepo & callback,
233  const ProgressData::ReceiverFnc &progress )
234  : _callback(callback)
235  {
236  repositories_in_stream(InputStream(repo_file), _callback, progress);
237  }
238 
240  const ProcessRepo & callback,
241  const ProgressData::ReceiverFnc &progress )
242  : _callback(callback)
243  {
244  repositories_in_stream(is, _callback, progress);
245  }
246 
248  {}
249 
250 
251  std::ostream & operator<<( std::ostream & str, const RepoFileReader & obj )
252  {
253  return str;
254  }
255 
256  } // namespace parser
258 } // namespace zypp
const ProcessCredentials & _callback
std::map< std::string, std::list< Url > > _gpgkeys
MultiLine _inMultiline
std::map< std::string, std::list< Url > > _baseurls
std::map< std::string, std::list< Url > > _metalink
std::map< std::string, std::list< Url > > _mirrorlist
Helper to create and pass std::istream.
Definition: InputStream.h:57
const Pathname & path() const
Path to the input file or empty if no file.
Definition: InputStream.h:111
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
Definition: ProgressData.h:139
What is known about a repository.
Definition: RepoInfo.h:72
void setPkgGpgCheck(TriBool value_r)
Set the value for pkgGpgCheck (or indeterminate to use the default).
Definition: RepoInfo.cc:434
void setGpgKeyUrls(url_set urls)
Set a list of gpgkey URLs defined for this repo.
Definition: RepoInfo.cc:526
void setMirrorListUrls(url_set urls)
Like setMirrorListUrl but take an url_set.
Definition: RepoInfo.cc:517
void addBaseUrl(const Url &url)
Add a base url.
Definition: RepoInfo.cc:634
void setKeepPackages(bool keep)
Set if packaqes downloaded from this repository will be kept in local cache.
Definition: RepoInfo.cc:667
void setService(const std::string &name)
sets service which added this repository
Definition: RepoInfo.cc:670
void setGpgCheck(TriBool value_r)
Set the value for gpgCheck (or indeterminate to use the default).
Definition: RepoInfo.cc:406
void setPath(const Pathname &path)
set the product path.
Definition: RepoInfo.cc:651
void setPriority(unsigned newval_r)
Set repository priority for solver.
Definition: RepoInfo.cc:399
void setRepoGpgCheck(TriBool value_r)
Set the value for repoGpgCheck (or indeterminate to use the default).
Definition: RepoInfo.cc:424
void setMetalinkUrls(url_set urls)
Like setMirrorListUrls but expect metalink format.
Definition: RepoInfo.cc:523
virtual void consume(const std::string &section)
Called when a section is found.
Definition: IniDict.cc:61
virtual void garbageLine(const std::string &section, const std::string &line)
Called whenever a garbage line is found.
Definition: IniParser.cc:70
Read repository data from a .repo file.
function< bool(const RepoInfo &)> ProcessRepo
Callback definition.
RepoFileReader(const Pathname &repo_file, const ProcessRepo &callback, const ProgressData::ReceiverFnc &progress=ProgressData::ReceiverFnc())
Constructor.
void setAutorefresh(bool autorefresh)
enable or disable autorefresh
Definition: RepoInfoBase.cc:91
void setFilepath(const Pathname &filename)
set the path to the .repo file
void setAlias(const std::string &alias)
set the repository alias
Definition: RepoInfoBase.cc:94
void setName(const std::string &name)
set the repository name
Definition: RepoInfoBase.cc:97
void setEnabled(bool enabled)
enable or disable the repository
Definition: RepoInfoBase.cc:88
Regular expression.
Definition: Regex.h:95
Regular expression match result.
Definition: Regex.h:168
unsigned size() const
Definition: Regex.cc:106
String related utilities and Regular expression matching.
std::map< std::string, std::string > read(const Pathname &_path)
Read sysconfig file path_r and return (key,valye) pairs.
Definition: Sysconfig.cc:34
std::ostream & operator<<(std::ostream &str, const IniDict &obj)
Definition: IniDict.cc:160
static void repositories_in_stream(const InputStream &is, const RepoFileReader::ProcessRepo &callback, const ProgressData::ReceiverFnc &progress)
List of RepoInfo's from a file.
TriBool strToTriBool(const C_Str &str)
Parse str into a bool if it's a legal true or false string; else indterminate.
Definition: String.cc:93
bool regex_match(const std::string &s, smatch &matches, const regex &regex)
\relates regex \ingroup ZYPP_STR_REGEX \relates regex \ingroup ZYPP_STR_REGEX
Definition: Regex.h:70
bool strToTrue(const C_Str &str)
Parsing boolean from string.
Definition: String.cc:63
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:28
#define MIL
Definition: Logger.h:96
#define ERR
Definition: Logger.h:98