struct RepoInfo::Impl
{
Impl()
- : _rawGpgCheck( indeterminate )
- , _rawRepoGpgCheck( indeterminate )
- , _rawPkgGpgCheck( indeterminate )
+ : _gpgCheck( indeterminate )
+ , _repoGpgCheck( indeterminate )
+ , _pkgGpgCheck( indeterminate )
, _validRepoSignature( indeterminate )
, keeppackages(indeterminate)
+ , _mirrorListForceMetalink(false)
, type(repo::RepoType::NONE_e)
, emptybaseurls(false)
{}
public:
static const unsigned defaultPriority = 99;
+ static const unsigned noPriority = unsigned(-1);
void setProbedType( const repo::RepoType & t ) const
{
{
emptybaseurls = true;
DBG << "MetadataPath: " << metadatapath << endl;
- repo::RepoMirrorList rmurls( mlurl, metadatapath );
+ repo::RepoMirrorList rmurls( mlurl, metadatapath, _mirrorListForceMetalink );
_baseUrls.raw().insert( _baseUrls.raw().end(), rmurls.getUrls().begin(), rmurls.getUrls().end() );
}
return _baseUrls;
RepoVariablesReplacedUrlList & gpgKeyUrls()
{ return _gpgKeyUrls; }
+
+ const std::set<std::string> & contentKeywords() const
+ { hasContent()/*init if not yet done*/; return _keywords.second; }
+
void addContent( const std::string & keyword_r )
- { _keywords.insert( keyword_r ); }
+ { _keywords.second.insert( keyword_r ); if ( ! hasContent() ) _keywords.first = true; }
- bool hasContent( const std::string & keyword_r ) const
+ bool hasContent() const
{
- if ( _keywords.empty() && ! metadatapath.empty() )
+ if ( !_keywords.first && ! metadatapath.empty() )
{
// HACK directly check master index file until RepoManager offers
- // some content probing ans zypepr uses it.
+ // some content probing and zypper uses it.
/////////////////////////////////////////////////////////////////
MIL << "Empty keywords...." << metadatapath << endl;
Pathname master;
xml::Reader reader( master );
while ( reader.seekToNode( 2, "content" ) )
{
- _keywords.insert( reader.nodeText().asString() );
+ _keywords.second.insert( reader.nodeText().asString() );
reader.seekToEndNode( 2, "content" );
}
- _keywords.insert( "" ); // valid content in _keywords even if empty
+ _keywords.first = true; // valid content in _keywords even if empty
}
else if ( PathInfo( (master=metadatapath/"/content") ).isFile() )
{
if ( str::split( line_r, std::back_inserter(words) ) > 1
&& words[0].length() == 12 /*"REPOKEYWORDS"*/ )
{
- this->_keywords.insert( ++words.begin(), words.end() );
+ 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.insert( "" );
+ _keywords.first = true; // valid content in _keywords even if empty
}
/////////////////////////////////////////////////////////////////
}
- return( _keywords.find( keyword_r ) != _keywords.end() );
+ 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;
+ 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!
+ //TODO: a missing ".repo_gpgcheck" might be plaindir(no Downloader) or not yet refreshed signed repo!
TriBool linkval = triBoolFromPath( metadatapath / ".repo_gpgcheck" );
return linkval;
}
_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 );
-
+ Pathname linkval( filesystem::readlink( path_r ) );
bool known = true;
if ( linkval == truePath )
ret_r = true;
//@}
- 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; }
-
+ TriBool _gpgCheck; ///< default gpgcheck behavior: Y/N/ZConf
+ TriBool _repoGpgCheck; ///< need to check repo sign.: Y/N/(ZConf(Y/N/gpgCheck))
+ TriBool _pkgGpgCheck; ///< need to check pkg sign.: Y/N/(ZConf(Y/N/gpgCheck && no valid repo sign.))
private:
TriBool _validRepoSignature;///< have signed and valid repo metadata
public:
TriBool keeppackages;
RepoVariablesReplacedUrl _mirrorListUrl;
+ bool _mirrorListForceMetalink;
repo::RepoType type;
Pathname path;
std::string service;
private:
mutable RepoVariablesReplacedUrlList _baseUrls;
- mutable std::set<std::string> _keywords;
+ mutable std::pair<FalseBool, std::set<std::string> > _keywords;
RepoVariablesReplacedUrlList _gpgKeyUrls;
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(); }
+ { return indeterminate(_pimpl->_gpgCheck) ? ZConfig::instance().gpgCheck() : (bool)_pimpl->_gpgCheck; }
void RepoInfo::setGpgCheck( TriBool value_r )
- { _pimpl->rawGpgCheck( value_r ); }
+ { _pimpl->_gpgCheck = value_r; }
void RepoInfo::setGpgCheck( bool value_r ) // deprecated legacy and for squid
{ setGpgCheck( TriBool(value_r) ); }
bool RepoInfo::repoGpgCheck() const
- { return gpgCheck() || _pimpl->cfgRepoGpgCheck(); }
-
- bool RepoInfo::repoGpgCheckIsMandatory() const
{
- bool ret = ( gpgCheck() && indeterminate(_pimpl->cfgRepoGpgCheck()) ) || _pimpl->cfgRepoGpgCheck();
- if ( ret && _pimpl->internalUnsignedConfirmed() ) // relax if unsigned repo was confirmed in the past
- ret = false;
- return ret;
+ if ( ! indeterminate(_pimpl->_repoGpgCheck) ) return _pimpl->_repoGpgCheck;
+ if ( ! indeterminate(ZConfig::instance().repoGpgCheck()) ) return ZConfig::instance().repoGpgCheck();
+ return gpgCheck(); // no preference: follow gpgCheck
}
void RepoInfo::setRepoGpgCheck( TriBool value_r )
- { _pimpl->rawRepoGpgCheck( value_r ); }
+ { _pimpl->_repoGpgCheck = value_r; }
bool RepoInfo::pkgGpgCheck() const
- { return _pimpl->cfgPkgGpgCheck() || ( gpgCheck() && !bool(validRepoSignature())/*enforced*/ ) ; }
-
- bool RepoInfo::pkgGpgCheckIsMandatory() const
- { return _pimpl->cfgPkgGpgCheck() || ( gpgCheck() && indeterminate(_pimpl->cfgPkgGpgCheck()) && !bool(validRepoSignature())/*enforced*/ ); }
+ {
+ if ( ! indeterminate(_pimpl->_pkgGpgCheck) ) return _pimpl->_pkgGpgCheck;
+ if ( ! indeterminate(ZConfig::instance().pkgGpgCheck()) ) return ZConfig::instance().pkgGpgCheck();
+ // no preference: follow gpgCheck and check package if repo signature not available or not checked
+ return gpgCheck() && ( !repoGpgCheck() || !(bool)validRepoSignature() ); // !(bool)TriBool ==> false or indeterminate
+ }
void RepoInfo::setPkgGpgCheck( TriBool value_r )
- { _pimpl->rawPkgGpgCheck( value_r ); }
-
+ { _pimpl->_pkgGpgCheck = value_r; }
void RepoInfo::getRawGpgChecks( TriBool & g_r, TriBool & r_r, TriBool & p_r ) const
{
- g_r = _pimpl->rawGpgCheck();
- r_r = _pimpl->rawRepoGpgCheck();
- p_r = _pimpl->rawPkgGpgCheck();
+ g_r = _pimpl->_gpgCheck;
+ r_r = _pimpl->_repoGpgCheck;
+ p_r = _pimpl->_pkgGpgCheck;
}
-
TriBool RepoInfo::validRepoSignature() const
{
- TriBool ret( _pimpl->internalValidRepoSignature() );
- if ( ret && !repoGpgCheck() ) ret = false; // invalidate any old signature if repoGpgCheck is off
+ TriBool ret = _pimpl->internalValidRepoSignature();
+ // keep indeterminate(=unsigned) but invalidate any signature if !repoGpgCheck
+ if ( !indeterminate(ret) && !repoGpgCheck() )
+ ret = false;
return ret;
}
void RepoInfo::setValidRepoSignature( TriBool value_r )
{ _pimpl->internalSetValidRepoSignature( value_r ); }
- ///////////////////////////////////////////////////////////////////
- namespace
- {
- 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.asEnum() )
- {
- 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::setMirrorListUrl( const Url & url_r ) // Raw
- { _pimpl->_mirrorListUrl.raw() = url_r; }
+ { _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 ); }
bool RepoInfo::baseUrlSet() const
{ return _pimpl->baseurl2dump(); }
+ const std::set<std::string> & RepoInfo::contentKeywords() const
+ { return _pimpl->contentKeywords(); }
void RepoInfo::addContent( const std::string & keyword_r )
{ _pimpl->addContent( keyword_r ); }
+ bool RepoInfo::hasContent() const
+ { return _pimpl->hasContent(); }
+
bool RepoInfo::hasContent( const std::string & keyword_r ) const
{ return _pimpl->hasContent( keyword_r ); }
accept = false;
}
}
- prog.close();
MIL << "License for " << name() << " has to be accepted: " << (accept?"true":"false" ) << endl;
return accept;
}
return std::string();
Locale getLang( Locale::bestMatch( avlocales, lang_r ) );
- if ( getLang == Locale::noCode
- && avlocales.find( Locale::noCode ) == avlocales.end() )
+ if ( !getLang && avlocales.find( Locale::noCode ) == avlocales.end() )
{
WAR << "License.tar.gz contains no fallback text! " << *this << endl;
// Using the fist locale instead of returning no text at all.
// now extract the license file.
static const std::string licenseFileFallback( "license.txt" );
- std::string licenseFile( getLang == Locale::noCode
- ? licenseFileFallback
- : str::form( "license.%s.txt", getLang.code().c_str() ) );
+ std::string licenseFile( !getLang ? licenseFileFallback
+ : str::form( "license.%s.txt", getLang.c_str() ) );
ExternalProgram::Arguments cmd;
cmd.push_back( "tar" );
str << tag_r << value_r << std::endl;
});
- strif( "- mirrorlist : ", rawMirrorListUrl().asString() );
+ strif( (_pimpl->_mirrorListForceMetalink ? "- metalink : " : "- mirrorlist : "), rawMirrorListUrl().asString() );
strif( "- path : ", path().asString() );
str << "- type : " << type() << std::endl;
str << "- priority : " << priority() << 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() ? "* ": " " )
+ str << "- gpgcheck : " << OUTS(_pimpl->_gpgCheck,gpgCheck())
+ << " repo" << OUTS(_pimpl->_repoGpgCheck,repoGpgCheck())
+ << " sig" << asString( validRepoSignature(), "?", "Y", "N" )
+ << " pkg" << OUTS(_pimpl->_pkgGpgCheck,pkgGpgCheck())
<< std::endl;
#undef OUTS
str << "path="<< path() << endl;
if ( ! (rawMirrorListUrl().asString().empty()) )
- str << "mirrorlist=" << rawMirrorListUrl() << endl;
+ str << (_pimpl->_mirrorListForceMetalink ? "metalink=" : "mirrorlist=") << rawMirrorListUrl() << endl;
str << "type=" << type().asString() << endl;
if ( priority() != defaultPriority() )
str << "priority=" << priority() << endl;
- if ( ! indeterminate(_pimpl->rawGpgCheck()) )
- str << "gpgcheck=" << (_pimpl->rawGpgCheck() ? "1" : "0") << endl;
+ if ( ! indeterminate(_pimpl->_gpgCheck) )
+ str << "gpgcheck=" << (_pimpl->_gpgCheck ? "1" : "0") << endl;
- if ( ! indeterminate(_pimpl->rawRepoGpgCheck()) )
- str << "repo_gpgcheck=" << (_pimpl->rawRepoGpgCheck() ? "1" : "0") << endl;
+ if ( ! indeterminate(_pimpl->_repoGpgCheck) )
+ str << "repo_gpgcheck=" << (_pimpl->_repoGpgCheck ? "1" : "0") << endl;
- if ( ! indeterminate(_pimpl->rawPkgGpgCheck()) )
- str << "pkg_gpgcheck=" << (_pimpl->rawPkgGpgCheck() ? "1" : "0") << endl;
+ if ( ! indeterminate(_pimpl->_pkgGpgCheck) )
+ str << "pkg_gpgcheck=" << (_pimpl->_pkgGpgCheck ? "1" : "0") << endl;
{
std::string indent( "gpgkey=");
if (!(tmpstr = gpgKeyUrl().asString()).empty())
str << " gpgkey=\"" << escape(tmpstr) << "\"";
if (!(tmpstr = mirrorListUrl().asString()).empty())
- str << " mirrorlist=\"" << escape(tmpstr) << "\"";
+ str << (_pimpl->_mirrorListForceMetalink ? " metalink=\"" : " mirrorlist=\"") << escape(tmpstr) << "\"";
str << ">" << endl;
if ( _pimpl->baseurl2dump() )
return obj.dumpOn(str);
}
- std::ostream & operator<<( std::ostream & str, const RepoInfo::GpgCheck & obj )
- {
- switch ( obj.asEnum() )
- {
-#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