X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=zypp%2FRepoInfo.cc;h=db230c72794d4910e67932cb823d317f429db8e9;hb=HEAD;hp=0567ad7307cda3aa0c6b6e739e2479d0ca5f03cb;hpb=cda9c2bb462026c6572ad6b5f80af83f7fe3ee25;p=platform%2Fupstream%2Flibzypp.git diff --git a/zypp/RepoInfo.cc b/zypp/RepoInfo.cc index 0567ad7..832425d 100644 --- a/zypp/RepoInfo.cc +++ b/zypp/RepoInfo.cc @@ -10,17 +10,38 @@ * */ #include - -#include "zypp/base/Logger.h" -#include "zypp/base/DefaultIntegral.h" -#include "zypp/parser/xml/XmlEscape.h" - -#include "zypp/RepoInfo.h" -#include "zypp/repo/RepoInfoBaseImpl.h" -#include "zypp/ExternalProgram.h" -#include "zypp/media/MediaAccess.h" - -using namespace std; +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +#include +#include +#include +#include +#include + +using std::endl; using zypp::xml::escape; /////////////////////////////////////////////////////////////////// @@ -32,13 +53,17 @@ namespace zypp // CLASS NAME : RepoInfo::Impl // /** RepoInfo implementation. */ - struct RepoInfo::Impl : public repo::RepoInfoBase::Impl + struct RepoInfo::Impl { Impl() - : repo::RepoInfoBase::Impl() - , gpgcheck(indeterminate) + : _rawGpgCheck( indeterminate ) + , _rawRepoGpgCheck( indeterminate ) + , _rawPkgGpgCheck( indeterminate ) + , _validRepoSignature( indeterminate ) , keeppackages(indeterminate) + , _mirrorListForceMetalink(false) , type(repo::RepoType::NONE_e) + , emptybaseurls(false) {} ~Impl() @@ -46,6 +71,7 @@ namespace zypp public: static const unsigned defaultPriority = 99; + static const unsigned noPriority = unsigned(-1); void setProbedType( const repo::RepoType & t ) const { @@ -58,26 +84,257 @@ namespace zypp } public: - Pathname licenseTgz() const - { return metadatapath.empty() ? Pathname() : metadatapath / "license.tar.gz"; } + /** Path to a license tarball in case it exists in the repo. */ + Pathname licenseTgz( const std::string & name_r ) const + { + Pathname ret; + if ( !metadataPath().empty() ) + { + std::string licenseStem( "license" ); + if ( !name_r.empty() ) + { + licenseStem += "-"; + licenseStem += name_r; + } + + filesystem::Glob g; + // TODO: REPOMD: this assumes we know the name of the tarball. In fact + // we'd need to get the file from repomd.xml () + g.add( metadataPath() / path / ("repodata/*"+licenseStem+".tar.gz") ); + if ( g.empty() ) + g.add( metadataPath() / path / (licenseStem+".tar.gz") ); + + if ( !g.empty() ) + ret = *g.begin(); + } + return ret; + } + + const RepoVariablesReplacedUrlList & baseUrls() const + { + const Url & mlurl( _mirrorListUrl.transformed() ); // Variables replaced! + if ( _baseUrls.empty() && ! mlurl.asString().empty() ) + { + emptybaseurls = true; + DBG << "MetadataPath: " << metadataPath() << endl; + repo::RepoMirrorList rmurls( mlurl, metadataPath(), _mirrorListForceMetalink ); + _baseUrls.raw().insert( _baseUrls.raw().end(), rmurls.getUrls().begin(), rmurls.getUrls().end() ); + } + return _baseUrls; + } + + RepoVariablesReplacedUrlList & baseUrls() + { return _baseUrls; } + + bool baseurl2dump() const + { return !emptybaseurls && !_baseUrls.empty(); } + + + const RepoVariablesReplacedUrlList & gpgKeyUrls() const + { return _gpgKeyUrls; } + + RepoVariablesReplacedUrlList & gpgKeyUrls() + { return _gpgKeyUrls; } + + + const std::set & contentKeywords() const + { hasContent()/*init if not yet done*/; return _keywords.second; } + + void addContent( const std::string & keyword_r ) + { _keywords.second.insert( keyword_r ); if ( ! hasContent() ) _keywords.first = true; } + + bool hasContent() const + { + if ( !_keywords.first && ! metadataPath().empty() ) + { + // HACK directly check master index file until RepoManager offers + // some content probing and zypper uses it. + ///////////////////////////////////////////////////////////////// + MIL << "Empty keywords...." << metadataPath() << endl; + Pathname master; + if ( PathInfo( (master=metadataPath()/"/repodata/repomd.xml") ).isFile() ) + { + //MIL << "GO repomd.." << endl; + xml::Reader reader( master ); + while ( reader.seekToNode( 2, "content" ) ) + { + _keywords.second.insert( reader.nodeText().asString() ); + reader.seekToEndNode( 2, "content" ); + } + _keywords.first = true; // valid content in _keywords even if empty + } + else if ( PathInfo( (master=metadataPath()/"/content") ).isFile() ) + { + //MIL << "GO content.." << endl; + iostr::forEachLine( InputStream( master ), + [this]( int num_r, std::string line_r )->bool + { + if ( str::startsWith( line_r, "REPOKEYWORDS" ) ) + { + std::vector words; + if ( str::split( line_r, std::back_inserter(words) ) > 1 + && words[0].length() == 12 /*"REPOKEYWORDS"*/ ) + { + this->_keywords.second.insert( ++words.begin(), words.end() ); + } + return true; // mult. occurrances are ok. + } + return( ! str::startsWith( line_r, "META " ) ); // no need to parse into META section. + } ); + _keywords.first = true; // valid content in _keywords even if empty + } + ///////////////////////////////////////////////////////////////// + } + return _keywords.first; + } + + bool hasContent( const std::string & keyword_r ) const + { return( hasContent() && _keywords.second.find( keyword_r ) != _keywords.second.end() ); } + + /** Signature check result needs to be stored/retrieved from _metadataPath. + * Don't call them from outside validRepoSignature/setValidRepoSignature + */ + //@{ + TriBool internalValidRepoSignature() const + { + if ( ! indeterminate(_validRepoSignature) ) + return _validRepoSignature; + // check metadata: + if ( ! metadataPath().empty() ) + { + // A missing ".repo_gpgcheck" might be plaindir(no Downloader) or not yet refreshed signed repo! + TriBool linkval = triBoolFromPath( metadataPath() / ".repo_gpgcheck" ); + return linkval; + } + return indeterminate; + } + + void internalSetValidRepoSignature( TriBool value_r ) + { + if ( PathInfo(metadataPath()).isDir() ) + { + Pathname gpgcheckFile( metadataPath() / ".repo_gpgcheck" ); + if ( PathInfo(gpgcheckFile).isExist() ) + { + TriBool linkval( indeterminate ); + if ( triBoolFromPath( gpgcheckFile, linkval ) && linkval == value_r ) + return; // existing symlink fits value_r + else + filesystem::unlink( gpgcheckFile ); // will write a new one + } + filesystem::symlink( asString(value_r), gpgcheckFile ); + } + _validRepoSignature = value_r; + } + + /** We definitely have a symlink pointing to "indeterminate" (for repoGpgCheckIsMandatory)? + * I.e. user accepted the unsigned repo in Downloader. A test whether `internalValidRepoSignature` + * is indeterminate would include not yet checked repos, which is unwanted here. + */ + bool internalUnsignedConfirmed() const + { + TriBool linkval( true ); // want to see it being switched to indeterminate + return triBoolFromPath( metadataPath() / ".repo_gpgcheck", linkval ) && indeterminate(linkval); + } + + bool triBoolFromPath( const Pathname & path_r, TriBool & ret_r ) const + { + static const Pathname truePath( "true" ); + static const Pathname falsePath( "false" ); + static const Pathname indeterminatePath( "indeterminate" ); + + // Quiet readlink; + static const ssize_t bufsiz = 63; + static char buf[bufsiz+1]; + ssize_t ret = ::readlink( path_r.c_str(), buf, bufsiz ); + buf[ret == -1 ? 0 : ret] = '\0'; + + Pathname linkval( buf ); + + bool known = true; + if ( linkval == truePath ) + ret_r = true; + else if ( linkval == falsePath ) + ret_r = false; + else if ( linkval == indeterminatePath ) + ret_r = indeterminate; + else + known = false; + return known; + } + + TriBool triBoolFromPath( const Pathname & path_r ) const + { TriBool ret(indeterminate); triBoolFromPath( path_r, ret ); return ret; } + + //@} + + private: + TriBool _rawGpgCheck; ///< default gpgcheck behavior: Y/N/ZConf + TriBool _rawRepoGpgCheck; ///< need to check repo sign.: Y/N/(ZConf(Y/N/gpgCheck)) + TriBool _rawPkgGpgCheck; ///< need to check pkg sign.: Y/N/(ZConf(Y/N/gpgCheck)) + + public: + TriBool rawGpgCheck() const { return _rawGpgCheck; } + TriBool rawRepoGpgCheck() const { return _rawRepoGpgCheck; } + TriBool rawPkgGpgCheck() const { return _rawPkgGpgCheck; } + void rawGpgCheck( TriBool val_r ) { _rawGpgCheck = val_r; } + void rawRepoGpgCheck( TriBool val_r ) { _rawRepoGpgCheck = val_r; } + void rawPkgGpgCheck( TriBool val_r ) { _rawPkgGpgCheck = val_r; } + bool cfgGpgCheck() const + { return indeterminate(_rawGpgCheck) ? ZConfig::instance().gpgCheck() : (bool)_rawGpgCheck; } + TriBool cfgRepoGpgCheck() const + { return indeterminate(_rawGpgCheck) && indeterminate(_rawRepoGpgCheck) ? ZConfig::instance().repoGpgCheck() : _rawRepoGpgCheck; } + TriBool cfgPkgGpgCheck() const + { return indeterminate(_rawGpgCheck) && indeterminate(_rawPkgGpgCheck) ? ZConfig::instance().pkgGpgCheck() : _rawPkgGpgCheck; } + + private: + TriBool _validRepoSignature;///< have signed and valid repo metadata public: - TriBool gpgcheck; TriBool keeppackages; - Url gpgkey_url; + RepoVariablesReplacedUrl _mirrorListUrl; + bool _mirrorListForceMetalink; repo::RepoType type; - Url mirrorlist_url; - std::set baseUrls; Pathname path; std::string service; std::string targetDistro; - Pathname metadatapath; - Pathname packagespath; + + void metadataPath( Pathname new_r ) + { _metadataPath = std::move( new_r ); } + + void packagesPath( Pathname new_r ) + { _packagesPath = std::move( new_r ); } + + bool usesAutoMethadataPaths() const + { return str::hasSuffix( _metadataPath.asString(), "/%AUTO%" ); } + + Pathname metadataPath() const + { + if ( usesAutoMethadataPaths() ) + return _metadataPath.dirname() / "%RAW%"; + return _metadataPath; + } + + Pathname packagesPath() const + { + if ( _packagesPath.empty() && usesAutoMethadataPaths() ) + return _metadataPath.dirname() / "%PKG%"; + return _packagesPath; + } + DefaultIntegral priority; - public: + mutable bool emptybaseurls; private: + Pathname _metadataPath; + Pathname _packagesPath; + + mutable RepoVariablesReplacedUrlList _baseUrls; + mutable std::pair > _keywords; + + RepoVariablesReplacedUrlList _gpgKeyUrls; + friend Impl * rwcowClone( const Impl * rhs ); /** clone for RWCOW_pointer */ Impl * clone() const @@ -99,132 +356,337 @@ namespace zypp const RepoInfo RepoInfo::noRepo; - /////////////////////////////////////////////////////////////////// - // - // METHOD NAME : RepoInfo::RepoInfo - // METHOD TYPE : Ctor - // RepoInfo::RepoInfo() : _pimpl( new Impl() ) {} - /////////////////////////////////////////////////////////////////// - // - // METHOD NAME : RepoInfo::~RepoInfo - // METHOD TYPE : Dtor - // RepoInfo::~RepoInfo() - { - //MIL << std::endl; - } + {} unsigned RepoInfo::priority() const { return _pimpl->priority; } + unsigned RepoInfo::defaultPriority() { return Impl::defaultPriority; } + + unsigned RepoInfo::noPriority() + { return Impl::noPriority; } + void RepoInfo::setPriority( unsigned newval_r ) + { _pimpl->priority = newval_r ? newval_r : Impl::defaultPriority; } + + + bool RepoInfo::gpgCheck() const + { return _pimpl->cfgGpgCheck(); } + + void RepoInfo::setGpgCheck( TriBool value_r ) + { _pimpl->rawGpgCheck( value_r ); } + + void RepoInfo::setGpgCheck( bool value_r ) // deprecated legacy and for squid + { setGpgCheck( TriBool(value_r) ); } + + + bool RepoInfo::repoGpgCheck() const + { return gpgCheck() || bool(_pimpl->cfgRepoGpgCheck()); } + + bool RepoInfo::repoGpgCheckIsMandatory() const { - _pimpl->priority = newval_r ? newval_r : Impl::defaultPriority; + bool ret = ( gpgCheck() && indeterminate(_pimpl->cfgRepoGpgCheck()) ) || bool(_pimpl->cfgRepoGpgCheck()); + if ( ret && _pimpl->internalUnsignedConfirmed() ) // relax if unsigned repo was confirmed in the past + ret = false; + return ret; } - void RepoInfo::setGpgCheck( bool check ) + void RepoInfo::setRepoGpgCheck( TriBool value_r ) + { _pimpl->rawRepoGpgCheck( value_r ); } + + + bool RepoInfo::pkgGpgCheck() const + { return bool(_pimpl->cfgPkgGpgCheck()) || ( gpgCheck() && !bool(validRepoSignature())/*enforced*/ ) ; } + + bool RepoInfo::pkgGpgCheckIsMandatory() const + { return bool(_pimpl->cfgPkgGpgCheck()) || ( gpgCheck() && indeterminate(_pimpl->cfgPkgGpgCheck()) && !bool(validRepoSignature())/*enforced*/ ); } + + void RepoInfo::setPkgGpgCheck( TriBool value_r ) + { _pimpl->rawPkgGpgCheck( value_r ); } + + + void RepoInfo::getRawGpgChecks( TriBool & g_r, TriBool & r_r, TriBool & p_r ) const { - _pimpl->gpgcheck = check; + g_r = _pimpl->rawGpgCheck(); + r_r = _pimpl->rawRepoGpgCheck(); + p_r = _pimpl->rawPkgGpgCheck(); } - void RepoInfo::setMirrorListUrl( const Url &url ) + + TriBool RepoInfo::validRepoSignature() const { - _pimpl->mirrorlist_url = url; + TriBool ret( _pimpl->internalValidRepoSignature() ); + if ( ret && !repoGpgCheck() ) ret = false; // invalidate any old signature if repoGpgCheck is off + return ret; } - void RepoInfo::setGpgKeyUrl( const Url &url ) + void RepoInfo::setValidRepoSignature( TriBool value_r ) + { _pimpl->internalSetValidRepoSignature( value_r ); } + + /////////////////////////////////////////////////////////////////// + namespace { - _pimpl->gpgkey_url = url; + inline bool changeGpgCheckTo( TriBool & lhs, TriBool rhs ) + { if ( ! sameTriboolState( lhs, rhs ) ) { lhs = rhs; return true; } return false; } + + inline bool changeGpgCheckTo( TriBool ogpg[3], TriBool g, TriBool r, TriBool p ) + { + bool changed = false; + if ( changeGpgCheckTo( ogpg[0], g ) ) changed = true; + if ( changeGpgCheckTo( ogpg[1], r ) ) changed = true; + if ( changeGpgCheckTo( ogpg[2], p ) ) changed = true; + return changed; + } + } // namespace + /////////////////////////////////////////////////////////////////// + bool RepoInfo::setGpgCheck( GpgCheck mode_r ) + { + TriBool ogpg[3]; // Gpg RepoGpg PkgGpg + getRawGpgChecks( ogpg[0], ogpg[1], ogpg[2] ); + + bool changed = false; + switch ( mode_r ) + { + case GpgCheck::On: + changed = changeGpgCheckTo( ogpg, true, indeterminate, indeterminate ); + break; + case GpgCheck::Strict: + changed = changeGpgCheckTo( ogpg, true, true, true ); + break; + case GpgCheck::AllowUnsigned: + changed = changeGpgCheckTo( ogpg, true, false, false ); + break; + case GpgCheck::AllowUnsignedRepo: + changed = changeGpgCheckTo( ogpg, true, false, indeterminate ); + break; + case GpgCheck::AllowUnsignedPackage: + changed = changeGpgCheckTo( ogpg, true, indeterminate, false ); + break; + case GpgCheck::Default: + changed = changeGpgCheckTo( ogpg, indeterminate, indeterminate, indeterminate ); + break; + case GpgCheck::Off: + changed = changeGpgCheckTo( ogpg, false, indeterminate, indeterminate ); + break; + case GpgCheck::indeterminate: // no change + break; + } + + if ( changed ) + { + setGpgCheck ( ogpg[0] ); + setRepoGpgCheck( ogpg[1] ); + setPkgGpgCheck ( ogpg[2] ); + } + return changed; } - void RepoInfo::addBaseUrl( const Url &url ) + void RepoInfo::setMirrorListUrl( const Url & url_r ) // Raw + { _pimpl->_mirrorListUrl.raw() = url_r; _pimpl->_mirrorListForceMetalink = false; } + + void RepoInfo::setMetalinkUrl( const Url & url_r ) // Raw + { _pimpl->_mirrorListUrl.raw() = url_r; _pimpl->_mirrorListForceMetalink = true; } + + void RepoInfo::setGpgKeyUrls( url_set urls ) + { _pimpl->gpgKeyUrls().raw().swap( urls ); } + + void RepoInfo::setGpgKeyUrl( const Url & url_r ) { - _pimpl->baseUrls.insert(url); + _pimpl->gpgKeyUrls().raw().clear(); + _pimpl->gpgKeyUrls().raw().push_back( url_r ); } - void RepoInfo::setBaseUrl( const Url &url ) + Pathname RepoInfo::provideKey(const std::string &keyID_r, const Pathname &targetDirectory_r) const { - _pimpl->baseUrls.clear(); - addBaseUrl(url); + if ( keyID_r.empty() ) + return Pathname(); + + MIL << "Check for " << keyID_r << " at " << targetDirectory_r << endl; + std::string keyIDStr( keyID_r.size() > 8 ? keyID_r.substr( keyID_r.size()-8 ) : keyID_r ); // print short ID in Jobreports + filesystem::TmpDir tmpKeyRingDir; + KeyRing tempKeyRing(tmpKeyRingDir.path()); + + // translator: %1% is a gpg key ID like 3DBDC284 + // %2% is a cache directories path + JobReport::info( str::Format(_("Looking for gpg key ID %1% in cache %2%.") ) % keyIDStr % targetDirectory_r ); + filesystem::dirForEach(targetDirectory_r, + StrMatcher(".key", Match::STRINGEND), + [&tempKeyRing]( const Pathname & dir_r, const std::string & str_r ){ + try { + + // deprecate a month old keys + PathInfo fileInfo ( dir_r/str_r ); + if ( Date::now() - fileInfo.mtime() > Date::month ) { + //if unlink fails, the file will be overriden in the next step, no need + //to show a error + filesystem::unlink( dir_r/str_r ); + } else { + tempKeyRing.multiKeyImport(dir_r/str_r, true); + } + } catch (const KeyRingException& e) { + ZYPP_CAUGHT(e); + ERR << "Error importing cached key from file '"<licenseTgz().asString() ); // if it not exists, avlocales was empty. + cmd.push_back( _pimpl->licenseTgz( name_r ).asString() ); // if it not exists, avlocales was empty. cmd.push_back( licenseFile ); std::string ret; @@ -321,10 +814,14 @@ namespace zypp return ret; } + LocaleSet RepoInfo::getLicenseLocales() const + { return getLicenseLocales( std::string() ); } + + LocaleSet RepoInfo::getLicenseLocales( const std::string & name_r ) const { - Pathname licenseTgz( _pimpl->licenseTgz() ); - if ( licenseTgz.empty() || ! PathInfo( licenseTgz ).isFile() ) + const Pathname & licenseTgz( _pimpl->licenseTgz( name_r ) ); + if ( licenseTgz.empty() ) return LocaleSet(); ExternalProgram::Arguments cmd; @@ -347,10 +844,6 @@ namespace zypp else ret.insert( Locale( std::string( output.c_str()+license.size(), output.size()- license.size() - dotTxt.size() ) ) ); } - else - { - WAR << " " << output; - } } prog.close(); return ret; @@ -361,26 +854,47 @@ namespace zypp std::ostream & RepoInfo::dumpOn( std::ostream & str ) const { RepoInfoBase::dumpOn(str); - for ( urls_const_iterator it = baseUrlsBegin(); - it != baseUrlsEnd(); - ++it ) + if ( _pimpl->baseurl2dump() ) { - str << "- url : " << *it << std::endl; + for ( const auto & url : _pimpl->baseUrls().raw() ) + { + str << "- url : " << url << std::endl; + } } - str << "- path : " << path() << std::endl; + + // print if non empty value + auto strif( [&] ( const std::string & tag_r, const std::string & value_r ) { + if ( ! value_r.empty() ) + str << tag_r << value_r << std::endl; + }); + + strif( (_pimpl->_mirrorListForceMetalink ? "- metalink : " : "- mirrorlist : "), rawMirrorListUrl().asString() ); + strif( "- path : ", path().asString() ); str << "- type : " << type() << std::endl; str << "- priority : " << priority() << std::endl; - str << "- gpgcheck : " << gpgCheck() << std::endl; - str << "- gpgkey : " << gpgKeyUrl() << std::endl; - str << "- keeppackages: " << keepPackages() << std::endl; - str << "- service : " << service() << std::endl; + // Yes No Default(Y) Default(N) +#define OUTS(T,B) ( indeterminate(T) ? (std::string("D(")+(B?"Y":"N")+")") : ((bool)T?"Y":"N") ) + str << "- gpgcheck : " << OUTS(_pimpl->rawGpgCheck(),gpgCheck()) + << " repo" << OUTS(_pimpl->rawRepoGpgCheck(),repoGpgCheck()) << (repoGpgCheckIsMandatory() ? "* ": " " ) + << "sig" << asString( validRepoSignature(), "?", "Y", "N" ) + << " pkg" << OUTS(_pimpl->rawPkgGpgCheck(),pkgGpgCheck()) << (pkgGpgCheckIsMandatory() ? "* ": " " ) + << std::endl; +#undef OUTS + + for ( const auto & url : _pimpl->gpgKeyUrls().raw() ) + { + str << "- gpgkey : " << url << std::endl; + } - if (!targetDistribution().empty()) - str << "- targetdistro: " << targetDistribution() << std::endl; + if ( ! indeterminate(_pimpl->keeppackages) ) + str << "- keeppackages: " << keepPackages() << std::endl; - if (!metadataPath().empty()) - str << "- metadataPath: " << metadataPath() << std::endl; + strif( "- service : ", service() ); + strif( "- targetdistro: ", targetDistribution() ); + strif( "- filePath: ", filepath().asString() ); + strif( "- metadataPath: ", metadataPath().asString() ); + strif( "- packagesPath: ", packagesPath().asString() ); return str; } @@ -389,30 +903,46 @@ namespace zypp { RepoInfoBase::dumpAsIniOn(str); - if ( ! _pimpl->baseUrls.empty() ) - str << "baseurl="; - for ( url_set::const_iterator it = _pimpl->baseUrls.begin(); - it != _pimpl->baseUrls.end(); - ++it ) + if ( _pimpl->baseurl2dump() ) { - str << *it << endl; + str << "baseurl="; + std::string indent; + for ( const auto & url : _pimpl->baseUrls().raw() ) + { + str << indent << url << endl; + if ( indent.empty() ) indent = " "; // "baseurl=" + } } if ( ! _pimpl->path.empty() ) str << "path="<< path() << endl; - if ( ! (_pimpl->mirrorlist_url.asString().empty()) ) - str << "mirrorlist=" << _pimpl->mirrorlist_url << endl; + if ( ! (rawMirrorListUrl().asString().empty()) ) + str << (_pimpl->_mirrorListForceMetalink ? "metalink=" : "mirrorlist=") << rawMirrorListUrl() << endl; str << "type=" << type().asString() << endl; if ( priority() != defaultPriority() ) str << "priority=" << priority() << endl; - if (!indeterminate(_pimpl->gpgcheck)) - str << "gpgcheck=" << (gpgCheck() ? "1" : "0") << endl; - if ( ! (gpgKeyUrl().asString().empty()) ) - str << "gpgkey=" <rawGpgCheck()) ) + str << "gpgcheck=" << (_pimpl->rawGpgCheck() ? "1" : "0") << endl; + + if ( ! indeterminate(_pimpl->rawRepoGpgCheck()) ) + str << "repo_gpgcheck=" << (_pimpl->rawRepoGpgCheck() ? "1" : "0") << endl; + + if ( ! indeterminate(_pimpl->rawPkgGpgCheck()) ) + str << "pkg_gpgcheck=" << (_pimpl->rawPkgGpgCheck() ? "1" : "0") << endl; + + { + std::string indent( "gpgkey="); + for ( const auto & url : _pimpl->gpgKeyUrls().raw() ) + { + str << indent << url << endl; + if ( indent[0] != ' ' ) + indent = " "; + } + } if (!indeterminate(_pimpl->keeppackages)) str << "keeppackages=" << keepPackages() << endl; @@ -423,12 +953,9 @@ namespace zypp return str; } - std::ostream & RepoInfo::dumpAsXMLOn( std::ostream & str) const - { return dumpAsXMLOn(str, ""); } - - std::ostream & RepoInfo::dumpAsXMLOn( std::ostream & str, const std::string & content) const + std::ostream & RepoInfo::dumpAsXmlOn( std::ostream & str, const std::string & content ) const { - string tmpstr; + std::string tmpstr; str << "_mirrorListForceMetalink ? " metalink=\"" : " mirrorlist=\"") << escape(tmpstr) << "\""; str << ">" << endl; - for (RepoInfo::urls_const_iterator urlit = baseUrlsBegin(); - urlit != baseUrlsEnd(); ++urlit) - str << "" << escape(urlit->asString()) << "" << endl; + if ( _pimpl->baseurl2dump() ) + { + for_( it, baseUrlsBegin(), baseUrlsEnd() ) // !transform iterator replaces variables + str << "" << escape((*it).asString()) << "" << endl; + } str << "" << endl; return str; @@ -459,6 +991,23 @@ namespace zypp return obj.dumpOn(str); } + std::ostream & operator<<( std::ostream & str, const RepoInfo::GpgCheck & obj ) + { + switch ( obj ) + { +#define OUTS( V ) case RepoInfo::V: return str << #V; break + OUTS( GpgCheck::On ); + OUTS( GpgCheck::Strict ); + OUTS( GpgCheck::AllowUnsigned ); + OUTS( GpgCheck::AllowUnsignedRepo ); + OUTS( GpgCheck::AllowUnsignedPackage ); + OUTS( GpgCheck::Default ); + OUTS( GpgCheck::Off ); + OUTS( GpgCheck::indeterminate ); +#undef OUTS + } + return str << "GpgCheck::UNKNOWN"; + } ///////////////////////////////////////////////////////////////// } // namespace zypp