// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
+// Copyright (c) 2011-2012 The PPCoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "headers.h"
+#include "util.h"
#include "strlcpy.h"
+#include "version.h"
+#include "ui_interface.h"
#include <boost/algorithm/string/join.hpp>
// Work around clang compilation problem in Boost 1.46:
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
#include <boost/foreach.hpp>
+#include <boost/thread.hpp>
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+
+#ifdef WIN32
+#ifdef _MSC_VER
+#pragma warning(disable:4786)
+#pragma warning(disable:4804)
+#pragma warning(disable:4805)
+#pragma warning(disable:4717)
+#endif
+#ifdef _WIN32_WINNT
+#undef _WIN32_WINNT
+#endif
+#define _WIN32_WINNT 0x0501
+#ifdef _WIN32_IE
+#undef _WIN32_IE
+#endif
+#define _WIN32_IE 0x0400
+#define WIN32_LEAN_AND_MEAN 1
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#include "shlobj.h"
+#include "shlwapi.h"
+#endif
+
+#ifndef WIN32
+#include <execinfo.h>
+#endif
using namespace std;
using namespace boost;
{
RAND_add(pdata, nSize, nSize/100.0);
memset(pdata, 0, nSize);
- printf("%s RandAddSeed() %d bytes\n", DateTimeStrFormat("%x %H:%M", GetTime()).c_str(), nSize);
+ printf("%s RandAddSeed() %d bytes\n", DateTimeStrFormat(GetTime()).c_str(), nSize);
}
#endif
}
return GetRand(nMax);
}
+uint256 GetRandHash()
+{
+ uint256 hash;
+ RAND_bytes((unsigned char*)&hash, sizeof(hash));
+ return hash;
+}
-
+static FILE* fileout = NULL;
inline int OutputDebugStringF(const char* pszFormat, ...)
{
else
{
// print to debug.log
- static FILE* fileout = NULL;
-
if (!fileout)
{
boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
if (fileout)
{
static bool fStartedNewLine = true;
+ static boost::mutex mutexDebugLog;
+ boost::mutex::scoped_lock scoped_lock(mutexDebugLog);
// Debug print useful for profiling
if (fLogTimestamps && fStartedNewLine)
- fprintf(fileout, "%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
+ fprintf(fileout, "%s ", DateTimeStrFormat(GetTime()).c_str());
if (pszFormat[strlen(pszFormat) - 1] == '\n')
fStartedNewLine = true;
else
*pend = '\0';
char* p1 = pszBuffer;
char* p2;
- while (p2 = strchr(p1, '\n'))
+ while ((p2 = strchr(p1, '\n')))
{
p2++;
char c = *p2;
va_start(arg_ptr, format);
int ret = _vsnprintf(buffer, limit, format, arg_ptr);
va_end(arg_ptr);
- if (ret < 0 || ret >= limit)
+ if (ret < 0 || ret >= (int)limit)
{
ret = limit - 1;
buffer[limit-1] = 0;
va_end(arg_ptr);
if (ret < 0 || ret >= limit)
{
- ret = limit - 1;
buffer[limit-1] = 0;
}
printf("ERROR: %s\n", buffer);
int64 n_abs = (n > 0 ? n : -n);
int64 quotient = n_abs/COIN;
int64 remainder = n_abs%COIN;
- string str = strprintf("%"PRI64d".%08"PRI64d, quotient, remainder);
+ string str = strprintf("%"PRI64d".%06"PRI64d, quotient, remainder);
// Right-trim excess 0's before the decimal point:
int nTrim = 0;
}
-static 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,
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,-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,
{
while (isspace(*psz))
psz++;
- char c = phexdigit[(unsigned char)*psz++];
- if (c == (char)-1)
+ signed char c = phexdigit[(unsigned char)*psz++];
+ if (c == (signed char)-1)
break;
unsigned char n = (c << 4);
c = phexdigit[(unsigned char)*psz++];
- if (c == (char)-1)
+ if (c == (signed char)-1)
break;
n |= c;
vch.push_back(n);
while (1)
{
- int dec = decode64_table[*p];
+ int dec = decode64_table[(unsigned char)*p];
if (dec == -1) break;
p++;
switch (mode)
break;
case 2: // 4n+2 base64 characters processed: require '=='
- if (left || p[0] != '=' || p[1] != '=' || decode64_table[p[2]] != -1)
+ if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1)
*pfInvalid = true;
break;
case 3: // 4n+3 base64 characters processed: require '='
- if (left || p[0] != '=' || decode64_table[p[1]] != -1)
+ if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1)
*pfInvalid = true;
break;
}
pszModule[0] = '\0';
GetModuleFileNameA(NULL, pszModule, sizeof(pszModule));
#else
- const char* pszModule = "bitcoin";
+ const char* pszModule = "ppcoin";
#endif
if (pex)
snprintf(pszMessage, 1000,
throw;
}
+void LogStackTrace() {
+ printf("\n\n******* exception encountered *******\n");
+ if (fileout)
+ {
+#ifndef WIN32
+ void* pszBuffer[32];
+ size_t size;
+ size = backtrace(pszBuffer, 32);
+ backtrace_symbols_fd(pszBuffer, size, fileno(fileout));
+#endif
+ }
+}
+
void PrintExceptionContinue(std::exception* pex, const char* pszThread)
{
char pszMessage[10000];
{
namespace fs = boost::filesystem;
- // Windows: C:\Documents and Settings\username\Application Data\Bitcoin
- // Mac: ~/Library/Application Support/Bitcoin
- // Unix: ~/.bitcoin
+ // Windows: C:\Documents and Settings\username\Application Data\PPCoin
+ // Mac: ~/Library/Application Support/PPCoin
+ // Unix: ~/.ppcoin
#ifdef WIN32
// Windows
- return MyGetSpecialFolderPath(CSIDL_APPDATA, true) / "Bitcoin";
+ return MyGetSpecialFolderPath(CSIDL_APPDATA, true) / "PPCoin";
#else
fs::path pathRet;
char* pszHome = getenv("HOME");
#ifdef MAC_OSX
// Mac
pathRet /= "Library/Application Support";
- filesystem::create_directory(pathRet);
- return pathRet / "Bitcoin";
+ fs::create_directory(pathRet);
+ return pathRet / "PPCoin";
#else
// Unix
- return pathRet / ".bitcoin";
+ return pathRet / ".ppcoin";
#endif
#endif
}
LOCK(csPathCached);
if (mapArgs.count("-datadir")) {
- path = mapArgs["-datadir"];
+ path = fs::system_complete(mapArgs["-datadir"]);
+ if (!fs::is_directory(path)) {
+ path = "";
+ return path;
+ }
} else {
path = GetDefaultDataDir();
}
{
namespace fs = boost::filesystem;
- fs::path pathConfigFile(GetArg("-conf", "bitcoin.conf"));
+ fs::path pathConfigFile(GetArg("-conf", "ppcoin.conf"));
if (!pathConfigFile.is_complete()) pathConfigFile = GetDataDir(false) / pathConfigFile;
return pathConfigFile;
}
-bool ReadConfigFile(map<string, string>& mapSettingsRet,
+void ReadConfigFile(map<string, string>& mapSettingsRet,
map<string, vector<string> >& mapMultiSettingsRet)
{
namespace fs = boost::filesystem;
fs::ifstream streamConfig(GetConfigFile());
if (!streamConfig.good())
- return true; // No bitcoin.conf file is OK
+ return; // No bitcoin.conf file is OK
set<string> setOptions;
setOptions.insert("*");
}
mapMultiSettingsRet[strKey].push_back(it->value[0]);
}
- return true;
}
boost::filesystem::path GetPidFile()
{
namespace fs = boost::filesystem;
- fs::path pathPidFile(GetArg("-pid", "bitcoind.pid"));
+ fs::path pathPidFile(GetArg("-pid", "ppcoind.pid"));
if (!pathPidFile.is_complete()) pathPidFile = GetDataDir() / pathPidFile;
return pathPidFile;
}
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.");
+ string strMessage = _("Warning: Please check that your computer's date and time are correct. If your clock is wrong PPCoin will not work properly.");
strMiscWarning = strMessage;
printf("*** %s\n", strMessage.c_str());
- ThreadSafeMessageBox(strMessage+" ", string("Bitcoin"), wxOK | wxICON_EXCLAMATION);
+ ThreadSafeMessageBox(strMessage+" ", string("PPCoin"), wxOK | wxICON_EXCLAMATION);
}
}
}
return ss.str();
}
+#ifdef WIN32
+boost::filesystem::path static StartupShortcutPath()
+{
+ return MyGetSpecialFolderPath(CSIDL_STARTUP, true) / "PPCoin.lnk";
+}
+
+bool GetStartOnSystemStartup()
+{
+ return filesystem::exists(StartupShortcutPath());
+}
+
+bool SetStartOnSystemStartup(bool fAutoStart)
+{
+ // If the shortcut exists already, remove it for updating
+ boost::filesystem::remove(StartupShortcutPath());
+
+ if (fAutoStart)
+ {
+ CoInitialize(NULL);
+
+ // Get a pointer to the IShellLink interface.
+ IShellLink* psl = NULL;
+ HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
+ CLSCTX_INPROC_SERVER, IID_IShellLink,
+ reinterpret_cast<void**>(&psl));
+
+ if (SUCCEEDED(hres))
+ {
+ // Get the current executable path
+ TCHAR pszExePath[MAX_PATH];
+ GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
+
+ TCHAR pszArgs[5] = TEXT("-min");
+
+ // Set the path to the shortcut target
+ psl->SetPath(pszExePath);
+ PathRemoveFileSpec(pszExePath);
+ psl->SetWorkingDirectory(pszExePath);
+ psl->SetShowCmd(SW_SHOWMINNOACTIVE);
+ psl->SetArguments(pszArgs);
+
+ // Query IShellLink for the IPersistFile interface for
+ // saving the shortcut in persistent storage.
+ IPersistFile* ppf = NULL;
+ hres = psl->QueryInterface(IID_IPersistFile,
+ reinterpret_cast<void**>(&ppf));
+ if (SUCCEEDED(hres))
+ {
+ WCHAR pwsz[MAX_PATH];
+ // Ensure that the string is ANSI.
+ MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().string().c_str(), -1, pwsz, MAX_PATH);
+ // Save the link by calling IPersistFile::Save.
+ hres = ppf->Save(pwsz, TRUE);
+ ppf->Release();
+ psl->Release();
+ CoUninitialize();
+ return true;
+ }
+ psl->Release();
+ }
+ CoUninitialize();
+ return false;
+ }
+ return true;
+}
+
+#elif defined(LINUX)
+
+// Follow the Desktop Application Autostart Spec:
+// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
+
+boost::filesystem::path static GetAutostartDir()
+{
+ namespace fs = boost::filesystem;
+
+ char* pszConfigHome = getenv("XDG_CONFIG_HOME");
+ if (pszConfigHome) return fs::path(pszConfigHome) / "autostart";
+ char* pszHome = getenv("HOME");
+ if (pszHome) return fs::path(pszHome) / ".config" / "autostart";
+ return fs::path();
+}
+
+boost::filesystem::path static GetAutostartFilePath()
+{
+ return GetAutostartDir() / "ppcoin.desktop";
+}
+
+bool GetStartOnSystemStartup()
+{
+ boost::filesystem::ifstream optionFile(GetAutostartFilePath());
+ if (!optionFile.good())
+ return false;
+ // Scan through file for "Hidden=true":
+ string line;
+ while (!optionFile.eof())
+ {
+ getline(optionFile, line);
+ if (line.find("Hidden") != string::npos &&
+ line.find("true") != string::npos)
+ return false;
+ }
+ optionFile.close();
+
+ return true;
+}
+
+bool SetStartOnSystemStartup(bool fAutoStart)
+{
+ if (!fAutoStart)
+ boost::filesystem::remove(GetAutostartFilePath());
+ else
+ {
+ char pszExePath[MAX_PATH+1];
+ memset(pszExePath, 0, sizeof(pszExePath));
+ if (readlink("/proc/self/exe", pszExePath, sizeof(pszExePath)-1) == -1)
+ return false;
+
+ boost::filesystem::create_directories(GetAutostartDir());
+
+ boost::filesystem::ofstream optionFile(GetAutostartFilePath(), ios_base::out|ios_base::trunc);
+ if (!optionFile.good())
+ return false;
+ // Write a bitcoin.desktop file to the autostart directory:
+ optionFile << "[Desktop Entry]\n";
+ optionFile << "Type=Application\n";
+ optionFile << "Name=PPCoin\n";
+ optionFile << "Exec=" << pszExePath << " -min\n";
+ optionFile << "Terminal=false\n";
+ optionFile << "Hidden=false\n";
+ optionFile.close();
+ }
+ return true;
+}
+#else
+
+// TODO: OSX startup stuff; see:
+// http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html
+
+bool GetStartOnSystemStartup() { return false; }
+bool SetStartOnSystemStartup(bool fAutoStart) { return false; }
+
+#endif
+
#ifdef DEBUG_LOCKORDER