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