Get rid of C style macros
[novacoin.git] / src / util.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "util.h"
7 #include "sync.h"
8 #include "version.h"
9 #include "ui_interface.h"
10
11 #include <boost/algorithm/string/join.hpp>
12 #include <boost/algorithm/string/case_conv.hpp> // for to_lower()
13 #include <boost/program_options/detail/config_file.hpp>
14 #include <boost/program_options/parsers.hpp>
15 #include <boost/filesystem.hpp>
16 #include <boost/filesystem/fstream.hpp>
17 #include <boost/date_time/posix_time/posix_time.hpp>
18 #include <boost/thread.hpp>
19
20 #include <openssl/crypto.h>
21 #include <openssl/rand.h>
22
23 #ifdef WIN32
24 #ifdef _WIN32_WINNT
25 #undef _WIN32_WINNT
26 #endif
27 #define _WIN32_WINNT 0x0501
28 #ifdef _WIN32_IE
29 #undef _WIN32_IE
30 #endif
31 #define _WIN32_IE 0x0501
32 #define WIN32_LEAN_AND_MEAN 1
33 #ifndef NOMINMAX
34 #define NOMINMAX
35 #endif
36 #include <io.h> /* for _commit */
37 #include "shlobj.h"
38 #elif defined(__linux__)
39 #include <sys/prctl.h>
40 #endif
41
42 #if !defined(WIN32) && !defined(ANDROID)
43 #include <execinfo.h>
44 #endif
45
46 using namespace std;
47 namespace bt = boost::posix_time;
48
49 map<string, string> mapArgs;
50 map<string, vector<string> > mapMultiArgs;
51 bool fDebug = false;
52 bool fDebugNet = false;
53 bool fPrintToConsole = false;
54 bool fPrintToDebugger = false;
55 bool fRequestShutdown = false;
56 bool fShutdown = false;
57 bool fDaemon = false;
58 bool fServer = false;
59 bool fCommandLine = false;
60 string strMiscWarning;
61 bool fTestNet = false;
62 bool fNoListen = false;
63 bool fLogTimestamps = false;
64 CMedianFilter<int64_t> vTimeOffsets(200,0);
65 bool fReopenDebugLog = false;
66
67 // Extended DecodeDumpTime implementation, see this page for details:
68 // http://stackoverflow.com/questions/3786201/parsing-of-date-time-from-string-boost
69 const locale formats[] = {
70     locale(locale::classic(),new bt::time_input_facet("%Y-%m-%dT%H:%M:%SZ")),
71     locale(locale::classic(),new bt::time_input_facet("%Y-%m-%d %H:%M:%S")),
72     locale(locale::classic(),new bt::time_input_facet("%Y/%m/%d %H:%M:%S")),
73     locale(locale::classic(),new bt::time_input_facet("%d.%m.%Y %H:%M:%S")),
74     locale(locale::classic(),new bt::time_input_facet("%Y-%m-%d"))
75 };
76
77 const size_t formats_n = sizeof(formats)/sizeof(formats[0]);
78
79 time_t pt_to_time_t(const bt::ptime& pt)
80 {
81     bt::ptime timet_start(boost::gregorian::date(1970,1,1));
82     bt::time_duration diff = pt - timet_start;
83     return diff.ticks()/bt::time_duration::rep_type::ticks_per_second;
84 }
85
86 // Init OpenSSL library multithreading support
87 static CCriticalSection** ppmutexOpenSSL;
88 void locking_callback(int mode, int i, const char* file, int line)
89 {
90     if (mode & CRYPTO_LOCK) {
91         ENTER_CRITICAL_SECTION(*ppmutexOpenSSL[i]);
92     } else {
93         LEAVE_CRITICAL_SECTION(*ppmutexOpenSSL[i]);
94     }
95 }
96
97 LockedPageManager LockedPageManager::instance;
98
99 // Init
100 class CInit
101 {
102 public:
103     CInit()
104     {
105         // Init OpenSSL library multithreading support
106         ppmutexOpenSSL = (CCriticalSection**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(CCriticalSection*));
107         for (int i = 0; i < CRYPTO_num_locks(); i++)
108             ppmutexOpenSSL[i] = new CCriticalSection();
109         CRYPTO_set_locking_callback(locking_callback);
110
111 #ifdef WIN32
112         // Seed random number generator with screen scrape and other hardware sources
113         RAND_screen();
114 #endif
115
116         // Seed random number generator with performance counter
117         RandAddSeed();
118     }
119     ~CInit()
120     {
121         // Shutdown OpenSSL library multithreading support
122         CRYPTO_set_locking_callback(NULL);
123         for (int i = 0; i < CRYPTO_num_locks(); i++)
124             delete ppmutexOpenSSL[i];
125         OPENSSL_free(ppmutexOpenSSL);
126     }
127 }
128 instance_of_cinit;
129
130 void RandAddSeed()
131 {
132     // Seed with CPU performance counter
133     int64_t nCounter = GetPerformanceCounter();
134     RAND_add(&nCounter, sizeof(nCounter), 1.5);
135     memset(&nCounter, 0, sizeof(nCounter));
136 }
137
138 void RandAddSeedPerfmon()
139 {
140     RandAddSeed();
141
142     // This can take up to 2 seconds, so only do it every 10 minutes
143     static int64_t nLastPerfmon;
144     if (GetTime() < nLastPerfmon + 10 * 60)
145         return;
146     nLastPerfmon = GetTime();
147
148 #ifdef WIN32
149     // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
150     // Seed with the entire set of perfmon data
151     unsigned char pdata[250000];
152     memset(pdata, 0, sizeof(pdata));
153     unsigned long nSize = sizeof(pdata);
154     long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
155     RegCloseKey(HKEY_PERFORMANCE_DATA);
156     if (ret == ERROR_SUCCESS)
157     {
158         RAND_add(pdata, nSize, nSize/100.0);
159         OPENSSL_cleanse(pdata, nSize);
160         printf("RandAddSeed() %lu bytes\n", nSize);
161     }
162 #endif
163 }
164
165 uint64_t GetRand(uint64_t nMax)
166 {
167     if (nMax == 0)
168         return 0;
169
170     // The range of the random source must be a multiple of the modulus
171     // to give every possible output value an equal possibility
172     uint64_t nRange = (numeric_limits<uint64_t>::max() / nMax) * nMax;
173     uint64_t nRand = 0;
174     do
175         RAND_bytes((unsigned char*)&nRand, sizeof(nRand));
176     while (nRand >= nRange);
177     return (nRand % nMax);
178 }
179
180 int GetRandInt(int nMax)
181 {
182     return static_cast<int>(GetRand(nMax));
183 }
184
185 uint256 GetRandHash()
186 {
187     uint256 hash;
188     RAND_bytes((unsigned char*)&hash, sizeof(hash));
189     return hash;
190 }
191
192 static FILE* fileout = NULL;
193
194 inline int OutputDebugStringF(const char* pszFormat, ...)
195 {
196     int ret = 0;
197     if (fPrintToConsole)
198     {
199         // print to console
200         va_list arg_ptr;
201         va_start(arg_ptr, pszFormat);
202         ret = vprintf(pszFormat, arg_ptr);
203         va_end(arg_ptr);
204     }
205     else if (!fPrintToDebugger)
206     {
207         // print to debug.log
208
209         if (!fileout)
210         {
211             boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
212             fileout = fopen(pathDebug.string().c_str(), "a");
213             if (fileout) setbuf(fileout, NULL); // unbuffered
214         }
215         if (fileout)
216         {
217             static bool fStartedNewLine = true;
218
219             // This routine may be called by global destructors during shutdown.
220             // Since the order of destruction of static/global objects is undefined,
221             // allocate mutexDebugLog on the heap the first time this routine
222             // is called to avoid crashes during shutdown.
223             static boost::mutex* mutexDebugLog = NULL;
224             if (mutexDebugLog == NULL) mutexDebugLog = new boost::mutex();
225             boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
226
227             // reopen the log file, if requested
228             if (fReopenDebugLog) {
229                 fReopenDebugLog = false;
230                 boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
231                 if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL)
232                     setbuf(fileout, NULL); // unbuffered
233             }
234
235             // Debug print useful for profiling
236             if (fLogTimestamps && fStartedNewLine)
237                 fprintf(fileout, "%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
238             if (pszFormat[strlen(pszFormat) - 1] == '\n')
239                 fStartedNewLine = true;
240             else
241                 fStartedNewLine = false;
242
243             va_list arg_ptr;
244             va_start(arg_ptr, pszFormat);
245             ret = vfprintf(fileout, pszFormat, arg_ptr);
246             va_end(arg_ptr);
247         }
248     }
249
250 #ifdef WIN32
251     if (fPrintToDebugger)
252     {
253         static CCriticalSection cs_OutputDebugStringF;
254
255         // accumulate and output a line at a time
256         {
257             LOCK(cs_OutputDebugStringF);
258             static string buffer;
259
260             va_list arg_ptr;
261             va_start(arg_ptr, pszFormat);
262             buffer += vstrprintf(pszFormat, arg_ptr);
263             va_end(arg_ptr);
264
265             size_t line_start = 0, line_end;
266             while((line_end = buffer.find('\n', line_start)) != string::npos)
267             {
268                 OutputDebugStringA(buffer.substr(line_start, line_end - line_start).c_str());
269                 line_start = line_end + 1;
270             }
271             buffer.erase(0, line_start);
272         }
273     }
274 #endif
275     return ret;
276 }
277
278 string vstrprintf(const char *format, va_list ap)
279 {
280     char buffer[50000];
281     char* p = buffer;
282     int limit = sizeof(buffer);
283     int ret;
284     for ( ; ; )
285     {
286 #ifndef _MSC_VER
287         va_list arg_ptr;
288         va_copy(arg_ptr, ap);
289 #else
290         va_list arg_ptr = ap;
291 #endif
292 #ifdef WIN32
293         ret = _vsnprintf(p, limit, format, arg_ptr);
294 #else
295         ret = vsnprintf(p, limit, format, arg_ptr);
296 #endif
297         va_end(arg_ptr);
298         if (ret >= 0 && ret < limit)
299             break;
300         if (p != buffer)
301             delete[] p;
302         limit *= 2;
303         p = new(nothrow) char[limit];
304         if (p == NULL)
305             throw bad_alloc();
306     }
307     string str(p, p+ret);
308     if (p != buffer)
309         delete[] p;
310     return str;
311 }
312
313 string real_strprintf(const char *format, int dummy, ...)
314 {
315     va_list arg_ptr;
316     va_start(arg_ptr, dummy);
317     string str = vstrprintf(format, arg_ptr);
318     va_end(arg_ptr);
319     return str;
320 }
321
322 string real_strprintf(const string &format, int dummy, ...)
323 {
324     va_list arg_ptr;
325     va_start(arg_ptr, dummy);
326     string str = vstrprintf(format.c_str(), arg_ptr);
327     va_end(arg_ptr);
328     return str;
329 }
330
331 bool error(const char *format, ...)
332 {
333     va_list arg_ptr;
334     va_start(arg_ptr, format);
335     string str = vstrprintf(format, arg_ptr);
336     va_end(arg_ptr);
337     printf("ERROR: %s\n", str.c_str());
338     return false;
339 }
340
341
342 void ParseString(const string& str, char c, vector<string>& v)
343 {
344     if (str.empty())
345         return;
346     string::size_type i1 = 0;
347     string::size_type i2;
348     for ( ; ; )
349     {
350         i2 = str.find(c, i1);
351         if (i2 == str.npos)
352         {
353             v.push_back(str.substr(i1));
354             return;
355         }
356         v.push_back(str.substr(i1, i2-i1));
357         i1 = i2+1;
358     }
359 }
360
361 string FormatMoney(int64_t n, bool fPlus)
362 {
363     // Note: not using straight sprintf here because we do NOT want
364     // localized number formatting.
365     int64_t n_abs = (n > 0 ? n : -n);
366     int64_t quotient = n_abs/COIN;
367     int64_t remainder = n_abs%COIN;
368     string str = strprintf("%" PRId64 ".%06" PRId64, quotient, remainder);
369
370     // Right-trim excess zeros before the decimal point:
371     size_t nTrim = 0;
372     for (size_t i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i)
373         ++nTrim;
374     if (nTrim)
375         str.erase(str.size()-nTrim, nTrim);
376
377     if (n < 0)
378         str.insert(0u, 1, '-');
379     else if (fPlus && n > 0)
380         str.insert(0u, 1, '+');
381     return str;
382 }
383
384 bool ParseMoney(const string& str, int64_t& nRet)
385 {
386     return ParseMoney(str.c_str(), nRet);
387 }
388
389 bool ParseMoney(const char* pszIn, int64_t& nRet)
390 {
391     string strWhole;
392     int64_t nUnits = 0;
393     const char* p = pszIn;
394     while (isspace(*p))
395         p++;
396     for (; *p; p++)
397     {
398         if (*p == '.')
399         {
400             p++;
401             int64_t nMult = CENT*10;
402             while (isdigit(*p) && (nMult > 0))
403             {
404                 nUnits += nMult * (*p++ - '0');
405                 nMult /= 10;
406             }
407             break;
408         }
409         if (isspace(*p))
410             break;
411         if (!isdigit(*p))
412             return false;
413         strWhole.insert(strWhole.end(), *p);
414     }
415     for (; *p; p++)
416         if (!isspace(*p))
417             return false;
418     if (strWhole.size() > 10) // guard against 63 bit overflow
419         return false;
420     if (nUnits < 0 || nUnits > COIN)
421         return false;
422     int64_t nWhole = strtoll(strWhole);
423     int64_t nValue = nWhole*COIN + nUnits;
424
425     nRet = nValue;
426     return true;
427 }
428
429 static const int8_t phexdigit[256] =
430 {
431     -1, -1, -1, -1, -1, -1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
432     -1, -1, -1, -1, -1, -1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
433     -1, -1, -1, -1, -1, -1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
434      0,  1,  2,  3,  4,  5,  6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
435     -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
436     -1, -1, -1, -1, -1, -1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
437     -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
438     -1, -1, -1, -1, -1, -1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
439     -1, -1, -1, -1, -1, -1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
440     -1, -1, -1, -1, -1, -1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
441     -1, -1, -1, -1, -1, -1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
442     -1, -1, -1, -1, -1, -1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
443     -1, -1, -1, -1, -1, -1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
444     -1, -1, -1, -1, -1, -1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
445     -1, -1, -1, -1, -1, -1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
446     -1, -1, -1, -1, -1, -1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
447 };
448
449 bool IsHex(const string& str)
450 {
451     for(unsigned char c :  str)
452     {
453         if (phexdigit[c] < 0)
454             return false;
455     }
456     return (str.size() > 0) && (str.size()%2 == 0);
457 }
458
459 vector<unsigned char> ParseHex(const char* psz)
460 {
461     // convert hex dump to vector
462     vector<unsigned char> vch;
463     for ( ; ; )
464     {
465         while (isspace(*psz))
466             psz++;
467         auto c = phexdigit[(unsigned char)*psz++];
468         if (c == (signed char)-1)
469             break;
470         auto n = (c << 4);
471         c = phexdigit[(uint8_t)*psz++];
472         if (c == (int8_t)-1)
473             break;
474         n |= c;
475         vch.push_back(n);
476     }
477     return vch;
478 }
479
480 static void InterpretNegativeSetting(string name, map<string, string>& mapSettingsRet)
481 {
482     // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set
483     if (name.find("-no") == 0)
484     {
485         string positive("-");
486         positive.append(name.begin()+3, name.end());
487         if (mapSettingsRet.count(positive) == 0)
488         {
489             bool value = !GetBoolArg(name);
490             mapSettingsRet[positive] = (value ? "1" : "0");
491         }
492     }
493 }
494
495 void ParseParameters(int argc, const char* const argv[])
496 {
497     mapArgs.clear();
498     mapMultiArgs.clear();
499     for (int i = 1; i < argc; i++)
500     {
501         string str(argv[i]);
502         string strValue;
503         size_t is_index = str.find('=');
504         if (is_index != string::npos)
505         {
506             strValue = str.substr(is_index+1);
507             str = str.substr(0, is_index);
508         }
509 #ifdef WIN32
510         boost::to_lower(str);
511         if (str.compare(0,1, "/") == 0)
512             str = "-" + str.substr(1);
513 #endif
514         if (str[0] != '-')
515             break;
516
517         mapArgs[str] = strValue;
518         mapMultiArgs[str].push_back(strValue);
519     }
520
521     // New 0.6 features:
522     for(const auto& entry : mapArgs)
523     {
524         string name = entry.first;
525
526         //  interpret --foo as -foo (as long as both are not set)
527         if (name.find("--") == 0)
528         {
529             string singleDash(name.begin()+1, name.end());
530             if (mapArgs.count(singleDash) == 0)
531                 mapArgs[singleDash] = entry.second;
532             name = singleDash;
533         }
534
535         // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set
536         InterpretNegativeSetting(name, mapArgs);
537     }
538 }
539
540 string GetArg(const string& strArg, const string& strDefault)
541 {
542     if (mapArgs.count(strArg))
543         return mapArgs[strArg];
544     return strDefault;
545 }
546
547 int64_t GetArg(const string& strArg, int64_t nDefault)
548 {
549     if (mapArgs.count(strArg))
550         return strtoll(mapArgs[strArg]);
551     return nDefault;
552 }
553
554 int32_t GetArgInt(const string& strArg, int32_t nDefault)
555 {
556     if (mapArgs.count(strArg))
557         return strtol(mapArgs[strArg]);
558     return nDefault;
559 }
560
561 uint32_t GetArgUInt(const string& strArg, uint32_t nDefault)
562 {
563     if (mapArgs.count(strArg))
564         return strtoul(mapArgs[strArg]);
565     return nDefault;
566 }
567
568 bool GetBoolArg(const string& strArg, bool fDefault)
569 {
570     if (mapArgs.count(strArg))
571     {
572         if (mapArgs[strArg].empty())
573             return true;
574         return (atoi(mapArgs[strArg]) != 0);
575     }
576     return fDefault;
577 }
578
579 bool SoftSetArg(const string& strArg, const string& strValue)
580 {
581     if (mapArgs.count(strArg) || mapMultiArgs.count(strArg))
582         return false;
583     mapArgs[strArg] = strValue;
584     mapMultiArgs[strArg].push_back(strValue);
585
586     return true;
587 }
588
589 bool SoftSetBoolArg(const string& strArg, bool fValue)
590 {
591     if (fValue)
592         return SoftSetArg(strArg, string("1"));
593     else
594         return SoftSetArg(strArg, string("0"));
595 }
596
597
598 string EncodeBase64(const unsigned char* pch, size_t len)
599 {
600     static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
601
602     string strRet="";
603     strRet.reserve((len+2)/3*4);
604
605     int mode=0, left=0;
606     const unsigned char *pchEnd = pch+len;
607
608     while (pch<pchEnd)
609     {
610         int enc = *(pch++);
611         switch (mode)
612         {
613             case 0: // we have no bits
614                 strRet += pbase64[enc >> 2];
615                 left = (enc & 3) << 4;
616                 mode = 1;
617                 break;
618
619             case 1: // we have two bits
620                 strRet += pbase64[left | (enc >> 4)];
621                 left = (enc & 15) << 2;
622                 mode = 2;
623                 break;
624
625             case 2: // we have four bits
626                 strRet += pbase64[left | (enc >> 6)];
627                 strRet += pbase64[enc & 63];
628                 mode = 0;
629                 break;
630         }
631     }
632
633     if (mode)
634     {
635         strRet += pbase64[left];
636         strRet += '=';
637         if (mode == 1)
638             strRet += '=';
639     }
640
641     return strRet;
642 }
643
644 string EncodeBase64(const string& str)
645 {
646     return EncodeBase64((const unsigned char*)str.c_str(), str.size());
647 }
648
649 vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid)
650 {
651     static const int decode64_table[256] =
652     {
653         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
654         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
655         -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
656         -1, -1, -1, -1, -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
657         15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
658         29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
659         49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
660         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
661         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
662         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
663         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
664         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
665         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
666     };
667
668     if (pfInvalid)
669         *pfInvalid = false;
670
671     vector<unsigned char> vchRet;
672     vchRet.reserve(strlen(p)*3/4);
673
674     int mode = 0;
675     int left = 0;
676
677     for ( ; ; )
678     {
679          int dec = decode64_table[(unsigned char)*p];
680          if (dec == -1) break;
681          p++;
682          switch (mode)
683          {
684              case 0: // we have no bits and get 6
685                  left = dec;
686                  mode = 1;
687                  break;
688
689               case 1: // we have 6 bits and keep 4
690                   vchRet.push_back((left<<2) | (dec>>4));
691                   left = dec & 15;
692                   mode = 2;
693                   break;
694
695              case 2: // we have 4 bits and get 6, we keep 2
696                  vchRet.push_back((left<<4) | (dec>>2));
697                  left = dec & 3;
698                  mode = 3;
699                  break;
700
701              case 3: // we have 2 bits and get 6
702                  vchRet.push_back((left<<6) | dec);
703                  mode = 0;
704                  break;
705          }
706     }
707
708     if (pfInvalid)
709         switch (mode)
710         {
711             case 0: // 4n base64 characters processed: ok
712                 break;
713
714             case 1: // 4n+1 base64 character processed: impossible
715                 *pfInvalid = true;
716                 break;
717
718             case 2: // 4n+2 base64 characters processed: require '=='
719                 if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1)
720                     *pfInvalid = true;
721                 break;
722
723             case 3: // 4n+3 base64 characters processed: require '='
724                 if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1)
725                     *pfInvalid = true;
726                 break;
727         }
728
729     return vchRet;
730 }
731
732 string DecodeBase64(const string& str)
733 {
734     vector<unsigned char> vchRet = DecodeBase64(str.c_str());
735     return string((const char*)&vchRet[0], vchRet.size());
736 }
737
738 string EncodeBase32(const unsigned char* pch, size_t len)
739 {
740     static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567";
741
742     string strRet="";
743     strRet.reserve((len+4)/5*8);
744
745     int mode=0, left=0;
746     const unsigned char *pchEnd = pch+len;
747
748     while (pch<pchEnd)
749     {
750         int enc = *(pch++);
751         switch (mode)
752         {
753             case 0: // we have no bits
754                 strRet += pbase32[enc >> 3];
755                 left = (enc & 7) << 2;
756                 mode = 1;
757                 break;
758
759             case 1: // we have three bits
760                 strRet += pbase32[left | (enc >> 6)];
761                 strRet += pbase32[(enc >> 1) & 31];
762                 left = (enc & 1) << 4;
763                 mode = 2;
764                 break;
765
766             case 2: // we have one bit
767                 strRet += pbase32[left | (enc >> 4)];
768                 left = (enc & 15) << 1;
769                 mode = 3;
770                 break;
771
772             case 3: // we have four bits
773                 strRet += pbase32[left | (enc >> 7)];
774                 strRet += pbase32[(enc >> 2) & 31];
775                 left = (enc & 3) << 3;
776                 mode = 4;
777                 break;
778
779             case 4: // we have two bits
780                 strRet += pbase32[left | (enc >> 5)];
781                 strRet += pbase32[enc & 31];
782                 mode = 0;
783         }
784     }
785
786     static const int nPadding[5] = {0, 6, 4, 3, 1};
787     if (mode)
788     {
789         strRet += pbase32[left];
790         for (int n=0; n<nPadding[mode]; n++)
791              strRet += '=';
792     }
793
794     return strRet;
795 }
796
797 string EncodeBase32(const string& str)
798 {
799     return EncodeBase32((const unsigned char*)str.c_str(), str.size());
800 }
801
802 vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid)
803 {
804     static const int decode32_table[256] =
805     {
806         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
807         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
808         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1,
809         -1, -1, -1, -1, -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
810         15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1,  0,  1,  2,
811          3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
812         23, 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
813         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
814         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
815         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
816         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
817         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
818         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
819     };
820
821     if (pfInvalid)
822         *pfInvalid = false;
823
824     vector<unsigned char> vchRet;
825     vchRet.reserve((strlen(p))*5/8);
826
827     int mode = 0;
828     int left = 0;
829
830     for ( ; ; )
831     {
832          int dec = decode32_table[(unsigned char)*p];
833          if (dec == -1) break;
834          p++;
835          switch (mode)
836          {
837              case 0: // we have no bits and get 5
838                  left = dec;
839                  mode = 1;
840                  break;
841
842               case 1: // we have 5 bits and keep 2
843                   vchRet.push_back((left<<3) | (dec>>2));
844                   left = dec & 3;
845                   mode = 2;
846                   break;
847
848              case 2: // we have 2 bits and keep 7
849                  left = left << 5 | dec;
850                  mode = 3;
851                  break;
852
853              case 3: // we have 7 bits and keep 4
854                  vchRet.push_back((left<<1) | (dec>>4));
855                  left = dec & 15;
856                  mode = 4;
857                  break;
858
859              case 4: // we have 4 bits, and keep 1
860                  vchRet.push_back((left<<4) | (dec>>1));
861                  left = dec & 1;
862                  mode = 5;
863                  break;
864
865              case 5: // we have 1 bit, and keep 6
866                  left = left << 5 | dec;
867                  mode = 6;
868                  break;
869
870              case 6: // we have 6 bits, and keep 3
871                  vchRet.push_back((left<<2) | (dec>>3));
872                  left = dec & 7;
873                  mode = 7;
874                  break;
875
876              case 7: // we have 3 bits, and keep 0
877                  vchRet.push_back((left<<5) | dec);
878                  mode = 0;
879                  break;
880          }
881     }
882
883     if (pfInvalid)
884         switch (mode)
885         {
886             case 0: // 8n base32 characters processed: ok
887                 break;
888
889             case 1: // 8n+1 base32 characters processed: impossible
890             case 3: //   +3
891             case 6: //   +6
892                 *pfInvalid = true;
893                 break;
894
895             case 2: // 8n+2 base32 characters processed: require '======'
896                 if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || p[4] != '=' || p[5] != '=' || decode32_table[(unsigned char)p[6]] != -1)
897                     *pfInvalid = true;
898                 break;
899
900             case 4: // 8n+4 base32 characters processed: require '===='
901                 if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1)
902                     *pfInvalid = true;
903                 break;
904
905             case 5: // 8n+5 base32 characters processed: require '==='
906                 if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || decode32_table[(unsigned char)p[3]] != -1)
907                     *pfInvalid = true;
908                 break;
909
910             case 7: // 8n+7 base32 characters processed: require '='
911                 if (left || p[0] != '=' || decode32_table[(unsigned char)p[1]] != -1)
912                     *pfInvalid = true;
913                 break;
914         }
915
916     return vchRet;
917 }
918
919 string DecodeBase32(const string& str)
920 {
921     vector<unsigned char> vchRet = DecodeBase32(str.c_str());
922     return string((const char*)&vchRet[0], vchRet.size());
923 }
924
925
926 int64_t DecodeDumpTime(const string& s)
927 {
928     bt::ptime pt;
929
930     for(size_t i=0; i<formats_n; ++i)
931     {
932         istringstream is(s);
933         is.imbue(formats[i]);
934         is >> pt;
935         if(pt != bt::ptime()) break;
936     }
937
938     return pt_to_time_t(pt);
939 }
940
941 string EncodeDumpTime(int64_t nTime) {
942     return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime);
943 }
944
945 string EncodeDumpString(const string &str) {
946     stringstream ret;
947     for(unsigned char c :  str) {
948         if (c <= 32 || c >= 128 || c == '%') {
949             ret << '%' << HexStr(&c, &c + 1);
950         } else {
951             ret << c;
952         }
953     }
954     return ret.str();
955 }
956
957 string DecodeDumpString(const string &str) {
958     stringstream ret;
959     for (unsigned int pos = 0; pos < str.length(); pos++) {
960         unsigned char c = str[pos];
961         if (c == '%' && pos+2 < str.length()) {
962             c = (((str[pos+1]>>6)*9+((str[pos+1]-'0')&15)) << 4) | 
963                 ((str[pos+2]>>6)*9+((str[pos+2]-'0')&15));
964             pos += 2;
965         }
966         ret << c;
967     }
968     return ret.str();
969 }
970
971 bool WildcardMatch(const char* psz, const char* mask)
972 {
973     for ( ; ; )
974     {
975         switch (*mask)
976         {
977         case '\0':
978             return (*psz == '\0');
979         case '*':
980             return WildcardMatch(psz, mask+1) || (*psz && WildcardMatch(psz+1, mask));
981         case '?':
982             if (*psz == '\0')
983                 return false;
984             break;
985         default:
986             if (*psz != *mask)
987                 return false;
988             break;
989         }
990         psz++;
991         mask++;
992     }
993 }
994
995 bool WildcardMatch(const string& str, const string& mask)
996 {
997     return WildcardMatch(str.c_str(), mask.c_str());
998 }
999
1000
1001 static string FormatException(exception* pex, const char* pszThread)
1002 {
1003 #ifdef WIN32
1004     char pszModule[MAX_PATH] = "";
1005     GetModuleFileNameA(NULL, pszModule, sizeof(pszModule));
1006 #else
1007     const char* pszModule = "novacoin";
1008 #endif
1009     if (pex)
1010         return strprintf(
1011             "EXCEPTION: %s       \n%s       \n%s in %s       \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
1012     else
1013         return strprintf(
1014             "UNKNOWN EXCEPTION       \n%s in %s       \n", pszModule, pszThread);
1015 }
1016
1017 void LogException(exception* pex, const char* pszThread)
1018 {
1019     string message = FormatException(pex, pszThread);
1020     printf("\n%s", message.c_str());
1021 }
1022
1023 void PrintException(exception* pex, const char* pszThread)
1024 {
1025     string message = FormatException(pex, pszThread);
1026     printf("\n\n************************\n%s\n", message.c_str());
1027     fprintf(stderr, "\n\n************************\n%s\n", message.c_str());
1028     strMiscWarning = message;
1029     throw;
1030 }
1031
1032 void LogStackTrace() {
1033     printf("\n\n******* exception encountered *******\n");
1034     if (fileout)
1035     {
1036 #if !defined(WIN32) && !defined(ANDROID)
1037         void* pszBuffer[32];
1038         size_t size;
1039         size = backtrace(pszBuffer, 32);
1040         backtrace_symbols_fd(pszBuffer, size, fileno(fileout));
1041 #endif
1042     }
1043 }
1044
1045 void PrintExceptionContinue(exception* pex, const char* pszThread)
1046 {
1047     string message = FormatException(pex, pszThread);
1048     printf("\n\n************************\n%s\n", message.c_str());
1049     fprintf(stderr, "\n\n************************\n%s\n", message.c_str());
1050     strMiscWarning = message;
1051 }
1052
1053 boost::filesystem::path GetDefaultDataDir()
1054 {
1055     namespace fs = boost::filesystem;
1056     // Windows < Vista: C:\Documents and Settings\Username\Application Data\NovaCoin
1057     // Windows >= Vista: C:\Users\Username\AppData\Roaming\NovaCoin
1058     // Mac: ~/Library/Application Support/NovaCoin
1059     // Unix: ~/.novacoin
1060 #ifdef WIN32
1061     // Windows
1062     return GetSpecialFolderPath(CSIDL_APPDATA) / "NovaCoin";
1063 #else
1064     fs::path pathRet;
1065     char* pszHome = getenv("HOME");
1066     if (pszHome == NULL || strlen(pszHome) == 0)
1067         pathRet = fs::path("/");
1068     else
1069         pathRet = fs::path(pszHome);
1070 #ifdef MAC_OSX
1071     // Mac
1072     pathRet /= "Library/Application Support";
1073     fs::create_directory(pathRet);
1074     return pathRet / "NovaCoin";
1075 #else
1076     // Unix
1077     return pathRet / ".novacoin";
1078 #endif
1079 #endif
1080 }
1081
1082 const boost::filesystem::path &GetDataDir(bool fNetSpecific)
1083 {
1084     namespace fs = boost::filesystem;
1085
1086     static fs::path pathCached[2];
1087     static CCriticalSection csPathCached;
1088     static bool cachedPath[2] = {false, false};
1089
1090     fs::path &path = pathCached[fNetSpecific];
1091
1092     // This can be called during exceptions by printf, so we cache the
1093     // value so we don't have to do memory allocations after that.
1094     if (cachedPath[fNetSpecific])
1095         return path;
1096
1097     LOCK(csPathCached);
1098
1099     if (mapArgs.count("-datadir")) {
1100         path = fs::system_complete(mapArgs["-datadir"]);
1101         if (!fs::is_directory(path)) {
1102             path = "";
1103             return path;
1104         }
1105     } else {
1106         path = GetDefaultDataDir();
1107     }
1108     if (fNetSpecific && GetBoolArg("-testnet", false))
1109         path /= "testnet2";
1110
1111     fs::create_directory(path);
1112
1113     cachedPath[fNetSpecific]=true;
1114     return path;
1115 }
1116
1117 string randomStrGen(int length) {
1118     static string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
1119     string result;
1120     result.resize(length);
1121     for (int32_t i = 0; i < length; i++)
1122         result[i] = charset[rand() % charset.length()];
1123
1124     return result;
1125 }
1126
1127 void createConf()
1128 {
1129     srand(static_cast<unsigned int>(time(NULL)));
1130
1131     ofstream pConf;
1132 #if BOOST_FILESYSTEM_VERSION >= 3
1133     pConf.open(GetConfigFile().generic_string().c_str());
1134 #else
1135     pConf.open(GetConfigFile().string().c_str());
1136 #endif
1137     pConf << "rpcuser=user\nrpcpassword="
1138             + randomStrGen(15)
1139             + "\nrpcport=8344"
1140             + "\n#(0=off, 1=on) daemon - run in the background as a daemon and accept commands"
1141             + "\ndaemon=0"
1142             + "\n#(0=off, 1=on) server - accept command line and JSON-RPC commands"
1143             + "\nserver=0"
1144             + "\nrpcallowip=127.0.0.1";
1145     pConf.close();
1146 }
1147
1148 boost::filesystem::path GetConfigFile()
1149 {
1150     boost::filesystem::path pathConfigFile(GetArg("-conf", "novacoin.conf"));
1151     if (!pathConfigFile.is_complete()) pathConfigFile = GetDataDir(false) / pathConfigFile;
1152     return pathConfigFile;
1153 }
1154
1155 void ReadConfigFile(map<string, string>& mapSettingsRet,
1156                     map<string, vector<string> >& mapMultiSettingsRet)
1157 {
1158     boost::filesystem::ifstream streamConfig(GetConfigFile());
1159     if (!streamConfig.good())
1160     {
1161         createConf();
1162         new(&streamConfig) boost::filesystem::ifstream(GetConfigFile());
1163         if(!streamConfig.good())
1164             return;
1165     }
1166
1167     set<string> setOptions;
1168     setOptions.insert("*");
1169
1170     for (boost::program_options::detail::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it)
1171     {
1172         // Don't overwrite existing settings so command line settings override bitcoin.conf
1173         string strKey = string("-") + it->string_key;
1174         if (mapSettingsRet.count(strKey) == 0)
1175         {
1176             mapSettingsRet[strKey] = it->value[0];
1177             // interpret nofoo=1 as foo=0 (and nofoo=0 as foo=1) as long as foo not set)
1178             InterpretNegativeSetting(strKey, mapSettingsRet);
1179         }
1180         mapMultiSettingsRet[strKey].push_back(it->value[0]);
1181     }
1182 }
1183
1184 boost::filesystem::path GetPidFile()
1185 {
1186     boost::filesystem::path pathPidFile(GetArg("-pid", "novacoind.pid"));
1187     if (!pathPidFile.is_complete()) pathPidFile = GetDataDir() / pathPidFile;
1188     return pathPidFile;
1189 }
1190
1191 #ifndef WIN32
1192 void CreatePidFile(const boost::filesystem::path &path, pid_t pid)
1193 {
1194     FILE* file = fopen(path.string().c_str(), "w");
1195     if (file)
1196     {
1197         fprintf(file, "%d\n", pid);
1198         fclose(file);
1199     }
1200 }
1201 #endif
1202
1203 bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest)
1204 {
1205 #ifdef WIN32
1206     return MoveFileExA(src.string().c_str(), dest.string().c_str(),
1207                        MOVEFILE_REPLACE_EXISTING) != 0;
1208 #else
1209     int rc = rename(src.string().c_str(), dest.string().c_str());
1210     return (rc == 0);
1211 #endif /* WIN32 */
1212 }
1213
1214 void FileCommit(FILE *fileout)
1215 {
1216     fflush(fileout);                // harmless if redundantly called
1217 #ifdef WIN32
1218     _commit(_fileno(fileout));
1219 #else
1220     fsync(fileno(fileout));
1221 #endif
1222 }
1223
1224 int GetFilesize(FILE* file)
1225 {
1226     int nSavePos = ftell(file);
1227     int nFilesize = -1;
1228     if (fseek(file, 0, SEEK_END) == 0)
1229         nFilesize = ftell(file);
1230     fseek(file, nSavePos, SEEK_SET);
1231     return nFilesize;
1232 }
1233
1234 void ShrinkDebugFile()
1235 {
1236     // Scroll debug.log if it's getting too big
1237     boost::filesystem::path pathLog = GetDataDir() / "debug.log";
1238     FILE* file = fopen(pathLog.string().c_str(), "r");
1239     if (file && GetFilesize(file) > 10 * 1000000)
1240     {
1241         // Restart the file with some of the end
1242         try {
1243             vector<char>* vBuf = new vector <char>(200000, 0);
1244             fseek(file, -((long)(vBuf->size())), SEEK_END);
1245             size_t nBytes = fread(&vBuf->operator[](0), 1, vBuf->size(), file);
1246             fclose(file);
1247             file = fopen(pathLog.string().c_str(), "w");
1248             if (file)
1249             {
1250                 fwrite(&vBuf->operator[](0), 1, nBytes, file);
1251                 fclose(file);
1252             }
1253             delete vBuf;
1254         }
1255         catch (const bad_alloc& e) {
1256             // Bad things happen - no free memory in heap at program startup
1257             fclose(file);
1258             printf("Warning: %s in %s:%d\n ShrinkDebugFile failed - debug.log expands further", e.what(), __FILE__, __LINE__);
1259         }
1260     }
1261 }
1262
1263 //
1264 // "Never go to sea with two chronometers; take one or three."
1265 // Our three time sources are:
1266 //  - System clock
1267 //  - Median of other nodes clocks
1268 //  - The user (asking the user to fix the system clock if the first two disagree)
1269 //
1270
1271 // System clock
1272 int64_t GetTime()
1273 {
1274     int64_t now = time(NULL);
1275     assert(now > 0);
1276     return now;
1277 }
1278
1279 // Trusted NTP offset or median of NTP samples.
1280 extern int64_t nNtpOffset;
1281
1282 // Median of time samples given by other nodes.
1283 static int64_t nNodesOffset = numeric_limits<int64_t>::max();
1284
1285 // Select time offset:
1286 int64_t GetTimeOffset()
1287 {
1288     // If NTP and system clock are in agreement within 40 minutes, then use NTP.
1289     if (abs(nNtpOffset) < 40 * 60)
1290         return nNtpOffset;
1291
1292     // If not, then choose between median peer time and system clock.
1293     if (abs(nNodesOffset) < 70 * 60)
1294         return nNodesOffset;
1295
1296     return 0;
1297 }
1298
1299 int64_t GetNodesOffset()
1300 {
1301         return nNodesOffset;
1302 }
1303
1304 int64_t GetAdjustedTime()
1305 {
1306     return GetTime() + GetTimeOffset();
1307 }
1308
1309 void AddTimeData(const CNetAddr& ip, int64_t nTime)
1310 {
1311     int64_t nOffsetSample = nTime - GetTime();
1312
1313     // Ignore duplicates
1314     static set<CNetAddr> setKnown;
1315     if (!setKnown.insert(ip).second)
1316         return;
1317
1318     // Add data
1319     vTimeOffsets.input(nOffsetSample);
1320     printf("Added time data, samples %d, offset %+" PRId64 " (%+" PRId64 " minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);
1321     if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
1322     {
1323         auto nMedian = vTimeOffsets.median();
1324         auto vSorted = vTimeOffsets.sorted();
1325         // Only let other nodes change our time by so much
1326         if (abs(nMedian) < 70 * 60)
1327         {
1328             nNodesOffset = nMedian;
1329         }
1330         else
1331         {
1332             nNodesOffset = numeric_limits<int64_t>::max();
1333
1334             static bool fDone;
1335             if (!fDone)
1336             {
1337                 bool fMatch = false;
1338
1339                 // If nobody has a time different than ours but within 5 minutes of ours, give a warning
1340                 for(auto nOffset :  vSorted)
1341                     if (nOffset != 0 && abs(nOffset) < 5 * 60)
1342                         fMatch = true;
1343
1344                 if (!fMatch)
1345                 {
1346                     fDone = true;
1347                     string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong NovaCoin will not work properly.");
1348                     strMiscWarning = strMessage;
1349                     printf("*** %s\n", strMessage.c_str());
1350                     uiInterface.ThreadSafeMessageBox(strMessage+" ", string("NovaCoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION);
1351                 }
1352             }
1353         }
1354         if (fDebug) {
1355             for(int64_t n :  vSorted)
1356                 printf("%+" PRId64 "  ", n);
1357             printf("|  ");
1358         }
1359         if (nNodesOffset != numeric_limits<int64_t>::max())
1360             printf("nNodesOffset = %+" PRId64 "  (%+" PRId64 " minutes)\n", nNodesOffset, nNodesOffset/60);
1361     }
1362 }
1363
1364 string FormatVersion(int nVersion)
1365 {
1366     if (nVersion%100 == 0)
1367         return strprintf("%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100);
1368     else
1369         return strprintf("%d.%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100, nVersion%100);
1370 }
1371
1372 string FormatFullVersion()
1373 {
1374     return CLIENT_BUILD;
1375 }
1376
1377 // Format the subversion field according to BIP 14 spec (https://en.bitcoin.it/wiki/BIP_0014)
1378 string FormatSubVersion(const string& name, int nClientVersion, const vector<string>& comments)
1379 {
1380     ostringstream ss;
1381     ss << "/";
1382     ss << name << ":" << FormatVersion(nClientVersion);
1383     if (!comments.empty())
1384         ss << "(" << boost::algorithm::join(comments, "; ") << ")";
1385     ss << "/";
1386     return ss.str();
1387 }
1388
1389 #ifdef WIN32
1390 boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate)
1391 {
1392     namespace fs = boost::filesystem;
1393
1394     char pszPath[MAX_PATH] = "";
1395
1396     if(SHGetSpecialFolderPathA(NULL, pszPath, nFolder, fCreate))
1397     {
1398         return fs::path(pszPath);
1399     }
1400
1401     printf("SHGetSpecialFolderPathA() failed, could not obtain requested path.\n");
1402     return fs::path("");
1403 }
1404 #endif
1405
1406 void runCommand(string strCommand)
1407 {
1408     int nErr = ::system(strCommand.c_str());
1409     if (nErr)
1410         printf("runCommand error: system(%s) returned %d\n", strCommand.c_str(), nErr);
1411 }
1412
1413 void RenameThread(const char* name)
1414 {
1415 #if defined(PR_SET_NAME)
1416     // Only the first 15 characters are used (16 - NUL terminator)
1417     ::prctl(PR_SET_NAME, name, 0, 0, 0);
1418 #elif 0 && (defined(__FreeBSD__) || defined(__OpenBSD__))
1419     // TODO: This is currently disabled because it needs to be verified to work
1420     //       on FreeBSD or OpenBSD first. When verified the '0 &&' part can be
1421     //       removed.
1422     pthread_set_name_np(pthread_self(), name);
1423
1424 // This is XCode 10.6-and-later; bring back if we drop 10.5 support:
1425 // #elif defined(MAC_OSX)
1426 //    pthread_setname_np(name);
1427
1428 #else
1429     // Prevent warnings for unused parameters...
1430     (void)name;
1431 #endif
1432 }
1433
1434 bool NewThread(void(*pfn)(void*), void* parg)
1435 {
1436     try
1437     {
1438         boost::thread(pfn, parg); // thread detaches when out of scope
1439     } catch(boost::thread_resource_error &e) {
1440         printf("Error creating thread: %s\n", e.what());
1441         return false;
1442     }
1443     return true;
1444 }
1445
1446 string DateTimeStrFormat(const char* pszFormat, int64_t nTime)
1447 {
1448     // locale takes ownership of the pointer
1449     locale loc(locale::classic(), new boost::posix_time::time_facet(pszFormat));
1450     stringstream ss;
1451     ss.imbue(loc);
1452     ss << boost::posix_time::from_time_t(nTime);
1453     return ss.str();
1454 }