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