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