Changeset View
Changeset View
Standalone View
Standalone View
src/util.cpp
// Copyright (c) 2009-2010 Satoshi Nakamoto | // Copyright (c) 2009-2010 Satoshi Nakamoto | ||||
// Copyright (c) 2009-2016 The Bitcoin Core developers | // Copyright (c) 2009-2016 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#if defined(HAVE_CONFIG_H) | #if defined(HAVE_CONFIG_H) | ||||
#include "config/bitcoin-config.h" | #include "config/bitcoin-config.h" | ||||
#endif | #endif | ||||
#include "util.h" | #include "util.h" | ||||
#include "chainparamsbase.h" | #include "chainparamsbase.h" | ||||
#include "fs.h" | #include "fs.h" | ||||
#include "random.h" | #include "random.h" | ||||
#include "serialize.h" | #include "serialize.h" | ||||
#include "sync.h" | |||||
#include "utilstrencodings.h" | #include "utilstrencodings.h" | ||||
#include "utiltime.h" | #include "utiltime.h" | ||||
#include <cstdarg> | #include <cstdarg> | ||||
#if (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)) | #if (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)) | ||||
#include <pthread.h> | #include <pthread.h> | ||||
#include <pthread_np.h> | #include <pthread_np.h> | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | |||||
#include <boost/thread.hpp> | #include <boost/thread.hpp> | ||||
#include <openssl/conf.h> | #include <openssl/conf.h> | ||||
#include <openssl/rand.h> | #include <openssl/rand.h> | ||||
const char *const BITCOIN_CONF_FILENAME = "bitcoin.conf"; | const char *const BITCOIN_CONF_FILENAME = "bitcoin.conf"; | ||||
const char *const BITCOIN_PID_FILENAME = "bitcoind.pid"; | const char *const BITCOIN_PID_FILENAME = "bitcoind.pid"; | ||||
CCriticalSection cs_args; | ArgsManager gArgs; | ||||
std::map<std::string, std::string> mapArgs; | |||||
static std::map<std::string, std::vector<std::string>> _mapMultiArgs; | |||||
const std::map<std::string, std::vector<std::string>> &mapMultiArgs = | |||||
_mapMultiArgs; | |||||
bool fPrintToConsole = false; | bool fPrintToConsole = false; | ||||
bool fPrintToDebugLog = true; | bool fPrintToDebugLog = true; | ||||
bool fLogTimestamps = DEFAULT_LOGTIMESTAMPS; | bool fLogTimestamps = DEFAULT_LOGTIMESTAMPS; | ||||
bool fLogTimeMicros = DEFAULT_LOGTIMEMICROS; | bool fLogTimeMicros = DEFAULT_LOGTIMEMICROS; | ||||
bool fLogIPs = DEFAULT_LOGIPS; | bool fLogIPs = DEFAULT_LOGIPS; | ||||
std::atomic<bool> fReopenDebugLog(false); | std::atomic<bool> fReopenDebugLog(false); | ||||
CTranslationInterface translationInterface; | CTranslationInterface translationInterface; | ||||
▲ Show 20 Lines • Show All 250 Lines • ▼ Show 20 Lines | static void InterpretNegativeSetting(std::string &strKey, | ||||
std::string &strValue) { | std::string &strValue) { | ||||
if (strKey.length() > 3 && strKey[0] == '-' && strKey[1] == 'n' && | if (strKey.length() > 3 && strKey[0] == '-' && strKey[1] == 'n' && | ||||
strKey[2] == 'o') { | strKey[2] == 'o') { | ||||
strKey = "-" + strKey.substr(3); | strKey = "-" + strKey.substr(3); | ||||
strValue = InterpretBool(strValue) ? "0" : "1"; | strValue = InterpretBool(strValue) ? "0" : "1"; | ||||
} | } | ||||
} | } | ||||
void ParseParameters(int argc, const char *const argv[]) { | void ArgsManager::ParseParameters(int argc, const char *const argv[]) { | ||||
LOCK(cs_args); | LOCK(cs_args); | ||||
mapArgs.clear(); | mapArgs.clear(); | ||||
_mapMultiArgs.clear(); | mapMultiArgs.clear(); | ||||
for (int i = 1; i < argc; i++) { | for (int i = 1; i < argc; i++) { | ||||
std::string str(argv[i]); | std::string str(argv[i]); | ||||
std::string strValue; | std::string strValue; | ||||
size_t is_index = str.find('='); | size_t is_index = str.find('='); | ||||
if (is_index != std::string::npos) { | if (is_index != std::string::npos) { | ||||
strValue = str.substr(is_index + 1); | strValue = str.substr(is_index + 1); | ||||
str = str.substr(0, is_index); | str = str.substr(0, is_index); | ||||
} | } | ||||
#ifdef WIN32 | #ifdef WIN32 | ||||
boost::to_lower(str); | boost::to_lower(str); | ||||
if (boost::algorithm::starts_with(str, "/")) str = "-" + str.substr(1); | if (boost::algorithm::starts_with(str, "/")) str = "-" + str.substr(1); | ||||
#endif | #endif | ||||
if (str[0] != '-') break; | if (str[0] != '-') break; | ||||
// Interpret --foo as -foo. | // Interpret --foo as -foo. | ||||
// If both --foo and -foo are set, the last takes effect. | // If both --foo and -foo are set, the last takes effect. | ||||
if (str.length() > 1 && str[1] == '-') str = str.substr(1); | if (str.length() > 1 && str[1] == '-') str = str.substr(1); | ||||
InterpretNegativeSetting(str, strValue); | InterpretNegativeSetting(str, strValue); | ||||
mapArgs[str] = strValue; | mapArgs[str] = strValue; | ||||
_mapMultiArgs[str].push_back(strValue); | mapMultiArgs[str].push_back(strValue); | ||||
} | } | ||||
} | } | ||||
bool IsArgSet(const std::string &strArg) { | std::vector<std::string> ArgsManager::GetArgs(const std::string &strArg) { | ||||
LOCK(cs_args); | |||||
return mapMultiArgs.at(strArg); | |||||
} | |||||
bool ArgsManager::IsArgSet(const std::string &strArg) { | |||||
LOCK(cs_args); | LOCK(cs_args); | ||||
return mapArgs.count(strArg); | return mapArgs.count(strArg); | ||||
} | } | ||||
std::string GetArg(const std::string &strArg, const std::string &strDefault) { | std::string ArgsManager::GetArg(const std::string &strArg, | ||||
const std::string &strDefault) { | |||||
LOCK(cs_args); | LOCK(cs_args); | ||||
if (mapArgs.count(strArg)) return mapArgs[strArg]; | if (mapArgs.count(strArg)) return mapArgs[strArg]; | ||||
return strDefault; | return strDefault; | ||||
} | } | ||||
int64_t GetArg(const std::string &strArg, int64_t nDefault) { | int64_t ArgsManager::GetArg(const std::string &strArg, int64_t nDefault) { | ||||
LOCK(cs_args); | LOCK(cs_args); | ||||
if (mapArgs.count(strArg)) return atoi64(mapArgs[strArg]); | if (mapArgs.count(strArg)) return atoi64(mapArgs[strArg]); | ||||
return nDefault; | return nDefault; | ||||
} | } | ||||
bool GetBoolArg(const std::string &strArg, bool fDefault) { | bool ArgsManager::GetBoolArg(const std::string &strArg, bool fDefault) { | ||||
LOCK(cs_args); | LOCK(cs_args); | ||||
if (mapArgs.count(strArg)) return InterpretBool(mapArgs[strArg]); | if (mapArgs.count(strArg)) return InterpretBool(mapArgs[strArg]); | ||||
return fDefault; | return fDefault; | ||||
} | } | ||||
bool SoftSetArg(const std::string &strArg, const std::string &strValue) { | bool ArgsManager::SoftSetArg(const std::string &strArg, | ||||
const std::string &strValue) { | |||||
LOCK(cs_args); | LOCK(cs_args); | ||||
if (mapArgs.count(strArg)) return false; | if (mapArgs.count(strArg)) { | ||||
mapArgs[strArg] = strValue; | return false; | ||||
} | |||||
ForceSetArg(strArg, strValue); | |||||
return true; | return true; | ||||
} | } | ||||
bool SoftSetBoolArg(const std::string &strArg, bool fValue) { | bool ArgsManager::SoftSetBoolArg(const std::string &strArg, bool fValue) { | ||||
if (fValue) | if (fValue) | ||||
return SoftSetArg(strArg, std::string("1")); | return SoftSetArg(strArg, std::string("1")); | ||||
else | else | ||||
return SoftSetArg(strArg, std::string("0")); | return SoftSetArg(strArg, std::string("0")); | ||||
} | } | ||||
void ForceSetArg(const std::string &strArg, const std::string &strValue) { | void ArgsManager::ForceSetArg(const std::string &strArg, | ||||
const std::string &strValue) { | |||||
LOCK(cs_args); | LOCK(cs_args); | ||||
mapArgs[strArg] = strValue; | mapArgs[strArg] = strValue; | ||||
mapMultiArgs[strArg].push_back(strValue); | |||||
} | } | ||||
/** | /** | ||||
* This function is only used for testing purpose so | * This function is only used for testing purpose so | ||||
* so we should not worry about element uniqueness and | * so we should not worry about element uniqueness and | ||||
* integrity of mapMultiArgs data structure | * integrity of mapMultiArgs data structure | ||||
*/ | */ | ||||
void ForceSetMultiArg(const std::string &strArg, const std::string &strValue) { | void ArgsManager::ForceSetMultiArg(const std::string &strArg, | ||||
const std::string &strValue) { | |||||
LOCK(cs_args); | LOCK(cs_args); | ||||
_mapMultiArgs[strArg].push_back(strValue); | if (mapArgs.count(strArg) == 0) { | ||||
mapArgs[strArg] = strValue; | |||||
} | |||||
mapMultiArgs[strArg].push_back(strValue); | |||||
} | } | ||||
void ClearArg(const std::string &strArg) { | void ArgsManager::ClearArg(const std::string &strArg) { | ||||
LOCK(cs_args); | LOCK(cs_args); | ||||
mapArgs.erase(strArg); | mapArgs.erase(strArg); | ||||
} | } | ||||
static const int screenWidth = 79; | static const int screenWidth = 79; | ||||
static const int optIndent = 2; | static const int optIndent = 2; | ||||
static const int msgIndent = 7; | static const int msgIndent = 7; | ||||
▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | |||||
fs::path GetConfigFile(const std::string &confPath) { | fs::path GetConfigFile(const std::string &confPath) { | ||||
fs::path pathConfigFile(confPath); | fs::path pathConfigFile(confPath); | ||||
if (!pathConfigFile.is_complete()) | if (!pathConfigFile.is_complete()) | ||||
pathConfigFile = GetDataDir(false) / pathConfigFile; | pathConfigFile = GetDataDir(false) / pathConfigFile; | ||||
return pathConfigFile; | return pathConfigFile; | ||||
} | } | ||||
void ReadConfigFile(const std::string &confPath) { | void ArgsManager::ReadConfigFile(const std::string &confPath) { | ||||
fs::ifstream streamConfig(GetConfigFile(confPath)); | fs::ifstream streamConfig(GetConfigFile(confPath)); | ||||
// No bitcoin.conf file is OK | // No bitcoin.conf file is OK | ||||
if (!streamConfig.good()) return; | if (!streamConfig.good()) return; | ||||
{ | { | ||||
LOCK(cs_args); | LOCK(cs_args); | ||||
std::set<std::string> setOptions; | std::set<std::string> setOptions; | ||||
setOptions.insert("*"); | setOptions.insert("*"); | ||||
for (boost::program_options::detail::config_file_iterator | for (boost::program_options::detail::config_file_iterator | ||||
it(streamConfig, setOptions), | it(streamConfig, setOptions), | ||||
end; | end; | ||||
it != end; ++it) { | it != end; ++it) { | ||||
// Don't overwrite existing settings so command line settings | // Don't overwrite existing settings so command line settings | ||||
// override bitcoin.conf | // override bitcoin.conf | ||||
std::string strKey = std::string("-") + it->string_key; | std::string strKey = std::string("-") + it->string_key; | ||||
std::string strValue = it->value[0]; | std::string strValue = it->value[0]; | ||||
InterpretNegativeSetting(strKey, strValue); | InterpretNegativeSetting(strKey, strValue); | ||||
if (mapArgs.count(strKey) == 0) mapArgs[strKey] = strValue; | if (mapArgs.count(strKey) == 0) { | ||||
_mapMultiArgs[strKey].push_back(strValue); | mapArgs[strKey] = strValue; | ||||
} | |||||
mapMultiArgs[strKey].push_back(strValue); | |||||
} | } | ||||
} | } | ||||
// If datadir is changed in .conf file: | // If datadir is changed in .conf file: | ||||
ClearDatadirCache(); | ClearDatadirCache(); | ||||
} | } | ||||
#ifndef WIN32 | #ifndef WIN32 | ||||
fs::path GetPidFile() { | fs::path GetPidFile() { | ||||
▲ Show 20 Lines • Show All 266 Lines • Show Last 20 Lines |