| 946 | } |
| 947 | |
| 948 | bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys) |
| 949 | { |
| 950 | { |
| 951 | LOCK(cs_args); |
| 952 | m_settings.ro_config.clear(); |
| 953 | m_config_sections.clear(); |
| 954 | } |
| 955 | |
| 956 | const std::string confPath = GetArg("-conf", BITCOIN_CONF_FILENAME); |
| 957 | std::ifstream stream{GetConfigFile(confPath)}; |
| 958 | |
| 959 | // not ok to have a config file specified that cannot be opened |
| 960 | if (IsArgSet("-conf") && !stream.good()) { |
| 961 | error = strprintf("specified config file \"%s\" could not be opened.", confPath); |
| 962 | return false; |
| 963 | } |
| 964 | // ok to not have a config file |
| 965 | if (stream.good()) { |
| 966 | if (!ReadConfigStream(stream, confPath, error, ignore_invalid_keys)) { |
| 967 | return false; |
| 968 | } |
| 969 | // `-includeconf` cannot be included in the command line arguments except |
| 970 | // as `-noincludeconf` (which indicates that no included conf file should be used). |
| 971 | bool use_conf_file{true}; |
| 972 | { |
| 973 | LOCK(cs_args); |
| 974 | if (auto* includes = util::FindKey(m_settings.command_line_options, "includeconf")) { |
| 975 | // ParseParameters() fails if a non-negated -includeconf is passed on the command-line |
| 976 | assert(util::SettingsSpan(*includes).last_negated()); |
| 977 | use_conf_file = false; |
| 978 | } |
| 979 | } |
| 980 | if (use_conf_file) { |
| 981 | std::string chain_id = GetChainName(); |
| 982 | std::vector<std::string> conf_file_names; |
| 983 | |
| 984 | auto add_includes = [&](const std::string& network, size_t skip = 0) { |
| 985 | size_t num_values = 0; |
| 986 | LOCK(cs_args); |
| 987 | if (auto* section = util::FindKey(m_settings.ro_config, network)) { |
| 988 | if (auto* values = util::FindKey(*section, "includeconf")) { |
| 989 | for (size_t i = std::max(skip, util::SettingsSpan(*values).negated()); i < values->size(); ++i) { |
| 990 | conf_file_names.push_back((*values)[i].get_str()); |
| 991 | } |
| 992 | num_values = values->size(); |
| 993 | } |
| 994 | } |
| 995 | return num_values; |
| 996 | }; |
| 997 | |
| 998 | // We haven't set m_network yet (that happens in SelectParams()), so manually check |
| 999 | // for network.includeconf args. |
| 1000 | const size_t chain_includes = add_includes(chain_id); |
| 1001 | const size_t default_includes = add_includes({}); |
| 1002 | |
| 1003 | for (const std::string& conf_file_name : conf_file_names) { |
| 1004 | std::ifstream conf_file_stream{GetConfigFile(conf_file_name)}; |
| 1005 | if (conf_file_stream.good()) { |
no test coverage detected