libzypp  17.31.31
RepomdFileReader.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 
14 #include <zypp/base/String.h>
15 #include <zypp/base/Logger.h>
16 #include <zypp/base/Regex.h>
17 
18 #include <zypp/Pathname.h>
19 #include <zypp/Date.h>
20 #include <zypp/Url.h>
21 #include <zypp/CheckSum.h>
22 #include <zypp/parser/xml/Reader.h>
23 
25 
26 #undef ZYPP_BASE_LOGGER_LOGGROUP
27 #define ZYPP_BASE_LOGGER_LOGGROUP "parser::yum"
28 
29 using std::endl;
30 using namespace zypp::xml;
31 
32 namespace zypp
33 {
34  namespace parser
35  {
36  namespace yum
37  {
38 
39 
41  //
42  // CLASS NAME : RepomdFileReader::Impl
43  //
45  {
46  public:
48  Impl(const Pathname &repomd_file, const ProcessResource & callback )
49  : _callback( callback )
50  {
51  Reader reader( repomd_file );
52  MIL << "Reading " << repomd_file << endl;
53  reader.foreachNode( bind( &RepomdFileReader::Impl::consumeNode, this, _1 ) );
54  }
55 
59  bool consumeNode( Reader & reader_r );
60 
61 
63  const std::set<std::string> & keywords() const
64  { return _keywords; }
65 
66  private:
68  CheckSum getChecksum( Reader & reader_r )
69  { return CheckSum( reader_r->getAttribute("type").asString(), reader_r.nodeText().asString() ); }
70 
72  ByteCount getSize( Reader & reader_r )
73  { return ByteCount( str::strtonum<ByteCount::SizeType>( reader_r.nodeText().asString() ) ); }
74 
75 
76  private:
79 
81  std::string _typeStr;
82 
85 
86  std::set<std::string> _keywords;
87  };
89 
90  /*
91  * xpath and multiplicity of processed nodes are included in the code
92  * for convenience:
93  *
94  * // xpath: <xpath> (?|*|+)
95  *
96  * if multiplicity is ommited, then the node has multiplicity 'one'.
97  */
98 
99  // --------------------------------------------------------------------------
100 
101  bool RepomdFileReader::Impl::consumeNode( Reader & reader_r )
102  {
103  if ( reader_r->nodeType() == XML_READER_TYPE_ELEMENT )
104  {
105  // xpath: /repomd
106  if ( reader_r->name() == "repomd" )
107  {
108  return true;
109  }
110 
111  // xpath: /repomd/data (+)
112  if ( reader_r->name() == "data" )
113  {
114  _typeStr = reader_r->getAttribute("type").asString();
115  return true;
116  }
117 
118  // xpath: /repomd/location
119  if ( reader_r->name() == "location" )
120  {
121  _location.setLocation( reader_r->getAttribute("href").asString(), 1 );
122  // ignoring attribute xml:base
123  return true;
124  }
125 
126  // xpath: /repomd/checksum
127  if ( reader_r->name() == "checksum" )
128  {
129  _location.setChecksum( getChecksum( reader_r ) );
130  return true;
131  }
132 
133  // xpath: /repomd/header-checksum
134  if ( reader_r->name() == "header-checksum" )
135  {
136  _location.setHeaderChecksum( getChecksum( reader_r ) );
137  return true;
138  }
139 
140  // xpath: /repomd/timestamp
141  if ( reader_r->name() == "timestamp" )
142  {
143  // ignore it
144  return true;
145  }
146 
147  // xpath: /repomd/size
148  if ( reader_r->name() == "size" )
149  {
150  _location.setDownloadSize( getSize( reader_r ) );
151  return true;
152  }
153 
154  // xpath: /repomd/header-size
155  if ( reader_r->name() == "header-size" )
156  {
157  _location.setHeaderSize( getSize( reader_r ) );
158  return true;
159  }
160 
161  // xpath: /tags/content
162  if ( reader_r->name() == "content" )
163  {
164  const auto & tag = reader_r.nodeText();
165  if ( tag.c_str() && *tag.c_str() )
166  _keywords.insert( tag.asString() ); // remember keyword
167  return true;
168  }
169  }
170 
171  else if ( reader_r->nodeType() == XML_READER_TYPE_END_ELEMENT )
172  {
173  // xpath: /repomd/data
174  if ( reader_r->name() == "data" )
175  {
176  if (_callback) {
177  _callback( std::move(_location), _typeStr );
178  _location = OnMediaLocation();
179  _typeStr.clear();
180  }
181  return true;
182  }
183  }
184 
185  return true;
186  }
187 
188 
190  //
191  // CLASS NAME : RepomdFileReader
192  //
194 
195  RepomdFileReader::RepomdFileReader( const Pathname & repomd_file, const ProcessResource & callback )
196  : _pimpl( new Impl(repomd_file, callback) )
197  {}
198 
200  : _pimpl( new Impl(repomd_file, ProcessResource()) )
201  {}
202 
204  {}
205 
206  const std::set<std::string> & RepomdFileReader::keywords() const
207  { return _pimpl->keywords(); }
208 
209  std::vector<std::pair<std::string,std::string>> RepomdFileReader::keyhints() const
210  {
211  std::vector<std::pair<std::string,std::string>> ret;
212  for ( const std::string & tag : keywords() ) {
213  // Get keyhints on the fly:
214  // gpg-pubkey-39db7c82-5847eb1f.asc?fpr=22C07BA534178CD02EFE22AAB88B2FD43DBDC284
215  // Fingerprint is explicitly mentioned or id/fpr can be derived from the filename
216  if ( tag.compare( 0,10,"gpg-pubkey" ) != 0 )
217  continue;
218 
219  static const str::regex rx( "^(gpg-pubkey([^?]*))(\\?fpr=([[:xdigit:]]{8,}))?$" );
220  str::smatch what;
221  if ( str::regex_match( tag.c_str(), what, rx ) ) {
222  std::string keyfile { what[1] };
223  std::string keyident;
224  if ( what.size(4) != std::string::npos ) { // with fpr=
225  keyident = what[4];
226  }
227  else {
228  static const str::regex rx( /*gpg-pubkey*/"^-([[:xdigit:]]{8,})" );
229  if ( str::regex_match( what[2], what, rx ) ) {
230  keyident = what[1];
231  }
232  else {
233  DBG << "Tag " << tag << " does not contain a keyident. ignore it." << endl;
234  continue;
235  }
236  }
237  ret.push_back( std::make_pair( std::move(keyfile), std::move(keyident) ) );
238  }
239  }
240  return ret;
241  }
242 
243  } // ns yum
244  } // ns parser
245 } // ns zypp
246 
247 // vim: set ts=2 sts=2 sw=2 et ai:
#define MIL
Definition: Logger.h:96
RepomdFileReader(const Pathname &repomd_file, const ProcessResource &callback)
CTOR.
unsigned size() const
Definition: Regex.cc:106
std::string _typeStr
The resource type string.
Describes a resource file located on a medium.
Regular expression.
Definition: Regex.h:94
Store and operate with byte count.
Definition: ByteCount.h:30
NodeType nodeType() const
Get the node type of the current node.
Definition: Node.h:126
function< bool(OnMediaLocation &&, const std::string &)> ProcessResource
Callback taking OnMediaLocation and the resource type string.
ByteCount getSize(Reader &reader_r)
Retrieve a size node.
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition: NonCopyable.h:26
OnMediaLocation _location
Location of metadata file.
XmlString getAttribute(const char *name_r) const
Provides a copy of the attribute value with the specified qualified name.
Definition: Node.h:71
std::vector< std::pair< std::string, std::string > > keyhints() const
gpg key hits shipped in keywords (bsc#1184326)
RW_pointer< Impl, rw_pointer::Scoped< Impl > > _pimpl
Impl(const Pathname &repomd_file, const ProcessResource &callback)
Ctro taking a ProcessResource callback.
const std::set< std::string > & keywords() const
repo keywords parsed on the fly
const ProcessCredentials & _callback
Regular expression match result.
Definition: Regex.h:167
XmlString nodeText()
If the current node is not empty, advances the reader to the next node, and returns the value...
Definition: Reader.cc:122
CheckSum getChecksum(Reader &reader_r)
Retrieve a checksum node.
std::string asString() const
Explicit conversion to std::string.
Definition: XmlString.h:77
bool foreachNode(ProcessNode fnc_r)
Definition: Reader.h:144
XmlString name() const
The qualified name of the node, equal to Prefix :LocalName.
Definition: Node.h:118
bool regex_match(const std::string &s, smatch &matches, const regex &regex)
regex ZYPP_STR_REGEX regex ZYPP_STR_REGEX
Definition: Regex.h:70
std::set< std::string > _keywords
repo keywords parsed on the fly
Interface of repomd.xml file reader.
ProcessResource _callback
Function for processing collected data.
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
#define DBG
Definition: Logger.h:95
const std::set< std::string > & keywords() const
repo keywords parsed on the fly
xmlTextReader based interface to iterate xml streams.
Definition: Reader.h:95