Remove boost foreach macro
[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 "interface.h"
10
11 #include <boost/algorithm/string/join.hpp>
12 #include <boost/algorithm/string/case_conv.hpp> // for to_lower()
13 #include <boost/algorithm/string/predicate.hpp> // for startswith() and endswith()
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 #include <openssl/crypto.h>
21 #include <openssl/rand.h>
22
23 #ifdef WIN32
24 #include <io.h> /* for _commit */
25 #include "shlobj.h"
26 #elif defined(__linux__)
27 # include <sys/prctl.h>
28 #endif
29
30 #if !defined(WIN32) && !defined(ANDROID)
31 #include <execinfo.h>
32 #endif
33
34
35 using namespace std;
36 namespace bt = boost::posix_time;
37
38 map<string, string> mapArgs;
39 map<string, vector<string> > mapMultiArgs;
40 bool fDebug = false;
41 bool fDebugNet = false;
42 bool fPrintToConsole = false;
43 bool fPrintToDebugger = false;
44 bool fRequestShutdown = false;
45 bool fShutdown = false;
46 bool fDaemon = false;
47 bool fServer = false;
48 bool fCommandLine = false;
49 string strMiscWarning;
50 bool fTestNet = false;
51 bool fNoListen = false;
52 bool fLogTimestamps = false;
53 CMedianFilter<int64_t> vTimeOffsets(200,0);
54 bool fReopenDebugLog = false;
55
56 // Extended DecodeDumpTime implementation, see this page for details:
57 // http://stackoverflow.com/questions/3786201/parsing-of-date-time-from-string-boost
58 const std::locale formats[] = {
59     std::locale(std::locale::classic(),new bt::time_input_facet("%Y-%m-%dT%H:%M:%SZ")),
60     std::locale(std::locale::classic(),new bt::time_input_facet("%Y-%m-%d %H:%M:%S")),
61     std::locale(std::locale::classic(),new bt::time_input_facet("%Y/%m/%d %H:%M:%S")),
62     std::locale(std::locale::classic(),new bt::time_input_facet("%d.%m.%Y %H:%M:%S")),
63     std::locale(std::locale::classic(),new bt::time_input_facet("%Y-%m-%d"))
64 };
65
66 const size_t formats_n = sizeof(formats)/sizeof(formats[0]);
67
68 std::time_t pt_to_time_t(const bt::ptime& pt)
69 {
70     bt::ptime timet_start(boost::gregorian::date(1970,1,1));
71     bt::time_duration diff = pt - timet_start;
72     return diff.ticks()/bt::time_duration::rep_type::ticks_per_second;
73 }
74
75 // Init OpenSSL library multithreading support
76 static CCriticalSection** ppmutexOpenSSL;
77 void locking_callback(int mode, int i, const char* file, int line)
78 {
79     if (mode & CRYPTO_LOCK) {
80         ENTER_CRITICAL_SECTION(*ppmutexOpenSSL[i]);
81     } else {
82         LEAVE_CRITICAL_SECTION(*ppmutexOpenSSL[i]);
83     }
84 }
85
86 LockedPageManager LockedPageManager::instance;
87
88 // Init
89 class CInit
90 {
91 public:
92     CInit()
93     {
94         // Init OpenSSL library multithreading support
95         ppmutexOpenSSL = (CCriticalSection**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(CCriticalSection*));
96         for (int i = 0; i < CRYPTO_num_locks(); i++)
97             ppmutexOpenSSL[i] = new CCriticalSection();
98         CRYPTO_set_locking_callback(locking_callback);
99
100 #ifdef WIN32
101         // Seed random number generator with screen scrape and other hardware sources
102         RAND_screen();
103 #endif
104
105         // Seed random number generator with performance counter
106         RandAddSeed();
107     }
108     ~CInit()
109     {
110         // Shutdown OpenSSL library multithreading support
111         CRYPTO_set_locking_callback(NULL);
112         for (int i = 0; i < CRYPTO_num_locks(); i++)
113             delete ppmutexOpenSSL[i];
114         OPENSSL_free(ppmutexOpenSSL);
115     }
116 }
117 instance_of_cinit;
118
119
120
121
122
123
124
125
126 void RandAddSeed()
127 {
128     // Seed with CPU performance counter
129     int64_t nCounter = GetPerformanceCounter();
130     RAND_add(&nCounter, sizeof(nCounter), 1.5);
131     memset(&nCounter, 0, sizeof(nCounter));
132 }
133
134 void RandAddSeedPerfmon()
135 {
136     RandAddSeed();
137
138     // This can take up to 2 seconds, so only do it every 10 minutes
139     static int64_t nLastPerfmon;
140     if (GetTime() < nLastPerfmon + 10 * 60)
141         return;
142     nLastPerfmon = GetTime();
143
144 #ifdef WIN32
145     // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
146     // Seed with the entire set of perfmon data
147     unsigned char pdata[250000];
148     memset(pdata, 0, sizeof(pdata));
149     unsigned long nSize = sizeof(pdata);
150     long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
151     RegCloseKey(HKEY_PERFORMANCE_DATA);
152     if (ret == ERROR_SUCCESS)
153     {
154         RAND_add(pdata, nSize, nSize/100.0);
155         OPENSSL_cleanse(pdata, nSize);
156         printf("RandAddSeed() %lu bytes\n", nSize);
157     }
158 #endif
159 }
160
161 uint64_t GetRand(uint64_t nMax)
162 {
163     if (nMax == 0)
164         return 0;
165
166     // The range of the random source must be a multiple of the modulus
167     // to give every possible output value an equal possibility
168     uint64_t nRange = (std::numeric_limits<uint64_t>::max() / nMax) * nMax;
169     uint64_t nRand = 0;
170     do
171         RAND_bytes((unsigned char*)&nRand, sizeof(nRand));
172     while (nRand >= nRange);
173     return (nRand % nMax);
174 }
175
176 int GetRandInt(int nMax)
177 {
178     return static_cast<int>(GetRand(nMax));
179 }
180
181 uint256 GetRandHash()
182 {
183     uint256 hash;
184     RAND_bytes((unsigned char*)&hash, sizeof(hash));
185     return hash;
186 }
187
188
189
190
191
192
193 static FILE* fileout = NULL;
194
195 inline int OutputDebugStringF(const char* pszFormat, ...)
196 {
197     int ret = 0;
198     if (fPrintToConsole)
199     {
200         // print to console
201         va_list arg_ptr;
202         va_start(arg_ptr, pszFormat);
203         ret = vprintf(pszFormat, arg_ptr);
204         va_end(arg_ptr);
205     }
206     else if (!fPrintToDebugger)
207     {
208         // print to debug.log
209
210         if (!fileout)
211         {
212             boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
213             fileout = fopen(pathDebug.string().c_str(), "a");
214             if (fileout) setbuf(fileout, NULL); // unbuffered
215         }
216         if (fileout)
217         {
218             static bool fStartedNewLine = true;
219
220             // This routine may be called by global destructors during shutdown.
221             // Since the order of destruction of static/global objects is undefined,
222             // allocate mutexDebugLog on the heap the first time this routine
223             // is called to avoid crashes during shutdown.
224             static boost::mutex* mutexDebugLog = NULL;
225             if (mutexDebugLog == NULL) mutexDebugLog = new boost::mutex();
226             boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
227
228             // reopen the log file, if requested
229             if (fReopenDebugLog) {
230                 fReopenDebugLog = false;
231                 boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
232                 if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL)
233                     setbuf(fileout, NULL); // unbuffered
234             }
235
236             // Debug print useful for profiling
237             if (fLogTimestamps && fStartedNewLine)
238                 fprintf(fileout, "%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
239             if (pszFormat[strlen(pszFormat) - 1] == '\n')
240                 fStartedNewLine = true;
241             else
242                 fStartedNewLine = false;
243
244             va_list arg_ptr;
245             va_start(arg_ptr, pszFormat);
246             ret = vfprintf(fileout, pszFormat, arg_ptr);
247             va_end(arg_ptr);
248         }
249     }
250
251 #ifdef WIN32
252     if (fPrintToDebugger)
253     {
254         static CCriticalSection cs_OutputDebugStringF;
255
256         // accumulate and output a line at a time
257         {
258             LOCK(cs_OutputDebugStringF);
259             static std::string buffer;
260
261             va_list arg_ptr;
262             va_start(arg_ptr, pszFormat);
263             buffer += vstrprintf(pszFormat, arg_ptr);
264             va_end(arg_ptr);
265
266             size_t line_start = 0, line_end;
267             while((line_end = buffer.find('\n', line_start)) != -1)
268             {
269                 OutputDebugStringA(buffer.substr(line_start, line_end - line_start).c_str());
270                 line_start = line_end + 1;
271             }
272             buffer.erase(0, line_start);
273         }
274     }
275 #endif
276     return ret;
277 }
278
279 string vstrprintf(const char *format, va_list ap)
280 {
281     char buffer[50000];
282     char* p = buffer;
283     int limit = sizeof(buffer);
284     int ret;
285     for ( ; ; )
286     {
287 #ifndef _MSC_VER
288         va_list arg_ptr;
289         va_copy(arg_ptr, ap);
290 #else
291         va_list arg_ptr = ap;
292 #endif
293 #ifdef WIN32
294         ret = _vsnprintf(p, limit, format, arg_ptr);
295 #else
296         ret = vsnprintf(p, limit, format, arg_ptr);
297 #endif
298         va_end(arg_ptr);
299         if (ret >= 0 && ret < limit)
300             break;
301         if (p != buffer)
302             delete[] p;
303         limit *= 2;
304         p = new(nothrow) char[limit];
305         if (p == NULL)
306             throw std::bad_alloc();
307     }
308     string str(p, p+ret);
309     if (p != buffer)
310         delete[] p;
311     return str;
312 }
313
314 string real_strprintf(const char *format, int dummy, ...)
315 {
316     va_list arg_ptr;
317     va_start(arg_ptr, dummy);
318     string str = vstrprintf(format, arg_ptr);
319     va_end(arg_ptr);
320     return str;
321 }
322
323 string real_strprintf(const std::string &format, int dummy, ...)
324 {
325     va_list arg_ptr;
326     va_start(arg_ptr, dummy);
327     string str = vstrprintf(format.c_str(), arg_ptr);
328     va_end(arg_ptr);
329     return str;
330 }
331
332 bool error(const char *format, ...)
333 {
334     va_list arg_ptr;
335     va_start(arg_ptr, format);
336     std::string str = vstrprintf(format, arg_ptr);
337     va_end(arg_ptr);
338     printf("ERROR: %s\n", str.c_str());
339     return false;
340 }
341
342
343 void ParseString(const string& str, char c, vector<string>& v)
344 {
345     if (str.empty())
346         return;
347     string::size_type i1 = 0;
348     string::size_type i2;
349     for ( ; ; )
350     {
351         i2 = str.find(c, i1);
352         if (i2 == str.npos)
353         {
354             v.push_back(str.substr(i1));
355             return;
356         }
357         v.push_back(str.substr(i1, i2-i1));
358         i1 = i2+1;
359     }
360 }
361
362
363 string FormatMoney(int64_t n, bool fPlus)
364 {
365     // Note: not using straight sprintf here because we do NOT want
366     // localized number formatting.
367     int64_t n_abs = (n > 0 ? n : -n);
368     int64_t quotient = n_abs/COIN;
369     int64_t remainder = n_abs%COIN;
370     string str = strprintf("%" PRId64 ".%06" PRId64, quotient, remainder);
371
372     // Right-trim excess zeros before the decimal point:
373     size_t nTrim = 0;
374     for (size_t i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i)
375         ++nTrim;
376     if (nTrim)
377         str.erase(str.size()-nTrim, nTrim);
378
379     if (n < 0)
380         str.insert(0u, 1, '-');
381     else if (fPlus && n > 0)
382         str.insert(0u, 1, '+');
383     return str;
384 }
385
386
387 bool ParseMoney(const string& str, int64_t& nRet)
388 {
389     return ParseMoney(str.c_str(), nRet);
390 }
391
392 bool ParseMoney(const char* pszIn, int64_t& nRet)
393 {
394     string strWhole;
395     int64_t nUnits = 0;
396     const char* p = pszIn;
397     while (isspace(*p))
398         p++;
399     for (; *p; p++)
400     {
401         if (*p == '.')
402         {
403             p++;
404             int64_t nMult = CENT*10;
405             while (isdigit(*p) && (nMult > 0))
406             {
407                 nUnits += nMult * (*p++ - '0');
408                 nMult /= 10;
409             }
410             break;
411         }
412         if (isspace(*p))
413             break;
414         if (!isdigit(*p))
415             return false;
416         strWhole.insert(strWhole.end(), *p);
417     }
418     for (; *p; p++)
419         if (!isspace(*p))
420             return false;
421     if (strWhole.size() > 10) // guard against 63 bit overflow
422         return false;
423     if (nUnits < 0 || nUnits > COIN)
424         return false;
425     int64_t nWhole = atoi64(strWhole);
426     int64_t nValue = nWhole*COIN + nUnits;
427
428     nRet = nValue;
429     return true;
430 }
431
432
433 static const signed char phexdigit[256] =
434 { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
435   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
436   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
437   0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
438   -1,0xa,0xb,0xc,0xd,0xe,0xf,-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,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
441   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
442   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
443   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
444   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
445   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
446   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
447   -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
451 bool IsHex(const string& str)
452 {
453     for (unsigned char c : str)
454     {
455         if (phexdigit[c] < 0)
456             return false;
457     }
458     return (str.size() > 0) && (str.size()%2 == 0);
459 }
460
461 vector<unsigned char> ParseHex(const char* psz)
462 {
463     // convert hex dump to vector
464     vector<unsigned char> vch;
465     for ( ; ; )
466     {
467         while (isspace(*psz))
468             psz++;
469         signed char c = phexdigit[(unsigned char)*psz++];
470         if (c == (signed char)-1)
471             break;
472         unsigned char n = (c << 4);
473         c = phexdigit[(unsigned char)*psz++];
474         if (c == (signed char)-1)
475             break;
476         n |= c;
477         vch.push_back(n);
478     }
479     return vch;
480 }
481
482 vector<unsigned char> ParseHex(const string& str)
483 {
484     return ParseHex(str.c_str());
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         std::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         std::string str(argv[i]);
509         std::string strValue;
510         size_t is_index = str.find('=');
511         if (is_index != std::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 (boost::algorithm::starts_with(str, "/"))
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             std::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 std::string GetArg(const std::string& strArg, const std::string& strDefault)
548 {
549     if (mapArgs.count(strArg))
550         return mapArgs[strArg];
551     return strDefault;
552 }
553
554 int64_t GetArg(const std::string& strArg, int64_t nDefault)
555 {
556     if (mapArgs.count(strArg))
557         return atoi64(mapArgs[strArg]);
558     return nDefault;
559 }
560
561 int32_t GetArgInt(const std::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 std::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 std::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 std::string& strArg, const std::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 std::string& strArg, bool fValue)
597 {
598     if (fValue)
599         return SoftSetArg(strArg, std::string("1"));
600     else
601         return SoftSetArg(strArg, std::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 std::string& s)
934 {
935     bt::ptime pt;
936
937     for(size_t i=0; i<formats_n; ++i)
938     {
939         std::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 std::string EncodeDumpTime(int64_t nTime) {
949     return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime);
950 }
951
952 std::string EncodeDumpString(const std::string &str) {
953     std::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 std::string DecodeDumpString(const std::string &str) {
965     std::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
1009
1010
1011
1012
1013
1014 static std::string FormatException(std::exception* pex, const char* pszThread)
1015 {
1016 #ifdef WIN32
1017     char pszModule[MAX_PATH] = "";
1018     GetModuleFileNameA(NULL, pszModule, sizeof(pszModule));
1019 #else
1020     const char* pszModule = "novacoin";
1021 #endif
1022     if (pex)
1023         return strprintf(
1024             "EXCEPTION: %s       \n%s       \n%s in %s       \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
1025     else
1026         return strprintf(
1027             "UNKNOWN EXCEPTION       \n%s in %s       \n", pszModule, pszThread);
1028 }
1029
1030 void LogException(std::exception* pex, const char* pszThread)
1031 {
1032     std::string message = FormatException(pex, pszThread);
1033     printf("\n%s", message.c_str());
1034 }
1035
1036 void PrintException(std::exception* pex, const char* pszThread)
1037 {
1038     std::string message = FormatException(pex, pszThread);
1039     printf("\n\n************************\n%s\n", message.c_str());
1040     fprintf(stderr, "\n\n************************\n%s\n", message.c_str());
1041     strMiscWarning = message;
1042     throw;
1043 }
1044
1045 void LogStackTrace() {
1046     printf("\n\n******* exception encountered *******\n");
1047     if (fileout)
1048     {
1049 #if !defined(WIN32) && !defined(ANDROID)
1050         void* pszBuffer[32];
1051         size_t size;
1052         size = backtrace(pszBuffer, 32);
1053         backtrace_symbols_fd(pszBuffer, size, fileno(fileout));
1054 #endif
1055     }
1056 }
1057
1058 void PrintExceptionContinue(std::exception* pex, const char* pszThread)
1059 {
1060     std::string message = FormatException(pex, pszThread);
1061     printf("\n\n************************\n%s\n", message.c_str());
1062     fprintf(stderr, "\n\n************************\n%s\n", message.c_str());
1063     strMiscWarning = message;
1064 }
1065
1066 boost::filesystem::path GetDefaultDataDir()
1067 {
1068     namespace fs = boost::filesystem;
1069     // Windows < Vista: C:\Documents and Settings\Username\Application Data\NovaCoin
1070     // Windows >= Vista: C:\Users\Username\AppData\Roaming\NovaCoin
1071     // Mac: ~/Library/Application Support/NovaCoin
1072     // Unix: ~/.novacoin
1073 #ifdef WIN32
1074     // Windows
1075     return GetSpecialFolderPath(CSIDL_APPDATA) / "NovaCoin";
1076 #else
1077     fs::path pathRet;
1078     char* pszHome = getenv("HOME");
1079     if (pszHome == NULL || strlen(pszHome) == 0)
1080         pathRet = fs::path("/");
1081     else
1082         pathRet = fs::path(pszHome);
1083 #ifdef __APPLE__
1084     // Mac
1085     pathRet /= "Library/Application Support";
1086     fs::create_directory(pathRet);
1087     return pathRet / "NovaCoin";
1088 #else
1089     // Unix
1090     return pathRet / ".novacoin";
1091 #endif
1092 #endif
1093 }
1094
1095 const boost::filesystem::path &GetDataDir(bool fNetSpecific)
1096 {
1097     namespace fs = boost::filesystem;
1098
1099     static fs::path pathCached[2];
1100     static CCriticalSection csPathCached;
1101     static bool cachedPath[2] = {false, false};
1102
1103     fs::path &path = pathCached[fNetSpecific];
1104
1105     // This can be called during exceptions by printf, so we cache the
1106     // value so we don't have to do memory allocations after that.
1107     if (cachedPath[fNetSpecific])
1108         return path;
1109
1110     LOCK(csPathCached);
1111
1112     if (mapArgs.count("-datadir")) {
1113         path = fs::system_complete(mapArgs["-datadir"]);
1114         if (!fs::is_directory(path)) {
1115             path = "";
1116             return path;
1117         }
1118     } else {
1119         path = GetDefaultDataDir();
1120     }
1121     if (fNetSpecific && GetBoolArg("-testnet", false))
1122         path /= "testnet2";
1123
1124     fs::create_directory(path);
1125
1126     cachedPath[fNetSpecific]=true;
1127     return path;
1128 }
1129
1130 string randomStrGen(int length) {
1131     static string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
1132     string result;
1133     result.resize(length);
1134     for (int32_t i = 0; i < length; i++)
1135         result[i] = charset[rand() % charset.length()];
1136
1137     return result;
1138 }
1139
1140 void createConf()
1141 {
1142     srand(static_cast<unsigned int>(time(NULL)));
1143
1144     ofstream pConf;
1145 #if BOOST_FILESYSTEM_VERSION >= 3
1146     pConf.open(GetConfigFile().generic_string().c_str());
1147 #else
1148     pConf.open(GetConfigFile().string().c_str());
1149 #endif
1150     pConf << "rpcuser=user\nrpcpassword="
1151             + randomStrGen(15)
1152             + "\nrpcport=8344"
1153             + "\n#(0=off, 1=on) daemon - run in the background as a daemon and accept commands"
1154             + "\ndaemon=0"
1155             + "\n#(0=off, 1=on) server - accept command line and JSON-RPC commands"
1156             + "\nserver=0"
1157             + "\nrpcallowip=127.0.0.1";
1158     pConf.close();
1159 }
1160
1161 boost::filesystem::path GetConfigFile()
1162 {
1163     boost::filesystem::path pathConfigFile(GetArg("-conf", "novacoin.conf"));
1164     if (!pathConfigFile.is_complete()) pathConfigFile = GetDataDir(false) / pathConfigFile;
1165     return pathConfigFile;
1166 }
1167
1168 void ReadConfigFile(map<string, string>& mapSettingsRet,
1169                     map<string, vector<string> >& mapMultiSettingsRet)
1170 {
1171     boost::filesystem::ifstream streamConfig(GetConfigFile());
1172     if (!streamConfig.good())
1173     {
1174         createConf();
1175         new(&streamConfig) boost::filesystem::ifstream(GetConfigFile());
1176         if(!streamConfig.good())
1177             return;
1178     }
1179
1180     set<string> setOptions;
1181     setOptions.insert("*");
1182
1183     for (boost::program_options::detail::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it)
1184     {
1185         // Don't overwrite existing settings so command line settings override bitcoin.conf
1186         string strKey = string("-") + it->string_key;
1187         if (mapSettingsRet.count(strKey) == 0)
1188         {
1189             mapSettingsRet[strKey] = it->value[0];
1190             // interpret nofoo=1 as foo=0 (and nofoo=0 as foo=1) as long as foo not set)
1191             InterpretNegativeSetting(strKey, mapSettingsRet);
1192         }
1193         mapMultiSettingsRet[strKey].push_back(it->value[0]);
1194     }
1195 }
1196
1197 boost::filesystem::path GetPidFile()
1198 {
1199     boost::filesystem::path pathPidFile(GetArg("-pid", "novacoind.pid"));
1200     if (!pathPidFile.is_complete()) pathPidFile = GetDataDir() / pathPidFile;
1201     return pathPidFile;
1202 }
1203
1204 #ifndef WIN32
1205 void CreatePidFile(const boost::filesystem::path &path, pid_t pid)
1206 {
1207     FILE* file = fopen(path.string().c_str(), "w");
1208     if (file)
1209     {
1210         fprintf(file, "%d\n", pid);
1211         fclose(file);
1212     }
1213 }
1214 #endif
1215
1216 bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest)
1217 {
1218 #ifdef WIN32
1219     return MoveFileExA(src.string().c_str(), dest.string().c_str(),
1220                        MOVEFILE_REPLACE_EXISTING) != 0;
1221 #else
1222     int rc = std::rename(src.string().c_str(), dest.string().c_str());
1223     return (rc == 0);
1224 #endif /* WIN32 */
1225 }
1226
1227 void FileCommit(FILE *fileout)
1228 {
1229     fflush(fileout);                // harmless if redundantly called
1230 #ifdef WIN32
1231     _commit(_fileno(fileout));
1232 #else
1233     fsync(fileno(fileout));
1234 #endif
1235 }
1236
1237 int GetFilesize(FILE* file)
1238 {
1239     int nSavePos = ftell(file);
1240     int nFilesize = -1;
1241     if (fseek(file, 0, SEEK_END) == 0)
1242         nFilesize = ftell(file);
1243     fseek(file, nSavePos, SEEK_SET);
1244     return nFilesize;
1245 }
1246
1247 void ShrinkDebugFile()
1248 {
1249     // Scroll debug.log if it's getting too big
1250     boost::filesystem::path pathLog = GetDataDir() / "debug.log";
1251     FILE* file = fopen(pathLog.string().c_str(), "r");
1252     if (file && GetFilesize(file) > 10 * 1000000)
1253     {
1254         // Restart the file with some of the end
1255         try {
1256             vector<char>* vBuf = new vector <char>(200000, 0);
1257             fseek(file, -((long)(vBuf->size())), SEEK_END);
1258             size_t nBytes = fread(&vBuf->operator[](0), 1, vBuf->size(), file);
1259             fclose(file);
1260             file = fopen(pathLog.string().c_str(), "w");
1261             if (file)
1262             {
1263                 fwrite(&vBuf->operator[](0), 1, nBytes, file);
1264                 fclose(file);
1265             }
1266             delete vBuf;
1267         }
1268         catch (const bad_alloc& e) {
1269             // Bad things happen - no free memory in heap at program startup
1270             fclose(file);
1271             printf("Warning: %s in %s:%d\n ShrinkDebugFile failed - debug.log expands further", e.what(), __FILE__, __LINE__);
1272         }
1273     }
1274 }
1275
1276
1277
1278
1279
1280
1281
1282
1283 //
1284 // "Never go to sea with two chronometers; take one or three."
1285 // Our three time sources are:
1286 //  - System clock
1287 //  - Median of other nodes clocks
1288 //  - The user (asking the user to fix the system clock if the first two disagree)
1289 //
1290
1291 // System clock
1292 int64_t GetTime()
1293 {
1294     int64_t now = time(NULL);
1295     assert(now > 0);
1296     return now;
1297 }
1298
1299 // Trusted NTP offset or median of NTP samples.
1300 extern int64_t nNtpOffset;
1301
1302 // Median of time samples given by other nodes.
1303 static int64_t nNodesOffset = INT64_MAX;
1304
1305 // Select time offset:
1306 int64_t GetTimeOffset()
1307 {
1308     // If NTP and system clock are in agreement within 40 minutes, then use NTP.
1309     if (abs64(nNtpOffset) < 40 * 60)
1310         return nNtpOffset;
1311
1312     // If not, then choose between median peer time and system clock.
1313     if (abs64(nNodesOffset) < 70 * 60)
1314         return nNodesOffset;
1315
1316     return 0;
1317 }
1318
1319 int64_t GetNodesOffset()
1320 {
1321         return nNodesOffset;
1322 }
1323
1324 int64_t GetAdjustedTime()
1325 {
1326     return GetTime() + GetTimeOffset();
1327 }
1328
1329 void AddTimeData(const CNetAddr& ip, int64_t nTime)
1330 {
1331     int64_t nOffsetSample = nTime - GetTime();
1332
1333     // Ignore duplicates
1334     static set<CNetAddr> setKnown;
1335     if (!setKnown.insert(ip).second)
1336         return;
1337
1338     // Add data
1339     vTimeOffsets.input(nOffsetSample);
1340     printf("Added time data, samples %d, offset %+" PRId64 " (%+" PRId64 " minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);
1341     if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
1342     {
1343         int64_t nMedian = vTimeOffsets.median();
1344         std::vector<int64_t> vSorted = vTimeOffsets.sorted();
1345         // Only let other nodes change our time by so much
1346         if (abs64(nMedian) < 70 * 60)
1347         {
1348             nNodesOffset = nMedian;
1349         }
1350         else
1351         {
1352             nNodesOffset = INT64_MAX;
1353
1354             static bool fDone;
1355             if (!fDone)
1356             {
1357                 bool fMatch = false;
1358
1359                 // If nobody has a time different than ours but within 5 minutes of ours, give a warning
1360                 for (int64_t nOffset : vSorted)
1361                     if (nOffset != 0 && abs64(nOffset) < 5 * 60)
1362                         fMatch = true;
1363
1364                 if (!fMatch)
1365                 {
1366                     fDone = true;
1367                     string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong NovaCoin will not work properly.");
1368                     strMiscWarning = strMessage;
1369                     printf("*** %s\n", strMessage.c_str());
1370                     uiInterface.ThreadSafeMessageBox(strMessage+" ", string("NovaCoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION);
1371                 }
1372             }
1373         }
1374         if (fDebug) {
1375             for (int64_t n : vSorted)
1376                 printf("%+" PRId64 "  ", n);
1377             printf("|  ");
1378         }
1379         if (nNodesOffset != INT64_MAX)
1380             printf("nNodesOffset = %+" PRId64 "  (%+" PRId64 " minutes)\n", nNodesOffset, nNodesOffset/60);
1381     }
1382 }
1383
1384 string FormatVersion(int nVersion)
1385 {
1386     if (nVersion%100 == 0)
1387         return strprintf("%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100);
1388     else
1389         return strprintf("%d.%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100, nVersion%100);
1390 }
1391
1392 string FormatFullVersion()
1393 {
1394     return CLIENT_BUILD;
1395 }
1396
1397 // Format the subversion field according to BIP 14 spec (https://en.bitcoin.it/wiki/BIP_0014)
1398 std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments)
1399 {
1400     std::ostringstream ss;
1401     ss << "/";
1402     ss << name << ":" << FormatVersion(nClientVersion);
1403     if (!comments.empty())
1404         ss << "(" << boost::algorithm::join(comments, "; ") << ")";
1405     ss << "/";
1406     return ss.str();
1407 }
1408
1409 #ifdef WIN32
1410 boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate)
1411 {
1412     namespace fs = boost::filesystem;
1413
1414     char pszPath[MAX_PATH] = "";
1415
1416     if(SHGetSpecialFolderPathA(NULL, pszPath, nFolder, fCreate))
1417     {
1418         return fs::path(pszPath);
1419     }
1420
1421     printf("SHGetSpecialFolderPathA() failed, could not obtain requested path.\n");
1422     return fs::path("");
1423 }
1424 #endif
1425
1426 void runCommand(std::string strCommand)
1427 {
1428     int nErr = ::system(strCommand.c_str());
1429     if (nErr)
1430         printf("runCommand error: system(%s) returned %d\n", strCommand.c_str(), nErr);
1431 }
1432
1433 void RenameThread(const char* name)
1434 {
1435 #if defined(PR_SET_NAME)
1436     // Only the first 15 characters are used (16 - NUL terminator)
1437     ::prctl(PR_SET_NAME, name, 0, 0, 0);
1438 #elif (defined(__FreeBSD__) || defined(__OpenBSD__))
1439     pthread_set_name_np(pthread_self(), name);
1440 #elif defined(__APPLE__)
1441     pthread_setname_np(name);
1442 #else
1443     // Prevent warnings for unused parameters...
1444     (void)name;
1445 #endif
1446 }
1447
1448 bool NewThread(void(*pfn)(void*), void* parg)
1449 {
1450     try
1451     {
1452         boost::thread(pfn, parg); // thread detaches when out of scope
1453     } catch(boost::thread_resource_error &e) {
1454         printf("Error creating thread: %s\n", e.what());
1455         return false;
1456     }
1457     return true;
1458 }
1459
1460 std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime)
1461 {
1462     // std::locale takes ownership of the pointer
1463     std::locale loc(std::locale::classic(), new boost::posix_time::time_facet(pszFormat));
1464     std::stringstream ss;
1465     ss.imbue(loc);
1466     ss << boost::posix_time::from_time_t(nTime);
1467     return ss.str();
1468 }