// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
-// Copyright (c) 2012 The PPCoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_UTIL_H
#include <sys/time.h>
#include <sys/resource.h>
#else
-typedef int pid_t; /* define for windows compatiblity */
+typedef int pid_t; /* define for Windows compatibility */
#endif
#include <map>
#include <vector>
#include <boost/thread.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/path.hpp>
-#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
-#include <boost/interprocess/sync/scoped_lock.hpp>
-#include <boost/interprocess/sync/interprocess_semaphore.hpp>
-#include <boost/interprocess/sync/lock_options.hpp>
#include <boost/date_time/gregorian/gregorian_types.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
static const int64 COIN = 1000000;
static const int64 CENT = 10000;
-#define loop for (;;)
#define BEGIN(a) ((char*)&(a))
#define END(a) ((char*)&((&(a))[1]))
#define UBEGIN(a) ((unsigned char*)&(a))
#define UEND(a) ((unsigned char*)&((&(a))[1]))
#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0]))
-#define printf OutputDebugStringF
-#ifdef snprintf
-#undef snprintf
-#endif
-#define snprintf my_snprintf
+#define UVOIDBEGIN(a) ((void*)&(a))
+#define CVOIDBEGIN(a) ((const void*)&(a))
+#define UINTBEGIN(a) ((uint32_t*)&(a))
+#define CUINTBEGIN(a) ((const uint32_t*)&(a))
#ifndef PRI64d
#if defined(_MSC_VER) || defined(__MSVCRT__)
#endif
#endif
+#ifndef THROW_WITH_STACKTRACE
+#define THROW_WITH_STACKTRACE(exception) \
+{ \
+ LogStackTrace(); \
+ throw (exception); \
+}
+void LogStackTrace();
+#endif
+
+
+/* Format characters for (s)size_t and ptrdiff_t */
+#if defined(_MSC_VER) || defined(__MSVCRT__)
+ /* (s)size_t and ptrdiff_t have the same size specifier in MSVC:
+ http://msdn.microsoft.com/en-us/library/tcxf1dw6%28v=vs.100%29.aspx
+ */
+ #define PRIszx "Ix"
+ #define PRIszu "Iu"
+ #define PRIszd "Id"
+ #define PRIpdx "Ix"
+ #define PRIpdu "Iu"
+ #define PRIpdd "Id"
+#else /* C99 standard */
+ #define PRIszx "zx"
+ #define PRIszu "zu"
+ #define PRIszd "zd"
+ #define PRIpdx "tx"
+ #define PRIpdu "tu"
+ #define PRIpdd "td"
+#endif
+
// This is needed because the foreach macro can't get over the comma in pair<t1, t2>
#define PAIRTYPE(t1, t2) std::pair<t1, t2>
#define S_IRUSR 0400
#define S_IWUSR 0200
#endif
-#define unlink _unlink
#else
-#define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d)
-#define strlwr(psz) to_lower(psz)
-#define _strlwr(psz) to_lower(psz)
#define MAX_PATH 1024
inline void Sleep(int64 n)
{
}
#endif
-#ifndef THROW_WITH_STACKTRACE
-#define THROW_WITH_STACKTRACE(exception) \
-{ \
- LogStackTrace(); \
- throw (exception); \
-}
-void LogStackTrace();
+/* This GNU C extension enables the compiler to check the format string against the parameters provided.
+ * X is the number of the "format string" parameter, and Y is the number of the first variadic parameter.
+ * Parameters count from 1.
+ */
+#ifdef __GNUC__
+#define ATTR_WARN_PRINTF(X,Y) __attribute__((format(printf,X,Y)))
+#else
+#define ATTR_WARN_PRINTF(X,Y)
#endif
+
+
extern std::map<std::string, std::string> mapArgs;
extern std::map<std::string, std::vector<std::string> > mapMultiArgs;
extern bool fDebug;
+extern bool fDebugNet;
extern bool fPrintToConsole;
extern bool fPrintToDebugger;
extern bool fRequestShutdown;
extern bool fTestNet;
extern bool fNoListen;
extern bool fLogTimestamps;
+extern bool fReopenDebugLog;
void RandAddSeed();
void RandAddSeedPerfmon();
-int OutputDebugStringF(const char* pszFormat, ...);
-int my_snprintf(char* buffer, size_t limit, const char* format, ...);
+int ATTR_WARN_PRINTF(1,2) OutputDebugStringF(const char* pszFormat, ...);
-/* It is not allowed to use va_start with a pass-by-reference argument.
- (C++ standard, 18.7, paragraph 3). Use a dummy argument to work around this, and use a
- macro to keep similar semantics.
+/*
+ Rationale for the real_strprintf / strprintf construction:
+ It is not allowed to use va_start with a pass-by-reference argument.
+ (C++ standard, 18.7, paragraph 3). Use a dummy argument to work around this, and use a
+ macro to keep similar semantics.
*/
+
+/** Overload strprintf for char*, so that GCC format type warnings can be given */
+std::string ATTR_WARN_PRINTF(1,3) real_strprintf(const char *format, int dummy, ...);
+/** Overload strprintf for std::string, to be able to use it with _ (translation).
+ * This will not support GCC format type warnings (-Wformat) so be careful.
+ */
std::string real_strprintf(const std::string &format, int dummy, ...);
#define strprintf(format, ...) real_strprintf(format, 0, __VA_ARGS__)
+std::string vstrprintf(const char *format, va_list ap);
+
+bool ATTR_WARN_PRINTF(1,2) error(const char *format, ...);
+
+/* Redefine printf so that it directs output to debug.log
+ *
+ * Do this *after* defining the other printf-like functions, because otherwise the
+ * __attribute__((format(printf,X,Y))) gets expanded to __attribute__((format(OutputDebugStringF,X,Y)))
+ * which confuses gcc.
+ */
+#define printf OutputDebugStringF
-bool error(const char *format, ...);
void LogException(std::exception* pex, const char* pszThread);
void PrintException(std::exception* pex, const char* pszThread);
void PrintExceptionContinue(std::exception* pex, const char* pszThread);
std::string DecodeBase64(const std::string& str);
std::string EncodeBase64(const unsigned char* pch, size_t len);
std::string EncodeBase64(const std::string& str);
+std::vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid = NULL);
+std::string DecodeBase32(const std::string& str);
+std::string EncodeBase32(const unsigned char* pch, size_t len);
+std::string EncodeBase32(const std::string& str);
void ParseParameters(int argc, const char*const argv[]);
bool WildcardMatch(const char* psz, const char* mask);
bool WildcardMatch(const std::string& str, const std::string& mask);
+void FileCommit(FILE *fileout);
int GetFilesize(FILE* file);
+bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest);
boost::filesystem::path GetDefaultDataDir();
const boost::filesystem::path &GetDataDir(bool fNetSpecific = true);
boost::filesystem::path GetConfigFile();
boost::filesystem::path GetPidFile();
+#ifndef WIN32
void CreatePidFile(const boost::filesystem::path &path, pid_t pid);
+#endif
void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map<std::string, std::vector<std::string> >& mapMultiSettingsRet);
-bool GetStartOnSystemStartup();
-bool SetStartOnSystemStartup(bool fAutoStart);
+#ifdef WIN32
+boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
+#endif
void ShrinkDebugFile();
int GetRandInt(int nMax);
uint64 GetRand(uint64 nMax);
int64 GetTime();
void SetMockTime(int64 nMockTimeIn);
int64 GetAdjustedTime();
+int64 GetTimeOffset();
std::string FormatFullVersion();
std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments);
void AddTimeData(const CNetAddr& ip, int64 nTime);
+void runCommand(std::string strCommand);
-
-
-/** Wrapped boost mutex: supports recursive locking, but no waiting */
-typedef boost::interprocess::interprocess_recursive_mutex CCriticalSection;
-
-/** Wrapped boost mutex: supports waiting but not recursive locking */
-typedef boost::interprocess::interprocess_mutex CWaitableCriticalSection;
-
-#ifdef DEBUG_LOCKORDER
-void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false);
-void LeaveCritical();
-#else
-void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false) {}
-void static inline LeaveCritical() {}
-#endif
-
-/** Wrapper around boost::interprocess::scoped_lock */
-template<typename Mutex>
-class CMutexLock
-{
-private:
- boost::interprocess::scoped_lock<Mutex> lock;
-public:
-
- void Enter(const char* pszName, const char* pszFile, int nLine)
- {
- if (!lock.owns())
- {
- EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()));
-#ifdef DEBUG_LOCKCONTENTION
- if (!lock.try_lock())
- {
- printf("LOCKCONTENTION: %s\n", pszName);
- printf("Locker: %s:%d\n", pszFile, nLine);
-#endif
- lock.lock();
-#ifdef DEBUG_LOCKCONTENTION
- }
-#endif
- }
- }
-
- void Leave()
- {
- if (lock.owns())
- {
- lock.unlock();
- LeaveCritical();
- }
- }
-
- bool TryEnter(const char* pszName, const char* pszFile, int nLine)
- {
- if (!lock.owns())
- {
- EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()), true);
- lock.try_lock();
- if (!lock.owns())
- LeaveCritical();
- }
- return lock.owns();
- }
-
- CMutexLock(Mutex& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) : lock(mutexIn, boost::interprocess::defer_lock)
- {
- if (fTry)
- TryEnter(pszName, pszFile, nLine);
- else
- Enter(pszName, pszFile, nLine);
- }
-
- ~CMutexLock()
- {
- if (lock.owns())
- LeaveCritical();
- }
-
- operator bool()
- {
- return lock.owns();
- }
-
- boost::interprocess::scoped_lock<Mutex> &GetLock()
- {
- return lock;
- }
-};
-
-typedef CMutexLock<CCriticalSection> CCriticalBlock;
-
-#define LOCK(cs) CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__)
-#define LOCK2(cs1,cs2) CCriticalBlock criticalblock1(cs1, #cs1, __FILE__, __LINE__),criticalblock2(cs2, #cs2, __FILE__, __LINE__)
-#define TRY_LOCK(cs,name) CCriticalBlock name(cs, #cs, __FILE__, __LINE__, true)
-
-#define ENTER_CRITICAL_SECTION(cs) \
- { \
- EnterCritical(#cs, __FILE__, __LINE__, (void*)(&cs)); \
- (cs).lock(); \
- }
-
-#define LEAVE_CRITICAL_SECTION(cs) \
- { \
- (cs).unlock(); \
- LeaveCritical(); \
- }
-
-#ifdef MAC_OSX
-// boost::interprocess::interprocess_semaphore seems to spinlock on OSX; prefer polling instead
-class CSemaphore
-{
-private:
- CCriticalSection cs;
- int val;
-
-public:
- CSemaphore(int init) : val(init) {}
-
- void wait() {
- do {
- {
- LOCK(cs);
- if (val>0) {
- val--;
- return;
- }
- }
- Sleep(100);
- } while(1);
- }
-
- bool try_wait() {
- LOCK(cs);
- if (val>0) {
- val--;
- return true;
- }
- return false;
- }
-
- void post() {
- LOCK(cs);
- val++;
- }
-};
-#else
-typedef boost::interprocess::interprocess_semaphore CSemaphore;
-#endif
-
inline std::string i64tostr(int64 n)
{
return strprintf("%"PRI64d, n);
return (n >= 0 ? n : -n);
}
+inline std::string leftTrim(std::string src, char chr)
+{
+ std::string::size_type pos = src.find_first_not_of(chr, 0);
+
+ if(pos > 0)
+ src.erase(0, pos);
+
+ return src;
+}
+
template<typename T>
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
{
- std::vector<char> rv;
- static char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+ std::string rv;
+ static const char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
rv.reserve((itend-itbegin)*3);
for(T it = itbegin; it < itend; ++it)
{
rv.push_back(hexmap[val&15]);
}
- return std::string(rv.begin(), rv.end());
+ return rv;
}
inline std::string HexStr(const std::vector<unsigned char>& vch, bool fSpaces=false)
#else
timeval t;
gettimeofday(&t, NULL);
- nCounter = t.tv_sec * 1000000 + t.tv_usec;
+ nCounter = (int64) t.tv_sec * 1000000 + t.tv_usec;
#endif
return nCounter;
}
return pszTime;
}
-static const std::string strTimestampFormat = "%F %H:%M:%S";
+static const std::string strTimestampFormat = "%Y-%m-%d %H:%M:%S UTC";
inline std::string DateTimeStrFormat(int64 nTime)
{
return DateTimeStrFormat(strTimestampFormat.c_str(), nTime);
}
+
template<typename T>
void skipspaces(T& it)
{
-// Randomize the stack to help protect against buffer overrun exploits
-#define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \
- { \
- static char nLoops; \
- if (nLoops <= 0) \
- nLoops = GetRand(20) + 1; \
- if (nLoops-- > 1) \
- { \
- ThreadFn; \
- return; \
- } \
- }
-
-
template<typename T1>
inline uint256 Hash(const T1 pbegin, const T1 pend)
{
return hash2;
}
+class CHashWriter
+{
+private:
+ SHA256_CTX ctx;
+
+public:
+ int nType;
+ int nVersion;
+
+ void Init() {
+ SHA256_Init(&ctx);
+ }
+
+ CHashWriter(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) {
+ Init();
+ }
+
+ CHashWriter& write(const char *pch, size_t size) {
+ SHA256_Update(&ctx, pch, size);
+ return (*this);
+ }
+
+ // invalidates the object
+ uint256 GetHash() {
+ uint256 hash1;
+ SHA256_Final((unsigned char*)&hash1, &ctx);
+ uint256 hash2;
+ SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
+ return hash2;
+ }
+
+ template<typename T>
+ CHashWriter& operator<<(const T& obj) {
+ // Serialize to this stream
+ ::Serialize(*this, obj, nType, nVersion);
+ return (*this);
+ }
+};
+
+
template<typename T1, typename T2>
inline uint256 Hash(const T1 p1begin, const T1 p1end,
const T2 p2begin, const T2 p2end)
template<typename T>
uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
{
- // Most of the time is spent allocating and deallocating CDataStream's
- // buffer. If this ever needs to be optimized further, make a CStaticStream
- // class with its buffer on the stack.
- CDataStream ss(nType, nVersion);
- ss.reserve(10000);
+ CHashWriter ss(nType, nVersion);
ss << obj;
- return Hash(ss.begin(), ss.end());
+ return ss.GetHash();
}
inline uint160 Hash160(const std::vector<unsigned char>& vch)
return hash2;
}
+/**
+ * Timing-attack-resistant comparison.
+ * Takes time proportional to length
+ * of first argument.
+ */
+template <typename T>
+bool TimingResistantEqual(const T& a, const T& b)
+{
+ if (b.size() == 0) return a.size() == 0;
+ size_t accumulator = a.size() ^ b.size();
+ for (size_t i = 0; i < a.size(); i++)
+ accumulator |= a[i] ^ b[i%b.size()];
+ return accumulator == 0;
+}
-/** Median filter over a stream of values.
+/** Median filter over a stream of values.
* Returns the median of the last N numbers
*/
template <typename T> class CMedianFilter
vValues.push_back(initial_value);
vSorted = vValues;
}
-
+
void input(T value)
{
if(vValues.size() == nSize)
}
};
+bool NewThread(void(*pfn)(void*), void* parg);
-
-
-
-
-
-
-
-
-// Note: It turns out we might have been able to use boost::thread
-// by using TerminateThread(boost::thread.native_handle(), 0);
#ifdef WIN32
-typedef HANDLE bitcoin_pthread_t;
-
-inline bitcoin_pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false)
-{
- DWORD nUnused = 0;
- HANDLE hthread =
- CreateThread(
- NULL, // default security
- 0, // inherit stack size from parent
- (LPTHREAD_START_ROUTINE)pfn, // function pointer
- parg, // argument
- 0, // creation option, start immediately
- &nUnused); // thread identifier
- if (hthread == NULL)
- {
- printf("Error: CreateThread() returned %d\n", GetLastError());
- return (bitcoin_pthread_t)0;
- }
- if (!fWantHandle)
- {
- CloseHandle(hthread);
- return (bitcoin_pthread_t)-1;
- }
- return hthread;
-}
-
inline void SetThreadPriority(int nPriority)
{
SetThreadPriority(GetCurrentThread(), nPriority);
}
#else
-inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false)
-{
- pthread_t hthread = 0;
- int ret = pthread_create(&hthread, NULL, (void*(*)(void*))pfn, parg);
- if (ret != 0)
- {
- printf("Error: pthread_create() returned %d\n", ret);
- return (pthread_t)0;
- }
- if (!fWantHandle)
- {
- pthread_detach(hthread);
- return (pthread_t)-1;
- }
- return hthread;
-}
#define THREAD_PRIORITY_LOWEST PRIO_MAX
#define THREAD_PRIORITY_BELOW_NORMAL 2
}
#endif
-
-
-
+void RenameThread(const char* name);
inline uint32_t ByteReverse(uint32_t value)
{