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