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