Fix CRLF
[novacoin.git] / util.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
4
5 #include "headers.h"
6
7
8 map<string, string> mapArgs;
9 map<string, vector<string> > mapMultiArgs;
10 bool fDebug = false;
11 bool fPrintToConsole = false;
12 bool fPrintToDebugger = false;
13 char pszSetDataDir[MAX_PATH] = "";
14 bool fShutdown = false;
15 bool fDaemon = false;
16 bool fCommandLine = false;
17
18
19
20
21
22 // Init openssl library multithreading support
23 static boost::interprocess::interprocess_mutex** ppmutexOpenSSL;
24 void locking_callback(int mode, int i, const char* file, int line)
25 {
26     if (mode & CRYPTO_LOCK)
27         ppmutexOpenSSL[i]->lock();
28     else
29         ppmutexOpenSSL[i]->unlock();
30 }
31
32 // Init
33 class CInit
34 {
35 public:
36     CInit()
37     {
38         // Init openssl library multithreading support
39         ppmutexOpenSSL = (boost::interprocess::interprocess_mutex**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(boost::interprocess::interprocess_mutex*));
40         for (int i = 0; i < CRYPTO_num_locks(); i++)
41             ppmutexOpenSSL[i] = new boost::interprocess::interprocess_mutex();
42         CRYPTO_set_locking_callback(locking_callback);
43
44 #ifdef __WXMSW__
45         // Seed random number generator with screen scrape and other hardware sources
46         RAND_screen();
47 #endif
48
49         // Seed random number generator with performance counter
50         RandAddSeed();
51     }
52     ~CInit()
53     {
54         // Shutdown openssl library multithreading support
55         CRYPTO_set_locking_callback(NULL);
56         for (int i = 0; i < CRYPTO_num_locks(); i++)
57             delete ppmutexOpenSSL[i];
58         OPENSSL_free(ppmutexOpenSSL);
59     }
60 }
61 instance_of_cinit;
62
63
64
65
66
67
68
69
70 void RandAddSeed()
71 {
72     // Seed with CPU performance counter
73     int64 nCounter = PerformanceCounter();
74     RAND_add(&nCounter, sizeof(nCounter), 1.5);
75     memset(&nCounter, 0, sizeof(nCounter));
76 }
77
78 void RandAddSeedPerfmon()
79 {
80     RandAddSeed();
81
82     // This can take up to 2 seconds, so only do it every 10 minutes
83     static int64 nLastPerfmon;
84     if (GetTime() < nLastPerfmon + 10 * 60)
85         return;
86     nLastPerfmon = GetTime();
87
88 #ifdef __WXMSW__
89     // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
90     // Seed with the entire set of perfmon data
91     unsigned char pdata[250000];
92     memset(pdata, 0, sizeof(pdata));
93     unsigned long nSize = sizeof(pdata);
94     long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
95     RegCloseKey(HKEY_PERFORMANCE_DATA);
96     if (ret == ERROR_SUCCESS)
97     {
98         uint256 hash;
99         SHA256(pdata, nSize, (unsigned char*)&hash);
100         RAND_add(&hash, sizeof(hash), min(nSize/500.0, (double)sizeof(hash)));
101         hash = 0;
102         memset(pdata, 0, nSize);
103
104         printf("%s RandAddSeed() %d bytes\n", DateTimeStrFormat("%x %H:%M", GetTime()).c_str(), nSize);
105     }
106 #endif
107 }
108
109 uint64 GetRand(uint64 nMax)
110 {
111     if (nMax == 0)
112         return 0;
113
114     // The range of the random source must be a multiple of the modulus
115     // to give every possible output value an equal possibility
116     uint64 nRange = (UINT64_MAX / nMax) * nMax;
117     uint64 nRand = 0;
118     do
119         RAND_bytes((unsigned char*)&nRand, sizeof(nRand));
120     while (nRand >= nRange);
121     return (nRand % nMax);
122 }
123
124
125
126
127
128
129
130
131
132
133
134 inline int OutputDebugStringF(const char* pszFormat, ...)
135 {
136     int ret = 0;
137     if (fPrintToConsole || wxTheApp == NULL)
138     {
139         // print to console
140         va_list arg_ptr;
141         va_start(arg_ptr, pszFormat);
142         ret = vprintf(pszFormat, arg_ptr);
143         va_end(arg_ptr);
144     }
145     else
146     {
147         // print to debug.log
148         char pszFile[MAX_PATH+100];
149         GetDataDir(pszFile);
150         strlcat(pszFile, "/debug.log", sizeof(pszFile));
151         FILE* fileout = fopen(pszFile, "a");
152         if (fileout)
153         {
154             //// Debug print useful for profiling
155             //fprintf(fileout, " %"PRI64d" ", GetTimeMillis());
156             va_list arg_ptr;
157             va_start(arg_ptr, pszFormat);
158             ret = vfprintf(fileout, pszFormat, arg_ptr);
159             va_end(arg_ptr);
160             fclose(fileout);
161         }
162     }
163
164 #ifdef __WXMSW__
165     if (fPrintToDebugger)
166     {
167         // accumulate a line at a time
168         static CCriticalSection cs_OutputDebugStringF;
169         CRITICAL_BLOCK(cs_OutputDebugStringF)
170         {
171             static char pszBuffer[50000];
172             static char* pend;
173             if (pend == NULL)
174                 pend = pszBuffer;
175             va_list arg_ptr;
176             va_start(arg_ptr, pszFormat);
177             int limit = END(pszBuffer) - pend - 2;
178             int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr);
179             va_end(arg_ptr);
180             if (ret < 0 || ret >= limit)
181             {
182                 pend = END(pszBuffer) - 2;
183                 *pend++ = '\n';
184             }
185             else
186                 pend += ret;
187             *pend = '\0';
188             char* p1 = pszBuffer;
189             char* p2;
190             while (p2 = strchr(p1, '\n'))
191             {
192                 p2++;
193                 char c = *p2;
194                 *p2 = '\0';
195                 OutputDebugStringA(p1);
196                 *p2 = c;
197                 p1 = p2;
198             }
199             if (p1 != pszBuffer)
200                 memmove(pszBuffer, p1, pend - p1 + 1);
201             pend -= (p1 - pszBuffer);
202         }
203     }
204 #endif
205     return ret;
206 }
207
208
209 // Safer snprintf
210 //  - prints up to limit-1 characters
211 //  - output string is always null terminated even if limit reached
212 //  - return value is the number of characters actually printed
213 int my_snprintf(char* buffer, size_t limit, const char* format, ...)
214 {
215     if (limit == 0)
216         return 0;
217     va_list arg_ptr;
218     va_start(arg_ptr, format);
219     int ret = _vsnprintf(buffer, limit, format, arg_ptr);
220     va_end(arg_ptr);
221     if (ret < 0 || ret >= limit)
222     {
223         ret = limit - 1;
224         buffer[limit-1] = 0;
225     }
226     return ret;
227 }
228
229
230 string strprintf(const char* format, ...)
231 {
232     char buffer[50000];
233     char* p = buffer;
234     int limit = sizeof(buffer);
235     int ret;
236     loop
237     {
238         va_list arg_ptr;
239         va_start(arg_ptr, format);
240         ret = _vsnprintf(p, limit, format, arg_ptr);
241         va_end(arg_ptr);
242         if (ret >= 0 && ret < limit)
243             break;
244         if (p != buffer)
245             delete p;
246         limit *= 2;
247         p = new char[limit];
248         if (p == NULL)
249             throw std::bad_alloc();
250     }
251     string str(p, p+ret);
252     if (p != buffer)
253         delete p;
254     return str;
255 }
256
257
258 bool error(const char* format, ...)
259 {
260     char buffer[50000];
261     int limit = sizeof(buffer);
262     va_list arg_ptr;
263     va_start(arg_ptr, format);
264     int ret = _vsnprintf(buffer, limit, format, arg_ptr);
265     va_end(arg_ptr);
266     if (ret < 0 || ret >= limit)
267     {
268         ret = limit - 1;
269         buffer[limit-1] = 0;
270     }
271     printf("ERROR: %s\n", buffer);
272     return false;
273 }
274
275
276 void ParseString(const string& str, char c, vector<string>& v)
277 {
278     if (str.empty())
279         return;
280     string::size_type i1 = 0;
281     string::size_type i2;
282     loop
283     {
284         i2 = str.find(c, i1);
285         if (i2 == str.npos)
286         {
287             v.push_back(str.substr(i1));
288             return;
289         }
290         v.push_back(str.substr(i1, i2-i1));
291         i1 = i2+1;
292     }
293 }
294
295
296 string FormatMoney(int64 n, bool fPlus)
297 {
298     n /= CENT;
299     string str = strprintf("%"PRI64d".%02"PRI64d, (n > 0 ? n : -n)/100, (n > 0 ? n : -n)%100);
300     for (int i = 6; i < str.size(); i += 4)
301         if (isdigit(str[str.size() - i - 1]))
302             str.insert(str.size() - i, 1, ',');
303     if (n < 0)
304         str.insert((unsigned int)0, 1, '-');
305     else if (fPlus && n > 0)
306         str.insert((unsigned int)0, 1, '+');
307     return str;
308 }
309
310
311 bool ParseMoney(const string& str, int64& nRet)
312 {
313     return ParseMoney(str.c_str(), nRet);
314 }
315
316 bool ParseMoney(const char* pszIn, int64& nRet)
317 {
318     string strWhole;
319     int64 nCents = 0;
320     const char* p = pszIn;
321     while (isspace(*p))
322         p++;
323     for (; *p; p++)
324     {
325         if (*p == ',' && p > pszIn && isdigit(p[-1]) && isdigit(p[1]) && isdigit(p[2]) && isdigit(p[3]) && !isdigit(p[4]))
326             continue;
327         if (*p == '.')
328         {
329             p++;
330             if (isdigit(*p))
331             {
332                 nCents = 10 * (*p++ - '0');
333                 if (isdigit(*p))
334                     nCents += (*p++ - '0');
335             }
336             break;
337         }
338         if (isspace(*p))
339             break;
340         if (!isdigit(*p))
341             return false;
342         strWhole.insert(strWhole.end(), *p);
343     }
344     for (; *p; p++)
345         if (!isspace(*p))
346             return false;
347     if (strWhole.size() > 14)
348         return false;
349     if (nCents < 0 || nCents > 99)
350         return false;
351     int64 nWhole = atoi64(strWhole);
352     int64 nPreValue = nWhole * 100 + nCents;
353     int64 nValue = nPreValue * CENT;
354     if (nValue / CENT != nPreValue)
355         return false;
356     if (nValue / COIN != nWhole)
357         return false;
358     nRet = nValue;
359     return true;
360 }
361
362
363 vector<unsigned char> ParseHex(const char* psz)
364 {
365     vector<unsigned char> vch;
366     while (isspace(*psz))
367         psz++;
368     vch.reserve((strlen(psz)+1)/3);
369
370     static char phexdigit[256] =
371     { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
372       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
373       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
374       0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
375       -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
376       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
377       -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1
378       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
379       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
380       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
381       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
382       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
383       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
384       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
385       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
386       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, };
387
388     while (*psz)
389     {
390         char c = phexdigit[(unsigned char)*psz++];
391         if (c == -1)
392             break;
393         unsigned char n = (c << 4);
394         if (*psz)
395         {
396             char c = phexdigit[(unsigned char)*psz++];
397             if (c == -1)
398                 break;
399             n |= c;
400             vch.push_back(n);
401         }
402         while (isspace(*psz))
403             psz++;
404     }
405
406     return vch;
407 }
408
409 vector<unsigned char> ParseHex(const std::string& str)
410 {
411     return ParseHex(str.c_str());
412 }
413
414
415 void ParseParameters(int argc, char* argv[])
416 {
417     mapArgs.clear();
418     mapMultiArgs.clear();
419     for (int i = 0; i < argc; i++)
420     {
421         char psz[10000];
422         strlcpy(psz, argv[i], sizeof(psz));
423         char* pszValue = (char*)"";
424         if (strchr(psz, '='))
425         {
426             pszValue = strchr(psz, '=');
427             *pszValue++ = '\0';
428         }
429         #ifdef __WXMSW__
430         _strlwr(psz);
431         if (psz[0] == '/')
432             psz[0] = '-';
433         #endif
434         mapArgs[psz] = pszValue;
435         mapMultiArgs[psz].push_back(pszValue);
436     }
437 }
438
439
440 const char* wxGetTranslation(const char* pszEnglish)
441 {
442     // Wrapper of wxGetTranslation returning the same const char* type as was passed in
443     static CCriticalSection cs;
444     CRITICAL_BLOCK(cs)
445     {
446         // Look in cache
447         static map<string, char*> mapCache;
448         map<string, char*>::iterator mi = mapCache.find(pszEnglish);
449         if (mi != mapCache.end())
450             return (*mi).second;
451
452         // wxWidgets translation
453         wxString strTranslated = wxGetTranslation(wxString(pszEnglish, wxConvUTF8));
454
455         // We don't cache unknown strings because caller might be passing in a
456         // dynamic string and we would keep allocating memory for each variation.
457         if (strcmp(pszEnglish, strTranslated.utf8_str()) == 0)
458             return pszEnglish;
459
460         // Add to cache, memory doesn't need to be freed.  We only cache because
461         // we must pass back a pointer to permanently allocated memory.
462         char* pszCached = new char[strlen(strTranslated.utf8_str())+1];
463         strcpy(pszCached, strTranslated.utf8_str());
464         mapCache[pszEnglish] = pszCached;
465         return pszCached;
466     }
467     return NULL;
468 }
469
470
471
472
473
474
475
476
477
478
479 void FormatException(char* pszMessage, std::exception* pex, const char* pszThread)
480 {
481 #ifdef __WXMSW__
482     char pszModule[MAX_PATH];
483     pszModule[0] = '\0';
484     GetModuleFileNameA(NULL, pszModule, sizeof(pszModule));
485 #else
486     // might not be thread safe, uses wxString
487     //const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str();
488     const char* pszModule = "bitcoin";
489 #endif
490     if (pex)
491         snprintf(pszMessage, 1000,
492             "EXCEPTION: %s       \n%s       \n%s in %s       \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
493     else
494         snprintf(pszMessage, 1000,
495             "UNKNOWN EXCEPTION       \n%s in %s       \n", pszModule, pszThread);
496 }
497
498 void LogException(std::exception* pex, const char* pszThread)
499 {
500     char pszMessage[1000];
501     FormatException(pszMessage, pex, pszThread);
502     printf("\n%s", pszMessage);
503 }
504
505 void PrintException(std::exception* pex, const char* pszThread)
506 {
507     char pszMessage[1000];
508     FormatException(pszMessage, pex, pszThread);
509     printf("\n\n************************\n%s\n", pszMessage);
510     fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
511     if (wxTheApp && !fDaemon && fGUI)
512         MyMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);
513     throw;
514     //DebugBreak();
515 }
516
517
518
519
520
521
522
523
524 #ifdef __WXMSW__
525 typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
526
527 string MyGetSpecialFolderPath(int nFolder, bool fCreate)
528 {
529     char pszPath[MAX_PATH+100] = "";
530
531     // SHGetSpecialFolderPath isn't always available on old Windows versions
532     HMODULE hShell32 = LoadLibraryA("shell32.dll");
533     if (hShell32)
534     {
535         PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath =
536             (PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA");
537         if (pSHGetSpecialFolderPath)
538             (*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate);
539         FreeModule(hShell32);
540     }
541
542     // Backup option
543     if (pszPath[0] == '\0')
544     {
545         if (nFolder == CSIDL_STARTUP)
546         {
547             strcpy(pszPath, getenv("USERPROFILE"));
548             strcat(pszPath, "\\Start Menu\\Programs\\Startup");
549         }
550         else if (nFolder == CSIDL_APPDATA)
551         {
552             strcpy(pszPath, getenv("APPDATA"));
553         }
554     }
555
556     return pszPath;
557 }
558 #endif
559
560 string GetDefaultDataDir()
561 {
562     // Windows: C:\Documents and Settings\username\Application Data\Bitcoin
563     // Mac: ~/Library/Application Support/Bitcoin
564     // Unix: ~/.bitcoin
565 #ifdef __WXMSW__
566     // Windows
567     return MyGetSpecialFolderPath(CSIDL_APPDATA, true) + "\\Bitcoin";
568 #else
569     char* pszHome = getenv("HOME");
570     if (pszHome == NULL || strlen(pszHome) == 0)
571         pszHome = (char*)"/";
572     string strHome = pszHome;
573     if (strHome[strHome.size()-1] != '/')
574         strHome += '/';
575 #ifdef __WXOSX__
576     // Mac
577     strHome += "Library/Application Support/";
578     _mkdir(strHome.c_str());
579     return strHome + "Bitcoin";
580 #else
581     // Unix
582     return strHome + ".bitcoin";
583 #endif
584 #endif
585 }
586
587 void GetDataDir(char* pszDir)
588 {
589     // pszDir must be at least MAX_PATH length.
590     if (pszSetDataDir[0] != 0)
591     {
592         strlcpy(pszDir, pszSetDataDir, MAX_PATH);
593         static bool fMkdirDone;
594         if (!fMkdirDone)
595         {
596             fMkdirDone = true;
597             _mkdir(pszDir);
598         }
599     }
600     else
601     {
602         // This can be called during exceptions by printf, so we cache the
603         // value so we don't have to do memory allocations after that.
604         static char pszCachedDir[MAX_PATH];
605         if (pszCachedDir[0] == 0)
606         {
607             //strlcpy(pszCachedDir, wxStandardPaths::Get().GetUserDataDir().c_str(), sizeof(pszCachedDir));
608             strlcpy(pszCachedDir, GetDefaultDataDir().c_str(), sizeof(pszCachedDir));
609             _mkdir(pszCachedDir);
610         }
611         strlcpy(pszDir, pszCachedDir, MAX_PATH);
612     }
613 }
614
615 string GetDataDir()
616 {
617     char pszDir[MAX_PATH];
618     GetDataDir(pszDir);
619     return pszDir;
620 }
621
622 int GetFilesize(FILE* file)
623 {
624     int nSavePos = ftell(file);
625     int nFilesize = -1;
626     if (fseek(file, 0, SEEK_END) == 0)
627         nFilesize = ftell(file);
628     fseek(file, nSavePos, SEEK_SET);
629     return nFilesize;
630 }
631
632 void ShrinkDebugFile()
633 {
634     // Scroll debug.log if it's getting too big
635     string strFile = GetDataDir() + "/debug.log";
636     FILE* file = fopen(strFile.c_str(), "r");
637     if (file && GetFilesize(file) > 10 * 1000000)
638     {
639         // Restart the file with some of the end
640         char pch[200000];
641         fseek(file, -sizeof(pch), SEEK_END);
642         int nBytes = fread(pch, 1, sizeof(pch), file);
643         fclose(file);
644         if (file = fopen(strFile.c_str(), "w"))
645         {
646             fwrite(pch, 1, nBytes, file);
647             fclose(file);
648         }
649     }
650 }
651
652
653
654
655
656
657
658
659
660
661
662 //
663 // "Never go to sea with two chronometers; take one or three."
664 // Our three chronometers are:
665 //  - System clock
666 //  - Median of other server's clocks
667 //  - NTP servers
668 //
669 // note: NTP isn't implemented yet, so until then we just use the median
670 //  of other nodes clocks to correct ours.
671 //
672 int64 GetTime()
673 {
674     return time(NULL);
675 }
676
677 static int64 nTimeOffset = 0;
678
679 int64 GetAdjustedTime()
680 {
681     return GetTime() + nTimeOffset;
682 }
683
684 void AddTimeData(unsigned int ip, int64 nTime)
685 {
686     int64 nOffsetSample = nTime - GetTime();
687
688     // Ignore duplicates
689     static set<unsigned int> setKnown;
690     if (!setKnown.insert(ip).second)
691         return;
692
693     // Add data
694     static vector<int64> vTimeOffsets;
695     if (vTimeOffsets.empty())
696         vTimeOffsets.push_back(0);
697     vTimeOffsets.push_back(nOffsetSample);
698     printf("Added time data, samples %d, offset %+"PRI64d" (%+"PRI64d" minutes)\n", vTimeOffsets.size(), vTimeOffsets.back(), vTimeOffsets.back()/60);
699     if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
700     {
701         sort(vTimeOffsets.begin(), vTimeOffsets.end());
702         int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2];
703         nTimeOffset = nMedian;
704         if ((nMedian > 0 ? nMedian : -nMedian) > 5 * 60)
705         {
706             // Only let other nodes change our clock so far before we
707             // go to the NTP servers
708             /// todo: Get time from NTP servers, then set a flag
709             ///    to make sure it doesn't get changed again
710         }
711         foreach(int64 n, vTimeOffsets)
712             printf("%+"PRI64d"  ", n);
713         printf("|  nTimeOffset = %+"PRI64d"  (%+"PRI64d" minutes)\n", nTimeOffset, nTimeOffset/60);
714     }
715 }