34 const fs::path &configuration_file_path) {
42 std::vector<std::pair<std::string, std::string>> &options,
43 std::list<SectionInfo> §ions) {
45 std::string::size_type pos;
47 while (std::getline(stream, str)) {
48 bool used_hash =
false;
49 if ((pos = str.find(
'#')) != std::string::npos) {
50 str = str.substr(0, pos);
53 const static std::string pattern =
" \t\r\n";
56 if (*str.begin() ==
'[' && *str.rbegin() ==
']') {
57 const std::string section = str.substr(1, str.size() - 2);
58 sections.emplace_back(
SectionInfo{section, filepath, linenr});
60 }
else if (*str.begin() ==
'-') {
62 "parse error on line %i: %s, options in configuration file "
63 "must be specified without leading -",
66 }
else if ((pos = str.find(
'=')) != std::string::npos) {
69 TrimString(std::string_view{str}.substr(0, pos), pattern);
71 std::string_view{str}.substr(pos + 1), pattern);
73 name.find(
"rpcpassword") != std::string::npos) {
75 "parse error on line %i, using # in rpcpassword can be "
76 "ambiguous and should be avoided",
80 options.emplace_back(
name, value);
81 if ((pos =
name.rfind(
'.')) != std::string::npos &&
83 sections.emplace_back(
87 error =
strprintf(
"parse error on line %i: %s", linenr, str);
88 if (str.size() >= 2 && str.substr(0, 2) ==
"no") {
89 error +=
strprintf(
", if you intended to specify a negated "
90 "option, use %s=1 instead",
102 const std::string &filepath,
104 bool ignore_invalid_keys) {
106 std::vector<std::pair<std::string, std::string>> options;
108 m_config_sections)) {
111 for (
const std::pair<std::string, std::string> &option : options) {
115 std::optional<util::SettingsValue> value =
120 m_settings.ro_config[key.
section][key.
name].push_back(*value);
122 if (ignore_invalid_keys) {
123 LogPrintf(
"Ignoring unknown configuration value %s\n",
126 error =
strprintf(
"Invalid configuration value %s",
127 option.first.c_str());
136 bool ignore_invalid_keys) {
139 m_settings.ro_config.clear();
140 m_config_sections.clear();
144 std::ifstream stream{conf_path};
149 ignore_invalid_keys)) {
155 bool use_conf_file{
true};
158 if (
auto *includes =
util::FindKey(m_settings.command_line_options,
163 use_conf_file =
false;
168 std::vector<std::string> conf_file_names;
170 auto add_includes = [&](
const std::string &network,
172 size_t num_values = 0;
177 for (
size_t i = std::max(
179 i < values->size(); ++i) {
180 conf_file_names.push_back((*values)[i].get_str());
182 num_values = values->size();
190 const size_t chain_includes = add_includes(chain_id);
191 const size_t default_includes = add_includes({});
193 for (
const std::string &conf_file_name : conf_file_names) {
194 std::ifstream conf_file_stream{
196 if (conf_file_stream.good()) {
198 error, ignore_invalid_keys)) {
201 LogPrintf(
"Included configuration file %s\n",
204 error =
"Failed to include configuration file " +
211 conf_file_names.clear();
212 add_includes(chain_id, chain_includes);
213 add_includes({}, default_includes);
215 if (chain_id_final != chain_id) {
218 add_includes(chain_id_final);
220 for (
const std::string &conf_file_name : conf_file_names) {
222 "warning: -includeconf cannot be used from "
223 "included files; ignoring -includeconf=%s\n",
232 error =
strprintf(
"specified data directory \"%s\" does not exist.",
233 GetArg(
"-datadir",
"").c_str());
241 if (path.is_absolute()) {
bool CheckDataDirOption(const ArgsManager &args)
std::optional< util::SettingsValue > InterpretValue(const KeyInfo &key, const std::optional< std::string > &value, unsigned int flags, std::string &error)
Interpret settings value based on registered flags.
KeyInfo InterpretKey(std::string key)
Parse "name", "section.name", "noname", "section.noname" settings keys.
std::string GetChainTypeString() const
Returns the appropriate chain name string from the program arguments.
fs::path GetDataDirNet() const
Get data directory path with appended network identifier.
std::optional< unsigned int > GetArgFlags(const std::string &name) const
Return Flags for known arg.
void ClearPathCache()
Clear cached directory paths.
fs::path GetDataDirBase() const
Get data directory path.
fs::path GetConfigFilePath() const
Return config file path (read-only)
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
bool ReadConfigStream(std::istream &stream, const std::string &filepath, std::string &error, bool ignore_invalid_keys=false)
bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
static bool GetConfigOptions(std::istream &stream, const std::string &filepath, std::string &error, std::vector< std::pair< std::string, std::string > > &options, std::list< SectionInfo > §ions)
fs::path AbsPathForConfigVal(const ArgsManager &args, const fs::path &path, bool net_specific)
Most paths passed as configuration arguments are treated as relative to the datadir if they are not a...
fs::path GetConfigFile(const ArgsManager &args, const fs::path &configuration_file_path)
static std::string PathToString(const path &path)
Convert path object to byte string.
static path PathFromString(const std::string &string)
Convert byte string to path object.
fs::path AbsPathJoin(const fs::path &base, const fs::path &path)
Helper function for joining two paths.
std::string_view TrimStringView(std::string_view str, std::string_view pattern=" \f\n\r\t\v")
std::string TrimString(std::string_view str, std::string_view pattern=" \f\n\r\t\v")
auto FindKey(Map &&map, Key &&key) -> decltype(&map.at(key))
Map lookup helper.
Accessor for list of settings that skips negated values when iterated over.
size_t negated() const
Number of negated values.
bool last_negated() const
True if the last value is negated.