libzypp 17.31.23
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>
23
25
26#undef ZYPP_BASE_LOGGER_LOGGROUP
27#define ZYPP_BASE_LOGGER_LOGGROUP "parser::yum"
28
29using std::endl;
30using namespace zypp::xml;
31
32namespace 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:
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
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 {
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 );
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:
Interface of repomd.xml file reader.
Store and operate with byte count.
Definition: ByteCount.h:31
Describes a resource file located on a medium.
OnMediaLocation & setDownloadSize(ByteCount val_r)
Set the downloadSize.
OnMediaLocation & setChecksum(CheckSum val_r)
Set the checksum.
OnMediaLocation & setHeaderSize(ByteCount val_r)
Set the headerSize.
OnMediaLocation & setLocation(Pathname filename_r, unsigned medianr_r=1)
Set filename_r and medianr_r (defaults to 1).
OnMediaLocation & setHeaderChecksum(CheckSum val_r)
Set the headerChecksum.
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
Impl(const Pathname &repomd_file, const ProcessResource &callback)
Ctro taking a ProcessResource callback.
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.
function< bool(OnMediaLocation &&, const std::string &)> ProcessResource
Callback taking OnMediaLocation and the resource type string.
RW_pointer< Impl, rw_pointer::Scoped< Impl > > _pimpl
const std::set< std::string > & keywords() const
repo keywords parsed on the fly
RepomdFileReader(const Pathname &repomd_file, const ProcessResource &callback)
CTOR.
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:140
bool foreachNode(ProcessNode fnc_r)
Definition: Reader.h:144
std::string asString() const
Explicit conversion to std::string.
Definition: XmlString.h:77
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition: NonCopyable.h:26
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
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
#define DBG
Definition: Logger.h:95
#define MIL
Definition: Logger.h:96