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