RepoInfo.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <iostream>
00013
00014 #include "zypp/base/Logger.h"
00015 #include "zypp/base/DefaultIntegral.h"
00016 #include "zypp/parser/xml/XmlEscape.h"
00017
00018 #include "zypp/RepoInfo.h"
00019 #include "zypp/repo/RepoInfoBaseImpl.h"
00020 #include "zypp/ExternalProgram.h"
00021 #include "zypp/media/MediaAccess.h"
00022
00023 using namespace std;
00024 using zypp::xml::escape;
00025
00027 namespace zypp
00028 {
00029
00031
00032
00033
00035 struct RepoInfo::Impl : public repo::RepoInfoBase::Impl
00036 {
00037 Impl()
00038 : repo::RepoInfoBase::Impl()
00039 , gpgcheck(indeterminate)
00040 , keeppackages(indeterminate)
00041 , type(repo::RepoType::NONE_e)
00042 {}
00043
00044 ~Impl()
00045 {}
00046
00047 public:
00048 static const unsigned defaultPriority = 99;
00049
00050 void setProbedType( const repo::RepoType & t ) const
00051 {
00052 if ( type == repo::RepoType::NONE
00053 && t != repo::RepoType::NONE )
00054 {
00055
00056 const_cast<Impl*>(this)->type = t;
00057 }
00058 }
00059
00060 public:
00061 Pathname licenseTgz() const
00062 { return metadatapath.empty() ? Pathname() : metadatapath / path / "license.tar.gz"; }
00063
00064
00065 public:
00066 TriBool gpgcheck;
00067 TriBool keeppackages;
00068 Url gpgkey_url;
00069 repo::RepoType type;
00070 Url mirrorlist_url;
00071 std::set<Url> baseUrls;
00072 Pathname path;
00073 std::string service;
00074 std::string targetDistro;
00075 Pathname metadatapath;
00076 Pathname packagespath;
00077 DefaultIntegral<unsigned,defaultPriority> priority;
00078 public:
00079
00080 private:
00081 friend Impl * rwcowClone<Impl>( const Impl * rhs );
00083 Impl * clone() const
00084 { return new Impl( *this ); }
00085 };
00087
00089 inline std::ostream & operator<<( std::ostream & str, const RepoInfo::Impl & obj )
00090 {
00091 return str << "RepoInfo::Impl";
00092 }
00093
00095
00096
00097
00099
00100 const RepoInfo RepoInfo::noRepo;
00101
00103
00104
00105
00106
00107 RepoInfo::RepoInfo()
00108 : _pimpl( new Impl() )
00109 {}
00110
00112
00113
00114
00115
00116 RepoInfo::~RepoInfo()
00117 {
00118
00119 }
00120
00121 unsigned RepoInfo::priority() const
00122 { return _pimpl->priority; }
00123 unsigned RepoInfo::defaultPriority()
00124 { return Impl::defaultPriority; }
00125 void RepoInfo::setPriority( unsigned newval_r )
00126 {
00127 _pimpl->priority = newval_r ? newval_r : Impl::defaultPriority;
00128 }
00129
00130 void RepoInfo::setGpgCheck( bool check )
00131 {
00132 _pimpl->gpgcheck = check;
00133 }
00134
00135 void RepoInfo::setMirrorListUrl( const Url &url )
00136 {
00137 _pimpl->mirrorlist_url = url;
00138 }
00139
00140 void RepoInfo::setGpgKeyUrl( const Url &url )
00141 {
00142 _pimpl->gpgkey_url = url;
00143 }
00144
00145 void RepoInfo::addBaseUrl( const Url &url )
00146 {
00147 _pimpl->baseUrls.insert(url);
00148 }
00149
00150 void RepoInfo::setBaseUrl( const Url &url )
00151 {
00152 _pimpl->baseUrls.clear();
00153 addBaseUrl(url);
00154 }
00155
00156 void RepoInfo::setPath( const Pathname &path )
00157 {
00158 _pimpl->path = path;
00159 }
00160
00161 void RepoInfo::setType( const repo::RepoType &t )
00162 {
00163 _pimpl->type = t;
00164 }
00165
00166 void RepoInfo::setProbedType( const repo::RepoType &t ) const
00167 { _pimpl->setProbedType( t ); }
00168
00169
00170 void RepoInfo::setMetadataPath( const Pathname &path )
00171 {
00172 _pimpl->metadatapath = path;
00173 }
00174
00175 void RepoInfo::setPackagesPath( const Pathname &path )
00176 {
00177 _pimpl->packagespath = path;
00178 }
00179
00180 void RepoInfo::setKeepPackages( bool keep )
00181 {
00182 _pimpl->keeppackages = keep;
00183 }
00184
00185 void RepoInfo::setService( const std::string& name )
00186 {
00187 _pimpl->service = name;
00188 }
00189
00190 void RepoInfo::setTargetDistribution(
00191 const std::string & targetDistribution)
00192 {
00193 _pimpl->targetDistro = targetDistribution;
00194 }
00195
00196 bool RepoInfo::gpgCheck() const
00197 { return indeterminate(_pimpl->gpgcheck) ? true : (bool) _pimpl->gpgcheck; }
00198
00199 Pathname RepoInfo::metadataPath() const
00200 { return _pimpl->metadatapath; }
00201
00202 Pathname RepoInfo::packagesPath() const
00203 { return _pimpl->packagespath; }
00204
00205 repo::RepoType RepoInfo::type() const
00206 { return _pimpl->type; }
00207
00208 Url RepoInfo::mirrorListUrl() const
00209 { return _pimpl->mirrorlist_url; }
00210
00211 Url RepoInfo::gpgKeyUrl() const
00212 { return _pimpl->gpgkey_url; }
00213
00214 std::set<Url> RepoInfo::baseUrls() const
00215 {
00216 RepoInfo::url_set replaced_urls;
00217 repo::RepoVariablesUrlReplacer replacer;
00218 for ( url_set::const_iterator it = _pimpl->baseUrls.begin();
00219 it != _pimpl->baseUrls.end();
00220 ++it )
00221 {
00222 replaced_urls.insert(replacer(*it));
00223 }
00224 return replaced_urls;
00225
00226 return _pimpl->baseUrls;
00227 }
00228
00229 Pathname RepoInfo::path() const
00230 { return _pimpl->path; }
00231
00232 std::string RepoInfo::service() const
00233 { return _pimpl->service; }
00234
00235 std::string RepoInfo::targetDistribution() const
00236 { return _pimpl->targetDistro; }
00237
00238 RepoInfo::urls_const_iterator RepoInfo::baseUrlsBegin() const
00239 {
00240 return make_transform_iterator( _pimpl->baseUrls.begin(),
00241 repo::RepoVariablesUrlReplacer() );
00242
00243 }
00244
00245 RepoInfo::urls_const_iterator RepoInfo::baseUrlsEnd() const
00246 {
00247
00248 return make_transform_iterator( _pimpl->baseUrls.end(),
00249 repo::RepoVariablesUrlReplacer() );
00250 }
00251
00252 RepoInfo::urls_size_type RepoInfo::baseUrlsSize() const
00253 { return _pimpl->baseUrls.size(); }
00254
00255 bool RepoInfo::baseUrlsEmpty() const
00256 { return _pimpl->baseUrls.empty(); }
00257
00258
00259 bool RepoInfo::keepPackages() const
00260 {
00261 if (indeterminate(_pimpl->keeppackages))
00262 {
00263 if (_pimpl->baseUrls.empty())
00264 return false;
00265 else if ( baseUrlsBegin()->schemeIsDownloading() )
00266 return true;
00267 else
00268 return false;
00269 }
00270
00271 return (bool) _pimpl->keeppackages;
00272 }
00273
00275
00276 bool RepoInfo::hasLicense() const
00277 {
00278 Pathname licenseTgz( _pimpl->licenseTgz() );
00279 SEC << licenseTgz << endl;
00280 SEC << PathInfo(licenseTgz) << endl;
00281
00282 return ! licenseTgz.empty() && PathInfo(licenseTgz).isFile();
00283 }
00284
00285 std::string RepoInfo::getLicense( const Locale & lang_r )
00286 {
00287 LocaleSet avlocales( getLicenseLocales() );
00288 if ( avlocales.empty() )
00289 return std::string();
00290
00291 Locale getLang( Locale::bestMatch( avlocales, lang_r ) );
00292 if ( getLang == Locale::noCode
00293 && avlocales.find( Locale::noCode ) == avlocales.end() )
00294 {
00295 WAR << "License.tar.gz contains no fallback text! " << *this << endl;
00296
00297
00298
00299 getLang = *avlocales.begin();
00300 }
00301
00302
00303 static const std::string licenseFileFallback( "license.txt" );
00304 std::string licenseFile( getLang == Locale::noCode
00305 ? licenseFileFallback
00306 : str::form( "license.%s.txt", getLang.code().c_str() ) );
00307
00308 ExternalProgram::Arguments cmd;
00309 cmd.push_back( "tar" );
00310 cmd.push_back( "-x" );
00311 cmd.push_back( "-z" );
00312 cmd.push_back( "-O" );
00313 cmd.push_back( "-f" );
00314 cmd.push_back( _pimpl->licenseTgz().asString() );
00315 cmd.push_back( licenseFile );
00316
00317 std::string ret;
00318 ExternalProgram prog( cmd, ExternalProgram::Discard_Stderr );
00319 for ( std::string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() )
00320 {
00321 ret += output;
00322 }
00323 prog.close();
00324 return ret;
00325 }
00326
00327 LocaleSet RepoInfo::getLicenseLocales() const
00328 {
00329 Pathname licenseTgz( _pimpl->licenseTgz() );
00330 if ( licenseTgz.empty() || ! PathInfo( licenseTgz ).isFile() )
00331 return LocaleSet();
00332
00333 ExternalProgram::Arguments cmd;
00334 cmd.push_back( "tar" );
00335 cmd.push_back( "-t" );
00336 cmd.push_back( "-z" );
00337 cmd.push_back( "-f" );
00338 cmd.push_back( licenseTgz.asString() );
00339
00340 LocaleSet ret;
00341 ExternalProgram prog( cmd, ExternalProgram::Stderr_To_Stdout );
00342 for ( std::string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() )
00343 {
00344 static const C_Str license( "license." );
00345 static const C_Str dotTxt( ".txt\n" );
00346 if ( str::hasPrefix( output, license ) && str::hasSuffix( output, dotTxt ) )
00347 {
00348 if ( output.size() <= license.size() + dotTxt.size() )
00349 ret.insert( Locale() );
00350 else
00351 ret.insert( Locale( std::string( output.c_str()+license.size(), output.size()- license.size() - dotTxt.size() ) ) );
00352 }
00353 else
00354 {
00355 WAR << " " << output;
00356 }
00357 }
00358 prog.close();
00359 return ret;
00360 }
00361
00363
00364 std::ostream & RepoInfo::dumpOn( std::ostream & str ) const
00365 {
00366 RepoInfoBase::dumpOn(str);
00367 for ( urls_const_iterator it = baseUrlsBegin();
00368 it != baseUrlsEnd();
00369 ++it )
00370 {
00371 str << "- url : " << *it << std::endl;
00372 }
00373 str << "- path : " << path() << std::endl;
00374 str << "- type : " << type() << std::endl;
00375 str << "- priority : " << priority() << std::endl;
00376
00377 str << "- gpgcheck : " << gpgCheck() << std::endl;
00378 str << "- gpgkey : " << gpgKeyUrl() << std::endl;
00379 str << "- keeppackages: " << keepPackages() << std::endl;
00380 str << "- service : " << service() << std::endl;
00381
00382 if (!targetDistribution().empty())
00383 str << "- targetdistro: " << targetDistribution() << std::endl;
00384
00385 if (!metadataPath().empty())
00386 str << "- metadataPath: " << metadataPath() << std::endl;
00387
00388 if (!packagesPath().empty())
00389 str << "- packagesPath: " << packagesPath() << std::endl;
00390
00391 return str;
00392 }
00393
00394 std::ostream & RepoInfo::dumpAsIniOn( std::ostream & str ) const
00395 {
00396 RepoInfoBase::dumpAsIniOn(str);
00397
00398 if ( ! _pimpl->baseUrls.empty() )
00399 str << "baseurl=";
00400 for ( url_set::const_iterator it = _pimpl->baseUrls.begin();
00401 it != _pimpl->baseUrls.end();
00402 ++it )
00403 {
00404 str << *it << endl;
00405 }
00406
00407 if ( ! _pimpl->path.empty() )
00408 str << "path="<< path() << endl;
00409
00410 if ( ! (_pimpl->mirrorlist_url.asString().empty()) )
00411 str << "mirrorlist=" << _pimpl->mirrorlist_url << endl;
00412
00413 str << "type=" << type().asString() << endl;
00414
00415 if ( priority() != defaultPriority() )
00416 str << "priority=" << priority() << endl;
00417
00418 if (!indeterminate(_pimpl->gpgcheck))
00419 str << "gpgcheck=" << (gpgCheck() ? "1" : "0") << endl;
00420 if ( ! (gpgKeyUrl().asString().empty()) )
00421 str << "gpgkey=" <<gpgKeyUrl() << endl;
00422
00423 if (!indeterminate(_pimpl->keeppackages))
00424 str << "keeppackages=" << keepPackages() << endl;
00425
00426 if( ! service().empty() )
00427 str << "service=" << service() << endl;
00428
00429 return str;
00430 }
00431
00432 std::ostream & RepoInfo::dumpAsXMLOn( std::ostream & str) const
00433 { return dumpAsXMLOn(str, ""); }
00434
00435 std::ostream & RepoInfo::dumpAsXMLOn( std::ostream & str, const std::string & content) const
00436 {
00437 string tmpstr;
00438 str
00439 << "<repo"
00440 << " alias=\"" << escape(alias()) << "\""
00441 << " name=\"" << escape(name()) << "\"";
00442 if (type() != repo::RepoType::NONE)
00443 str << " type=\"" << type().asString() << "\"";
00444 str
00445 << " enabled=\"" << enabled() << "\""
00446 << " autorefresh=\"" << autorefresh() << "\""
00447 << " gpgcheck=\"" << gpgCheck() << "\"";
00448 if (!(tmpstr = gpgKeyUrl().asString()).empty())
00449 str << " gpgkey=\"" << escape(tmpstr) << "\"";
00450 if (!(tmpstr = mirrorListUrl().asString()).empty())
00451 str << " mirrorlist=\"" << escape(tmpstr) << "\"";
00452 str << ">" << endl;
00453
00454 for (RepoInfo::urls_const_iterator urlit = baseUrlsBegin();
00455 urlit != baseUrlsEnd(); ++urlit)
00456 str << "<url>" << escape(urlit->asString()) << "</url>" << endl;
00457
00458 str << "</repo>" << endl;
00459 return str;
00460 }
00461
00462
00463 std::ostream & operator<<( std::ostream & str, const RepoInfo & obj )
00464 {
00465 return obj.dumpOn(str);
00466 }
00467
00468
00470 }