aboutsummaryrefslogtreecommitdiff
path: root/src/util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.cpp')
-rw-r--r--src/util.cpp189
1 files changed, 82 insertions, 107 deletions
diff --git a/src/util.cpp b/src/util.cpp
index cccf2df48..5a8f85ade 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -5,8 +5,7 @@
#include "util.h"
-#include "chainparams.h"
-#include "netbase.h"
+#include "chainparamsbase.h"
#include "sync.h"
#include "ui_interface.h"
#include "uint256.h"
@@ -78,11 +77,12 @@
// See also: http://stackoverflow.com/questions/10020179/compilation-fail-in-boost-librairies-program-options
// http://clang.debian.net/status.php?version=3.0&key=CANNOT_FIND_FUNCTION
namespace boost {
+
namespace program_options {
std::string to_internal(const std::string&);
}
-}
+} // namespace boost
using namespace std;
@@ -168,16 +168,31 @@ void RandAddSeedPerfmon()
#ifdef WIN32
// Don't need this on Linux, OpenSSL automatically uses /dev/urandom
// Seed with the entire set of perfmon data
- unsigned char pdata[250000];
- memset(pdata, 0, sizeof(pdata));
- unsigned long nSize = sizeof(pdata);
- long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
+ std::vector <unsigned char> vData(250000,0);
+ long ret = 0;
+ unsigned long nSize = 0;
+ const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data
+ while (true)
+ {
+ nSize = vData.size();
+ ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, begin_ptr(vData), &nSize);
+ if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize)
+ break;
+ vData.resize(std::max((vData.size()*3)/2, nMaxSize)); // Grow size of buffer exponentially
+ }
RegCloseKey(HKEY_PERFORMANCE_DATA);
if (ret == ERROR_SUCCESS)
{
- RAND_add(pdata, nSize, nSize/100.0);
- OPENSSL_cleanse(pdata, nSize);
- LogPrint("rand", "RandAddSeed() %lu bytes\n", nSize);
+ RAND_add(begin_ptr(vData), nSize, nSize/100.0);
+ OPENSSL_cleanse(begin_ptr(vData), nSize);
+ LogPrint("rand", "%s: %lu bytes\n", __func__, nSize);
+ } else {
+ static bool warned = false; // Warn only once
+ if (!warned)
+ {
+ LogPrintf("%s: Warning: RegQueryValueExA(HKEY_PERFORMANCE_DATA) failed with code %i\n", __func__, ret);
+ warned = true;
+ }
}
#endif
}
@@ -405,6 +420,11 @@ const signed char p_util_hexdigit[256] =
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, };
+signed char HexDigit(char c)
+{
+ return p_util_hexdigit[(unsigned char)c];
+}
+
bool IsHex(const string& str)
{
BOOST_FOREACH(char c, str)
@@ -460,6 +480,7 @@ void ParseParameters(int argc, const char* const argv[])
{
mapArgs.clear();
mapMultiArgs.clear();
+
for (int i = 1; i < argc; i++)
{
std::string str(argv[i]);
@@ -475,9 +496,15 @@ void ParseParameters(int argc, const char* const argv[])
if (boost::algorithm::starts_with(str, "/"))
str = "-" + str.substr(1);
#endif
+
if (str[0] != '-')
break;
+ // Interpret --foo as -foo.
+ // If both --foo and -foo are set, the last takes effect.
+ if (str.length() > 1 && str[1] == '-')
+ str = str.substr(1);
+
mapArgs[str] = strValue;
mapMultiArgs[str].push_back(strValue);
}
@@ -485,19 +512,8 @@ void ParseParameters(int argc, const char* const argv[])
// New 0.6 features:
BOOST_FOREACH(const PAIRTYPE(string,string)& entry, mapArgs)
{
- string name = entry.first;
-
- // interpret --foo as -foo (as long as both are not set)
- if (name.find("--") == 0)
- {
- std::string singleDash(name.begin()+1, name.end());
- if (mapArgs.count(singleDash) == 0)
- mapArgs[singleDash] = entry.second;
- name = singleDash;
- }
-
// interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set
- InterpretNegativeSetting(name, mapArgs);
+ InterpretNegativeSetting(entry.first, mapArgs);
}
}
@@ -923,7 +939,7 @@ boost::filesystem::path GetDefaultDataDir()
#endif
}
-static boost::filesystem::path pathCached[CChainParams::MAX_NETWORK_TYPES+1];
+static boost::filesystem::path pathCached[CBaseChainParams::MAX_NETWORK_TYPES+1];
static CCriticalSection csPathCached;
const boost::filesystem::path &GetDataDir(bool fNetSpecific)
@@ -932,8 +948,8 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific)
LOCK(csPathCached);
- int nNet = CChainParams::MAX_NETWORK_TYPES;
- if (fNetSpecific) nNet = Params().NetworkID();
+ int nNet = CBaseChainParams::MAX_NETWORK_TYPES;
+ if (fNetSpecific) nNet = BaseParams().NetworkID();
fs::path &path = pathCached[nNet];
@@ -952,7 +968,7 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific)
path = GetDefaultDataDir();
}
if (fNetSpecific)
- path /= Params().DataDir();
+ path /= BaseParams().DataDir();
fs::create_directories(path);
@@ -961,7 +977,7 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific)
void ClearDatadirCache()
{
- std::fill(&pathCached[0], &pathCached[CChainParams::MAX_NETWORK_TYPES+1],
+ std::fill(&pathCached[0], &pathCached[CBaseChainParams::MAX_NETWORK_TYPES+1],
boost::filesystem::path());
}
@@ -1145,15 +1161,15 @@ void ShrinkDebugFile()
if (file && boost::filesystem::file_size(pathLog) > 10 * 1000000)
{
// Restart the file with some of the end
- char pch[200000];
- fseek(file, -sizeof(pch), SEEK_END);
- int nBytes = fread(pch, 1, sizeof(pch), file);
+ std::vector <char> vch(200000,0);
+ fseek(file, -vch.size(), SEEK_END);
+ int nBytes = fread(begin_ptr(vch), 1, vch.size(), file);
fclose(file);
file = fopen(pathLog.string().c_str(), "w");
if (file)
{
- fwrite(pch, 1, nBytes, file);
+ fwrite(begin_ptr(vch), 1, nBytes, file);
fclose(file);
}
}
@@ -1161,13 +1177,6 @@ void ShrinkDebugFile()
fclose(file);
}
-//
-// "Never go to sea with two chronometers; take one or three."
-// Our three time sources are:
-// - System clock
-// - Median of other nodes clocks
-// - The user (asking the user to fix the system clock if the first two disagree)
-//
static int64_t nMockTime = 0; // For unit testing
int64_t GetTime()
@@ -1182,75 +1191,6 @@ void SetMockTime(int64_t nMockTimeIn)
nMockTime = nMockTimeIn;
}
-static CCriticalSection cs_nTimeOffset;
-static int64_t nTimeOffset = 0;
-
-int64_t GetTimeOffset()
-{
- LOCK(cs_nTimeOffset);
- return nTimeOffset;
-}
-
-int64_t GetAdjustedTime()
-{
- return GetTime() + GetTimeOffset();
-}
-
-void AddTimeData(const CNetAddr& ip, int64_t nTime)
-{
- int64_t nOffsetSample = nTime - GetTime();
-
- LOCK(cs_nTimeOffset);
- // Ignore duplicates
- static set<CNetAddr> setKnown;
- if (!setKnown.insert(ip).second)
- return;
-
- // Add data
- static CMedianFilter<int64_t> vTimeOffsets(200,0);
- vTimeOffsets.input(nOffsetSample);
- LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);
- if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
- {
- int64_t nMedian = vTimeOffsets.median();
- std::vector<int64_t> vSorted = vTimeOffsets.sorted();
- // Only let other nodes change our time by so much
- if (abs64(nMedian) < 70 * 60)
- {
- nTimeOffset = nMedian;
- }
- else
- {
- nTimeOffset = 0;
-
- static bool fDone;
- if (!fDone)
- {
- // If nobody has a time different than ours but within 5 minutes of ours, give a warning
- bool fMatch = false;
- BOOST_FOREACH(int64_t nOffset, vSorted)
- if (nOffset != 0 && abs64(nOffset) < 5 * 60)
- fMatch = true;
-
- if (!fMatch)
- {
- fDone = true;
- string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin will not work properly.");
- strMiscWarning = strMessage;
- LogPrintf("*** %s\n", strMessage);
- uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
- }
- }
- }
- if (fDebug) {
- BOOST_FOREACH(int64_t n, vSorted)
- LogPrintf("%+d ", n);
- LogPrintf("| ");
- }
- LogPrintf("nTimeOffset = %+d (%+d minutes)\n", nTimeOffset, nTimeOffset/60);
- }
-}
-
uint32_t insecure_rand_Rz = 11;
uint32_t insecure_rand_Rw = 11;
void seed_insecure_rand(bool fDeterministic)
@@ -1407,3 +1347,38 @@ std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime)
ss << boost::posix_time::from_time_t(nTime);
return ss.str();
}
+
+std::string FormatParagraph(const std::string in, size_t width, size_t indent)
+{
+ std::stringstream out;
+ size_t col = 0;
+ size_t ptr = 0;
+ while(ptr < in.size())
+ {
+ // Find beginning of next word
+ ptr = in.find_first_not_of(' ', ptr);
+ if (ptr == std::string::npos)
+ break;
+ // Find end of next word
+ size_t endword = in.find_first_of(' ', ptr);
+ if (endword == std::string::npos)
+ endword = in.size();
+ // Add newline and indentation if this wraps over the allowed width
+ if (col > 0)
+ {
+ if ((col + endword - ptr) > width)
+ {
+ out << '\n';
+ for(size_t i=0; i<indent; ++i)
+ out << ' ';
+ col = 0;
+ } else
+ out << ' ';
+ }
+ // Append word
+ out << in.substr(ptr, endword - ptr);
+ col += endword - ptr;
+ ptr = endword;
+ }
+ return out.str();
+}