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