3ad31dd6c246188e9448dc4e7e30c3da675ec8d4
[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 license.txt or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "util.h"
7 #include "strlcpy.h"
8 #include "version.h"
9 #include "ui_interface.h"
10 #include <boost/algorithm/string/join.hpp>
11
12 // Work around clang compilation problem in Boost 1.46:
13 // /usr/include/boost/program_options/detail/config_file.hpp:163:17: error: call to function 'to_internal' that is neither visible in the template definition nor found by argument-dependent lookup
14 // See also: http://stackoverflow.com/questions/10020179/compilation-fail-in-boost-librairies-program-options
15 //           http://clang.debian.net/status.php?version=3.0&key=CANNOT_FIND_FUNCTION
16 namespace boost {
17     namespace program_options {
18         std::string to_internal(const std::string&);
19     }
20 }
21
22 #include <boost/program_options/detail/config_file.hpp>
23 #include <boost/program_options/parsers.hpp>
24 #include <boost/filesystem.hpp>
25 #include <boost/filesystem/fstream.hpp>
26 #include <boost/interprocess/sync/interprocess_mutex.hpp>
27 #include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
28 #include <boost/foreach.hpp>
29 #include <openssl/crypto.h>
30 #include <openssl/rand.h>
31
32 #ifdef WIN32
33 #ifdef _MSC_VER
34 #pragma warning(disable:4786)
35 #pragma warning(disable:4804)
36 #pragma warning(disable:4805)
37 #pragma warning(disable:4717)
38 #endif
39 #ifdef _WIN32_WINNT
40 #undef _WIN32_WINNT
41 #endif
42 #define _WIN32_WINNT 0x0501
43 #ifdef _WIN32_IE
44 #undef _WIN32_IE
45 #endif
46 #define _WIN32_IE 0x0400
47 #define WIN32_LEAN_AND_MEAN 1
48 #ifndef NOMINMAX
49 #define NOMINMAX
50 #endif
51 #include "shlobj.h"
52 #include "shlwapi.h"
53 #endif
54
55 using namespace std;
56 using namespace boost;
57
58 map<string, string> mapArgs;
59 map<string, vector<string> > mapMultiArgs;
60 bool fDebug = false;
61 bool fPrintToConsole = false;
62 bool fPrintToDebugger = false;
63 bool fRequestShutdown = false;
64 bool fShutdown = false;
65 bool fDaemon = false;
66 bool fServer = false;
67 bool fCommandLine = false;
68 string strMiscWarning;
69 bool fTestNet = false;
70 bool fNoListen = false;
71 bool fLogTimestamps = false;
72 CMedianFilter<int64> vTimeOffsets(200,0);
73
74 // Init openssl library multithreading support
75 static boost::interprocess::interprocess_mutex** ppmutexOpenSSL;
76 void locking_callback(int mode, int i, const char* file, int line)
77 {
78     if (mode & CRYPTO_LOCK)
79         ppmutexOpenSSL[i]->lock();
80     else
81         ppmutexOpenSSL[i]->unlock();
82 }
83
84 // Init
85 class CInit
86 {
87 public:
88     CInit()
89     {
90         // Init openssl library multithreading support
91         ppmutexOpenSSL = (boost::interprocess::interprocess_mutex**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(boost::interprocess::interprocess_mutex*));
92         for (int i = 0; i < CRYPTO_num_locks(); i++)
93             ppmutexOpenSSL[i] = new boost::interprocess::interprocess_mutex();
94         CRYPTO_set_locking_callback(locking_callback);
95
96 #ifdef WIN32
97         // Seed random number generator with screen scrape and other hardware sources
98         RAND_screen();
99 #endif
100
101         // Seed random number generator with performance counter
102         RandAddSeed();
103     }
104     ~CInit()
105     {
106         // Shutdown openssl library multithreading support
107         CRYPTO_set_locking_callback(NULL);
108         for (int i = 0; i < CRYPTO_num_locks(); i++)
109             delete ppmutexOpenSSL[i];
110         OPENSSL_free(ppmutexOpenSSL);
111     }
112 }
113 instance_of_cinit;
114
115
116
117
118
119
120
121
122 void RandAddSeed()
123 {
124     // Seed with CPU performance counter
125     int64 nCounter = GetPerformanceCounter();
126     RAND_add(&nCounter, sizeof(nCounter), 1.5);
127     memset(&nCounter, 0, sizeof(nCounter));
128 }
129
130 void RandAddSeedPerfmon()
131 {
132     RandAddSeed();
133
134     // This can take up to 2 seconds, so only do it every 10 minutes
135     static int64 nLastPerfmon;
136     if (GetTime() < nLastPerfmon + 10 * 60)
137         return;
138     nLastPerfmon = GetTime();
139
140 #ifdef WIN32
141     // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
142     // Seed with the entire set of perfmon data
143     unsigned char pdata[250000];
144     memset(pdata, 0, sizeof(pdata));
145     unsigned long nSize = sizeof(pdata);
146     long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
147     RegCloseKey(HKEY_PERFORMANCE_DATA);
148     if (ret == ERROR_SUCCESS)
149     {
150         RAND_add(pdata, nSize, nSize/100.0);
151         memset(pdata, 0, nSize);
152         printf("%s RandAddSeed() %d bytes\n", DateTimeStrFormat("%x %H:%M", GetTime()).c_str(), nSize);
153     }
154 #endif
155 }
156
157 uint64 GetRand(uint64 nMax)
158 {
159     if (nMax == 0)
160         return 0;
161
162     // The range of the random source must be a multiple of the modulus
163     // to give every possible output value an equal possibility
164     uint64 nRange = (std::numeric_limits<uint64>::max() / nMax) * nMax;
165     uint64 nRand = 0;
166     do
167         RAND_bytes((unsigned char*)&nRand, sizeof(nRand));
168     while (nRand >= nRange);
169     return (nRand % nMax);
170 }
171
172 int GetRandInt(int nMax)
173 {
174     return GetRand(nMax);
175 }
176
177
178
179
180
181
182
183
184
185
186
187 inline int OutputDebugStringF(const char* pszFormat, ...)
188 {
189     int ret = 0;
190     if (fPrintToConsole)
191     {
192         // print to console
193         va_list arg_ptr;
194         va_start(arg_ptr, pszFormat);
195         ret = vprintf(pszFormat, arg_ptr);
196         va_end(arg_ptr);
197     }
198     else
199     {
200         // print to debug.log
201         static FILE* fileout = NULL;
202
203         if (!fileout)
204         {
205             boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
206             fileout = fopen(pathDebug.string().c_str(), "a");
207             if (fileout) setbuf(fileout, NULL); // unbuffered
208         }
209         if (fileout)
210         {
211             static bool fStartedNewLine = true;
212
213             // Debug print useful for profiling
214             if (fLogTimestamps && fStartedNewLine)
215                 fprintf(fileout, "%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
216             if (pszFormat[strlen(pszFormat) - 1] == '\n')
217                 fStartedNewLine = true;
218             else
219                 fStartedNewLine = false;
220
221             va_list arg_ptr;
222             va_start(arg_ptr, pszFormat);
223             ret = vfprintf(fileout, pszFormat, arg_ptr);
224             va_end(arg_ptr);
225         }
226     }
227
228 #ifdef WIN32
229     if (fPrintToDebugger)
230     {
231         static CCriticalSection cs_OutputDebugStringF;
232
233         // accumulate a line at a time
234         {
235             LOCK(cs_OutputDebugStringF);
236             static char pszBuffer[50000];
237             static char* pend;
238             if (pend == NULL)
239                 pend = pszBuffer;
240             va_list arg_ptr;
241             va_start(arg_ptr, pszFormat);
242             int limit = END(pszBuffer) - pend - 2;
243             int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr);
244             va_end(arg_ptr);
245             if (ret < 0 || ret >= limit)
246             {
247                 pend = END(pszBuffer) - 2;
248                 *pend++ = '\n';
249             }
250             else
251                 pend += ret;
252             *pend = '\0';
253             char* p1 = pszBuffer;
254             char* p2;
255             while ((p2 = strchr(p1, '\n')))
256             {
257                 p2++;
258                 char c = *p2;
259                 *p2 = '\0';
260                 OutputDebugStringA(p1);
261                 *p2 = c;
262                 p1 = p2;
263             }
264             if (p1 != pszBuffer)
265                 memmove(pszBuffer, p1, pend - p1 + 1);
266             pend -= (p1 - pszBuffer);
267         }
268     }
269 #endif
270     return ret;
271 }
272
273
274 // Safer snprintf
275 //  - prints up to limit-1 characters
276 //  - output string is always null terminated even if limit reached
277 //  - return value is the number of characters actually printed
278 int my_snprintf(char* buffer, size_t limit, const char* format, ...)
279 {
280     if (limit == 0)
281         return 0;
282     va_list arg_ptr;
283     va_start(arg_ptr, format);
284     int ret = _vsnprintf(buffer, limit, format, arg_ptr);
285     va_end(arg_ptr);
286     if (ret < 0 || ret >= (int)limit)
287     {
288         ret = limit - 1;
289         buffer[limit-1] = 0;
290     }
291     return ret;
292 }
293
294 string real_strprintf(const std::string &format, int dummy, ...)
295 {
296     char buffer[50000];
297     char* p = buffer;
298     int limit = sizeof(buffer);
299     int ret;
300     loop
301     {
302         va_list arg_ptr;
303         va_start(arg_ptr, dummy);
304         ret = _vsnprintf(p, limit, format.c_str(), arg_ptr);
305         va_end(arg_ptr);
306         if (ret >= 0 && ret < limit)
307             break;
308         if (p != buffer)
309             delete[] p;
310         limit *= 2;
311         p = new char[limit];
312         if (p == NULL)
313             throw std::bad_alloc();
314     }
315     string str(p, p+ret);
316     if (p != buffer)
317         delete[] p;
318     return str;
319 }
320
321 bool error(const char *format, ...)
322 {
323     char buffer[50000];
324     int limit = sizeof(buffer);
325     va_list arg_ptr;
326     va_start(arg_ptr, format);
327     int ret = _vsnprintf(buffer, limit, format, arg_ptr);
328     va_end(arg_ptr);
329     if (ret < 0 || ret >= limit)
330     {
331         buffer[limit-1] = 0;
332     }
333     printf("ERROR: %s\n", buffer);
334     return false;
335 }
336
337
338 void ParseString(const string& str, char c, vector<string>& v)
339 {
340     if (str.empty())
341         return;
342     string::size_type i1 = 0;
343     string::size_type i2;
344     loop
345     {
346         i2 = str.find(c, i1);
347         if (i2 == str.npos)
348         {
349             v.push_back(str.substr(i1));
350             return;
351         }
352         v.push_back(str.substr(i1, i2-i1));
353         i1 = i2+1;
354     }
355 }
356
357
358 string FormatMoney(int64 n, bool fPlus)
359 {
360     // Note: not using straight sprintf here because we do NOT want
361     // localized number formatting.
362     int64 n_abs = (n > 0 ? n : -n);
363     int64 quotient = n_abs/COIN;
364     int64 remainder = n_abs%COIN;
365     string str = strprintf("%"PRI64d".%08"PRI64d, quotient, remainder);
366
367     // Right-trim excess 0's before the decimal point:
368     int nTrim = 0;
369     for (int i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i)
370         ++nTrim;
371     if (nTrim)
372         str.erase(str.size()-nTrim, nTrim);
373
374     if (n < 0)
375         str.insert((unsigned int)0, 1, '-');
376     else if (fPlus && n > 0)
377         str.insert((unsigned int)0, 1, '+');
378     return str;
379 }
380
381
382 bool ParseMoney(const string& str, int64& nRet)
383 {
384     return ParseMoney(str.c_str(), nRet);
385 }
386
387 bool ParseMoney(const char* pszIn, int64& nRet)
388 {
389     string strWhole;
390     int64 nUnits = 0;
391     const char* p = pszIn;
392     while (isspace(*p))
393         p++;
394     for (; *p; p++)
395     {
396         if (*p == '.')
397         {
398             p++;
399             int64 nMult = CENT*10;
400             while (isdigit(*p) && (nMult > 0))
401             {
402                 nUnits += nMult * (*p++ - '0');
403                 nMult /= 10;
404             }
405             break;
406         }
407         if (isspace(*p))
408             break;
409         if (!isdigit(*p))
410             return false;
411         strWhole.insert(strWhole.end(), *p);
412     }
413     for (; *p; p++)
414         if (!isspace(*p))
415             return false;
416     if (strWhole.size() > 10) // guard against 63 bit overflow
417         return false;
418     if (nUnits < 0 || nUnits > COIN)
419         return false;
420     int64 nWhole = atoi64(strWhole);
421     int64 nValue = nWhole*COIN + nUnits;
422
423     nRet = nValue;
424     return true;
425 }
426
427
428 static signed char phexdigit[256] =
429 { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
430   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
431   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
432   0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
433   -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
434   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
435   -1,0xa,0xb,0xc,0xd,0xe,0xf,-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   -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   -1,-1,-1,-1,-1,-1,-1,-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
446 bool IsHex(const string& str)
447 {
448     BOOST_FOREACH(unsigned char c, str)
449     {
450         if (phexdigit[c] < 0)
451             return false;
452     }
453     return (str.size() > 0) && (str.size()%2 == 0);
454 }
455
456 vector<unsigned char> ParseHex(const char* psz)
457 {
458     // convert hex dump to vector
459     vector<unsigned char> vch;
460     loop
461     {
462         while (isspace(*psz))
463             psz++;
464         signed char c = phexdigit[(unsigned char)*psz++];
465         if (c == (signed char)-1)
466             break;
467         unsigned char n = (c << 4);
468         c = phexdigit[(unsigned char)*psz++];
469         if (c == (signed char)-1)
470             break;
471         n |= c;
472         vch.push_back(n);
473     }
474     return vch;
475 }
476
477 vector<unsigned char> ParseHex(const string& str)
478 {
479     return ParseHex(str.c_str());
480 }
481
482 static void InterpretNegativeSetting(string name, map<string, string>& mapSettingsRet)
483 {
484     // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set
485     if (name.find("-no") == 0)
486     {
487         std::string positive("-");
488         positive.append(name.begin()+3, name.end());
489         if (mapSettingsRet.count(positive) == 0)
490         {
491             bool value = !GetBoolArg(name);
492             mapSettingsRet[positive] = (value ? "1" : "0");
493         }
494     }
495 }
496
497 void ParseParameters(int argc, const char*const argv[])
498 {
499     mapArgs.clear();
500     mapMultiArgs.clear();
501     for (int i = 1; i < argc; i++)
502     {
503         char psz[10000];
504         strlcpy(psz, argv[i], sizeof(psz));
505         char* pszValue = (char*)"";
506         if (strchr(psz, '='))
507         {
508             pszValue = strchr(psz, '=');
509             *pszValue++ = '\0';
510         }
511         #ifdef WIN32
512         _strlwr(psz);
513         if (psz[0] == '/')
514             psz[0] = '-';
515         #endif
516         if (psz[0] != '-')
517             break;
518
519         mapArgs[psz] = pszValue;
520         mapMultiArgs[psz].push_back(pszValue);
521     }
522
523     // New 0.6 features:
524     BOOST_FOREACH(const PAIRTYPE(string,string)& entry, mapArgs)
525     {
526         string name = entry.first;
527
528         //  interpret --foo as -foo (as long as both are not set)
529         if (name.find("--") == 0)
530         {
531             std::string singleDash(name.begin()+1, name.end());
532             if (mapArgs.count(singleDash) == 0)
533                 mapArgs[singleDash] = entry.second;
534             name = singleDash;
535         }
536
537         // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set
538         InterpretNegativeSetting(name, mapArgs);
539     }
540 }
541
542 std::string GetArg(const std::string& strArg, const std::string& strDefault)
543 {
544     if (mapArgs.count(strArg))
545         return mapArgs[strArg];
546     return strDefault;
547 }
548
549 int64 GetArg(const std::string& strArg, int64 nDefault)
550 {
551     if (mapArgs.count(strArg))
552         return atoi64(mapArgs[strArg]);
553     return nDefault;
554 }
555
556 bool GetBoolArg(const std::string& strArg, bool fDefault)
557 {
558     if (mapArgs.count(strArg))
559     {
560         if (mapArgs[strArg].empty())
561             return true;
562         return (atoi(mapArgs[strArg]) != 0);
563     }
564     return fDefault;
565 }
566
567 bool SoftSetArg(const std::string& strArg, const std::string& strValue)
568 {
569     if (mapArgs.count(strArg))
570         return false;
571     mapArgs[strArg] = strValue;
572     return true;
573 }
574
575 bool SoftSetBoolArg(const std::string& strArg, bool fValue)
576 {
577     if (fValue)
578         return SoftSetArg(strArg, std::string("1"));
579     else
580         return SoftSetArg(strArg, std::string("0"));
581 }
582
583
584 string EncodeBase64(const unsigned char* pch, size_t len)
585 {
586     static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
587
588     string strRet="";
589     strRet.reserve((len+2)/3*4);
590
591     int mode=0, left=0;
592     const unsigned char *pchEnd = pch+len;
593
594     while (pch<pchEnd)
595     {
596         int enc = *(pch++);
597         switch (mode)
598         {
599             case 0: // we have no bits
600                 strRet += pbase64[enc >> 2];
601                 left = (enc & 3) << 4;
602                 mode = 1;
603                 break;
604
605             case 1: // we have two bits
606                 strRet += pbase64[left | (enc >> 4)];
607                 left = (enc & 15) << 2;
608                 mode = 2;
609                 break;
610
611             case 2: // we have four bits
612                 strRet += pbase64[left | (enc >> 6)];
613                 strRet += pbase64[enc & 63];
614                 mode = 0;
615                 break;
616         }
617     }
618
619     if (mode)
620     {
621         strRet += pbase64[left];
622         strRet += '=';
623         if (mode == 1)
624             strRet += '=';
625     }
626
627     return strRet;
628 }
629
630 string EncodeBase64(const string& str)
631 {
632     return EncodeBase64((const unsigned char*)str.c_str(), str.size());
633 }
634
635 vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid)
636 {
637     static const int decode64_table[256] =
638     {
639         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
640         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
641         -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
642         -1, -1, -1, -1, -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
643         15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
644         29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
645         49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
646         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
647         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
648         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
649         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
650         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
651         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
652     };
653
654     if (pfInvalid)
655         *pfInvalid = false;
656
657     vector<unsigned char> vchRet;
658     vchRet.reserve(strlen(p)*3/4);
659
660     int mode = 0;
661     int left = 0;
662
663     while (1)
664     {
665          int dec = decode64_table[(unsigned char)*p];
666          if (dec == -1) break;
667          p++;
668          switch (mode)
669          {
670              case 0: // we have no bits and get 6
671                  left = dec;
672                  mode = 1;
673                  break;
674
675               case 1: // we have 6 bits and keep 4
676                   vchRet.push_back((left<<2) | (dec>>4));
677                   left = dec & 15;
678                   mode = 2;
679                   break;
680
681              case 2: // we have 4 bits and get 6, we keep 2
682                  vchRet.push_back((left<<4) | (dec>>2));
683                  left = dec & 3;
684                  mode = 3;
685                  break;
686
687              case 3: // we have 2 bits and get 6
688                  vchRet.push_back((left<<6) | dec);
689                  mode = 0;
690                  break;
691          }
692     }
693
694     if (pfInvalid)
695         switch (mode)
696         {
697             case 0: // 4n base64 characters processed: ok
698                 break;
699
700             case 1: // 4n+1 base64 character processed: impossible
701                 *pfInvalid = true;
702                 break;
703
704             case 2: // 4n+2 base64 characters processed: require '=='
705                 if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1)
706                     *pfInvalid = true;
707                 break;
708
709             case 3: // 4n+3 base64 characters processed: require '='
710                 if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1)
711                     *pfInvalid = true;
712                 break;
713         }
714
715     return vchRet;
716 }
717
718 string DecodeBase64(const string& str)
719 {
720     vector<unsigned char> vchRet = DecodeBase64(str.c_str());
721     return string((const char*)&vchRet[0], vchRet.size());
722 }
723
724
725 bool WildcardMatch(const char* psz, const char* mask)
726 {
727     loop
728     {
729         switch (*mask)
730         {
731         case '\0':
732             return (*psz == '\0');
733         case '*':
734             return WildcardMatch(psz, mask+1) || (*psz && WildcardMatch(psz+1, mask));
735         case '?':
736             if (*psz == '\0')
737                 return false;
738             break;
739         default:
740             if (*psz != *mask)
741                 return false;
742             break;
743         }
744         psz++;
745         mask++;
746     }
747 }
748
749 bool WildcardMatch(const string& str, const string& mask)
750 {
751     return WildcardMatch(str.c_str(), mask.c_str());
752 }
753
754
755
756
757
758
759
760
761 void FormatException(char* pszMessage, std::exception* pex, const char* pszThread)
762 {
763 #ifdef WIN32
764     char pszModule[MAX_PATH];
765     pszModule[0] = '\0';
766     GetModuleFileNameA(NULL, pszModule, sizeof(pszModule));
767 #else
768     const char* pszModule = "bitcoin";
769 #endif
770     if (pex)
771         snprintf(pszMessage, 1000,
772             "EXCEPTION: %s       \n%s       \n%s in %s       \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
773     else
774         snprintf(pszMessage, 1000,
775             "UNKNOWN EXCEPTION       \n%s in %s       \n", pszModule, pszThread);
776 }
777
778 void LogException(std::exception* pex, const char* pszThread)
779 {
780     char pszMessage[10000];
781     FormatException(pszMessage, pex, pszThread);
782     printf("\n%s", pszMessage);
783 }
784
785 void PrintException(std::exception* pex, const char* pszThread)
786 {
787     char pszMessage[10000];
788     FormatException(pszMessage, pex, pszThread);
789     printf("\n\n************************\n%s\n", pszMessage);
790     fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
791     strMiscWarning = pszMessage;
792     throw;
793 }
794
795 void PrintExceptionContinue(std::exception* pex, const char* pszThread)
796 {
797     char pszMessage[10000];
798     FormatException(pszMessage, pex, pszThread);
799     printf("\n\n************************\n%s\n", pszMessage);
800     fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
801     strMiscWarning = pszMessage;
802 }
803
804 #ifdef WIN32
805 boost::filesystem::path MyGetSpecialFolderPath(int nFolder, bool fCreate)
806 {
807     namespace fs = boost::filesystem;
808
809     char pszPath[MAX_PATH] = "";
810     if(SHGetSpecialFolderPathA(NULL, pszPath, nFolder, fCreate))
811     {
812         return fs::path(pszPath);
813     }
814     else if (nFolder == CSIDL_STARTUP)
815     {
816         return fs::path(getenv("USERPROFILE")) / "Start Menu" / "Programs" / "Startup";
817     }
818     else if (nFolder == CSIDL_APPDATA)
819     {
820         return fs::path(getenv("APPDATA"));
821     }
822     return fs::path("");
823 }
824 #endif
825
826 boost::filesystem::path GetDefaultDataDir()
827 {
828     namespace fs = boost::filesystem;
829
830     // Windows: C:\Documents and Settings\username\Application Data\Bitcoin
831     // Mac: ~/Library/Application Support/Bitcoin
832     // Unix: ~/.bitcoin
833 #ifdef WIN32
834     // Windows
835     return MyGetSpecialFolderPath(CSIDL_APPDATA, true) / "Bitcoin";
836 #else
837     fs::path pathRet;
838     char* pszHome = getenv("HOME");
839     if (pszHome == NULL || strlen(pszHome) == 0)
840         pathRet = fs::path("/");
841     else
842         pathRet = fs::path(pszHome);
843 #ifdef MAC_OSX
844     // Mac
845     pathRet /= "Library/Application Support";
846     fs::create_directory(pathRet);
847     return pathRet / "Bitcoin";
848 #else
849     // Unix
850     return pathRet / ".bitcoin";
851 #endif
852 #endif
853 }
854
855 const boost::filesystem::path &GetDataDir(bool fNetSpecific)
856 {
857     namespace fs = boost::filesystem;
858
859     static fs::path pathCached[2];
860     static CCriticalSection csPathCached;
861     static bool cachedPath[2] = {false, false};
862
863     fs::path &path = pathCached[fNetSpecific];
864
865     // This can be called during exceptions by printf, so we cache the
866     // value so we don't have to do memory allocations after that.
867     if (cachedPath[fNetSpecific])
868         return path;
869
870     LOCK(csPathCached);
871
872     if (mapArgs.count("-datadir")) {
873         path = fs::system_complete(mapArgs["-datadir"]);
874         if (!fs::is_directory(path)) {
875             path = "";
876             return path;
877         }
878     } else {
879         path = GetDefaultDataDir();
880     }
881     if (fNetSpecific && GetBoolArg("-testnet", false))
882         path /= "testnet";
883
884     fs::create_directory(path);
885
886     cachedPath[fNetSpecific]=true;
887     return path;
888 }
889
890 boost::filesystem::path GetConfigFile()
891 {
892     namespace fs = boost::filesystem;
893
894     fs::path pathConfigFile(GetArg("-conf", "bitcoin.conf"));
895     if (!pathConfigFile.is_complete()) pathConfigFile = GetDataDir(false) / pathConfigFile;
896     return pathConfigFile;
897 }
898
899 void ReadConfigFile(map<string, string>& mapSettingsRet,
900                     map<string, vector<string> >& mapMultiSettingsRet)
901 {
902     namespace fs = boost::filesystem;
903     namespace pod = boost::program_options::detail;
904
905     fs::ifstream streamConfig(GetConfigFile());
906     if (!streamConfig.good())
907         return; // No bitcoin.conf file is OK
908
909     set<string> setOptions;
910     setOptions.insert("*");
911
912     for (pod::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it)
913     {
914         // Don't overwrite existing settings so command line settings override bitcoin.conf
915         string strKey = string("-") + it->string_key;
916         if (mapSettingsRet.count(strKey) == 0)
917         {
918             mapSettingsRet[strKey] = it->value[0];
919             //  interpret nofoo=1 as foo=0 (and nofoo=0 as foo=1) as long as foo not set)
920             InterpretNegativeSetting(strKey, mapSettingsRet);
921         }
922         mapMultiSettingsRet[strKey].push_back(it->value[0]);
923     }
924 }
925
926 boost::filesystem::path GetPidFile()
927 {
928     namespace fs = boost::filesystem;
929
930     fs::path pathPidFile(GetArg("-pid", "bitcoind.pid"));
931     if (!pathPidFile.is_complete()) pathPidFile = GetDataDir() / pathPidFile;
932     return pathPidFile;
933 }
934
935 void CreatePidFile(const boost::filesystem::path &path, pid_t pid)
936 {
937     FILE* file = fopen(path.string().c_str(), "w");
938     if (file)
939     {
940         fprintf(file, "%d\n", pid);
941         fclose(file);
942     }
943 }
944
945 int GetFilesize(FILE* file)
946 {
947     int nSavePos = ftell(file);
948     int nFilesize = -1;
949     if (fseek(file, 0, SEEK_END) == 0)
950         nFilesize = ftell(file);
951     fseek(file, nSavePos, SEEK_SET);
952     return nFilesize;
953 }
954
955 void ShrinkDebugFile()
956 {
957     // Scroll debug.log if it's getting too big
958     boost::filesystem::path pathLog = GetDataDir() / "debug.log";
959     FILE* file = fopen(pathLog.string().c_str(), "r");
960     if (file && GetFilesize(file) > 10 * 1000000)
961     {
962         // Restart the file with some of the end
963         char pch[200000];
964         fseek(file, -sizeof(pch), SEEK_END);
965         int nBytes = fread(pch, 1, sizeof(pch), file);
966         fclose(file);
967
968         file = fopen(pathLog.string().c_str(), "w");
969         if (file)
970         {
971             fwrite(pch, 1, nBytes, file);
972             fclose(file);
973         }
974     }
975 }
976
977
978
979
980
981
982
983
984 //
985 // "Never go to sea with two chronometers; take one or three."
986 // Our three time sources are:
987 //  - System clock
988 //  - Median of other nodes's clocks
989 //  - The user (asking the user to fix the system clock if the first two disagree)
990 //
991 static int64 nMockTime = 0;  // For unit testing
992
993 int64 GetTime()
994 {
995     if (nMockTime) return nMockTime;
996
997     return time(NULL);
998 }
999
1000 void SetMockTime(int64 nMockTimeIn)
1001 {
1002     nMockTime = nMockTimeIn;
1003 }
1004
1005 static int64 nTimeOffset = 0;
1006
1007 int64 GetAdjustedTime()
1008 {
1009     return GetTime() + nTimeOffset;
1010 }
1011
1012 void AddTimeData(const CNetAddr& ip, int64 nTime)
1013 {
1014     int64 nOffsetSample = nTime - GetTime();
1015
1016     // Ignore duplicates
1017     static set<CNetAddr> setKnown;
1018     if (!setKnown.insert(ip).second)
1019         return;
1020
1021     // Add data
1022     vTimeOffsets.input(nOffsetSample);
1023     printf("Added time data, samples %d, offset %+"PRI64d" (%+"PRI64d" minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);
1024     if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
1025     {
1026         int64 nMedian = vTimeOffsets.median();
1027         std::vector<int64> vSorted = vTimeOffsets.sorted();
1028         // Only let other nodes change our time by so much
1029         if (abs64(nMedian) < 70 * 60)
1030         {
1031             nTimeOffset = nMedian;
1032         }
1033         else
1034         {
1035             nTimeOffset = 0;
1036
1037             static bool fDone;
1038             if (!fDone)
1039             {
1040                 // If nobody has a time different than ours but within 5 minutes of ours, give a warning
1041                 bool fMatch = false;
1042                 BOOST_FOREACH(int64 nOffset, vSorted)
1043                     if (nOffset != 0 && abs64(nOffset) < 5 * 60)
1044                         fMatch = true;
1045
1046                 if (!fMatch)
1047                 {
1048                     fDone = true;
1049                     string strMessage = _("Warning: Please check that your computer's date and time are correct.  If your clock is wrong Bitcoin will not work properly.");
1050                     strMiscWarning = strMessage;
1051                     printf("*** %s\n", strMessage.c_str());
1052                     ThreadSafeMessageBox(strMessage+" ", string("Bitcoin"), wxOK | wxICON_EXCLAMATION);
1053                 }
1054             }
1055         }
1056         if (fDebug) {
1057             BOOST_FOREACH(int64 n, vSorted)
1058                 printf("%+"PRI64d"  ", n);
1059             printf("|  ");
1060         }
1061         printf("nTimeOffset = %+"PRI64d"  (%+"PRI64d" minutes)\n", nTimeOffset, nTimeOffset/60);
1062     }
1063 }
1064
1065
1066
1067
1068
1069
1070
1071
1072 string FormatVersion(int nVersion)
1073 {
1074     if (nVersion%100 == 0)
1075         return strprintf("%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100);
1076     else
1077         return strprintf("%d.%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100, nVersion%100);
1078 }
1079
1080 string FormatFullVersion()
1081 {
1082     return CLIENT_BUILD;
1083 }
1084
1085 // Format the subversion field according to BIP 14 spec (https://en.bitcoin.it/wiki/BIP_0014)
1086 std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments)
1087 {
1088     std::ostringstream ss;
1089     ss << "/";
1090     ss << name << ":" << FormatVersion(nClientVersion);
1091     if (!comments.empty())
1092         ss << "(" << boost::algorithm::join(comments, "; ") << ")";
1093     ss << "/";
1094     return ss.str();
1095 }
1096
1097 #ifdef WIN32
1098 boost::filesystem::path static StartupShortcutPath()
1099 {
1100     return MyGetSpecialFolderPath(CSIDL_STARTUP, true) / "Bitcoin.lnk";
1101 }
1102
1103 bool GetStartOnSystemStartup()
1104 {
1105     return filesystem::exists(StartupShortcutPath());
1106 }
1107
1108 bool SetStartOnSystemStartup(bool fAutoStart)
1109 {
1110     // If the shortcut exists already, remove it for updating
1111     boost::filesystem::remove(StartupShortcutPath());
1112
1113     if (fAutoStart)
1114     {
1115         CoInitialize(NULL);
1116
1117         // Get a pointer to the IShellLink interface.
1118         IShellLink* psl = NULL;
1119         HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
1120                                 CLSCTX_INPROC_SERVER, IID_IShellLink,
1121                                 reinterpret_cast<void**>(&psl));
1122
1123         if (SUCCEEDED(hres))
1124         {
1125             // Get the current executable path
1126             TCHAR pszExePath[MAX_PATH];
1127             GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
1128
1129             TCHAR pszArgs[5] = TEXT("-min");
1130
1131             // Set the path to the shortcut target
1132             psl->SetPath(pszExePath);
1133             PathRemoveFileSpec(pszExePath);
1134             psl->SetWorkingDirectory(pszExePath);
1135             psl->SetShowCmd(SW_SHOWMINNOACTIVE);
1136             psl->SetArguments(pszArgs);
1137
1138             // Query IShellLink for the IPersistFile interface for
1139             // saving the shortcut in persistent storage.
1140             IPersistFile* ppf = NULL;
1141             hres = psl->QueryInterface(IID_IPersistFile,
1142                                        reinterpret_cast<void**>(&ppf));
1143             if (SUCCEEDED(hres))
1144             {
1145                 WCHAR pwsz[MAX_PATH];
1146                 // Ensure that the string is ANSI.
1147                 MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().string().c_str(), -1, pwsz, MAX_PATH);
1148                 // Save the link by calling IPersistFile::Save.
1149                 hres = ppf->Save(pwsz, TRUE);
1150                 ppf->Release();
1151                 psl->Release();
1152                 CoUninitialize();
1153                 return true;
1154             }
1155             psl->Release();
1156         }
1157         CoUninitialize();
1158         return false;
1159     }
1160     return true;
1161 }
1162
1163 #elif defined(LINUX)
1164
1165 // Follow the Desktop Application Autostart Spec:
1166 //  http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
1167
1168 boost::filesystem::path static GetAutostartDir()
1169 {
1170     namespace fs = boost::filesystem;
1171
1172     char* pszConfigHome = getenv("XDG_CONFIG_HOME");
1173     if (pszConfigHome) return fs::path(pszConfigHome) / "autostart";
1174     char* pszHome = getenv("HOME");
1175     if (pszHome) return fs::path(pszHome) / ".config" / "autostart";
1176     return fs::path();
1177 }
1178
1179 boost::filesystem::path static GetAutostartFilePath()
1180 {
1181     return GetAutostartDir() / "bitcoin.desktop";
1182 }
1183
1184 bool GetStartOnSystemStartup()
1185 {
1186     boost::filesystem::ifstream optionFile(GetAutostartFilePath());
1187     if (!optionFile.good())
1188         return false;
1189     // Scan through file for "Hidden=true":
1190     string line;
1191     while (!optionFile.eof())
1192     {
1193         getline(optionFile, line);
1194         if (line.find("Hidden") != string::npos &&
1195             line.find("true") != string::npos)
1196             return false;
1197     }
1198     optionFile.close();
1199
1200     return true;
1201 }
1202
1203 bool SetStartOnSystemStartup(bool fAutoStart)
1204 {
1205     if (!fAutoStart)
1206         boost::filesystem::remove(GetAutostartFilePath());
1207     else
1208     {
1209         char pszExePath[MAX_PATH+1];
1210         memset(pszExePath, 0, sizeof(pszExePath));
1211         if (readlink("/proc/self/exe", pszExePath, sizeof(pszExePath)-1) == -1)
1212             return false;
1213
1214         boost::filesystem::create_directories(GetAutostartDir());
1215
1216         boost::filesystem::ofstream optionFile(GetAutostartFilePath(), ios_base::out|ios_base::trunc);
1217         if (!optionFile.good())
1218             return false;
1219         // Write a bitcoin.desktop file to the autostart directory:
1220         optionFile << "[Desktop Entry]\n";
1221         optionFile << "Type=Application\n";
1222         optionFile << "Name=Bitcoin\n";
1223         optionFile << "Exec=" << pszExePath << " -min\n";
1224         optionFile << "Terminal=false\n";
1225         optionFile << "Hidden=false\n";
1226         optionFile.close();
1227     }
1228     return true;
1229 }
1230 #else
1231
1232 // TODO: OSX startup stuff; see:
1233 // http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html
1234
1235 bool GetStartOnSystemStartup() { return false; }
1236 bool SetStartOnSystemStartup(bool fAutoStart) { return false; }
1237
1238 #endif
1239
1240
1241
1242 #ifdef DEBUG_LOCKORDER
1243 //
1244 // Early deadlock detection.
1245 // Problem being solved:
1246 //    Thread 1 locks  A, then B, then C
1247 //    Thread 2 locks  D, then C, then A
1248 //     --> may result in deadlock between the two threads, depending on when they run.
1249 // Solution implemented here:
1250 // Keep track of pairs of locks: (A before B), (A before C), etc.
1251 // Complain if any thread trys to lock in a different order.
1252 //
1253
1254 struct CLockLocation
1255 {
1256     CLockLocation(const char* pszName, const char* pszFile, int nLine)
1257     {
1258         mutexName = pszName;
1259         sourceFile = pszFile;
1260         sourceLine = nLine;
1261     }
1262
1263     std::string ToString() const
1264     {
1265         return mutexName+"  "+sourceFile+":"+itostr(sourceLine);
1266     }
1267
1268 private:
1269     std::string mutexName;
1270     std::string sourceFile;
1271     int sourceLine;
1272 };
1273
1274 typedef std::vector< std::pair<void*, CLockLocation> > LockStack;
1275
1276 static boost::interprocess::interprocess_mutex dd_mutex;
1277 static std::map<std::pair<void*, void*>, LockStack> lockorders;
1278 static boost::thread_specific_ptr<LockStack> lockstack;
1279
1280
1281 static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, const LockStack& s1, const LockStack& s2)
1282 {
1283     printf("POTENTIAL DEADLOCK DETECTED\n");
1284     printf("Previous lock order was:\n");
1285     BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s2)
1286     {
1287         if (i.first == mismatch.first) printf(" (1)");
1288         if (i.first == mismatch.second) printf(" (2)");
1289         printf(" %s\n", i.second.ToString().c_str());
1290     }
1291     printf("Current lock order is:\n");
1292     BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s1)
1293     {
1294         if (i.first == mismatch.first) printf(" (1)");
1295         if (i.first == mismatch.second) printf(" (2)");
1296         printf(" %s\n", i.second.ToString().c_str());
1297     }
1298 }
1299
1300 static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
1301 {
1302     bool fOrderOK = true;
1303     if (lockstack.get() == NULL)
1304         lockstack.reset(new LockStack);
1305
1306     if (fDebug) printf("Locking: %s\n", locklocation.ToString().c_str());
1307     dd_mutex.lock();
1308
1309     (*lockstack).push_back(std::make_pair(c, locklocation));
1310
1311     if (!fTry) BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, (*lockstack))
1312     {
1313         if (i.first == c) break;
1314
1315         std::pair<void*, void*> p1 = std::make_pair(i.first, c);
1316         if (lockorders.count(p1))
1317             continue;
1318         lockorders[p1] = (*lockstack);
1319
1320         std::pair<void*, void*> p2 = std::make_pair(c, i.first);
1321         if (lockorders.count(p2))
1322         {
1323             potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
1324             break;
1325         }
1326     }
1327     dd_mutex.unlock();
1328 }
1329
1330 static void pop_lock()
1331 {
1332     if (fDebug) 
1333     {
1334         const CLockLocation& locklocation = (*lockstack).rbegin()->second;
1335         printf("Unlocked: %s\n", locklocation.ToString().c_str());
1336     }
1337     dd_mutex.lock();
1338     (*lockstack).pop_back();
1339     dd_mutex.unlock();
1340 }
1341
1342 void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry)
1343 {
1344     push_lock(cs, CLockLocation(pszName, pszFile, nLine), fTry);
1345 }
1346
1347 void LeaveCritical()
1348 {
1349     pop_lock();
1350 }
1351
1352 #endif /* DEBUG_LOCKORDER */