libzypp 17.37.17
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>
24
26
27#undef ZYPP_BASE_LOGGER_LOGGROUP
28#define ZYPP_BASE_LOGGER_LOGGROUP "parser::yum"
29
30using std::endl;
31using namespace zypp::xml;
32
33namespace 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:
70 { return CheckSum( reader_r->getAttribute("type").asString(), reader_r.nodeText().asString() ); }
71
73 ByteCount getSize( Reader & reader_r )
75
76
77 private:
80
82 std::string _typeStr;
83
86
87 std::set<std::string> _keywords;
88 };
89
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
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 );
180 _typeStr.clear();
181 }
182 return true;
183 }
184 }
185
186 return true;
187 }
188
189
191 //
192 // CLASS NAME : RepomdFileReader
193 //
195
197 : _pimpl( new Impl(repomd_file, std::move(callback)) )
198 {}
199
201 : _pimpl( new Impl(repomd_file, ProcessResource()) )
202 {}
203
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:
Interface of repomd.xml file reader.
Store and operate with byte count.
Definition ByteCount.h:32
Describes a resource file located on a medium.
CheckSum getChecksum(Reader &reader_r)
Retrieve a checksum node.
bool consumeNode(Reader &reader_r)
Callback provided to the XML parser.
const std::set< std::string > & keywords() const
repo keywords parsed on the fly
ByteCount getSize(Reader &reader_r)
Retrieve a size node.
std::set< std::string > _keywords
repo keywords parsed on the fly
std::string _typeStr
The resource type string.
OnMediaLocation _location
Location of metadata file.
ProcessResource _callback
Function for processing collected data.
Impl(const Pathname &repomd_file, ProcessResource &&callback)
Ctro taking a ProcessResource callback.
RW_pointer< Impl, rw_pointer::Scoped< Impl > > _pimpl
function< bool(OnMediaLocation &&, const std::string &)> ProcessResource
Callback taking OnMediaLocation and the resource type string.
RepomdFileReader(const Pathname &repomd_file, ProcessResource callback)
CTOR.
const std::set< std::string > & keywords() const
repo keywords parsed on the fly
std::vector< std::pair< std::string, std::string > > keyhints() const
gpg key hits shipped in keywords (bsc#1184326)
Regular expression.
Definition Regex.h:95
Regular expression match result.
Definition Regex.h:168
unsigned size() const
Definition Regex.cc:106
NodeType nodeType() const
Get the node type of the current node.
Definition Node.h:126
XmlString getAttribute(const char *name_r) const
Provides a copy of the attribute value with the specified qualified name.
Definition Node.h:71
XmlString name() const
The qualified name of the node, equal to Prefix :LocalName.
Definition Node.h:118
xmlTextReader based interface to iterate xml streams.
Definition Reader.h:96
XmlString nodeText()
If the current node is not empty, advances the reader to the next node, and returns the value.
Definition Reader.cc:122
bool foreachNode(const ProcessNode &fnc_r)
Definition Reader.h:144
std::string asString() const
Explicit conversion to std::string.
Definition XmlString.h:77
Definition Arch.h:364
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition NonCopyable.h:26
Callbacks light.
Definition Callback.h:146
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
TInt strtonum(const C_Str &str)
Parsing numbers from string.
Easy-to use interface to the ZYPP dependency resolver.
#define DBG
Definition Logger.h:99
#define MIL
Definition Logger.h:100