Dash Core  0.12.2.1
P2P Digital Currency
util.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2015 The Bitcoin Core developers
3 // Copyright (c) 2014-2017 The Dash Core developers
4 // Distributed under the MIT software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #if defined(HAVE_CONFIG_H)
8 #include "config/dash-config.h"
9 #endif
10 
11 #include "util.h"
12 
14 #include "chainparamsbase.h"
15 #include "random.h"
16 #include "serialize.h"
17 #include "sync.h"
18 #include "utilstrencodings.h"
19 #include "utiltime.h"
20 
21 #include <stdarg.h>
22 
23 #if (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__))
24 #include <pthread.h>
25 #include <pthread_np.h>
26 #endif
27 
28 
29 #ifndef WIN32
30 // for posix_fallocate
31 #ifdef __linux__
32 
33 #ifdef _POSIX_C_SOURCE
34 #undef _POSIX_C_SOURCE
35 #endif
36 
37 #define _POSIX_C_SOURCE 200112L
38 
39 #endif // __linux__
40 
41 #include <algorithm>
42 #include <fcntl.h>
43 #include <sys/resource.h>
44 #include <sys/stat.h>
45 
46 #else
47 
48 #ifdef _MSC_VER
49 #pragma warning(disable:4786)
50 #pragma warning(disable:4804)
51 #pragma warning(disable:4805)
52 #pragma warning(disable:4717)
53 #endif
54 
55 #ifdef _WIN32_WINNT
56 #undef _WIN32_WINNT
57 #endif
58 #define _WIN32_WINNT 0x0501
59 
60 #ifdef _WIN32_IE
61 #undef _WIN32_IE
62 #endif
63 #define _WIN32_IE 0x0501
64 
65 #define WIN32_LEAN_AND_MEAN 1
66 #ifndef NOMINMAX
67 #define NOMINMAX
68 #endif
69 
70 #include <io.h> /* for _commit */
71 #include <shlobj.h>
72 #endif
73 
74 #ifdef HAVE_SYS_PRCTL_H
75 #include <sys/prctl.h>
76 #endif
77 
78 #include <boost/algorithm/string/case_conv.hpp> // for to_lower()
79 #include <boost/algorithm/string/join.hpp>
80 #include <boost/algorithm/string/predicate.hpp> // for startswith() and endswith()
81 #include <boost/algorithm/string/split.hpp>
82 #include <boost/algorithm/string/classification.hpp>
83 #include <boost/filesystem.hpp>
84 #include <boost/filesystem/fstream.hpp>
85 #include <boost/foreach.hpp>
86 #include <boost/program_options/detail/config_file.hpp>
87 #include <boost/program_options/parsers.hpp>
88 #include <boost/thread.hpp>
89 #include <openssl/crypto.h>
90 #include <openssl/rand.h>
91 #include <openssl/conf.h>
92 
93 // Work around clang compilation problem in Boost 1.46:
94 // /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
95 // See also: http://stackoverflow.com/questions/10020179/compilation-fail-in-boost-librairies-program-options
96 // http://clang.debian.net/status.php?version=3.0&key=CANNOT_FIND_FUNCTION
97 namespace boost {
98 
99  namespace program_options {
100  std::string to_internal(const std::string&);
101  }
102 
103 } // namespace boost
104 
105 using namespace std;
106 
107 //Dash only features
108 bool fMasterNode = false;
109 bool fLiteMode = false;
117 int nWalletBackups = 10;
118 
119 const char * const BITCOIN_CONF_FILENAME = "dash.conf";
120 const char * const BITCOIN_PID_FILENAME = "dashd.pid";
121 
122 map<string, string> mapArgs;
123 map<string, vector<string> > mapMultiArgs;
124 bool fDebug = false;
125 bool fPrintToConsole = false;
126 bool fPrintToDebugLog = true;
127 bool fDaemon = false;
128 bool fServer = false;
134 volatile bool fReopenDebugLog = false;
136 
139 void locking_callback(int mode, int i, const char* file, int line) NO_THREAD_SAFETY_ANALYSIS
140 {
141  if (mode & CRYPTO_LOCK) {
143  } else {
145  }
146 }
147 
148 // Init
149 class CInit
150 {
151 public:
153  {
154  // Init OpenSSL library multithreading support
155  ppmutexOpenSSL = (CCriticalSection**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(CCriticalSection*));
156  for (int i = 0; i < CRYPTO_num_locks(); i++)
157  ppmutexOpenSSL[i] = new CCriticalSection();
158  CRYPTO_set_locking_callback(locking_callback);
159 
160  // OpenSSL can optionally load a config file which lists optional loadable modules and engines.
161  // We don't use them so we don't require the config. However some of our libs may call functions
162  // which attempt to load the config file, possibly resulting in an exit() or crash if it is missing
163  // or corrupt. Explicitly tell OpenSSL not to try to load the file. The result for our libs will be
164  // that the config appears to have been loaded and there are no modules/engines available.
165  OPENSSL_no_config();
166 
167 #ifdef WIN32
168  // Seed OpenSSL PRNG with current contents of the screen
169  RAND_screen();
170 #endif
171 
172  // Seed OpenSSL PRNG with performance counter
173  RandAddSeed();
174  }
176  {
177  // Securely erase the memory used by the PRNG
178  RAND_cleanup();
179  // Shutdown OpenSSL library multithreading support
180  CRYPTO_set_locking_callback(NULL);
181  for (int i = 0; i < CRYPTO_num_locks(); i++)
182  delete ppmutexOpenSSL[i];
183  OPENSSL_free(ppmutexOpenSSL);
184  }
185 }
187 
199 static boost::once_flag debugPrintInitFlag = BOOST_ONCE_INIT;
200 
210 static FILE* fileout = NULL;
211 static boost::mutex* mutexDebugLog = NULL;
212 static list<string> *vMsgsBeforeOpenLog;
213 
214 static int FileWriteStr(const std::string &str, FILE *fp)
215 {
216  return fwrite(str.data(), 1, str.size(), fp);
217 }
218 
219 static void DebugPrintInit()
220 {
221  assert(mutexDebugLog == NULL);
222  mutexDebugLog = new boost::mutex();
223  vMsgsBeforeOpenLog = new list<string>;
224 }
225 
227 {
228  boost::call_once(&DebugPrintInit, debugPrintInitFlag);
229  boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
230 
231  assert(fileout == NULL);
232  assert(vMsgsBeforeOpenLog);
233  boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
234  fileout = fopen(pathDebug.string().c_str(), "a");
235  if (fileout) setbuf(fileout, NULL); // unbuffered
236 
237  // dump buffered messages from before we opened the log
238  while (!vMsgsBeforeOpenLog->empty()) {
240  vMsgsBeforeOpenLog->pop_front();
241  }
242 
243  delete vMsgsBeforeOpenLog;
244  vMsgsBeforeOpenLog = NULL;
245 }
246 
247 bool LogAcceptCategory(const char* category)
248 {
249  if (category != NULL)
250  {
251  // Give each thread quick access to -debug settings.
252  // This helps prevent issues debugging global destructors,
253  // where mapMultiArgs might be deleted before another
254  // global destructor calls LogPrint()
255  static boost::thread_specific_ptr<set<string> > ptrCategory;
256 
257  if (!fDebug) {
258  if (ptrCategory.get() != NULL) {
259  LogPrintf("debug turned off: thread %s\n", GetThreadName());
260  ptrCategory.release();
261  }
262  return false;
263  }
264 
265  if (ptrCategory.get() == NULL)
266  {
267  std::string strThreadName = GetThreadName();
268  LogPrintf("debug turned on:\n");
269  for (int i = 0; i < (int)mapMultiArgs["-debug"].size(); ++i)
270  LogPrintf(" thread %s category %s\n", strThreadName, mapMultiArgs["-debug"][i]);
271  const vector<string>& categories = mapMultiArgs["-debug"];
272  ptrCategory.reset(new set<string>(categories.begin(), categories.end()));
273  // thread_specific_ptr automatically deletes the set when the thread ends.
274  // "dash" is a composite category enabling all Dash-related debug output
275  if(ptrCategory->count(string("dash"))) {
276  ptrCategory->insert(string("privatesend"));
277  ptrCategory->insert(string("instantsend"));
278  ptrCategory->insert(string("masternode"));
279  ptrCategory->insert(string("spork"));
280  ptrCategory->insert(string("keepass"));
281  ptrCategory->insert(string("mnpayments"));
282  ptrCategory->insert(string("gobject"));
283  }
284  }
285  const set<string>& setCategories = *ptrCategory.get();
286 
287  // if not debugging everything and not debugging specific category, LogPrint does nothing.
288  if (setCategories.count(string("")) == 0 &&
289  setCategories.count(string("1")) == 0 &&
290  setCategories.count(string(category)) == 0)
291  return false;
292  }
293  return true;
294 }
295 
301 static std::string LogTimestampStr(const std::string &str, bool *fStartedNewLine)
302 {
303  string strStamped;
304 
305  if (!fLogTimestamps)
306  return str;
307 
308  if (*fStartedNewLine) {
309  int64_t nTimeMicros = GetLogTimeMicros();
310  strStamped = DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nTimeMicros/1000000);
311  if (fLogTimeMicros)
312  strStamped += strprintf(".%06d", nTimeMicros%1000000);
313  strStamped += ' ' + str;
314  } else
315  strStamped = str;
316 
317  return strStamped;
318 }
319 
325 static std::string LogThreadNameStr(const std::string &str, bool *fStartedNewLine)
326 {
327  string strThreadLogged;
328 
329  if (!fLogThreadNames)
330  return str;
331 
332  std::string strThreadName = GetThreadName();
333 
334  if (*fStartedNewLine)
335  strThreadLogged = strprintf("%16s | %s", strThreadName.c_str(), str.c_str());
336  else
337  strThreadLogged = str;
338 
339  return strThreadLogged;
340 }
341 
342 int LogPrintStr(const std::string &str)
343 {
344  int ret = 0; // Returns total number of characters written
345  static bool fStartedNewLine = true;
346 
347  std::string strThreadLogged = LogThreadNameStr(str, &fStartedNewLine);
348  std::string strTimestamped = LogTimestampStr(strThreadLogged, &fStartedNewLine);
349 
350  if (!str.empty() && str[str.size()-1] == '\n')
351  fStartedNewLine = true;
352  else
353  fStartedNewLine = false;
354 
355  if (fPrintToConsole)
356  {
357  // print to console
358  ret = fwrite(strTimestamped.data(), 1, strTimestamped.size(), stdout);
359  fflush(stdout);
360  }
361  else if (fPrintToDebugLog)
362  {
363  boost::call_once(&DebugPrintInit, debugPrintInitFlag);
364  boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
365 
366  // buffer if we haven't opened the log yet
367  if (fileout == NULL) {
368  assert(vMsgsBeforeOpenLog);
369  ret = strTimestamped.length();
370  vMsgsBeforeOpenLog->push_back(strTimestamped);
371  }
372  else
373  {
374  // reopen the log file, if requested
375  if (fReopenDebugLog) {
376  fReopenDebugLog = false;
377  boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
378  if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL)
379  setbuf(fileout, NULL); // unbuffered
380  }
381 
382  ret = FileWriteStr(strTimestamped, fileout);
383  }
384  }
385  return ret;
386 }
387 
389 static bool InterpretBool(const std::string& strValue)
390 {
391  if (strValue.empty())
392  return true;
393  return (atoi(strValue) != 0);
394 }
395 
397 static void InterpretNegativeSetting(std::string& strKey, std::string& strValue)
398 {
399  if (strKey.length()>3 && strKey[0]=='-' && strKey[1]=='n' && strKey[2]=='o')
400  {
401  strKey = "-" + strKey.substr(3);
402  strValue = InterpretBool(strValue) ? "0" : "1";
403  }
404 }
405 
406 void ParseParameters(int argc, const char* const argv[])
407 {
408  mapArgs.clear();
409  mapMultiArgs.clear();
410 
411  for (int i = 1; i < argc; i++)
412  {
413  std::string str(argv[i]);
414  std::string strValue;
415  size_t is_index = str.find('=');
416  if (is_index != std::string::npos)
417  {
418  strValue = str.substr(is_index+1);
419  str = str.substr(0, is_index);
420  }
421 #ifdef WIN32
422  boost::to_lower(str);
423  if (boost::algorithm::starts_with(str, "/"))
424  str = "-" + str.substr(1);
425 #endif
426 
427  if (str[0] != '-')
428  break;
429 
430  // Interpret --foo as -foo.
431  // If both --foo and -foo are set, the last takes effect.
432  if (str.length() > 1 && str[1] == '-')
433  str = str.substr(1);
434  InterpretNegativeSetting(str, strValue);
435 
436  mapArgs[str] = strValue;
437  mapMultiArgs[str].push_back(strValue);
438  }
439 }
440 
441 std::string GetArg(const std::string& strArg, const std::string& strDefault)
442 {
443  if (mapArgs.count(strArg))
444  return mapArgs[strArg];
445  return strDefault;
446 }
447 
448 int64_t GetArg(const std::string& strArg, int64_t nDefault)
449 {
450  if (mapArgs.count(strArg))
451  return atoi64(mapArgs[strArg]);
452  return nDefault;
453 }
454 
455 bool GetBoolArg(const std::string& strArg, bool fDefault)
456 {
457  if (mapArgs.count(strArg))
458  return InterpretBool(mapArgs[strArg]);
459  return fDefault;
460 }
461 
462 bool SoftSetArg(const std::string& strArg, const std::string& strValue)
463 {
464  if (mapArgs.count(strArg))
465  return false;
466  mapArgs[strArg] = strValue;
467  return true;
468 }
469 
470 bool SoftSetBoolArg(const std::string& strArg, bool fValue)
471 {
472  if (fValue)
473  return SoftSetArg(strArg, std::string("1"));
474  else
475  return SoftSetArg(strArg, std::string("0"));
476 }
477 
478 static const int screenWidth = 79;
479 static const int optIndent = 2;
480 static const int msgIndent = 7;
481 
482 std::string HelpMessageGroup(const std::string &message) {
483  return std::string(message) + std::string("\n\n");
484 }
485 
486 std::string HelpMessageOpt(const std::string &option, const std::string &message) {
487  return std::string(optIndent,' ') + std::string(option) +
488  std::string("\n") + std::string(msgIndent,' ') +
490  std::string("\n\n");
491 }
492 
493 static std::string FormatException(const std::exception* pex, const char* pszThread)
494 {
495 #ifdef WIN32
496  char pszModule[MAX_PATH] = "";
497  GetModuleFileNameA(NULL, pszModule, sizeof(pszModule));
498 #else
499  const char* pszModule = "dash";
500 #endif
501  if (pex)
502  return strprintf(
503  "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
504  else
505  return strprintf(
506  "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread);
507 }
508 
509 void PrintExceptionContinue(const std::exception* pex, const char* pszThread)
510 {
511  std::string message = FormatException(pex, pszThread);
512  LogPrintf("\n\n************************\n%s\n", message);
513  fprintf(stderr, "\n\n************************\n%s\n", message.c_str());
514 }
515 
516 boost::filesystem::path GetDefaultDataDir()
517 {
518  namespace fs = boost::filesystem;
519  // Windows < Vista: C:\Documents and Settings\Username\Application Data\DashCore
520  // Windows >= Vista: C:\Users\Username\AppData\Roaming\DashCore
521  // Mac: ~/Library/Application Support/DashCore
522  // Unix: ~/.dashcore
523 #ifdef WIN32
524  // Windows
525  return GetSpecialFolderPath(CSIDL_APPDATA) / "DashCore";
526 #else
527  fs::path pathRet;
528  char* pszHome = getenv("HOME");
529  if (pszHome == NULL || strlen(pszHome) == 0)
530  pathRet = fs::path("/");
531  else
532  pathRet = fs::path(pszHome);
533 #ifdef MAC_OSX
534  // Mac
535  return pathRet / "Library/Application Support/DashCore";
536 #else
537  // Unix
538  return pathRet / ".dashcore";
539 #endif
540 #endif
541 }
542 
543 static boost::filesystem::path pathCached;
544 static boost::filesystem::path pathCachedNetSpecific;
546 
547 const boost::filesystem::path &GetDataDir(bool fNetSpecific)
548 {
549  namespace fs = boost::filesystem;
550 
552 
553  fs::path &path = fNetSpecific ? pathCachedNetSpecific : pathCached;
554 
555  // This can be called during exceptions by LogPrintf(), so we cache the
556  // value so we don't have to do memory allocations after that.
557  if (!path.empty())
558  return path;
559 
560  if (mapArgs.count("-datadir")) {
561  path = fs::system_complete(mapArgs["-datadir"]);
562  if (!fs::is_directory(path)) {
563  path = "";
564  return path;
565  }
566  } else {
567  path = GetDefaultDataDir();
568  }
569  if (fNetSpecific)
570  path /= BaseParams().DataDir();
571 
572  fs::create_directories(path);
573 
574  return path;
575 }
576 
577 static boost::filesystem::path backupsDirCached;
579 
580 const boost::filesystem::path &GetBackupsDir()
581 {
582  namespace fs = boost::filesystem;
583 
585 
586  fs::path &backupsDir = backupsDirCached;
587 
588  if (!backupsDir.empty())
589  return backupsDir;
590 
591  if (mapArgs.count("-walletbackupsdir")) {
592  backupsDir = fs::absolute(mapArgs["-walletbackupsdir"]);
593  // Path must exist
594  if (fs::is_directory(backupsDir)) return backupsDir;
595  // Fallback to default path if it doesn't
596  LogPrintf("%s: Warning: incorrect parameter -walletbackupsdir, path must exist! Using default path.\n", __func__);
597  strMiscWarning = _("Warning: incorrect parameter -walletbackupsdir, path must exist! Using default path.");
598  }
599  // Default path
600  backupsDir = GetDataDir() / "backups";
601 
602  return backupsDir;
603 }
604 
606 {
607  pathCached = boost::filesystem::path();
608  pathCachedNetSpecific = boost::filesystem::path();
609 }
610 
611 boost::filesystem::path GetConfigFile()
612 {
613  boost::filesystem::path pathConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME));
614  if (!pathConfigFile.is_complete())
615  pathConfigFile = GetDataDir(false) / pathConfigFile;
616 
617  return pathConfigFile;
618 }
619 
620 boost::filesystem::path GetMasternodeConfigFile()
621 {
622  boost::filesystem::path pathConfigFile(GetArg("-mnconf", "masternode.conf"));
623  if (!pathConfigFile.is_complete()) pathConfigFile = GetDataDir() / pathConfigFile;
624  return pathConfigFile;
625 }
626 
627 void ReadConfigFile(map<string, string>& mapSettingsRet,
628  map<string, vector<string> >& mapMultiSettingsRet)
629 {
630  boost::filesystem::ifstream streamConfig(GetConfigFile());
631  if (!streamConfig.good()){
632  // Create empty dash.conf if it does not excist
633  FILE* configFile = fopen(GetConfigFile().string().c_str(), "a");
634  if (configFile != NULL)
635  fclose(configFile);
636  return; // Nothing to read, so just return
637  }
638 
639  set<string> setOptions;
640  setOptions.insert("*");
641 
642  for (boost::program_options::detail::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it)
643  {
644  // Don't overwrite existing settings so command line settings override dash.conf
645  string strKey = string("-") + it->string_key;
646  string strValue = it->value[0];
647  InterpretNegativeSetting(strKey, strValue);
648  if (mapSettingsRet.count(strKey) == 0)
649  mapSettingsRet[strKey] = strValue;
650  mapMultiSettingsRet[strKey].push_back(strValue);
651  }
652  // If datadir is changed in .conf file:
654 }
655 
656 #ifndef WIN32
657 boost::filesystem::path GetPidFile()
658 {
659  boost::filesystem::path pathPidFile(GetArg("-pid", BITCOIN_PID_FILENAME));
660  if (!pathPidFile.is_complete()) pathPidFile = GetDataDir() / pathPidFile;
661  return pathPidFile;
662 }
663 
664 void CreatePidFile(const boost::filesystem::path &path, pid_t pid)
665 {
666  FILE* file = fopen(path.string().c_str(), "w");
667  if (file)
668  {
669  fprintf(file, "%d\n", pid);
670  fclose(file);
671  }
672 }
673 #endif
674 
675 bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest)
676 {
677 #ifdef WIN32
678  return MoveFileExA(src.string().c_str(), dest.string().c_str(),
679  MOVEFILE_REPLACE_EXISTING) != 0;
680 #else
681  int rc = std::rename(src.string().c_str(), dest.string().c_str());
682  return (rc == 0);
683 #endif /* WIN32 */
684 }
685 
691 bool TryCreateDirectory(const boost::filesystem::path& p)
692 {
693  try
694  {
695  return boost::filesystem::create_directory(p);
696  } catch (const boost::filesystem::filesystem_error&) {
697  if (!boost::filesystem::exists(p) || !boost::filesystem::is_directory(p))
698  throw;
699  }
700 
701  // create_directory didn't create the directory, it had to have existed already
702  return false;
703 }
704 
705 void FileCommit(FILE *fileout)
706 {
707  fflush(fileout); // harmless if redundantly called
708 #ifdef WIN32
709  HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(fileout));
710  FlushFileBuffers(hFile);
711 #else
712  #if defined(__linux__) || defined(__NetBSD__)
713  fdatasync(fileno(fileout));
714  #elif defined(__APPLE__) && defined(F_FULLFSYNC)
715  fcntl(fileno(fileout), F_FULLFSYNC, 0);
716  #else
717  fsync(fileno(fileout));
718  #endif
719 #endif
720 }
721 
722 bool TruncateFile(FILE *file, unsigned int length) {
723 #if defined(WIN32)
724  return _chsize(_fileno(file), length) == 0;
725 #else
726  return ftruncate(fileno(file), length) == 0;
727 #endif
728 }
729 
734 int RaiseFileDescriptorLimit(int nMinFD) {
735 #if defined(WIN32)
736  return 2048;
737 #else
738  struct rlimit limitFD;
739  if (getrlimit(RLIMIT_NOFILE, &limitFD) != -1) {
740  if (limitFD.rlim_cur < (rlim_t)nMinFD) {
741  limitFD.rlim_cur = nMinFD;
742  if (limitFD.rlim_cur > limitFD.rlim_max)
743  limitFD.rlim_cur = limitFD.rlim_max;
744  setrlimit(RLIMIT_NOFILE, &limitFD);
745  getrlimit(RLIMIT_NOFILE, &limitFD);
746  }
747  return limitFD.rlim_cur;
748  }
749  return nMinFD; // getrlimit failed, assume it's fine
750 #endif
751 }
752 
757 void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length) {
758 #if defined(WIN32)
759  // Windows-specific version
760  HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
761  LARGE_INTEGER nFileSize;
762  int64_t nEndPos = (int64_t)offset + length;
763  nFileSize.u.LowPart = nEndPos & 0xFFFFFFFF;
764  nFileSize.u.HighPart = nEndPos >> 32;
765  SetFilePointerEx(hFile, nFileSize, 0, FILE_BEGIN);
766  SetEndOfFile(hFile);
767 #elif defined(MAC_OSX)
768  // OSX specific version
769  fstore_t fst;
770  fst.fst_flags = F_ALLOCATECONTIG;
771  fst.fst_posmode = F_PEOFPOSMODE;
772  fst.fst_offset = 0;
773  fst.fst_length = (off_t)offset + length;
774  fst.fst_bytesalloc = 0;
775  if (fcntl(fileno(file), F_PREALLOCATE, &fst) == -1) {
776  fst.fst_flags = F_ALLOCATEALL;
777  fcntl(fileno(file), F_PREALLOCATE, &fst);
778  }
779  ftruncate(fileno(file), fst.fst_length);
780 #elif defined(__linux__)
781  // Version using posix_fallocate
782  off_t nEndPos = (off_t)offset + length;
783  posix_fallocate(fileno(file), 0, nEndPos);
784 #else
785  // Fallback version
786  // TODO: just write one byte per block
787  static const char buf[65536] = {};
788  fseek(file, offset, SEEK_SET);
789  while (length > 0) {
790  unsigned int now = 65536;
791  if (length < now)
792  now = length;
793  fwrite(buf, 1, now, file); // allowed to fail; this function is advisory anyway
794  length -= now;
795  }
796 #endif
797 }
798 
800 {
801  // Amount of debug.log to save at end when shrinking (must fit in memory)
802  constexpr size_t RECENT_DEBUG_HISTORY_SIZE = 10 * 1000000;
803  // Scroll debug.log if it's getting too big
804  boost::filesystem::path pathLog = GetDataDir() / "debug.log";
805  FILE* file = fopen(pathLog.string().c_str(), "r");
806  // If debug.log file is more than 10% bigger the RECENT_DEBUG_HISTORY_SIZE
807  // trim it down by saving only the last RECENT_DEBUG_HISTORY_SIZE bytes
808  if (file && boost::filesystem::file_size(pathLog) > 11 * (RECENT_DEBUG_HISTORY_SIZE / 10))
809  {
810  // Restart the file with some of the end
811  std::vector<char> vch(RECENT_DEBUG_HISTORY_SIZE, 0);
812  fseek(file, -((long)vch.size()), SEEK_END);
813  int nBytes = fread(begin_ptr(vch), 1, vch.size(), file);
814  fclose(file);
815 
816  file = fopen(pathLog.string().c_str(), "w");
817  if (file)
818  {
819  fwrite(begin_ptr(vch), 1, nBytes, file);
820  fclose(file);
821  }
822  }
823  else if (file != NULL)
824  fclose(file);
825 }
826 
827 #ifdef WIN32
828 boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate)
829 {
830  namespace fs = boost::filesystem;
831 
832  char pszPath[MAX_PATH] = "";
833 
834  if(SHGetSpecialFolderPathA(NULL, pszPath, nFolder, fCreate))
835  {
836  return fs::path(pszPath);
837  }
838 
839  LogPrintf("SHGetSpecialFolderPathA() failed, could not obtain requested path.\n");
840  return fs::path("");
841 }
842 #endif
843 
844 boost::filesystem::path GetTempPath() {
845 #if BOOST_FILESYSTEM_VERSION == 3
846  return boost::filesystem::temp_directory_path();
847 #else
848  // TODO: remove when we don't support filesystem v2 anymore
849  boost::filesystem::path path;
850 #ifdef WIN32
851  char pszPath[MAX_PATH] = "";
852 
853  if (GetTempPathA(MAX_PATH, pszPath))
854  path = boost::filesystem::path(pszPath);
855 #else
856  path = boost::filesystem::path("/tmp");
857 #endif
858  if (path.empty() || !boost::filesystem::is_directory(path)) {
859  LogPrintf("GetTempPath(): failed to find temp path\n");
860  return boost::filesystem::path("");
861  }
862  return path;
863 #endif
864 }
865 
866 void runCommand(const std::string& strCommand)
867 {
868  int nErr = ::system(strCommand.c_str());
869  if (nErr)
870  LogPrintf("runCommand error: system(%s) returned %d\n", strCommand, nErr);
871 }
872 
873 void RenameThread(const char* name)
874 {
875 #if defined(PR_SET_NAME)
876  // Only the first 15 characters are used (16 - NUL terminator)
877  ::prctl(PR_SET_NAME, name, 0, 0, 0);
878 #elif (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__))
879  pthread_set_name_np(pthread_self(), name);
880 
881 #elif defined(MAC_OSX)
882  pthread_setname_np(name);
883 #else
884  // Prevent warnings for unused parameters...
885  (void)name;
886 #endif
887 }
888 
889 std::string GetThreadName()
890 {
891  char name[16];
892 #if defined(PR_GET_NAME)
893  // Only the first 15 characters are used (16 - NUL terminator)
894  ::prctl(PR_GET_NAME, name, 0, 0, 0);
895 #elif defined(MAC_OSX)
896  pthread_getname_np(pthread_self(), name, 16);
897 // #elif (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__))
898 // #else
899  // no get_name here
900 #endif
901  return std::string(name);
902 }
903 
905 {
906  // On most POSIX systems (e.g. Linux, but not BSD) the environment's locale
907  // may be invalid, in which case the "C" locale is used as fallback.
908 #if !defined(WIN32) && !defined(MAC_OSX) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
909  try {
910  std::locale(""); // Raises a runtime error if current locale is invalid
911  } catch (const std::runtime_error&) {
912  setenv("LC_ALL", "C", 1);
913  }
914 #endif
915  // The path locale is lazy initialized and to avoid deinitialization errors
916  // in multithreading environments, it is set explicitly by the main thread.
917  // A dummy locale is used to extract the internal default locale, used by
918  // boost::filesystem::path, which is then used to explicitly imbue the path.
919  std::locale loc = boost::filesystem::path::imbue(std::locale::classic());
920  boost::filesystem::path::imbue(loc);
921 }
922 
924 {
925 #ifdef WIN32
926  // Initialize Windows Sockets
927  WSADATA wsadata;
928  int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
929  if (ret != NO_ERROR || LOBYTE(wsadata.wVersion ) != 2 || HIBYTE(wsadata.wVersion) != 2)
930  return false;
931 #endif
932  return true;
933 }
934 
935 void SetThreadPriority(int nPriority)
936 {
937 #ifdef WIN32
938  SetThreadPriority(GetCurrentThread(), nPriority);
939 #else // WIN32
940 #ifdef PRIO_THREAD
941  setpriority(PRIO_THREAD, 0, nPriority);
942 #else // PRIO_THREAD
943  setpriority(PRIO_PROCESS, 0, nPriority);
944 #endif // PRIO_THREAD
945 #endif // WIN32
946 }
947 
949 {
950 #if BOOST_VERSION >= 105600
951  return boost::thread::physical_concurrency();
952 #else // Must fall back to hardware_concurrency, which unfortunately counts virtual cores
953  return boost::thread::hardware_concurrency();
954 #endif
955 }
956 
957 
958 uint32_t StringVersionToInt(const std::string& strVersion)
959 {
960  std::vector<std::string> tokens;
961  boost::split(tokens, strVersion, boost::is_any_of("."));
962  if(tokens.size() != 3)
963  throw std::bad_cast();
964  uint32_t nVersion = 0;
965  for(unsigned idx = 0; idx < 3; idx++)
966  {
967  if(tokens[idx].length() == 0)
968  throw std::bad_cast();
969  uint32_t value = boost::lexical_cast<uint32_t>(tokens[idx]);
970  if(value > 255)
971  throw std::bad_cast();
972  nVersion <<= 8;
973  nVersion |= value;
974  }
975  return nVersion;
976 }
977 
978 std::string IntVersionToString(uint32_t nVersion)
979 {
980  if((nVersion >> 24) > 0) // MSB is always 0
981  throw std::bad_cast();
982  if(nVersion == 0)
983  throw std::bad_cast();
984  std::array<std::string, 3> tokens;
985  for(unsigned idx = 0; idx < 3; idx++)
986  {
987  unsigned shift = (2 - idx) * 8;
988  uint32_t byteValue = (nVersion >> shift) & 0xff;
989  tokens[idx] = boost::lexical_cast<std::string>(byteValue);
990  }
991  return boost::join(tokens, ".");
992 }
993 
994 std::string SafeIntVersionToString(uint32_t nVersion)
995 {
996  try
997  {
998  return IntVersionToString(nVersion);
999  }
1000  catch(const std::bad_cast&)
1001  {
1002  return "invalid_version";
1003  }
1004 }
1005 
const boost::filesystem::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:547
std::string HelpMessageOpt(const std::string &option, const std::string &message)
Definition: util.cpp:486
const std::string & DataDir() const
#define NO_THREAD_SAFETY_ANALYSIS
Definition: threadsafety.h:52
bool SetupNetworking()
Definition: util.cpp:923
static list< string > * vMsgsBeforeOpenLog
Definition: util.cpp:212
void SetThreadPriority(int nPriority)
Definition: util.cpp:935
int64_t GetLogTimeMicros()
Definition: utiltime.cpp:56
Definition: init.h:14
const char *const BITCOIN_CONF_FILENAME
Definition: util.cpp:119
void FileCommit(FILE *fileout)
Definition: util.cpp:705
string strMiscWarning
Definition: util.cpp:129
bool fDebug
Definition: util.cpp:124
void CreatePidFile(const boost::filesystem::path &path, pid_t pid)
Definition: util.cpp:664
const char *const BITCOIN_PID_FILENAME
Definition: util.cpp:120
#define strprintf
Definition: tinyformat.h:1011
static boost::filesystem::path backupsDirCached
Definition: util.cpp:577
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Definition: util.cpp:470
boost::filesystem::path GetTempPath()
Definition: util.cpp:844
std::string DateTimeStrFormat(const char *pszFormat, int64_t nTime)
Definition: utiltime.cpp:81
static FILE * fileout
Definition: util.cpp:210
boost::filesystem::path GetPidFile()
Definition: util.cpp:657
static boost::once_flag debugPrintInitFlag
Definition: util.cpp:199
#define MAX_PATH
Definition: compat.h:73
const CBaseChainParams & BaseParams()
static const int msgIndent
Definition: util.cpp:480
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
Definition: util.cpp:509
bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest)
Definition: util.cpp:675
void locking_callback(int mode, int i, const char *file, int line) NO_THREAD_SAFETY_ANALYSIS
Definition: util.cpp:139
static const bool DEFAULT_LOGTIMEMICROS
Definition: util.h:50
void RenameThread(const char *name)
Definition: util.cpp:873
static const int screenWidth
Definition: util.cpp:478
volatile bool fReopenDebugLog
Definition: util.cpp:134
static const bool DEFAULT_LOGTIMESTAMPS
Definition: util.h:52
static boost::filesystem::path pathCachedNetSpecific
Definition: util.cpp:544
int RaiseFileDescriptorLimit(int nMinFD)
Definition: util.cpp:734
bool fMasterNode
Definition: util.cpp:108
uint32_t StringVersionToInt(const std::string &strVersion)
Converts version strings to 4-byte unsigned integer.
Definition: util.cpp:958
class CInit instance_of_cinit
std::string SafeIntVersionToString(uint32_t nVersion)
Copy of the IntVersionToString, that returns "Invalid version" string instead of throwing std::bad_ca...
Definition: util.cpp:994
bool fDaemon
Definition: util.cpp:127
CTranslationInterface translationInterface
Definition: util.cpp:135
static boost::filesystem::path pathCached
Definition: util.cpp:543
bool fLiteMode
Definition: util.cpp:109
static const bool DEFAULT_LOGIPS
Definition: util.h:51
int nWalletBackups
Definition: util.cpp:117
bool TruncateFile(FILE *file, unsigned int length)
Definition: util.cpp:722
bool GetBoolArg(const std::string &strArg, bool fDefault)
Definition: util.cpp:455
#define LogPrintf(...)
Definition: util.h:98
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Definition: util.cpp:462
#define LEAVE_CRITICAL_SECTION(cs)
Definition: sync.h:178
~CInit()
Definition: util.cpp:175
#define LOCK(cs)
Definition: sync.h:168
const char * name
Definition: rest.cpp:37
bool fLogTimeMicros
Definition: util.cpp:131
static int FileWriteStr(const std::string &str, FILE *fp)
Definition: util.cpp:214
bool fServer
Definition: util.cpp:128
bool TryCreateDirectory(const boost::filesystem::path &p)
Definition: util.cpp:691
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length)
Definition: util.cpp:757
static const int optIndent
Definition: util.cpp:479
std::string FormatParagraph(const std::string &in, size_t width, size_t indent)
static std::string FormatException(const std::exception *pex, const char *pszThread)
Definition: util.cpp:493
std::string IntVersionToString(uint32_t nVersion)
Converts version as 4-byte unsigned integer to string.
Definition: util.cpp:978
std::string GetThreadName()
Definition: util.cpp:889
static CCriticalSection csBackupsDirCached
Definition: util.cpp:578
static std::string LogTimestampStr(const std::string &str, bool *fStartedNewLine)
Definition: util.cpp:301
static CCriticalSection csPathCached
Definition: util.cpp:545
static const bool DEFAULT_LOGTHREADNAMES
Definition: util.h:53
void ParseParameters(int argc, const char *const argv[])
Definition: util.cpp:406
V::value_type * begin_ptr(V &v)
Definition: serialize.h:54
bool fLogTimestamps
Definition: util.cpp:130
static boost::mutex * mutexDebugLog
Definition: util.cpp:211
#define ENTER_CRITICAL_SECTION(cs)
Definition: sync.h:172
bool fLogIPs
Definition: util.cpp:133
Definition: util.cpp:149
const boost::filesystem::path & GetBackupsDir()
Definition: util.cpp:580
void ReadConfigFile(map< string, string > &mapSettingsRet, map< string, vector< string > > &mapMultiSettingsRet)
Definition: util.cpp:627
bool fPrintToConsole
Definition: util.cpp:125
void OpenDebugLog()
Definition: util.cpp:226
static void InterpretNegativeSetting(std::string &strKey, std::string &strValue)
Definition: util.cpp:397
bool fPrintToDebugLog
Definition: util.cpp:126
CInit()
Definition: util.cpp:152
void runCommand(const std::string &strCommand)
Definition: util.cpp:866
void ClearDatadirCache()
Definition: util.cpp:605
bool LogAcceptCategory(const char *category)
Definition: util.cpp:247
int64_t atoi64(const char *psz)
void RandAddSeed()
Definition: random.cpp:38
boost::filesystem::path GetMasternodeConfigFile()
Definition: util.cpp:620
AnnotatedMixin< boost::recursive_mutex > CCriticalSection
Definition: sync.h:78
static CCriticalSection ** ppmutexOpenSSL
Definition: util.cpp:138
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Definition: util.cpp:441
static bool InterpretBool(const std::string &strValue)
Definition: util.cpp:389
static std::string LogThreadNameStr(const std::string &str, bool *fStartedNewLine)
Definition: util.cpp:325
bool fLogThreadNames
Definition: util.cpp:132
static void DebugPrintInit()
Definition: util.cpp:219
int GetNumCores()
Definition: util.cpp:948
void SetupEnvironment()
Definition: util.cpp:904
map< string, vector< string > > mapMultiArgs
Definition: util.cpp:123
std::string HelpMessageGroup(const std::string &message)
Definition: util.cpp:482
int LogPrintStr(const std::string &str)
Definition: util.cpp:342
void ShrinkDebugFile()
Definition: util.cpp:799
std::string _(const char *psz)
Definition: util.h:84
int atoi(const std::string &str)
map< string, string > mapArgs
Definition: util.cpp:122
boost::filesystem::path GetDefaultDataDir()
Definition: util.cpp:516
boost::filesystem::path GetConfigFile()
Definition: util.cpp:611