Version 1.1.0.0 update

This commit is contained in:
transcoder
2014-02-12 04:09:36 -07:00
parent 58decdbca7
commit f03acc635f
481 changed files with 156398 additions and 57772 deletions

View File

@@ -1,16 +1,25 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Copyright (c) 2011-2012 Litecoin Developers
// Copyright (c) 2013 CasinoCoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef WIN32
// for posix_fallocate
#ifdef __linux__
#define _POSIX_C_SOURCE 200112L
#endif
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/resource.h>
#endif
#include "util.h"
#include "sync.h"
#include "strlcpy.h"
#include "version.h"
#include "ui_interface.h"
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
#include <boost/algorithm/string/predicate.hpp> // for startswith() and endswith()
// Work around clang compilation problem in Boost 1.46:
// /usr/include/boost/program_options/detail/config_file.hpp:163:17: error: call to function 'to_internal' that is neither visible in the template definition nor found by argument-dependent lookup
@@ -65,19 +74,19 @@ bool fDebug = false;
bool fDebugNet = false;
bool fPrintToConsole = false;
bool fPrintToDebugger = false;
bool fRequestShutdown = false;
bool fShutdown = false;
bool fDaemon = false;
bool fServer = false;
bool fCommandLine = false;
string strMiscWarning;
bool fTestNet = false;
bool fBloomFilters = true;
bool fNoListen = false;
bool fLogTimestamps = false;
CMedianFilter<int64> vTimeOffsets(200,0);
bool fReopenDebugLog = false;
volatile bool fReopenDebugLog = false;
bool fCachedPath[2] = {false, false};
// Init openssl library multithreading support
// Init OpenSSL library multithreading support
static CCriticalSection** ppmutexOpenSSL;
void locking_callback(int mode, int i, const char* file, int line)
{
@@ -88,13 +97,15 @@ void locking_callback(int mode, int i, const char* file, int line)
}
}
LockedPageManager LockedPageManager::instance;
// Init
class CInit
{
public:
CInit()
{
// Init openssl library multithreading support
// Init OpenSSL library multithreading support
ppmutexOpenSSL = (CCriticalSection**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(CCriticalSection*));
for (int i = 0; i < CRYPTO_num_locks(); i++)
ppmutexOpenSSL[i] = new CCriticalSection();
@@ -110,7 +121,7 @@ public:
}
~CInit()
{
// Shutdown openssl library multithreading support
// Shutdown OpenSSL library multithreading support
CRYPTO_set_locking_callback(NULL);
for (int i = 0; i < CRYPTO_num_locks(); i++)
delete ppmutexOpenSSL[i];
@@ -155,8 +166,8 @@ void RandAddSeedPerfmon()
if (ret == ERROR_SUCCESS)
{
RAND_add(pdata, nSize, nSize/100.0);
memset(pdata, 0, nSize);
printf("RandAddSeed() %d bytes\n", nSize);
OPENSSL_cleanse(pdata, nSize);
printf("RandAddSeed() %lu bytes\n", nSize);
}
#endif
}
@@ -194,56 +205,76 @@ uint256 GetRandHash()
//
// OutputDebugStringF (aka printf -- there is a #define that we really
// should get rid of one day) has been broken a couple of times now
// by well-meaning people adding mutexes in the most straightforward way.
// It breaks because it may be called by global destructors during shutdown.
// Since the order of destruction of static/global objects is undefined,
// defining a mutex as a global object doesn't work (the mutex gets
// destroyed, and then some later destructor calls OutputDebugStringF,
// maybe indirectly, and you get a core dump at shutdown trying to lock
// the mutex).
inline int OutputDebugStringF(const char* pszFormat, ...)
static boost::once_flag debugPrintInitFlag = BOOST_ONCE_INIT;
// We use boost::call_once() to make sure these are initialized in
// in a thread-safe manner the first time it is called:
static FILE* fileout = NULL;
static boost::mutex* mutexDebugLog = NULL;
static void DebugPrintInit()
{
int ret = 0;
assert(fileout == NULL);
assert(mutexDebugLog == NULL);
boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
fileout = fopen(pathDebug.string().c_str(), "a");
if (fileout) setbuf(fileout, NULL); // unbuffered
mutexDebugLog = new boost::mutex();
}
int OutputDebugStringF(const char* pszFormat, ...)
{
int ret = 0; // Returns total number of characters written
if (fPrintToConsole)
{
// print to console
va_list arg_ptr;
va_start(arg_ptr, pszFormat);
ret = vprintf(pszFormat, arg_ptr);
ret += vprintf(pszFormat, arg_ptr);
va_end(arg_ptr);
}
else
else if (!fPrintToDebugger)
{
// print to debug.log
static FILE* fileout = NULL;
static bool fStartedNewLine = true;
boost::call_once(&DebugPrintInit, debugPrintInitFlag);
if (!fileout)
{
if (fileout == NULL)
return ret;
boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
// reopen the log file, if requested
if (fReopenDebugLog) {
fReopenDebugLog = false;
boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
fileout = fopen(pathDebug.string().c_str(), "a");
if (fileout) setbuf(fileout, NULL); // unbuffered
if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL)
setbuf(fileout, NULL); // unbuffered
}
if (fileout)
{
static bool fStartedNewLine = true;
static boost::mutex mutexDebugLog;
boost::mutex::scoped_lock scoped_lock(mutexDebugLog);
// reopen the log file, if requested
if (fReopenDebugLog) {
fReopenDebugLog = false;
boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL)
setbuf(fileout, NULL); // unbuffered
}
// Debug print useful for profiling
if (fLogTimestamps && fStartedNewLine)
ret += fprintf(fileout, "%s ", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()).c_str());
if (pszFormat[strlen(pszFormat) - 1] == '\n')
fStartedNewLine = true;
else
fStartedNewLine = false;
// Debug print useful for profiling
if (fLogTimestamps && fStartedNewLine)
fprintf(fileout, "%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
if (pszFormat[strlen(pszFormat) - 1] == '\n')
fStartedNewLine = true;
else
fStartedNewLine = false;
va_list arg_ptr;
va_start(arg_ptr, pszFormat);
ret = vfprintf(fileout, pszFormat, arg_ptr);
va_end(arg_ptr);
}
va_list arg_ptr;
va_start(arg_ptr, pszFormat);
ret += vfprintf(fileout, pszFormat, arg_ptr);
va_end(arg_ptr);
}
#ifdef WIN32
@@ -266,6 +297,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
{
OutputDebugStringA(buffer.substr(line_start, line_end - line_start).c_str());
line_start = line_end + 1;
ret += line_end-line_start;
}
buffer.erase(0, line_start);
}
@@ -274,7 +306,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
return ret;
}
string vstrprintf(const std::string &format, va_list ap)
string vstrprintf(const char *format, va_list ap)
{
char buffer[50000];
char* p = buffer;
@@ -284,7 +316,11 @@ string vstrprintf(const std::string &format, va_list ap)
{
va_list arg_ptr;
va_copy(arg_ptr, ap);
ret = _vsnprintf(p, limit, format.c_str(), arg_ptr);
#ifdef WIN32
ret = _vsnprintf(p, limit, format, arg_ptr);
#else
ret = vsnprintf(p, limit, format, arg_ptr);
#endif
va_end(arg_ptr);
if (ret >= 0 && ret < limit)
break;
@@ -301,7 +337,7 @@ string vstrprintf(const std::string &format, va_list ap)
return str;
}
string real_strprintf(const std::string &format, int dummy, ...)
string real_strprintf(const char *format, int dummy, ...)
{
va_list arg_ptr;
va_start(arg_ptr, dummy);
@@ -310,6 +346,15 @@ string real_strprintf(const std::string &format, int dummy, ...)
return str;
}
string real_strprintf(const std::string &format, int dummy, ...)
{
va_list arg_ptr;
va_start(arg_ptr, dummy);
string str = vstrprintf(format.c_str(), arg_ptr);
va_end(arg_ptr);
return str;
}
bool error(const char *format, ...)
{
va_list arg_ptr;
@@ -350,7 +395,7 @@ string FormatMoney(int64 n, bool fPlus)
int64 remainder = n_abs%COIN;
string str = strprintf("%"PRI64d".%08"PRI64d, quotient, remainder);
// Right-trim excess 0's before the decimal point:
// Right-trim excess zeros before the decimal point:
int nTrim = 0;
for (int i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i)
++nTrim;
@@ -410,8 +455,21 @@ bool ParseMoney(const char* pszIn, int64& nRet)
return true;
}
// safeChars chosen to allow simple messages/URLs/email addresses, but avoid anything
// even possibly remotely dangerous like & or >
static string safeChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 .,;_/:?@");
string SanitizeString(const string& str)
{
string strResult;
for (std::string::size_type i = 0; i < str.size(); i++)
{
if (safeChars.find(str[i]) != std::string::npos)
strResult.push_back(str[i]);
}
return strResult;
}
static signed char phexdigit[256] =
static const signed char phexdigit[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,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
@@ -486,24 +544,24 @@ void ParseParameters(int argc, const char* const argv[])
mapMultiArgs.clear();
for (int i = 1; i < argc; i++)
{
char psz[10000];
strlcpy(psz, argv[i], sizeof(psz));
char* pszValue = (char*)"";
if (strchr(psz, '='))
std::string str(argv[i]);
std::string strValue;
size_t is_index = str.find('=');
if (is_index != std::string::npos)
{
pszValue = strchr(psz, '=');
*pszValue++ = '\0';
strValue = str.substr(is_index+1);
str = str.substr(0, is_index);
}
#ifdef WIN32
_strlwr(psz);
if (psz[0] == '/')
psz[0] = '-';
#endif
if (psz[0] != '-')
#ifdef WIN32
boost::to_lower(str);
if (boost::algorithm::starts_with(str, "/"))
str = "-" + str.substr(1);
#endif
if (str[0] != '-')
break;
mapArgs[psz] = pszValue;
mapMultiArgs[psz].push_back(pszValue);
mapArgs[str] = strValue;
mapMultiArgs[str].push_back(strValue);
}
// New 0.6 features:
@@ -973,10 +1031,10 @@ void PrintExceptionContinue(std::exception* pex, const char* pszThread)
boost::filesystem::path GetDefaultDataDir()
{
namespace fs = boost::filesystem;
// Windows < Vista: C:\Documents and Settings\Username\Application Data\CasinoCoin
// Windows >= Vista: C:\Users\Username\AppData\Roaming\CasinoCoin
// Mac: ~/Library/Application Support/CasinoCoin
// Unix: ~/.casinocoin
// Windows < Vista: C:\Documents and Settings\Username\Application Data\Bitcoin
// Windows >= Vista: C:\Users\Username\AppData\Roaming\Bitcoin
// Mac: ~/Library/Application Support/Bitcoin
// Unix: ~/.bitcoin
#ifdef WIN32
// Windows
return GetSpecialFolderPath(CSIDL_APPDATA) / "CasinoCoin";
@@ -1005,13 +1063,12 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific)
static fs::path pathCached[2];
static CCriticalSection csPathCached;
static bool cachedPath[2] = {false, false};
fs::path &path = pathCached[fNetSpecific];
// This can be called during exceptions by printf, so we cache the
// value so we don't have to do memory allocations after that.
if (cachedPath[fNetSpecific])
if (fCachedPath[fNetSpecific])
return path;
LOCK(csPathCached);
@@ -1028,9 +1085,9 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific)
if (fNetSpecific && GetBoolArg("-testnet", false))
path /= "testnet3";
fs::create_directory(path);
fs::create_directories(path);
cachedPath[fNetSpecific]=true;
fCachedPath[fNetSpecific] = true;
return path;
}
@@ -1046,14 +1103,17 @@ void ReadConfigFile(map<string, string>& mapSettingsRet,
{
boost::filesystem::ifstream streamConfig(GetConfigFile());
if (!streamConfig.good())
return; // No casinocoin.conf file is OK
return; // No bitcoin.conf file is OK
// clear path cache after loading config file
fCachedPath[0] = fCachedPath[1] = false;
set<string> setOptions;
setOptions.insert("*");
for (boost::program_options::detail::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it)
{
// Don't overwrite existing settings so command line settings override casinocoin.conf
// Don't overwrite existing settings so command line settings override bitcoin.conf
string strKey = string("-") + it->string_key;
if (mapSettingsRet.count(strKey) == 0)
{
@@ -1072,6 +1132,7 @@ boost::filesystem::path GetPidFile()
return pathPidFile;
}
#ifndef WIN32
void CreatePidFile(const boost::filesystem::path &path, pid_t pid)
{
FILE* file = fopen(path.string().c_str(), "w");
@@ -1081,6 +1142,7 @@ void CreatePidFile(const boost::filesystem::path &path, pid_t pid)
fclose(file);
}
}
#endif
bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest)
{
@@ -1099,7 +1161,13 @@ void FileCommit(FILE *fileout)
#ifdef WIN32
_commit(_fileno(fileout));
#else
#if defined(__linux__) || defined(__NetBSD__)
fdatasync(fileno(fileout));
#elif defined(__APPLE__) && defined(F_FULLFSYNC)
fcntl(fileno(fileout), F_FULLFSYNC, 0);
#else
fsync(fileno(fileout));
#endif
#endif
}
@@ -1113,6 +1181,80 @@ int GetFilesize(FILE* file)
return nFilesize;
}
bool TruncateFile(FILE *file, unsigned int length) {
#if defined(WIN32)
return _chsize(_fileno(file), length) == 0;
#else
return ftruncate(fileno(file), length) == 0;
#endif
}
// this function tries to raise the file descriptor limit to the requested number.
// It returns the actual file descriptor limit (which may be more or less than nMinFD)
int RaiseFileDescriptorLimit(int nMinFD) {
#if defined(WIN32)
return 2048;
#else
struct rlimit limitFD;
if (getrlimit(RLIMIT_NOFILE, &limitFD) != -1) {
if (limitFD.rlim_cur < (rlim_t)nMinFD) {
limitFD.rlim_cur = nMinFD;
if (limitFD.rlim_cur > limitFD.rlim_max)
limitFD.rlim_cur = limitFD.rlim_max;
setrlimit(RLIMIT_NOFILE, &limitFD);
getrlimit(RLIMIT_NOFILE, &limitFD);
}
return limitFD.rlim_cur;
}
return nMinFD; // getrlimit failed, assume it's fine
#endif
}
// this function tries to make a particular range of a file allocated (corresponding to disk space)
// it is advisory, and the range specified in the arguments will never contain live data
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length) {
#if defined(WIN32)
// Windows-specific version
HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
LARGE_INTEGER nFileSize;
int64 nEndPos = (int64)offset + length;
nFileSize.u.LowPart = nEndPos & 0xFFFFFFFF;
nFileSize.u.HighPart = nEndPos >> 32;
SetFilePointerEx(hFile, nFileSize, 0, FILE_BEGIN);
SetEndOfFile(hFile);
#elif defined(MAC_OSX)
// OSX specific version
fstore_t fst;
fst.fst_flags = F_ALLOCATECONTIG;
fst.fst_posmode = F_PEOFPOSMODE;
fst.fst_offset = 0;
fst.fst_length = (off_t)offset + length;
fst.fst_bytesalloc = 0;
if (fcntl(fileno(file), F_PREALLOCATE, &fst) == -1) {
fst.fst_flags = F_ALLOCATEALL;
fcntl(fileno(file), F_PREALLOCATE, &fst);
}
ftruncate(fileno(file), fst.fst_length);
#elif defined(__linux__)
// Version using posix_fallocate
off_t nEndPos = (off_t)offset + length;
posix_fallocate(fileno(file), 0, nEndPos);
#else
// Fallback version
// TODO: just write one byte per block
static const char buf[65536] = {};
fseek(file, offset, SEEK_SET);
while (length > 0) {
unsigned int now = 65536;
if (length < now)
now = length;
fwrite(buf, 1, now, file); // allowed to fail; this function is advisory anyway
length -= now;
}
#endif
}
void ShrinkDebugFile()
{
// Scroll debug.log if it's getting too big
@@ -1133,6 +1275,8 @@ void ShrinkDebugFile()
fclose(file);
}
}
else if(file != NULL)
fclose(file);
}
@@ -1165,9 +1309,14 @@ void SetMockTime(int64 nMockTimeIn)
static int64 nTimeOffset = 0;
int64 GetTimeOffset()
{
return nTimeOffset;
}
int64 GetAdjustedTime()
{
return GetTime() + nTimeOffset;
return GetTime() + GetTimeOffset();
}
void AddTimeData(const CNetAddr& ip, int64 nTime)
@@ -1207,10 +1356,10 @@ void AddTimeData(const CNetAddr& ip, int64 nTime)
if (!fMatch)
{
fDone = true;
string strMessage = _("Warning: Please check that your computer's date and time are correct. If your clock is wrong CasinoCoin will not work properly.");
string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong CasinoCoin will not work properly.");
strMiscWarning = strMessage;
printf("*** %s\n", strMessage.c_str());
uiInterface.ThreadSafeMessageBox(strMessage+" ", string("CasinoCoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION);
uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
}
}
}
@@ -1223,12 +1372,26 @@ void AddTimeData(const CNetAddr& ip, int64 nTime)
}
}
uint32_t insecure_rand_Rz = 11;
uint32_t insecure_rand_Rw = 11;
void seed_insecure_rand(bool fDeterministic)
{
//The seed values have some unlikely fixed points which we avoid.
if(fDeterministic)
{
insecure_rand_Rz = insecure_rand_Rw = 11;
} else {
uint32_t tmp;
do {
RAND_bytes((unsigned char*)&tmp, 4);
} while(tmp == 0 || tmp == 0x9068ffffU);
insecure_rand_Rz = tmp;
do {
RAND_bytes((unsigned char*)&tmp, 4);
} while(tmp == 0 || tmp == 0x464fffffU);
insecure_rand_Rw = tmp;
}
}
string FormatVersion(int nVersion)
{
@@ -1272,6 +1435,28 @@ boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate)
}
#endif
boost::filesystem::path GetTempPath() {
#if BOOST_FILESYSTEM_VERSION == 3
return boost::filesystem::temp_directory_path();
#else
// TODO: remove when we don't support filesystem v2 anymore
boost::filesystem::path path;
#ifdef WIN32
char pszPath[MAX_PATH] = "";
if (GetTempPathA(MAX_PATH, pszPath))
path = boost::filesystem::path(pszPath);
#else
path = boost::filesystem::path("/tmp");
#endif
if (path.empty() || !boost::filesystem::is_directory(path)) {
printf("GetTempPath(): failed to find temp path\n");
return boost::filesystem::path("");
}
return path;
#endif
}
void runCommand(std::string strCommand)
{
int nErr = ::system(strCommand.c_str());
@@ -1302,3 +1487,15 @@ void RenameThread(const char* name)
(void)name;
#endif
}
bool NewThread(void(*pfn)(void*), void* parg)
{
try
{
boost::thread(pfn, parg); // thread detaches when out of scope
} catch(boost::thread_resource_error &e) {
printf("Error creating thread: %s\n", e.what());
return false;
}
return true;
}