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