Comparing sensitive data, confidential files or internal emails?

Most legal and privacy policies prohibit uploading sensitive data online. Diffchecker Desktop ensures your confidential information never leaves your computer. Work offline and compare documents securely.

Untitled diff

Created Diff never expires
10 removals
930 lines
9 additions
929 lines
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Copyright (c) 2009-2012 The Bitcoin developers
// Copyright (c) 2011-2012 The Peercoin developers
// Copyright (c) 2011-2012 The Peercoin developers
// Copyright (c) 2013-2014 The Peershares developers
// Copyright (c) 2013-2014 The Peershares developers
// Copyright (c) 2015-2015 The Decent developers
// Distributed under the MIT/X11 software license, see the accompanying
// Distributed under the MIT/X11 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.


#include "util.h"
#include "util.h"
#include "strlcpy.h"
#include "strlcpy.h"
#include "version.h"
#include "version.h"
#include "ui_interface.h"
#include "ui_interface.h"
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/join.hpp>


// Work around clang compilation problem in Boost 1.46:
// 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
// /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
// See also: http://stackoverflow.com/questions/10020179/compilation-fail-in-boost-librairies-program-options
// 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
// http://clang.debian.net/status.php?version=3.0&key=CANNOT_FIND_FUNCTION
namespace boost {
namespace boost {
namespace program_options {
namespace program_options {
std::string to_internal(const std::string&);
std::string to_internal(const std::string&);
}
}
}
}


#include <boost/program_options/detail/config_file.hpp>
#include <boost/program_options/detail/config_file.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
#include <boost/foreach.hpp>
#include <boost/foreach.hpp>
#include <boost/thread.hpp>
#include <boost/thread.hpp>
#include <openssl/crypto.h>
#include <openssl/crypto.h>
#include <openssl/rand.h>
#include <openssl/rand.h>


#ifdef WIN32
#ifdef WIN32
#ifdef _MSC_VER
#ifdef _MSC_VER
#pragma warning(disable:4786)
#pragma warning(disable:4786)
#pragma warning(disable:4804)
#pragma warning(disable:4804)
#pragma warning(disable:4805)
#pragma warning(disable:4805)
#pragma warning(disable:4717)
#pragma warning(disable:4717)
#endif
#endif
#ifdef _WIN32_WINNT
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#endif
#define _WIN32_WINNT 0x0501
#define _WIN32_WINNT 0x0501
#ifdef _WIN32_IE
#ifdef _WIN32_IE
#undef _WIN32_IE
#undef _WIN32_IE
#endif
#endif
#define _WIN32_IE 0x0501
#define _WIN32_IE 0x0501
#define WIN32_LEAN_AND_MEAN 1
#define WIN32_LEAN_AND_MEAN 1
#ifndef NOMINMAX
#ifndef NOMINMAX
#define NOMINMAX
#define NOMINMAX
#endif
#endif
#include "shlobj.h"
#include "shlobj.h"
#include "shlwapi.h"
#include "shlwapi.h"
#endif
#endif


#ifndef WIN32
#ifndef WIN32
#include <execinfo.h>
#include <execinfo.h>
#endif
#endif


using namespace std;
using namespace std;
using namespace boost;
using namespace boost;


map<string, string> mapArgs;
map<string, string> mapArgs;
map<string, vector<string> > mapMultiArgs;
map<string, vector<string> > mapMultiArgs;
map<string, string> mapPeercoinArgs;
map<string, string> mapPeercoinArgs;
bool fDebug = false;
bool fDebug = false;
bool fPrintToConsole = false;
bool fPrintToConsole = false;
bool fPrintToDebugger = false;
bool fPrintToDebugger = false;
bool fRequestShutdown = false;
bool fRequestShutdown = false;
bool fShutdown = false;
bool fShutdown = false;
bool fDaemon = false;
bool fDaemon = false;
bool fServer = false;
bool fServer = false;
bool fCommandLine = false;
bool fCommandLine = false;
string strMiscWarning;
string strMiscWarning;
bool fTestNet = false;
bool fTestNet = false;
bool fNoListen = false;
bool fNoListen = false;
bool fLogTimestamps = false;
bool fLogTimestamps = false;
CMedianFilter<int64> vTimeOffsets(200,0);
CMedianFilter<int64> vTimeOffsets(200,0);


// Init openssl library multithreading support
// Init openssl library multithreading support
static boost::interprocess::interprocess_mutex** ppmutexOpenSSL;
static boost::interprocess::interprocess_mutex** ppmutexOpenSSL;
void locking_callback(int mode, int i, const char* file, int line)
void locking_callback(int mode, int i, const char* file, int line)
{
{
if (mode & CRYPTO_LOCK)
if (mode & CRYPTO_LOCK)
ppmutexOpenSSL[i]->lock();
ppmutexOpenSSL[i]->lock();
else
else
ppmutexOpenSSL[i]->unlock();
ppmutexOpenSSL[i]->unlock();
}
}


// Init
// Init
class CInit
class CInit
{
{
public:
public:
CInit()
CInit()
{
{
// Init openssl library multithreading support
// Init openssl library multithreading support
ppmutexOpenSSL = (boost::interprocess::interprocess_mutex**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(boost::interprocess::interprocess_mutex*));
ppmutexOpenSSL = (boost::interprocess::interprocess_mutex**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(boost::interprocess::interprocess_mutex*));
for (int i = 0; i < CRYPTO_num_locks(); i++)
for (int i = 0; i < CRYPTO_num_locks(); i++)
ppmutexOpenSSL[i] = new boost::interprocess::interprocess_mutex();
ppmutexOpenSSL[i] = new boost::interprocess::interprocess_mutex();
CRYPTO_set_locking_callback(locking_callback);
CRYPTO_set_locking_callback(locking_callback);


#ifdef WIN32
#ifdef WIN32
// Seed random number generator with screen scrape and other hardware sources
// Seed random number generator with screen scrape and other hardware sources
RAND_screen();
RAND_screen();
#endif
#endif


// Seed random number generator with performance counter
// Seed random number generator with performance counter
RandAddSeed();
RandAddSeed();
}
}
~CInit()
~CInit()
{
{
// Shutdown openssl library multithreading support
// Shutdown openssl library multithreading support
CRYPTO_set_locking_callback(NULL);
CRYPTO_set_locking_callback(NULL);
for (int i = 0; i < CRYPTO_num_locks(); i++)
for (int i = 0; i < CRYPTO_num_locks(); i++)
delete ppmutexOpenSSL[i];
delete ppmutexOpenSSL[i];
OPENSSL_free(ppmutexOpenSSL);
OPENSSL_free(ppmutexOpenSSL);
}
}
}
}
instance_of_cinit;
instance_of_cinit;
















void RandAddSeed()
void RandAddSeed()
{
{
// Seed with CPU performance counter
// Seed with CPU performance counter
int64 nCounter = GetPerformanceCounter();
int64 nCounter = GetPerformanceCounter();
RAND_add(&nCounter, sizeof(nCounter), 1.5);
RAND_add(&nCounter, sizeof(nCounter), 1.5);
memset(&nCounter, 0, sizeof(nCounter));
memset(&nCounter, 0, sizeof(nCounter));
}
}


void RandAddSeedPerfmon()
void RandAddSeedPerfmon()
{
{
RandAddSeed();
RandAddSeed();


// This can take up to 2 seconds, so only do it every 10 minutes
// This can take up to 2 seconds, so only do it every 10 minutes
static int64 nLastPerfmon;
static int64 nLastPerfmon;
if (GetTime() < nLastPerfmon + 10 * 60)
if (GetTime() < nLastPerfmon + 10 * 60)
return;
return;
nLastPerfmon = GetTime();
nLastPerfmon = GetTime();


#ifdef WIN32
#ifdef WIN32
// Don't need this on Linux, OpenSSL automatically uses /dev/urandom
// Don't need this on Linux, OpenSSL automatically uses /dev/urandom
// Seed with the entire set of perfmon data
// Seed with the entire set of perfmon data
unsigned char pdata[250000];
unsigned char pdata[250000];
memset(pdata, 0, sizeof(pdata));
memset(pdata, 0, sizeof(pdata));
unsigned long nSize = sizeof(pdata);
unsigned long nSize = sizeof(pdata);
long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
RegCloseKey(HKEY_PERFORMANCE_DATA);
RegCloseKey(HKEY_PERFORMANCE_DATA);
if (ret == ERROR_SUCCESS)
if (ret == ERROR_SUCCESS)
{
{
RAND_add(pdata, nSize, nSize/100.0);
RAND_add(pdata, nSize, nSize/100.0);
memset(pdata, 0, nSize);
memset(pdata, 0, nSize);
printf("%s RandAddSeed() %d bytes\n", DateTimeStrFormat(GetTime()).c_str(), nSize);
printf("%s RandAddSeed() %d bytes\n", DateTimeStrFormat(GetTime()).c_str(), nSize);
}
}
#endif
#endif
}
}


uint64 GetRand(uint64 nMax)
uint64 GetRand(uint64 nMax)
{
{
if (nMax == 0)
if (nMax == 0)
return 0;
return 0;


// The range of the random source must be a multiple of the modulus
// The range of the random source must be a multiple of the modulus
// to give every possible output value an equal possibility
// to give every possible output value an equal possibility
uint64 nRange = (std::numeric_limits<uint64>::max() / nMax) * nMax;
uint64 nRange = (std::numeric_limits<uint64>::max() / nMax) * nMax;
uint64 nRand = 0;
uint64 nRand = 0;
do
do
RAND_bytes((unsigned char*)&nRand, sizeof(nRand));
RAND_bytes((unsigned char*)&nRand, sizeof(nRand));
while (nRand >= nRange);
while (nRand >= nRange);
return (nRand % nMax);
return (nRand % nMax);
}
}


int GetRandInt(int nMax)
int GetRandInt(int nMax)
{
{
return GetRand(nMax);
return GetRand(nMax);
}
}


uint256 GetRandHash()
uint256 GetRandHash()
{
{
uint256 hash;
uint256 hash;
RAND_bytes((unsigned char*)&hash, sizeof(hash));
RAND_bytes((unsigned char*)&hash, sizeof(hash));
return hash;
return hash;
}
}
















static FILE* fileout = NULL;
static FILE* fileout = NULL;


inline int OutputDebugStringF(const char* pszFormat, ...)
inline int OutputDebugStringF(const char* pszFormat, ...)
{
{
int ret = 0;
int ret = 0;
if (fPrintToConsole)
if (fPrintToConsole)
{
{
// print to console
// print to console
va_list arg_ptr;
va_list arg_ptr;
va_start(arg_ptr, pszFormat);
va_start(arg_ptr, pszFormat);
ret = vprintf(pszFormat, arg_ptr);
ret = vprintf(pszFormat, arg_ptr);
va_end(arg_ptr);
va_end(arg_ptr);
}
}
else
else
{
{
// print to debug.log
// print to debug.log
if (!fileout)
if (!fileout)
{
{
boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
fileout = fopen(pathDebug.string().c_str(), "a");
fileout = fopen(pathDebug.string().c_str(), "a");
if (fileout) setbuf(fileout, NULL); // unbuffered
if (fileout) setbuf(fileout, NULL); // unbuffered
}
}
if (fileout)
if (fileout)
{
{
static bool fStartedNewLine = true;
static bool fStartedNewLine = true;
static boost::mutex mutexDebugLog;
static boost::mutex mutexDebugLog;
boost::mutex::scoped_lock scoped_lock(mutexDebugLog);
boost::mutex::scoped_lock scoped_lock(mutexDebugLog);


// Debug print useful for profiling
// Debug print useful for profiling
if (fLogTimestamps && fStartedNewLine)
if (fLogTimestamps && fStartedNewLine)
fprintf(fileout, "%s ", DateTimeStrFormat(GetTime()).c_str());
fprintf(fileout, "%s ", DateTimeStrFormat(GetTime()).c_str());
if (pszFormat[strlen(pszFormat) - 1] == '\n')
if (pszFormat[strlen(pszFormat) - 1] == '\n')
fStartedNewLine = true;
fStartedNewLine = true;
else
else
fStartedNewLine = false;
fStartedNewLine = false;


va_list arg_ptr;
va_list arg_ptr;
va_start(arg_ptr, pszFormat);
va_start(arg_ptr, pszFormat);
ret = vfprintf(fileout, pszFormat, arg_ptr);
ret = vfprintf(fileout, pszFormat, arg_ptr);
va_end(arg_ptr);
va_end(arg_ptr);
}
}
}
}


#ifdef WIN32
#ifdef WIN32
if (fPrintToDebugger)
if (fPrintToDebugger)
{
{
static CCriticalSection cs_OutputDebugStringF;
static CCriticalSection cs_OutputDebugStringF;


// accumulate a line at a time
// accumulate a line at a time
{
{
LOCK(cs_OutputDebugStringF);
LOCK(cs_OutputDebugStringF);
static char pszBuffer[50000];
static char pszBuffer[50000];
static char* pend;
static char* pend;
if (pend == NULL)
if (pend == NULL)
pend = pszBuffer;
pend = pszBuffer;
va_list arg_ptr;
va_list arg_ptr;
va_start(arg_ptr, pszFormat);
va_start(arg_ptr, pszFormat);
int limit = END(pszBuffer) - pend - 2;
int limit = END(pszBuffer) - pend - 2;
int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr);
int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr);
va_end(arg_ptr);
va_end(arg_ptr);
if (ret < 0 || ret >= limit)
if (ret < 0 || ret >= limit)
{
{
pend = END(pszBuffer) - 2;
pend = END(pszBuffer) - 2;
*pend++ = '\n';
*pend++ = '\n';
}
}
else
else
pend += ret;
pend += ret;
*pend = '\0';
*pend = '\0';
char* p1 = pszBuffer;
char* p1 = pszBuffer;
char* p2;
char* p2;
while ((p2 = strchr(p1, '\n')))
while ((p2 = strchr(p1, '\n')))
{
{
p2++;
p2++;
char c = *p2;
char c = *p2;
*p2 = '\0';
*p2 = '\0';
OutputDebugStringA(p1);
OutputDebugStringA(p1);
*p2 = c;
*p2 = c;
p1 = p2;
p1 = p2;
}
}
if (p1 != pszBuffer)
if (p1 != pszBuffer)
memmove(pszBuffer, p1, pend - p1 + 1);
memmove(pszBuffer, p1, pend - p1 + 1);
pend -= (p1 - pszBuffer);
pend -= (p1 - pszBuffer);
}
}
}
}
#endif
#endif
return ret;
return ret;
}
}




// Safer snprintf
// Safer snprintf
// - prints up to limit-1 characters
// - prints up to limit-1 characters
// - output string is always null terminated even if limit reached
// - output string is always null terminated even if limit reached
// - return value is the number of characters actually printed
// - return value is the number of characters actually printed
int my_snprintf(char* buffer, size_t limit, const char* format, ...)
int my_snprintf(char* buffer, size_t limit, const char* format, ...)
{
{
if (limit == 0)
if (limit == 0)
return 0;
return 0;
va_list arg_ptr;
va_list arg_ptr;
va_start(arg_ptr, format);
va_start(arg_ptr, format);
int ret = _vsnprintf(buffer, limit, format, arg_ptr);
int ret = _vsnprintf(buffer, limit, format, arg_ptr);
va_end(arg_ptr);
va_end(arg_ptr);
if (ret < 0 || ret >= (int)limit)
if (ret < 0 || ret >= (int)limit)
{
{
ret = limit - 1;
ret = limit - 1;
buffer[limit-1] = 0;
buffer[limit-1] = 0;
}
}
return ret;
return ret;
}
}


string real_strprintf(const std::string &format, int dummy, ...)
string real_strprintf(const std::string &format, int dummy, ...)
{
{
char buffer[50000];
char buffer[50000];
char* p = buffer;
char* p = buffer;
int limit = sizeof(buffer);
int limit = sizeof(buffer);
int ret;
int ret;
loop
loop
{
{
va_list arg_ptr;
va_list arg_ptr;
va_start(arg_ptr, dummy);
va_start(arg_ptr, dummy);
ret = _vsnprintf(p, limit, format.c_str(), arg_ptr);
ret = _vsnprintf(p, limit, format.c_str(), arg_ptr);
va_end(arg_ptr);
va_end(arg_ptr);
if (ret >= 0 && ret < limit)
if (ret >= 0 && ret < limit)
break;
break;
if (p != buffer)
if (p != buffer)
delete[] p;
delete[] p;
limit *= 2;
limit *= 2;
p = new char[limit];
p = new char[limit];
if (p == NULL)
if (p == NULL)
throw std::bad_alloc();
throw std::bad_alloc();
}
}
string str(p, p+ret);
string str(p, p+ret);
if (p != buffer)
if (p != buffer)
delete[] p;
delete[] p;
return str;
return str;
}
}


bool error(const char *format, ...)
bool error(const char *format, ...)
{
{
char buffer[50000];
char buffer[50000];
int limit = sizeof(buffer);
int limit = sizeof(buffer);
va_list arg_ptr;
va_list arg_ptr;
va_start(arg_ptr, format);
va_start(arg_ptr, format);
int ret = _vsnprintf(buffer, limit, format, arg_ptr);
int ret = _vsnprintf(buffer, limit, format, arg_ptr);
va_end(arg_ptr);
va_end(arg_ptr);
if (ret < 0 || ret >= limit)
if (ret < 0 || ret >= limit)
{
{
buffer[limit-1] = 0;
buffer[limit-1] = 0;
}
}
printf("ERROR: %s\n", buffer);
printf("ERROR: %s\n", buffer);
return false;
return false;
}
}




void ParseString(const string& str, char c, vector<string>& v)
void ParseString(const string& str, char c, vector<string>& v)
{
{
if (str.empty())
if (str.empty())
return;
return;
string::size_type i1 = 0;
string::size_type i1 = 0;
string::size_type i2;
string::size_type i2;
loop
loop
{
{
i2 = str.find(c, i1);
i2 = str.find(c, i1);
if (i2 == str.npos)
if (i2 == str.npos)
{
{
v.push_back(str.substr(i1));
v.push_back(str.substr(i1));
return;
return;
}
}
v.push_back(str.substr(i1, i2-i1));
v.push_back(str.substr(i1, i2-i1));
i1 = i2+1;
i1 = i2+1;
}
}
}
}




string FormatMoney(int64 n, bool fPlus)
string FormatMoney(int64 n, bool fPlus)
{
{
// Note: not using straight sprintf here because we do NOT want
// Note: not using straight sprintf here because we do NOT want
// localized number formatting.
// localized number formatting.
int64 n_abs = (n > 0 ? n : -n);
int64 n_abs = (n > 0 ? n : -n);
int64 quotient = n_abs/COIN;
int64 quotient = n_abs/COIN;
int64 remainder = n_abs%COIN;
int64 remainder = n_abs%COIN;
string str = strprintf("%"PRI64d".%06"PRI64d, quotient, remainder);
string str = strprintf("%"PRI64d".%06"PRI64d, quotient, remainder);


// Right-trim excess 0's before the decimal point:
// Right-trim excess 0's before the decimal point:
int nTrim = 0;
int nTrim = 0;
for (int i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i)
for (int i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i)
++nTrim;
++nTrim;
if (nTrim)
if (nTrim)
str.erase(str.size()-nTrim, nTrim);
str.erase(str.size()-nTrim, nTrim);


if (n < 0)
if (n < 0)
str.insert((unsigned int)0, 1, '-');
str.insert((unsigned int)0, 1, '-');
else if (fPlus && n > 0)
else if (fPlus && n > 0)
str.insert((unsigned int)0, 1, '+');
str.insert((unsigned int)0, 1, '+');
return str;
return str;
}
}




bool ParseMoney(const string& str, int64& nRet)
bool ParseMoney(const string& str, int64& nRet)
{
{
return ParseMoney(str.c_str(), nRet);
return ParseMoney(str.c_str(), nRet);
}
}


bool ParseMoney(const char* pszIn, int64& nRet)
bool ParseMoney(const char* pszIn, int64& nRet)
{
{
string strWhole;
string strWhole;
int64 nUnits = 0;
int64 nUnits = 0;
const char* p = pszIn;
const char* p = pszIn;
while (isspace(*p))
while (isspace(*p))
p++;
p++;
for (; *p; p++)
for (; *p; p++)
{
{
if (*p == '.')
if (*p == '.')
{
{
p++;
p++;
int64 nMult = CENT*10;
int64 nMult = CENT*10;
while (isdigit(*p) && (nMult > 0))
while (isdigit(*p) && (nMult > 0))
{
{
nUnits += nMult * (*p++ - '0');
nUnits += nMult * (*p++ - '0');
nMult /= 10;
nMult /= 10;
}
}
break;
break;
}
}
if (isspace(*p))
if (isspace(*p))
break;
break;
if (!isdigit(*p))
if (!isdigit(*p))
return false;
return false;
strWhole.insert(strWhole.end(), *p);
strWhole.insert(strWhole.end(), *p);
}
}
for (; *p; p++)
for (; *p; p++)
if (!isspace(*p))
if (!isspace(*p))
return false;
return false;
if (strWhole.size() > 10) // guard against 63 bit overflow
if (strWhole.size() > 10) // guard against 63 bit overflow
return false;
return false;
if (nUnits < 0 || nUnits > COIN)
if (nUnits < 0 || nUnits > COIN)
return false;
return false;
int64 nWhole = atoi64(strWhole);
int64 nWhole = atoi64(strWhole);
int64 nValue = nWhole*COIN + nUnits;
int64 nValue = nWhole*COIN + nUnits;


nRet = nValue;
nRet = nValue;
return true;
return true;
}
}




static signed char phexdigit[256] =
static 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,
-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,
0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
-1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,0xa,0xb,0xc,0xd,0xe,0xf,-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,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,0xa,0xb,0xc,0xd,0xe,0xf,-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,-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,-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,-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,-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,-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,-1,-1,-1,-1,-1,-1,-1,-1,-1, };


bool IsHex(const string& str)
bool IsHex(const string& str)
{
{
BOOST_FOREACH(unsigned char c, str)
BOOST_FOREACH(unsigned char c, str)
{
{
if (phexdigit[c] < 0)
if (phexdigit[c] < 0)
return false;
return false;
}
}
return (str.size() > 0) && (str.size()%2 == 0);
return (str.size() > 0) && (str.size()%2 == 0);
}
}


vector<unsigned char> ParseHex(const char* psz)
vector<unsigned char> ParseHex(const char* psz)
{
{
// convert hex dump to vector
// convert hex dump to vector
vector<unsigned char> vch;
vector<unsigned char> vch;
loop
loop
{
{
while (isspace(*psz))
while (isspace(*psz))
psz++;
psz++;
signed char c = phexdigit[(unsigned char)*psz++];
signed char c = phexdigit[(unsigned char)*psz++];
if (c == (signed char)-1)
if (c == (signed char)-1)
break;
break;
unsigned char n = (c << 4);
unsigned char n = (c << 4);
c = phexdigit[(unsigned char)*psz++];
c = phexdigit[(unsigned char)*psz++];
if (c == (signed char)-1)
if (c == (signed char)-1)
break;
break;
n |= c;
n |= c;
vch.push_back(n);
vch.push_back(n);
}
}
return vch;
return vch;
}
}


vector<unsigned char> ParseHex(const string& str)
vector<unsigned char> ParseHex(const string& str)
{
{
return ParseHex(str.c_str());
return ParseHex(str.c_str());
}
}


static void InterpretNegativeSetting(string name, map<string, string>& mapSettingsRet)
static void InterpretNegativeSetting(string name, map<string, string>& mapSettingsRet)
{
{
// interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set
// interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set
if (name.find("-no") == 0)
if (name.find("-no") == 0)
{
{
std::string positive("-");
std::string positive("-");
positive.append(name.begin()+3, name.end());
positive.append(name.begin()+3, name.end());
if (mapSettingsRet.count(positive) == 0)
if (mapSettingsRet.count(positive) == 0)
{
{
bool value = !GetBoolArg(name);
bool value = !GetBoolArg(name);
mapSettingsRet[positive] = (value ? "1" : "0");
mapSettingsRet[positive] = (value ? "1" : "0");
}
}
}
}
}
}


void ParseParameters(int argc, const char*const argv[])
void ParseParameters(int argc, const char*const argv[])
{
{
mapArgs.clear();
mapArgs.clear();
mapMultiArgs.clear();
mapMultiArgs.clear();
for (int i = 1; i < argc; i++)
for (int i = 1; i < argc; i++)
{
{
char psz[10000];
char psz[10000];
strlcpy(psz, argv[i], sizeof(psz));
strlcpy(psz, argv[i], sizeof(psz));
char* pszValue = (char*)"";
char* pszValue = (char*)"";
if (strchr(psz, '='))
if (strchr(psz, '='))
{
{
pszValue = strchr(psz, '=');
pszValue = strchr(psz, '=');
*pszValue++ = '\0';
*pszValue++ = '\0';
}
}
#ifdef WIN32
#ifdef WIN32
_strlwr(psz);
_strlwr(psz);
if (psz[0] == '/')
if (psz[0] == '/')
psz[0] = '-';
psz[0] = '-';
#endif
#endif
if (psz[0] != '-')
if (psz[0] != '-')
break;
break;


mapArgs[psz] = pszValue;
mapArgs[psz] = pszValue;
mapMultiArgs[psz].push_back(pszValue);
mapMultiArgs[psz].push_back(pszValue);
}
}


// New 0.6 features:
// New 0.6 features:
BOOST_FOREACH(const PAIRTYPE(string,string)& entry, mapArgs)
BOOST_FOREACH(const PAIRTYPE(string,string)& entry, mapArgs)
{
{
string name = entry.first;
string name = entry.first;


// interpret --foo as -foo (as long as both are not set)
// interpret --foo as -foo (as long as both are not set)
if (name.find("--") == 0)
if (name.find("--") == 0)
{
{
std::string singleDash(name.begin()+1, name.end());
std::string singleDash(name.begin()+1, name.end());
if (mapArgs.count(singleDash) == 0)
if (mapArgs.count(singleDash) == 0)
mapArgs[singleDash] = entry.second;
mapArgs[singleDash] = entry.second;
name = singleDash;
name = singleDash;
}
}


// interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set
// interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set
InterpretNegativeSetting(name, mapArgs);
InterpretNegativeSetting(name, mapArgs);
}
}
}
}


std::string GetArg(const std::string& strArg, const std::string& strDefault)
std::string GetArg(const std::string& strArg, const std::string& strDefault)
{
{
if (mapArgs.count(strArg))
if (mapArgs.count(strArg))
return mapArgs[strArg];
return mapArgs[strArg];
return strDefault;
return strDefault;
}
}


std::string GetPeercoinArg(const std::string& strArg, const std::string& strDefault)
std::string GetPeercoinArg(const std::string& strArg, const std::string& strDefault)
{
{
if (mapPeercoinArgs.count(strArg))
if (mapPeercoinArgs.count(strArg))
return mapPeercoinArgs[strArg];
return mapPeercoinArgs[strArg];
return strDefault;
return strDefault;
}
}


int64 GetArg(const std::string& strArg, int64 nDefault)
int64 GetArg(const std::string& strArg, int64 nDefault)
{
{
if (mapArgs.count(strArg))
if (mapArgs.count(strArg))
return atoi64(mapArgs[strArg]);
return atoi64(mapArgs[strArg]);
return nDefault;
return nDefault;
}
}


int64 GetPeercoinArg(const std::string& strArg, int64 nDefault)
int64 GetPeercoinArg(const std::string& strArg, int64 nDefault)
{
{
if (mapPeercoinArgs.count(strArg))
if (mapPeercoinArgs.count(strArg))
return atoi64(mapPeercoinArgs[strArg]);
return atoi64(mapPeercoinArgs[strArg]);
return nDefault;
return nDefault;
}
}


bool GetBoolArg(const std::string& strArg, bool fDefault)
bool GetBoolArg(const std::string& strArg, bool fDefault)
{
{
if (mapArgs.count(strArg))
if (mapArgs.count(strArg))
{
{
if (mapArgs[strArg].empty())
if (mapArgs[strArg].empty())
return true;
return true;
return (atoi(mapArgs[strArg]) != 0);
return (atoi(mapArgs[strArg]) != 0);
}
}
return fDefault;
return fDefault;
}
}


bool GetPeercoinBoolArg(const std::string& strArg, bool fDefault)
bool GetPeercoinBoolArg(const std::string& strArg, bool fDefault)
{
{
if (mapPeercoinArgs.count(strArg))
if (mapPeercoinArgs.count(strArg))
{
{
if (mapPeercoinArgs[strArg].empty())
if (mapPeercoinArgs[strArg].empty())
return true;
return true;
return (atoi(mapPeercoinArgs[strArg]) != 0);
return (atoi(mapPeercoinArgs[strArg]) != 0);
}
}
return fDefault;
return fDefault;
}
}


bool SoftSetArg(const std::string& strArg, const std::string& strValue)
bool SoftSetArg(const std::string& strArg, const std::string& strValue)
{
{
if (mapArgs.count(strArg))
if (mapArgs.count(strArg))
return false;
return false;
mapArgs[strArg] = strValue;
mapArgs[strArg] = strValue;
return true;
return true;
}
}


bool SoftSetBoolArg(const std::string& strArg, bool fValue)
bool 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"));
}
}




string EncodeBase64(const unsigned char* pch, size_t len)
string EncodeBase64(const unsigned char* pch, size_t len)
{
{
static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";


string strRet="";
string strRet="";
strRet.reserve((len+2)/3*4);
strRet.reserve((len+2)/3*4);


int mode=0, left=0;
int mode=0, left=0;
const unsigned char *pchEnd = pch+len;
const unsigned char *pchEnd = pch+len;


while (pch<pchEnd)
while (pch<pchEnd)
{
{
int enc = *(pch++);
int enc = *(pch++);
switch (mode)
switch (mode)
{
{
case 0: // we have no bits
case 0: // we have no bits
strRet += pbase64[enc >> 2];
strRet += pbase64[enc >> 2];
left = (enc & 3) << 4;
left = (enc & 3) << 4;
mode = 1;
mode = 1;
break;
break;


case 1: // we have two bits
case 1: // we have two bits
strRet += pbase64[left | (enc >> 4)];
strRet += pbase64[left | (enc >> 4)];
left = (enc & 15) << 2;
left = (enc & 15) << 2;
mode = 2;
mode = 2;
break;
break;


case 2: // we have four bits
case 2: // we have four bits
strRet += pbase64[left | (enc >> 6)];
strRet += pbase64[left | (enc >> 6)];
strRet += pbase64[enc & 63];
strRet += pbase64[enc & 63];
mode = 0;
mode = 0;
break;
break;
}
}
}
}


if (mode)
if (mode)
{
{
strRet += pbase64[left];
strRet += pbase64[left];
strRet += '=';
strRet += '=';
if (mode == 1)
if (mode == 1)
strRet += '=';
strRet += '=';
}
}


return strRet;
return strRet;
}
}


string EncodeBase64(const string& str)
string EncodeBase64(const string& str)
{
{
return EncodeBase64((const unsigned char*)str.c_str(), str.size());
return EncodeBase64((const unsigned char*)str.c_str(), str.size());
}
}


vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid)
vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid)
{
{
static const int decode64_table[256] =
static const int decode64_table[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, -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, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
-1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
-1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
-1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
49, 50, 51, -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, -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, -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, -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, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
};


if (pfInvalid)
if (pfInvalid)
*pfInvalid = false;
*pfInvalid = false;


vector<unsigned char> vchRet;
vector<unsigned char> vchRet;
vchRet.reserve(strlen(p)*3/4);
vchRet.reserve(strlen(p)*3/4);


int mode = 0;
int mode = 0;
int left = 0;
int left = 0;


while (1)
while (1)
{
{
int dec = decode64_table[(unsigned char)*p];
int dec = decode64_table[(unsigned char)*p];
if (dec == -1) break;
if (dec == -1) break;
p++;
p++;
switch (mode)
switch (mode)
{
{
case 0: // we have no bits and get 6
case 0: // we have no bits and get 6
left = dec;
left = dec;
mode = 1;
mode = 1;
break;
break;


case 1: // we have 6 bits and keep 4
case 1: // we have 6 bits and keep 4
vchRet.push_back((left<<2) | (dec>>4));
vchRet.push_back((left<<2) | (dec>>4));
left = dec & 15;
left = dec & 15;
mode = 2;
mode = 2;
break;
break;


case 2: // we have 4 bits and get 6, we keep 2
case 2: // we have 4 bits and get 6, we keep 2
vchRet.push_back((left<<4) | (dec>>2));
vchRet.push_back((left<<4) | (dec>>2));
left = dec & 3;
left = dec & 3;
mode = 3;
mode = 3;
break;
break;


case 3: // we have 2 bits and get 6
case 3: // we have 2 bits and get 6
vchRet.push_back((left<<6) | dec);
vchRet.push_back((left<<6) | dec);
mode = 0;
mode = 0;
break;
break;
}
}
}
}


if (pfInvalid)
if (pfInvalid)
switch (mode)
switch (mode)
{
{
case 0: // 4n base64 characters processed: ok
case 0: // 4n base64 characters processed: ok
break;
break;


case 1: // 4n+1 base64 character processed: impossible
case 1: // 4n+1 base64 character processed: impossible
*pfInvalid = true;
*pfInvalid = true;
break;
break;


case 2: // 4n+2 base64 characters processed: require '=='
case 2: // 4n+2 base64 characters processed: require '=='
if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1)
if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1)
*pfInvalid = true;
*pfInvalid = true;
break;
break;


case 3: // 4n+3 base64 characters processed: require '='
case 3: // 4n+3 base64 characters processed: require '='
if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1)
if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1)
*pfInvalid = true;
*pfInvalid = true;
break;
break;
}
}


return vchRet;
return vchRet;
}
}


string DecodeBase64(const string& str)
string DecodeBase64(const string& str)
{
{
vector<unsigned char> vchRet = DecodeBase64(str.c_str());
vector<unsigned char> vchRet = DecodeBase64(str.c_str());
return string((const char*)&vchRet[0], vchRet.size());
return string((const char*)&vchRet[0], vchRet.size());
}
}




bool WildcardMatch(const char* psz, const char* mask)
bool WildcardMatch(const char* psz, const char* mask)
{
{
loop
loop
{
{
switch (*mask)
switch (*mask)
{
{
case '\0':
case '\0':
return (*psz == '\0');
return (*psz == '\0');
case '*':
case '*':
return WildcardMatch(psz, mask+1) || (*psz && WildcardMatch(psz+1, mask));
return WildcardMatch(psz, mask+1) || (*psz && WildcardMatch(psz+1, mask));
case '?':
case '?':
if (*psz == '\0')
if (*psz == '\0')
return false;
return false;
break;
break;
default:
default:
if (*psz != *mask)
if (*psz != *mask)
return false;
return false;
break;
break;
}
}
psz++;
psz++;
mask++;
mask++;
}
}
}
}


bool WildcardMatch(const string& str, const string& mask)
bool WildcardMatch(const string& str, const string& mask)
{
{
return WildcardMatch(str.c_str(), mask.c_str());
return WildcardMatch(str.c_str(), mask.c_str());
}
}
















void FormatException(char* pszMessage, std::exception* pex, const char* pszThread)
void FormatException(char* pszMessage, std::exception* pex, const char* pszThread)
{
{
#ifdef WIN32
#ifdef WIN32
char pszModule[MAX_PATH];
char pszModule[MAX_PATH];
pszModule[0] = '\0';
pszModule[0] = '\0';
GetModuleFileNameA(NULL, pszModule, sizeof(pszModule));
GetModuleFileNameA(NULL, pszModule, sizeof(pszModule));
#else
#else
const char* pszModule = "peershares";
const char* pszModule = "decent";
#endif
#endif
if (pex)
if (pex)
snprintf(pszMessage, 1000,
snprintf(pszMessage, 1000,
"EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
"EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
else
else
snprintf(pszMessage, 1000,
snprintf(pszMessage, 1000,
"UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread);
"UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread);
}
}


void LogException(std::exception* pex, const char* pszThread)
void LogException(std::exception* pex, const char* pszThread)
{
{
char pszMessage[10000];
char pszMessage[10000];
FormatException(pszMessage, pex, pszThread);
FormatException(pszMessage, pex, pszThread);
printf("\n%s", pszMessage);
printf("\n%s", pszMessage);
}
}


void PrintException(std::exception* pex, const char* pszThread)
void PrintException(std::exception* pex, const char* pszThread)
{
{
char pszMessage[10000];
char pszMessage[10000];
FormatException(pszMessage, pex, pszThread);
FormatException(pszMessage, pex, pszThread);
printf("\n\n************************\n%s\n", pszMessage);
printf("\n\n************************\n%s\n", pszMessage);
fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
strMiscWarning = pszMessage;
strMiscWarning = pszMessage;
throw;
throw;
}
}


void LogStackTrace() {
void LogStackTrace() {
printf("\n\n******* exception encountered *******\n");
printf("\n\n******* exception encountered *******\n");
if (fileout)
if (fileout)
{
{
#ifndef WIN32
#ifndef WIN32
void* pszBuffer[32];
void* pszBuffer[32];
size_t size;
size_t size;
size = backtrace(pszBuffer, 32);
size = backtrace(pszBuffer, 32);
backtrace_symbols_fd(pszBuffer, size, fileno(fileout));
backtrace_symbols_fd(pszBuffer, size, fileno(fileout));
#endif
#endif
}
}
}
}


void PrintExceptionContinue(std::exception* pex, const char* pszThread)
void PrintExceptionContinue(std::exception* pex, const char* pszThread)
{
{
char pszMessage[10000];
char pszMessage[10000];
FormatException(pszMessage, pex, pszThread);
FormatException(pszMessage, pex, pszThread);
printf("\n\n************************\n%s\n", pszMessage);
printf("\n\n************************\n%s\n", pszMessage);
fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
strMiscWarning = pszMessage;
strMiscWarning = pszMessage;
}
}


#ifdef WIN32
#ifdef WIN32
boost::filesystem::path MyGetSpecialFolderPath(int nFolder, bool fCreate)
boost::filesystem::path MyGetSpecialFolderPath(int nFolder, bool fCreate)
{
{
namespace fs = boost::filesystem;
namespace fs = boost::filesystem;


char pszPath[MAX_PATH] = "";
char pszPath[MAX_PATH] = "";
if(SHGetSpecialFolderPathA(NULL, pszPath, nFolder, fCreate))
if(SHGetSpecialFolderPathA(NULL, pszPath, nFolder, fCreate))
{
{
return fs::path(pszPath);
return fs::path(pszPath);
}
}
else if (nFolder == CSIDL_STARTUP)
else if (nFolder == CSIDL_STARTUP)
{
{
return fs::path(getenv("USERPROFILE")) / "Start Menu" / "Programs" / "Startup";
return fs::path(getenv("USERPROFILE")) / "Start Menu" / "Programs" / "Startup";
}
}
else if (nFolder == CSIDL_APPDATA)
else if (nFolder == CSIDL_APPDATA)
{
{
return fs::path(getenv("APPDATA"));
return fs::path(getenv("APPDATA"));
}
}
return fs::path("");
return fs::path("");
}
}
#endif
#endif


boost::filesystem::path GetDefaultDataDir()
boost::filesystem::path GetDefaultDataDir()
{
{
namespace fs = boost::filesystem;
namespace fs = boost::filesystem;


// Windows: C:\Documents and Settings\username\Application Data\PPCoin
// Windows: C:\Documents and Settings\username\Application Data\Decent
// Mac: ~/Library/Application Support/PPCoin
// Mac: ~/Library/Application Support/Decent
// Unix: ~/.peershares
// Unix: ~/.decent
#ifdef WIN32
#ifdef WIN32
// Windows
// Windows
return MyGetSpecialFolderPath(CSIDL_APPDATA, true) / "Peershares";
return MyGetSpecialFolderPath(CSIDL_APPDATA, true) / "Decent";
#else
#else
fs::path pathRet;
fs::path pathRet;
char* pszHome = getenv("HOME");
char* pszHome = getenv("HOME");
if (pszHome == NULL || strlen(pszHome) == 0)
if (pszHome == NULL || strlen(pszHome) == 0)
pathRet = fs::path("/");
pathRet = fs::path("/");
else
else
pathRet = fs::path(pszHome);
pathRet = fs::path(pszHome);
#ifdef MAC_OSX
#ifdef MAC_OSX
// Mac
// Mac
pathRet /= "Library/Application Support";
pathRet /= "Library/Application Support";
fs::create_directory(pathRet);
fs::create_directory(pathRet);
return pathRet / "Peershares";
return pathRet / "Decent";
#else
#else
// Unix
// Unix
return pathRet / ".peershares";
return pathRet / ".decent";
#endif
#endif
#endif
#endif
}
}


boost::filesystem::path GetDefaultPeercoinDataDir()
boost::filesystem::path GetDefaultPeercoinDataDir()
{
{
namespace fs = boost::filesystem;
namespace fs = boost::filesystem;


// Windows: C:\Documents and Settings\username\Application Data\PPCoin
// Windows: C:\Documents and Settings\username\Application Data\PPCoin
// Mac: ~/Library/Application Support/PPCoin
// Mac: ~/Library/Application Support/PPCoin
// Unix: ~/.peershares
// Unix: ~/.peershares
#ifdef WIN32
#ifdef WIN32
// Windows
// Windows
return MyGetSpecialFolderPath(CSIDL_APPDATA, true) / "PPCoin";
return MyGetSpecialFolderPath(CSIDL_APPDATA, true) / "PPCoin";
#else
#else
fs::path pathRet;
fs::path pathRet;
char* pszHome = getenv("HOME");
char* pszHome = getenv("HOME");
if (pszHome == NULL || strlen(pszHome) == 0)
if (pszHome == NULL || strlen(pszHome) == 0)
pathRet = fs::path("/");
pathRet = fs::path("/");
else
else
pathRet = fs::path(pszHome);
pathRet = fs::path(pszHome);
#ifdef MAC_OSX
#ifdef MAC_OSX
// Mac
// Mac
pathRet /= "Library/Application Support";
pathRet /= "Library/Application Support";
fs::create_directory(pathRet);
fs::create_directory(pathRet);
return pathRet / "PPCoin";
return p
#else