libzypp 17.38.15

RepoFileReader.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12#include <iostream>
13#include <zypp/ZYppCallbacks.h>
14#include <zypp-core/base/LogTools.h>
15#include <zypp-core/base/String.h>
16#include <zypp-core/base/StringV.h>
17#include <utility>
18#include <zypp-core/base/InputStream>
19#include <zypp-core/base/UserRequestException>
20
21#include <zypp-core/parser/IniDict>
22#include <zypp/parser/RepoFileReader.h>
23
24 using std::endl;
25
27 namespace zypp
28{
30 namespace parser
31 {
33 namespace {
34
39 class RepoFileParser : public IniDict
40 {
41 public:
42 RepoFileParser( const InputStream & is_r )
43 { read( is_r ); }
44
45 using IniDict::consume; // don't hide overloads we don't redefine here
46
47 void consume( const std::string & section_r, const std::string & key_r, const std::string & value_r ) override
48 {
49 if ( key_r == "baseurl" )
50 {
51 _inMultiline = MultiLine::baseurl;
52 storeUrl( _baseurls[section_r], value_r );
53 }
54 else if ( key_r == "gpgkey" )
55 {
56 _inMultiline = MultiLine::gpgkey;
57 storeUrl( _gpgkeys[section_r], value_r );
58 }
59 else if ( key_r == "mirrorlist" )
60 {
61 _inMultiline = MultiLine::mirrorlist;
62 storeUrl( _mirrorlist[section_r], value_r );
63 }
64 else if ( key_r == "metalink" )
65 {
66 _inMultiline = MultiLine::metalink;
67 storeUrl( _metalink[section_r], value_r );
68 }
69 else
70 {
71 _inMultiline = MultiLine::none;
72 IniDict::consume( section_r, key_r, value_r );
73 }
74 }
75
76 void garbageLine( const std::string & section_r, const std::string & line_r ) override
77 {
78 switch ( _inMultiline )
79 {
80 case MultiLine::baseurl:
81 storeUrl( _baseurls[section_r], line_r );
82 break;
83
84 case MultiLine::gpgkey:
85 storeUrl( _gpgkeys[section_r], line_r );
86 break;
87
88 case MultiLine::mirrorlist:
89 storeUrl( _mirrorlist[section_r], line_r );
90 break;
91
92 case MultiLine::metalink:
93 storeUrl( _metalink[section_r], line_r );
94 break;
95
96 case MultiLine::none:
97 IniDict::garbageLine( section_r, line_r ); // throw
98 break;
99 }
100 }
101
102 std::list<Url> & baseurls( const std::string & section_r )
103 { return _baseurls[section_r]; }
104
105 std::list<Url> & gpgkeys( const std::string & section_r )
106 { return _gpgkeys[section_r]; }
107
108 std::list<Url> & mirrorlist( const std::string & section_r )
109 { return _mirrorlist[section_r]; }
110
111 std::list<Url> & metalink( const std::string & section_r )
112 { return _metalink[section_r]; }
113
114 private:
115 void storeUrl( std::list<Url> & store_r, const std::string & line_r )
116 {
117 // #285: Fedora/dnf allows WS separated urls (and an optional comma)
118 strv::splitRx( line_r, "[,[:blank:]]*[[:blank:]][,[:blank:]]*", [&store_r]( std::string_view w ) {
119 if ( ! w.empty() )
120 store_r.push_back( Url(std::string(w)) );
121 });
122 }
123
124 enum class MultiLine { none, baseurl, gpgkey, mirrorlist, metalink };
125 MultiLine _inMultiline = MultiLine::none;
126
127 std::map<std::string,std::list<Url>> _baseurls;
128 std::map<std::string,std::list<Url>> _gpgkeys;
129 std::map<std::string,std::list<Url>> _mirrorlist;
130 std::map<std::string,std::list<Url>> _metalink;
131 };
132
133 } //namespace
135
140 static void repositories_in_stream( const InputStream &is,
141 const RepoFileReader::ProcessRepo &callback,
142 const ProgressData::ReceiverFnc &progress )
143 try {
144 RepoFileParser dict(is);
145 for_( its, dict.sectionsBegin(), dict.sectionsEnd() )
146 {
147 RepoInfo info;
148 info.setAlias(*its);
149 std::string proxy;
150 std::string proxyport;
151
152 for_( it, dict.entriesBegin(*its), dict.entriesEnd(*its) )
153 {
154 //MIL << (*it).first << endl;
155 if (it->first == "name" )
156 info.setName(it-> second);
157 else if ( it->first == "enabled" )
158 info.setEnabled( str::strToTrue( it->second ) );
159 else if ( it->first == "priority" )
160 info.setPriority( str::strtonum<unsigned>( it->second ) );
161 else if ( it->first == "path" ) {
162 Pathname location { it->second };
163 if ( location.relativeDotDot() ) {
164 // Don't accept downloadable data outside repo root
165 JobReport::warning( str::sconcat( *its,": hostile path=",location," => ", location.absolutename() ) );
166 pWAR( "Hostile path=", location, "=>", location.absolutename() );
167 location = location.absolutename();
168 }
169 info.setPath( location );
170 }
171 else if ( it->first == "type" )
172 ; // bsc#1177427 et.al.: type in a .repo file is legacy - ignore it and let RepoManager probe
173 else if ( it->first == "autorefresh" )
174 info.setAutorefresh( str::strToTrue( it->second ) );
175 else if ( it->first == "gpgcheck" )
176 info.setGpgCheck( str::strToTriBool( it->second ) );
177 else if ( it->first == "repo_gpgcheck" )
178 info.setRepoGpgCheck( str::strToTrue( it->second ) );
179 else if ( it->first == "pkg_gpgcheck" )
180 info.setPkgGpgCheck( str::strToTrue( it->second ) );
181 else if ( it->first == "keeppackages" )
182 info.setKeepPackages( str::strToTrue( it->second ) );
183 else if ( it->first == "service" )
184 info.setService( it->second );
185 else if ( it->first == "proxy" )
186 {
187 // Translate it into baseurl queryparams
188 // NOTE: The hack here does not add proxy to mirrorlist urls but the
189 // original code worked without complains, so keep it for now.
190 static const str::regex ex( ":[0-9]+$" ); // portspec
191 str::smatch what;
192 if ( str::regex_match( it->second, what, ex ) )
193 {
194 proxy = it->second.substr( 0, it->second.size() - what[0].size() );
195 proxyport = what[0].substr( 1 );
196 }
197 else
198 {
199 proxy = it->second;
200 }
201 }
202 else
203 {
204 // Extra tags are directly forwarded to the RepoInfo.
205 if ( not info.setExtraValue( it->first, it->second ) ) {
206 WAR << "Unknown attribute in [" << *its << "]: " << it->first << "=" << it->second << " not interpreted; preserved as an extra value" << endl;
207 }
208 }
209 }
210
211 for ( auto & url : dict.baseurls( *its ) )
212 {
213 if ( ! proxy.empty() && url.getQueryParam( "proxy" ).empty() )
214 {
215 url.setQueryParam( "proxy", proxy );
216 url.setQueryParam( "proxyport", proxyport );
217 }
218 info.addBaseUrl( url );
219 }
220
221 if ( ! dict.gpgkeys( *its ).empty() )
222 info.setGpgKeyUrls( std::move(dict.gpgkeys( *its )) );
223
224 if ( ! dict.mirrorlist( *its ).empty() ) // parser tolerates multiple definitions, but 1st one wins
225 info.setMirrorlistUrl( dict.mirrorlist( *its ).front() );
226
227 if ( ! dict.metalink( *its ).empty() ) // parser tolerates multiple definitions, but 1st one wins
228 info.setMetalinkUrl( dict.metalink( *its ).front() );
229
230 info.setFilepath(is.path());
231 MIL << info << endl;
232 // add it to the list.
233 callback(info);
234 //if (!progress.tick())
235 // ZYPP_THROW(AbortRequestException());
236 }
237 }
238 catch ( Exception & ex ) {
239 ex.addHistory( "Parsing .repo file "+is.name() );
240 ZYPP_RETHROW( ex );
241 }
242
244 //
245 // CLASS NAME : RepoFileReader
246 //
248
249 RepoFileReader::RepoFileReader( const Pathname & repo_file,
250 ProcessRepo callback,
251 const ProgressData::ReceiverFnc &progress )
252 : _callback(std::move(callback))
253 {
254 repositories_in_stream(InputStream(repo_file), _callback, progress);
255 }
256
257 RepoFileReader::RepoFileReader( const InputStream &is,
258 ProcessRepo callback,
259 const ProgressData::ReceiverFnc &progress )
260 : _callback(std::move(callback))
261 {
262 repositories_in_stream(is, _callback, progress);
263 }
264
265 RepoFileReader::~RepoFileReader()
266 {}
267
268
269 std::ostream & operator<<( std::ostream & str, const RepoFileReader & obj )
270 {
271 return str;
272 }
273
274 } // namespace parser
276} // namespace zypp
for_
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition Easy.h:27
ZYPP_RETHROW
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
Definition Exception.h:479
LogTools.h
pWAR
#define pWAR
Definition LogTools.h:316
MIL
#define MIL
Definition Logger.h:130
WAR
#define WAR
Definition Logger.h:131
RepoFileReader.h
StringV.h
String.h
ZYppCallbacks.h
zypp::Exception
Base class for Exception.
Definition Exception.h:153
zypp::Exception::addHistory
void addHistory(const std::string &msg_r)
Add some message text to the history.
Definition Exception.cc:189
zypp::InputStream
Helper to create and pass std::istream.
Definition inputstream.h:57
zypp::InputStream::path
const Pathname & path() const
Path to the input file or empty if no file.
Definition inputstream.h:111
zypp::InputStream::InputStream
InputStream()
Default ctor providing std::cin.
Definition inputstream.cc:63
zypp::ProgressData::ReceiverFnc
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
Definition progressdata.h:140
zypp::RepoInfo
What is known about a repository.
Definition RepoInfo.h:72
zypp::RepoInfo::setPkgGpgCheck
void setPkgGpgCheck(TriBool value_r)
Set the value for pkgGpgCheck (or indeterminate to use the default).
Definition RepoInfo.cc:639
zypp::RepoInfo::setGpgKeyUrls
void setGpgKeyUrls(url_set urls)
Set a list of gpgkey URLs defined for this repo.
Definition RepoInfo.cc:740
zypp::RepoInfo::setMetalinkUrl
void setMetalinkUrl(const Url &url)
Set the raw metalink url.
Definition RepoInfo.cc:722
zypp::RepoInfo::setMirrorlistUrl
void setMirrorlistUrl(const Url &url)
Set the raw mirrorlist url.
Definition RepoInfo.cc:719
zypp::RepoInfo::setKeepPackages
void setKeepPackages(bool keep)
Set if packaqes downloaded from this repository will be kept in local cache.
Definition RepoInfo.cc:804
zypp::RepoInfo::setService
void setService(const std::string &name)
sets service which added this repository
Definition RepoInfo.cc:807
zypp::RepoInfo::setExtraValue
bool setExtraValue(const std::string &key_r, std::string value_r)
Remember extra value_r for key_r.
Definition RepoInfo.cc:1254
zypp::RepoInfo::setGpgCheck
void setGpgCheck(TriBool value_r)
Set the value for gpgCheck (or indeterminate to use the default).
Definition RepoInfo.cc:616
zypp::RepoInfo::addBaseUrl
void addBaseUrl(Url url)
Add a base url.
Definition RepoInfo.cc:752
zypp::RepoInfo::setPath
void setPath(const Pathname &path)
set the product path.
Definition RepoInfo.cc:785
zypp::RepoInfo::setPriority
void setPriority(unsigned newval_r)
Set repository priority for solver.
Definition RepoInfo.cc:609
zypp::RepoInfo::setRepoGpgCheck
void setRepoGpgCheck(TriBool value_r)
Set the value for repoGpgCheck (or indeterminate to use the default).
Definition RepoInfo.cc:629
zypp::Url::Url
Url()
Definition Url.cc:306
zypp::filesystem::Pathname
Pathname.
Definition Pathname.h:48
zypp::filesystem::Pathname::relativeDotDot
bool relativeDotDot() const
Test for a relative path referring to ../.
Definition Pathname.h:124
zypp::filesystem::Pathname::absolutename
Pathname absolutename() const
Return this path, adding a leading '/' if relative.
Definition Pathname.h:148
zypp::parser::IniDict
Parses a INI file and offers its structure as a dictionary.
Definition inidict.h:42
zypp::parser::IniDict::consume
void consume(const std::string &section) override
Called when a section is found.
Definition inidict.cc:64
zypp::parser::IniParser::garbageLine
virtual void garbageLine(const std::string &section, const std::string &line)
Called whenever a garbage line is found.
Definition iniparser.cc:78
zypp::parser::RepoFileReader::operator<<
friend std::ostream & operator<<(std::ostream &str, const RepoFileReader &obj)
relates: RepoFileReader Stream output
Definition RepoFileReader.cc:269
zypp::parser::RepoFileReader::ProcessRepo
function< bool(const RepoInfo &)> ProcessRepo
Callback definition.
Definition RepoFileReader.h:64
zypp::parser::RepoFileReader::RepoFileReader
RepoFileReader(const Pathname &repo_file, ProcessRepo callback, const ProgressData::ReceiverFnc &progress=ProgressData::ReceiverFnc())
Constructor.
Definition RepoFileReader.cc:249
zypp::parser::RepoFileReader::~RepoFileReader
~RepoFileReader()
Dtor.
Definition RepoFileReader.cc:265
zypp::parser::RepoFileReader::_callback
ProcessRepo _callback
Definition RepoFileReader.h:105
zypp::repo::RepoInfoBase::setAutorefresh
void setAutorefresh(bool autorefresh)
enable or disable autorefresh
Definition RepoInfoBase.cc:92
zypp::repo::RepoInfoBase::setFilepath
void setFilepath(const Pathname &filename)
set the path to the .repo file
Definition RepoInfoBase.cc:101
zypp::repo::RepoInfoBase::setAlias
void setAlias(const std::string &alias)
set the repository alias
Definition RepoInfoBase.cc:95
zypp::repo::RepoInfoBase::setName
void setName(const std::string &name)
set the repository name
Definition RepoInfoBase.cc:98
zypp::repo::RepoInfoBase::setEnabled
void setEnabled(bool enabled)
enable or disable the repository
Definition RepoInfoBase.cc:89
zypp::str::regex
Regular expression.
Definition Regex.h:95
zypp::str::smatch
Regular expression match result.
Definition Regex.h:168
zypp::str::smatch::size
unsigned size() const
Definition Regex.cc:106
zypp::str::regex_match
bool regex_match(const char *s, smatch &matches, const regex &regex) ZYPP_API
Regular expression matching.
Definition Regex.cc:80
std
Definition ansi.h:855
str
String related utilities and Regular expression matching.
ztui::none
@ none
Definition Table.h:92
zypp::base::sysconfig::read
std::map< std::string, std::string > read(const Pathname &_path)
Read sysconfig file path_r and return (key,valye) pairs.
Definition sysconfig.cc:34
zypp::callback
Callbacks light.
Definition Callback.h:146
zypp::parser
Definition HistoryLogReader.cc:30
zypp::parser::repositories_in_stream
static void repositories_in_stream(const InputStream &is, const RepoFileReader::ProcessRepo &callback, const ProgressData::ReceiverFnc &progress)
List of RepoInfo's from a file.
Definition RepoFileReader.cc:140
zypp::str::strToTrue
bool strToTrue(const C_Str &str)
Parsing boolean from string.
Definition String.cc:66
zypp::str::strToTriBool
TriBool strToTriBool(const C_Str &str)
Parse str into a bool if it's a legal true or false string; else indeterminate.
Definition String.cc:96
zypp::str::strtonum
TInt strtonum(const C_Str &str)
Parsing numbers from string.
zypp::str::sconcat
std::string sconcat(Args &&... args)
Concat words as string.
Definition LogTools.h:276
zypp::url
Url details namespace.
Definition UrlBase.cc:58
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition CodePitfalls.doc:2
zypp::JobReport::warning
static bool warning(const std::string &msg_r, const UserData &userData_r=UserData())
send warning text
Definition ZYppCallbacks.h:1136