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