libzypp: zypp-core/parser/econfdict.cc Source File

libzypp 17.38.14

econfdict.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
11#include "econfdict.h"
12
13#include <tuple> // std::ignore
14#include <optional>
15
16#include <zypp-core/APIConfig.h>
17#include <zypp-core/Pathname.h>
18#include <zypp-core/fs/PathInfo.h>
19#include <zypp-core/base/LogTools.h>
20
21namespace zypp::parser {
22
23 namespace econf {
24
36 struct ConfigurationContext
37 {
38 using Exception = EconfException;
39 static Pathname _defaultDistconfDir;
40
41 ConfigurationContext()
42 : ConfigurationContext( "/etc", _defaultDistconfDir )
43 {}
44
45 ConfigurationContext( std::optional<Pathname> etcDir_r, std::optional<Pathname> usrDir_r )
46 : _etcDir( std::move(etcDir_r) )
47 , _usrDir( std::move(usrDir_r) )
48 {}
49
50 const std::optional<Pathname> & etcDir() const { return _etcDir; }
51 const std::optional<Pathname> & usrDir() const { return _usrDir; }
52
53 std::vector<Pathname> getConfigFiles( const std::string & stem_r, const Pathname & root_r = Pathname("/") ) const
54 {
55 // configStem must denote a config file below some root dir:
56 // [PROJECT/]EXAMPLE[.SUFFIX]
57 Pathname configStem { stem_r };
58 if ( configStem.relative() ) {
59 if ( configStem.relativeDotDot() )
60 ZYPP_THROW( Exception(str::sprint("Config stem must not refer to '../':", configStem)) );
61 configStem = configStem.absolutename();
62 }
63 if ( configStem.emptyOrRoot() )
64 ZYPP_THROW( Exception(str::sprint("Config stem must not be empty:", configStem)) );
65 pMIL( "getConfigFiles for stem", configStem, "below", root_r, "in", _etcDir, _usrDir );
66 Pathname configDir { configStem.extend( ".d" ) }; // [PROJECT/]EXAMPLE[.SUFFIX].d
67 std::string configSuffix { configStem.extension() }; // [.SUFFIX]
68
69 // relevant lookup dirs in order of preference:
70 std::vector<Pathname> lookupDirs;
71 if ( _etcDir )
72 takeLookupDirIf( lookupDirs, root_r / *_etcDir ); // system configuration
73 takeLookupDirIf( lookupDirs, root_r / "/run" ); // /run for ephemeral overrides
74 if ( _usrDir )
75 takeLookupDirIf( lookupDirs, root_r / *_usrDir ); // vendor configuration
76
77 // now collect base config and drop-ins to parse:
78 PathInfo basecfgToParse; // the full (base) config to parse (if any)
79 std::map<std::string,PathInfo> dropinsToParse; // drop-ins to parse (1st. wins; lex sorted)
80
81 for ( const Pathname & ldir : lookupDirs ) {
82 // base config
83 PathInfo basecfg { ldir / configStem };
84 takeOrMask( basecfg, basecfgToParse );
85
86 // dropins
87 PathInfo dropinDir { ldir / configDir };
88 if ( dropinDir.isDir() ) {
89 filesystem::dirForEachExt( dropinDir.path(), [&]( const zypp::Pathname &p, const zypp::filesystem::DirEntry &entry ) {
90 if ( entry.name[0] == '.' )
91 return true;
92 if ( not ( configSuffix.empty() || str::hasSuffix( entry.name, configSuffix ) ) )
93 return true;
94 PathInfo dropin { p / entry.name };
95 takeOrMask( dropin, dropinsToParse[entry.name] );
96 return true;
97 } );
98 }
99 }
100
101 // prepare the list to parse
102 std::vector<Pathname> ret;
103 handOutIf( ret, basecfgToParse );
104 for ( const auto & [_,p] : dropinsToParse ) {
105 std::ignore = _; // silence warning: unused variable
106 handOutIf( ret, p );
107 }
108 if ( ret.empty() )
109 pMIL( "No config files found for stem", configStem, "below", root_r );
110 return ret;
111 }
112
113 private:
115 static void takeLookupDirIf( std::vector<Pathname> & lookupDirs_r, Pathname dir_r )
116 {
117 if ( PathInfo(dir_r).isDir() )
118 lookupDirs_r.push_back( dir_r );
119 }
120
122 static bool isSet( const PathInfo & file_r )
123 { return not file_r.path().empty(); }
124
126 static void takeOrMask( const PathInfo & file_r, PathInfo & toParse_r )
127 {
128 if ( file_r.isExist() && not file_r.isDir() ) {
129 if ( isSet( toParse_r ) ) {
130 pDBG( "masked", file_r, "by", toParse_r );
131 } else {
132 toParse_r = std::move(file_r); //file_r.path();
133 }
134 }
135 }
136
138 static void handOutIf( std::vector<Pathname> & ret_r, const PathInfo & file_r )
139 {
140 if ( isSet( file_r ) ) {
141 pMIL( "take", file_r );
142 ret_r.push_back( file_r.path() );
143 }
144 }
145
146
147 private:
148 std::optional<Pathname> _etcDir;
149 std::optional<Pathname> _usrDir;
150 };
151
152 Pathname ConfigurationContext::_defaultDistconfDir { APIConfig(LIBZYPP_ZYPPCONFDIR) };
153
154 } // namespace econf
155
156 EconfDict::EconfDict()
157 {}
158
159 EconfDict::EconfDict( const std::string & stem_r, const Pathname & root_r )
160 : IniDict()
161 {
162 for ( const Pathname & file : econf::ConfigurationContext().getConfigFiles( stem_r, root_r ) ) {
163 read( file );
164 }
165 pDBG( stem_r, "below", root_r, ":", *this );
166 }
167
168 Pathname EconfDict::defaultDistconfDir()
169 { return econf::ConfigurationContext::_defaultDistconfDir; }
170
171 void EconfDict::defaultDistconfDir( Pathname path_r )
172 { econf::ConfigurationContext::_defaultDistconfDir = std::move(path_r); }
173} // namespace zypp::parser
174
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
_
#define _(MSG)
Definition Gettext.h:39
LogTools.h
pMIL
#define pMIL
Definition LogTools.h:315
pDBG
#define pDBG
Definition LogTools.h:314
Pathname.h
zypp::Exception::Exception
Exception()
Default ctor.
Definition Exception.cc:94
zypp::PathInfo::PathInfo
PathInfo()
Definition PathInfo.cc:131
zypp::Pathname::Pathname
Pathname()
Default ctor: an empty path.
Definition Pathname.h:51
zypp::filesystem::PathInfo
Wrapper class for stat/lstat.
Definition PathInfo.h:226
zypp::filesystem::PathInfo::path
const Pathname & path() const
Return current Pathname.
Definition PathInfo.h:251
zypp::filesystem::PathInfo::isDir
bool isDir() const
Definition PathInfo.h:296
zypp::filesystem::PathInfo::isExist
bool isExist() const
Return whether valid stat info exists.
Definition PathInfo.h:286
zypp::filesystem::Pathname
Pathname.
Definition Pathname.h:48
zypp::filesystem::Pathname::extend
Pathname extend(const std::string &r) const
Append string r to the last component of the path.
Definition Pathname.h:192
zypp::filesystem::Pathname::relativeDotDot
bool relativeDotDot() const
Test for a relative path referring to ../.
Definition Pathname.h:124
zypp::filesystem::Pathname::emptyOrRoot
bool emptyOrRoot() const
Test for "" or "/".
Definition Pathname.h:127
zypp::filesystem::Pathname::empty
bool empty() const
Test for an empty path.
Definition Pathname.h:117
zypp::filesystem::Pathname::absolutename
Pathname absolutename() const
Return this path, adding a leading '/' if relative.
Definition Pathname.h:148
zypp::filesystem::Pathname::extension
std::string extension() const
Return all of the characters in name after and including the last dot in the last element of name.
Definition Pathname.h:144
zypp::filesystem::Pathname::relative
bool relative() const
Test for a relative path.
Definition Pathname.h:121
zypp::parser::EconfException
Thrown by EconfDict.
Definition parseexception.h:49
zypp::parser::IniDict::read
void read(const InputStream &is, const ProgressData::ReceiverFnc &progress=ProgressData::ReceiverFnc())
Fill a dictionary from a InputStream containing a ini structured file.
Definition inidict.cc:50
zypp::parser::IniDict::IniDict
IniDict(const InputStream &is, const ProgressData::ReceiverFnc &progress=ProgressData::ReceiverFnc())
Creates a dictionary from a InputStream containing a ini structured file.
Definition inidict.cc:40
econfdict.h
std
Definition ansi.h:855
zypp::filesystem::dirForEachExt
int dirForEachExt(const Pathname &dir_r, const function< bool(const Pathname &, const DirEntry &)> &fnc_r)
Simiar to.
Definition PathInfo.cc:612
zypp::parser::econf
Definition econfdict.cc:23
zypp::parser
Definition HistoryLogReader.cc:30
zypp::str::sprint
std::string sprint(Args &&... args)
Print words as string.
Definition LogTools.h:266
zypp::filesystem::DirEntry
Listentry returned by readdir.
Definition PathInfo.h:517
zypp::filesystem::DirEntry::name
std::string name
Definition PathInfo.h:518
zypp::parser::EconfDict::defaultDistconfDir
static Pathname defaultDistconfDir()
Where the vendor configuration files live (APIConfig(LIBZYPP_ZYPPCONFDIR)).
Definition econfdict.cc:168
zypp::parser::EconfDict::EconfDict
EconfDict()
Definition econfdict.cc:156
zypp::parser::econf::ConfigurationContext
Provide access to the prioritized list of files and drop-ins to read and merge for a specific config ...
Definition econfdict.cc:37
zypp::parser::econf::ConfigurationContext::takeOrMask
static void takeOrMask(const PathInfo &file_r, PathInfo &toParse_r)
The 1st viable file_r is stored in toParse_r; candidates found later are masked.
Definition econfdict.cc:126
zypp::parser::econf::ConfigurationContext::getConfigFiles
std::vector< Pathname > getConfigFiles(const std::string &stem_r, const Pathname &root_r=Pathname("/")) const
Definition econfdict.cc:53
zypp::parser::econf::ConfigurationContext::handOutIf
static void handOutIf(std::vector< Pathname > &ret_r, const PathInfo &file_r)
Store set values in ret_r.
Definition econfdict.cc:138
zypp::parser::econf::ConfigurationContext::takeLookupDirIf
static void takeLookupDirIf(std::vector< Pathname > &lookupDirs_r, Pathname dir_r)
Remember valid lookup dirs.
Definition econfdict.cc:115
zypp::parser::econf::ConfigurationContext::Exception
EconfException Exception
Definition econfdict.cc:38
zypp::parser::econf::ConfigurationContext::ConfigurationContext
ConfigurationContext()
Definition econfdict.cc:41
zypp::parser::econf::ConfigurationContext::_etcDir
std::optional< Pathname > _etcDir
system configuration: /etc
Definition econfdict.cc:148
zypp::parser::econf::ConfigurationContext::usrDir
const std::optional< Pathname > & usrDir() const
Definition econfdict.cc:51
zypp::parser::econf::ConfigurationContext::isSet
static bool isSet(const PathInfo &file_r)
An empty path denotes the unset value.
Definition econfdict.cc:122
zypp::parser::econf::ConfigurationContext::ConfigurationContext
ConfigurationContext(std::optional< Pathname > etcDir_r, std::optional< Pathname > usrDir_r)
Definition econfdict.cc:45
zypp::parser::econf::ConfigurationContext::_defaultDistconfDir
static Pathname _defaultDistconfDir
APIConfig(LIBZYPP_ZYPPCONFDIR) but amendable for Testing.
Definition econfdict.cc:39
zypp::parser::econf::ConfigurationContext::etcDir
const std::optional< Pathname > & etcDir() const
Definition econfdict.cc:50
zypp::parser::econf::ConfigurationContext::_usrDir
std::optional< Pathname > _usrDir
vendor configuration: distconfdir (APIConfig(LIBZYPP_ZYPPCONFDIR))
Definition econfdict.cc:149
PathInfo.h