Back to home page

Bitcoin sources

 
 

    


File indexing completed on 2020-06-25 15:48:43

0001 // Copyright (c) 2009-2010 Satoshi Nakamoto
0002 // Copyright (c) 2009-2012 The Bitcoin developers
0003 // Distributed under the MIT/X11 software license, see the accompanying
0004 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
0005 #include "knobs.h"
0006 #include "headers.h"
0007 #include "strlcpy.h"
0008 #include <boost/program_options/detail/config_file.hpp>
0009 #include <boost/program_options/parsers.hpp>
0010 #include <boost/filesystem.hpp>
0011 #include <boost/filesystem/fstream.hpp>
0012 #include <boost/interprocess/sync/interprocess_mutex.hpp>
0013 #include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
0014 #include <boost/foreach.hpp>
0015 
0016 using namespace std;
0017 using namespace boost;
0018 
0019 map<string, string> mapArgs;
0020 map<string, vector<string> > mapMultiArgs;
0021 bool fDebug = false;
0022 bool fPrintToConsole = false;
0023 bool fPrintToDebugger = false;
0024 bool fCanEat = false;
0025 bool fVerifyAll = false;
0026 char pszSetDataDir[MAX_PATH] = "";
0027 bool fRequestShutdown = false;
0028 bool fShutdown = false;
0029 bool fDaemon = false;
0030 bool fServer = false;
0031 bool fCommandLine = false;
0032 string strMiscWarning;
0033 bool fNoListen = false;
0034 bool fLogTimestamps = false;
0035 bool fLowS = false;
0036 bool fHighS = false;
0037 
0038 std::string CLIENT_NAME(DEFAULT_CLIENT_NAME);
0039 
0040 
0041 // Workaround for "multiple definition of `_tls_used'"
0042 // http://svn.boost.org/trac/boost/ticket/4258
0043 extern "C" void tss_cleanup_implemented() { }
0044 
0045 
0046 
0047 
0048 
0049 // Init openssl library multithreading support
0050 static boost::interprocess::interprocess_mutex** ppmutexOpenSSL;
0051 void locking_callback(int mode, int i, const char* file, int line)
0052 {
0053     if (mode & CRYPTO_LOCK)
0054         ppmutexOpenSSL[i]->lock();
0055     else
0056         ppmutexOpenSSL[i]->unlock();
0057 }
0058 
0059 // Init
0060 class CInit
0061 {
0062 public:
0063     CInit()
0064     {
0065         // Init openssl library multithreading support
0066         ppmutexOpenSSL = (boost::interprocess::interprocess_mutex**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(boost::interprocess::interprocess_mutex*));
0067         for (int i = 0; i < CRYPTO_num_locks(); i++)
0068             ppmutexOpenSSL[i] = new boost::interprocess::interprocess_mutex();
0069         CRYPTO_set_locking_callback(locking_callback);
0070 
0071         // Seed random number generator with performance counter
0072         RandAddSeed();
0073     }
0074     ~CInit()
0075     {
0076         // Shutdown openssl library multithreading support
0077         CRYPTO_set_locking_callback(NULL);
0078         for (int i = 0; i < CRYPTO_num_locks(); i++)
0079             delete ppmutexOpenSSL[i];
0080         OPENSSL_free(ppmutexOpenSSL);
0081     }
0082 }
0083 instance_of_cinit;
0084 
0085 
0086 
0087 
0088 
0089 
0090 
0091 
0092 void RandAddSeed()
0093 {
0094     // Seed with CPU performance counter
0095     int64 nCounter = GetPerformanceCounter();
0096     RAND_add(&nCounter, sizeof(nCounter), 1.5);
0097     memset(&nCounter, 0, sizeof(nCounter));
0098 }
0099 
0100 void RandAddSeedPerfmon()
0101 {
0102     RandAddSeed();
0103 
0104     // This can take up to 2 seconds, so only do it every 10 minutes
0105     static int64 nLastPerfmon;
0106     if (GetTime() < nLastPerfmon + 10 * 60)
0107         return;
0108     nLastPerfmon = GetTime();
0109 
0110 }
0111 
0112 uint64 GetRand(uint64 nMax)
0113 {
0114     if (nMax == 0)
0115         return 0;
0116 
0117     // The range of the random source must be a multiple of the modulus
0118     // to give every possible output value an equal possibility
0119     uint64 nRange = (UINT64_MAX / nMax) * nMax;
0120     uint64 nRand = 0;
0121     do
0122         RAND_bytes((unsigned char*)&nRand, sizeof(nRand));
0123     while (nRand >= nRange);
0124     return (nRand % nMax);
0125 }
0126 
0127 int GetRandInt(int nMax)
0128 {
0129     return GetRand(nMax);
0130 }
0131 
0132 
0133 
0134 
0135 
0136 
0137 
0138 
0139 
0140 
0141 
0142 inline int OutputDebugStringF(const char* pszFormat, ...)
0143 {
0144     int ret = 0;
0145     if (fPrintToConsole)
0146     {
0147         // print to console
0148         va_list arg_ptr;
0149         va_start(arg_ptr, pszFormat);
0150         ret = vprintf(pszFormat, arg_ptr);
0151         va_end(arg_ptr);
0152     }
0153     else
0154     {
0155         // print to debug.log
0156         static FILE* fileout = NULL;
0157 
0158         if (!fileout)
0159         {
0160             char pszFile[MAX_PATH+100];
0161             GetDataDir(pszFile);
0162             strlcat(pszFile, "/debug.log", sizeof(pszFile));
0163             fileout = fopen(pszFile, "a");
0164             if (fileout) setbuf(fileout, NULL); // unbuffered
0165         }
0166         if (fileout)
0167         {
0168             static bool fStartedNewLine = true;
0169 
0170             // Debug print useful for profiling
0171             if (fLogTimestamps && fStartedNewLine)
0172                 fprintf(fileout, "%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
0173             if (pszFormat[strlen(pszFormat) - 1] == '\n')
0174                 fStartedNewLine = true;
0175             else
0176                 fStartedNewLine = false;
0177 
0178             va_list arg_ptr;
0179             va_start(arg_ptr, pszFormat);
0180             ret = vfprintf(fileout, pszFormat, arg_ptr);
0181             va_end(arg_ptr);
0182         }
0183     }
0184 
0185     return ret;
0186 }
0187 
0188 
0189 // Safer snprintf
0190 //  - prints up to limit-1 characters
0191 //  - output string is always null terminated even if limit reached
0192 //  - return value is the number of characters actually printed
0193 int my_snprintf(char* buffer, size_t limit, const char* format, ...)
0194 {
0195     if (limit == 0)
0196         return 0;
0197     va_list arg_ptr;
0198     va_start(arg_ptr, format);
0199     int ret = _vsnprintf(buffer, limit, format, arg_ptr);
0200     va_end(arg_ptr);
0201     if (ret < 0 || ret >= limit)
0202     {
0203         ret = limit - 1;
0204         buffer[limit-1] = 0;
0205     }
0206     return ret;
0207 }
0208 
0209 string strprintf(const std::string &format, ...)
0210 {
0211     char buffer[50000];
0212     char* p = buffer;
0213     int limit = sizeof(buffer);
0214     int ret;
0215     loop
0216     {
0217         va_list arg_ptr;
0218         va_start(arg_ptr, format);
0219         ret = _vsnprintf(p, limit, format.c_str(), arg_ptr);
0220         va_end(arg_ptr);
0221         if (ret >= 0 && ret < limit)
0222             break;
0223         if (p != buffer)
0224             delete[] p;
0225         limit *= 2;
0226         p = new char[limit];
0227         if (p == NULL)
0228             throw std::bad_alloc();
0229     }
0230     string str(p, p+ret);
0231     if (p != buffer)
0232         delete[] p;
0233     return str;
0234 }
0235 
0236 bool error(const std::string &format, ...)
0237 {
0238     char buffer[50000];
0239     int limit = sizeof(buffer);
0240     va_list arg_ptr;
0241     va_start(arg_ptr, format);
0242     int ret = _vsnprintf(buffer, limit, format.c_str(), arg_ptr);
0243     va_end(arg_ptr);
0244     if (ret < 0 || ret >= limit)
0245     {
0246         ret = limit - 1;
0247         buffer[limit-1] = 0;
0248     }
0249     printf("ERROR: %s\n", buffer);
0250     return false;
0251 }
0252 
0253 
0254 void ParseString(const string& str, char c, vector<string>& v)
0255 {
0256     if (str.empty())
0257         return;
0258     string::size_type i1 = 0;
0259     string::size_type i2;
0260     loop
0261     {
0262         i2 = str.find(c, i1);
0263         if (i2 == str.npos)
0264         {
0265             v.push_back(str.substr(i1));
0266             return;
0267         }
0268         v.push_back(str.substr(i1, i2-i1));
0269         i1 = i2+1;
0270     }
0271 }
0272 
0273 
0274 string FormatMoney(int64 n, bool fPlus)
0275 {
0276     // Note: not using straight sprintf here because we do NOT want
0277     // localized number formatting.
0278     int64 n_abs = (n > 0 ? n : -n);
0279     int64 quotient = n_abs/COIN;
0280     int64 remainder = n_abs%COIN;
0281     string str = strprintf("%"PRI64d".%08"PRI64d, quotient, remainder);
0282 
0283     // Right-trim excess 0's before the decimal point:
0284     int nTrim = 0;
0285     for (int i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i)
0286         ++nTrim;
0287     if (nTrim)
0288         str.erase(str.size()-nTrim, nTrim);
0289 
0290     if (n < 0)
0291         str.insert((unsigned int)0, 1, '-');
0292     else if (fPlus && n > 0)
0293         str.insert((unsigned int)0, 1, '+');
0294     return str;
0295 }
0296 
0297 
0298 bool ParseMoney(const string& str, int64& nRet)
0299 {
0300     return ParseMoney(str.c_str(), nRet);
0301 }
0302 
0303 bool ParseMoney(const char* pszIn, int64& nRet)
0304 {
0305     string strWhole;
0306     int64 nUnits = 0;
0307     const char* p = pszIn;
0308     while (isspace(*p))
0309         p++;
0310     for (; *p; p++)
0311     {
0312         if (*p == '.')
0313         {
0314             p++;
0315             int64 nMult = CENT*10;
0316             while (isdigit(*p) && (nMult > 0))
0317             {
0318                 nUnits += nMult * (*p++ - '0');
0319                 nMult /= 10;
0320             }
0321             break;
0322         }
0323         if (isspace(*p))
0324             break;
0325         if (!isdigit(*p))
0326             return false;
0327         strWhole.insert(strWhole.end(), *p);
0328     }
0329     for (; *p; p++)
0330         if (!isspace(*p))
0331             return false;
0332     if (strWhole.size() > 10) // guard against 63 bit overflow
0333         return false;
0334     if (nUnits < 0 || nUnits > COIN)
0335         return false;
0336     int64 nWhole = atoi64(strWhole);
0337     int64 nValue = nWhole*COIN + nUnits;
0338 
0339     nRet = nValue;
0340     return true;
0341 }
0342 
0343 
0344 vector<unsigned char> ParseHex(const char* psz)
0345 {
0346     static char phexdigit[256] =
0347     { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0348       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0349       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0350       0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
0351       -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0352       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0353       -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1
0354       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0355       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0356       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0357       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0358       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0359       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0360       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0361       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0362       -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, };
0363 
0364     // convert hex dump to vector
0365     vector<unsigned char> vch;
0366     loop
0367     {
0368         while (isspace(*psz))
0369             psz++;
0370         char c = phexdigit[(unsigned char)*psz++];
0371         if (c == (char)-1)
0372             break;
0373         unsigned char n = (c << 4);
0374         c = phexdigit[(unsigned char)*psz++];
0375         if (c == (char)-1)
0376             break;
0377         n |= c;
0378         vch.push_back(n);
0379     }
0380     return vch;
0381 }
0382 
0383 vector<unsigned char> ParseHex(const string& str)
0384 {
0385     return ParseHex(str.c_str());
0386 }
0387 
0388 void ParseParameters(int argc, char* argv[])
0389 {
0390     mapArgs.clear();
0391     mapMultiArgs.clear();
0392     for (int i = 1; i < argc; i++)
0393     {
0394         char psz[10000];
0395         strlcpy(psz, argv[i], sizeof(psz));
0396         char* pszValue = (char*)"";
0397         if (strchr(psz, '='))
0398         {
0399             pszValue = strchr(psz, '=');
0400             *pszValue++ = '\0';
0401         }
0402         if (psz[0] != '-')
0403             break;
0404         mapArgs[psz] = pszValue;
0405         mapMultiArgs[psz].push_back(pszValue);
0406     }
0407 }
0408 
0409 bool SoftSetArg(const std::string& strArg, const std::string& strValue)
0410 {
0411     if (mapArgs.count(strArg))
0412         return false;
0413     mapArgs[strArg] = strValue;
0414     return true;
0415 }
0416 
0417 bool SoftSetArg(const std::string& strArg, bool fValue)
0418 {
0419     if (fValue)
0420         return SoftSetArg(strArg, std::string("1"));
0421     else
0422         return SoftSetArg(strArg, std::string("0"));
0423 }
0424 
0425 
0426 string EncodeBase64(const unsigned char* pch, size_t len)
0427 {
0428     static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
0429 
0430     string strRet="";
0431     strRet.reserve((len+2)/3*4);
0432 
0433     int mode=0, left=0;
0434     const unsigned char *pchEnd = pch+len;
0435 
0436     while (pch<pchEnd)
0437     {
0438         int enc = *(pch++);
0439         switch (mode)
0440         {
0441             case 0: // we have no bits
0442                 strRet += pbase64[enc >> 2];
0443                 left = (enc & 3) << 4;
0444                 mode = 1;
0445                 break;
0446 
0447             case 1: // we have two bits
0448                 strRet += pbase64[left | (enc >> 4)];
0449                 left = (enc & 15) << 2;
0450                 mode = 2;
0451                 break;
0452 
0453             case 2: // we have four bits
0454                 strRet += pbase64[left | (enc >> 6)];
0455                 strRet += pbase64[enc & 63];
0456                 mode = 0;
0457                 break;
0458         }
0459     }
0460 
0461     if (mode)
0462     {
0463         strRet += pbase64[left];
0464         strRet += '=';
0465         if (mode == 1)
0466             strRet += '=';
0467     }
0468 
0469     return strRet;
0470 }
0471 
0472 string EncodeBase64(const string& str)
0473 {
0474     return EncodeBase64((const unsigned char*)str.c_str(), str.size());
0475 }
0476 
0477 vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid)
0478 {
0479     static const int decode64_table[256] =
0480     {
0481         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0482         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0483         -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
0484         -1, -1, -1, -1, -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
0485         15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
0486         29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
0487         49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0488         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0489         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0490         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0491         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0492         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0493         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
0494     };
0495 
0496     if (pfInvalid)
0497         *pfInvalid = false;
0498 
0499     vector<unsigned char> vchRet;
0500     vchRet.reserve(strlen(p)*3/4);
0501 
0502     int mode = 0;
0503     int left = 0;
0504 
0505     while (1)
0506     {
0507          int dec = decode64_table[*p];
0508          if (dec == -1) break;
0509          p++;
0510          switch (mode)
0511          {
0512              case 0: // we have no bits and get 6
0513                  left = dec;
0514                  mode = 1;
0515                  break;
0516 
0517               case 1: // we have 6 bits and keep 4
0518                   vchRet.push_back((left<<2) | (dec>>4));
0519                   left = dec & 15;
0520                   mode = 2;
0521                   break;
0522 
0523              case 2: // we have 4 bits and get 6, we keep 2
0524                  vchRet.push_back((left<<4) | (dec>>2));
0525                  left = dec & 3;
0526                  mode = 3;
0527                  break;
0528 
0529              case 3: // we have 2 bits and get 6
0530                  vchRet.push_back((left<<6) | dec);
0531                  mode = 0;
0532                  break;
0533          }
0534     }
0535 
0536     if (pfInvalid)
0537         switch (mode)
0538         {
0539             case 0: // 4n base64 characters processed: ok
0540                 break;
0541 
0542             case 1: // 4n+1 base64 character processed: impossible
0543                 *pfInvalid = true;
0544                 break;
0545 
0546             case 2: // 4n+2 base64 characters processed: require '=='
0547                 if (left || p[0] != '=' || p[1] != '=' || decode64_table[p[2]] != -1)
0548                     *pfInvalid = true;
0549                 break;
0550 
0551             case 3: // 4n+3 base64 characters processed: require '='
0552                 if (left || p[0] != '=' || decode64_table[p[1]] != -1)
0553                     *pfInvalid = true;
0554                 break;
0555         }
0556 
0557     return vchRet;
0558 }
0559 
0560 string DecodeBase64(const string& str)
0561 {
0562     vector<unsigned char> vchRet = DecodeBase64(str.c_str());
0563     return string((const char*)&vchRet[0], vchRet.size());
0564 }
0565 
0566 
0567 bool WildcardMatch(const char* psz, const char* mask)
0568 {
0569     loop
0570     {
0571         switch (*mask)
0572         {
0573         case '\0':
0574             return (*psz == '\0');
0575         case '*':
0576             return WildcardMatch(psz, mask+1) || (*psz && WildcardMatch(psz+1, mask));
0577         case '?':
0578             if (*psz == '\0')
0579                 return false;
0580             break;
0581         default:
0582             if (*psz != *mask)
0583                 return false;
0584             break;
0585         }
0586         psz++;
0587         mask++;
0588     }
0589 }
0590 
0591 bool WildcardMatch(const string& str, const string& mask)
0592 {
0593     return WildcardMatch(str.c_str(), mask.c_str());
0594 }
0595 
0596 
0597 
0598 
0599 
0600 
0601 
0602 
0603 void FormatException(char* pszMessage, std::exception* pex, const char* pszThread)
0604 {
0605     const char* pszModule = "bitcoin";
0606     if (pex)
0607         snprintf(pszMessage, 1000,
0608             "EXCEPTION: %s       \n%s       \n%s in %s       \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
0609     else
0610         snprintf(pszMessage, 1000,
0611             "UNKNOWN EXCEPTION       \n%s in %s       \n", pszModule, pszThread);
0612 }
0613 
0614 void LogException(std::exception* pex, const char* pszThread)
0615 {
0616     char pszMessage[10000];
0617     FormatException(pszMessage, pex, pszThread);
0618     printf("\n%s", pszMessage);
0619 }
0620 
0621 void PrintException(std::exception* pex, const char* pszThread)
0622 {
0623     char pszMessage[10000];
0624     FormatException(pszMessage, pex, pszThread);
0625     printf("\n\n************************\n%s\n", pszMessage);
0626     fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
0627     strMiscWarning = pszMessage;
0628     throw;
0629 }
0630 
0631 void ThreadOneMessageBox(string strMessage)
0632 {
0633     // Skip message boxes if one is already open
0634     static bool fMessageBoxOpen;
0635     if (fMessageBoxOpen)
0636         return;
0637     fMessageBoxOpen = true;
0638     ThreadSafeMessageBox(strMessage, "Bitcoin", wxOK | wxICON_EXCLAMATION);
0639     fMessageBoxOpen = false;
0640 }
0641 
0642 void PrintExceptionContinue(std::exception* pex, const char* pszThread)
0643 {
0644     char pszMessage[10000];
0645     FormatException(pszMessage, pex, pszThread);
0646     printf("\n\n************************\n%s\n", pszMessage);
0647     fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
0648     strMiscWarning = pszMessage;
0649 }
0650 
0651 string GetDefaultDataDir()
0652 {
0653     // Mac: ~/Library/Application Support/Bitcoin
0654     // Unix: ~/.bitcoin
0655     char* pszHome = getenv("HOME");
0656     if (pszHome == NULL || strlen(pszHome) == 0)
0657         pszHome = (char*)"/";
0658     string strHome = pszHome;
0659     if (strHome[strHome.size()-1] != '/')
0660         strHome += '/';
0661 #ifdef MAC_OSX
0662     // Mac
0663     strHome += "Library/Application Support/";
0664     filesystem::create_directory(strHome.c_str());
0665     return strHome + "Bitcoin";
0666 #else
0667     // Unix
0668     return strHome + ".bitcoin";
0669 #endif
0670 }
0671 
0672 void GetDataDir(char* pszDir)
0673 {
0674     // pszDir must be at least MAX_PATH length.
0675     int nVariation;
0676     if (pszSetDataDir[0] != 0)
0677     {
0678         strlcpy(pszDir, pszSetDataDir, MAX_PATH);
0679         nVariation = 0;
0680     }
0681     else
0682     {
0683         // This can be called during exceptions by printf, so we cache the
0684         // value so we don't have to do memory allocations after that.
0685         static char pszCachedDir[MAX_PATH];
0686         if (pszCachedDir[0] == 0)
0687             strlcpy(pszCachedDir, GetDefaultDataDir().c_str(), sizeof(pszCachedDir));
0688         strlcpy(pszDir, pszCachedDir, MAX_PATH);
0689         nVariation = 1;
0690     }
0691     static bool pfMkdir[4];
0692     if (!pfMkdir[nVariation])
0693     {
0694         pfMkdir[nVariation] = true;
0695         boost::filesystem::create_directory(pszDir);
0696     }
0697 }
0698 
0699 string GetDataDir()
0700 {
0701     char pszDir[MAX_PATH];
0702     GetDataDir(pszDir);
0703     return pszDir;
0704 }
0705 
0706 string GetConfigFile()
0707 {
0708     namespace fs = boost::filesystem;
0709     fs::path pathConfig(GetArg("-conf", "bitcoin.conf"));
0710     if (!pathConfig.is_complete())
0711         pathConfig = fs::path(GetDataDir()) / pathConfig;
0712     return pathConfig.string();
0713 }
0714 
0715 void ReadConfigFile(map<string, string>& mapSettingsRet,
0716                     map<string, vector<string> >& mapMultiSettingsRet)
0717 {
0718     namespace fs = boost::filesystem;
0719     namespace pod = boost::program_options::detail;
0720 
0721     fs::ifstream streamConfig(GetConfigFile());
0722     if (!streamConfig.good())
0723         return;
0724 
0725     set<string> setOptions;
0726     setOptions.insert("*");
0727     
0728     for (pod::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it)
0729     {
0730         // Don't overwrite existing settings so command line settings override bitcoin.conf
0731         string strKey = string("-") + it->string_key;
0732         if (mapSettingsRet.count(strKey) == 0)
0733             mapSettingsRet[strKey] = it->value[0];
0734         mapMultiSettingsRet[strKey].push_back(it->value[0]);
0735     }
0736 }
0737 
0738 string GetPidFile()
0739 {
0740     namespace fs = boost::filesystem;
0741     fs::path pathConfig(GetArg("-pid", "bitcoind.pid"));
0742     if (!pathConfig.is_complete())
0743         pathConfig = fs::path(GetDataDir()) / pathConfig;
0744     return pathConfig.string();
0745 }
0746 
0747 void CreatePidFile(string pidFile, pid_t pid)
0748 {
0749     FILE* file = fopen(pidFile.c_str(), "w");
0750     if (file)
0751     {
0752         fprintf(file, "%d\n", pid);
0753         fclose(file);
0754     }
0755 }
0756 
0757 int GetFilesize(FILE* file)
0758 {
0759     int nSavePos = ftell(file);
0760     int nFilesize = -1;
0761     if (fseek(file, 0, SEEK_END) == 0)
0762         nFilesize = ftell(file);
0763     fseek(file, nSavePos, SEEK_SET);
0764     return nFilesize;
0765 }
0766 
0767 void ShrinkDebugFile()
0768 {
0769     // Scroll debug.log if it's getting too big
0770     string strFile = GetDataDir() + "/debug.log";
0771     FILE* file = fopen(strFile.c_str(), "r");
0772     if (file && GetFilesize(file) > 10 * 1000000)
0773     {
0774         // Restart the file with some of the end
0775         char pch[200000];
0776         fseek(file, -sizeof(pch), SEEK_END);
0777         int nBytes = fread(pch, 1, sizeof(pch), file);
0778         fclose(file);
0779 
0780         file = fopen(strFile.c_str(), "w");
0781         if (file)
0782         {
0783             fwrite(pch, 1, nBytes, file);
0784             fclose(file);
0785         }
0786     }
0787 }
0788 
0789 
0790 
0791 
0792 
0793 
0794 
0795 
0796 //
0797 // "Never go to sea with two chronometers; take one or three."
0798 // Our three time sources are:
0799 //  - System clock
0800 //  - Median of other nodes's clocks
0801 //  - The user (asking the user to fix the system clock if the first two disagree)
0802 //
0803 static int64 nMockTime = 0;  // For unit testing
0804 
0805 int64 GetTime()
0806 {
0807     if (nMockTime) return nMockTime;
0808 
0809     return time(NULL);
0810 }
0811 
0812 void SetMockTime(int64 nMockTimeIn)
0813 {
0814     nMockTime = nMockTimeIn;
0815 }
0816 
0817 static int64 nTimeOffset = 0;
0818 
0819 int64 GetAdjustedTime()
0820 {
0821     return GetTime() + nTimeOffset;
0822 }
0823 
0824 void AddTimeData(unsigned int ip, int64 nTime)
0825 {
0826     int64 nOffsetSample = nTime - GetTime();
0827 
0828     // Ignore duplicates
0829     static set<unsigned int> setKnown;
0830     if (!setKnown.insert(ip).second)
0831         return;
0832 
0833     // Add data
0834     static vector<int64> vTimeOffsets;
0835     if (vTimeOffsets.empty())
0836         vTimeOffsets.push_back(0);
0837     vTimeOffsets.push_back(nOffsetSample);
0838     printf("Added time data, samples %d, offset %+"PRI64d" (%+"PRI64d" minutes)\n", vTimeOffsets.size(), vTimeOffsets.back(), vTimeOffsets.back()/60);
0839     if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
0840     {
0841         sort(vTimeOffsets.begin(), vTimeOffsets.end());
0842         int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2];
0843         // Only let other nodes change our time by so much
0844         if (abs64(nMedian) < 70 * 60)
0845         {
0846             nTimeOffset = nMedian;
0847         }
0848         else
0849         {
0850             nTimeOffset = 0;
0851 
0852             static bool fDone;
0853             if (!fDone)
0854             {
0855                 // If nobody has a time different than ours but within 5 minutes of ours, give a warning
0856                 bool fMatch = false;
0857                 BOOST_FOREACH(int64 nOffset, vTimeOffsets)
0858                     if (nOffset != 0 && abs64(nOffset) < 5 * 60)
0859                         fMatch = true;
0860 
0861                 if (!fMatch)
0862                 {
0863                     fDone = true;
0864                     string strMessage = _("Warning: Please check that your computer's date and time are correct.  If your clock is wrong Bitcoin will not work properly.");
0865                     strMiscWarning = strMessage;
0866                     printf("*** %s\n", strMessage.c_str());
0867                     boost::thread(boost::bind(ThreadSafeMessageBox, strMessage+" ", string("Bitcoin"), wxOK | wxICON_EXCLAMATION, (wxWindow*)NULL, -1, -1));
0868                 }
0869             }
0870         }
0871         BOOST_FOREACH(int64 n, vTimeOffsets)
0872             printf("%+"PRI64d"  ", n);
0873         printf("|  nTimeOffset = %+"PRI64d"  (%+"PRI64d" minutes)\n", nTimeOffset, nTimeOffset/60);
0874     }
0875 }
0876 
0877 
0878 
0879 
0880 
0881 
0882 
0883 
0884 
0885 string FormatVersion(int nVersion)
0886 {
0887     if (nVersion%100 == 0)
0888         return strprintf("%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100);
0889     else
0890         return strprintf("%d.%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100, nVersion%100);
0891 }
0892 
0893 string FormatFullVersion()
0894 {
0895     string s = FormatVersion(VERSION);
0896     return s;
0897 }
0898 
0899 std::string FormatSubVersion(const std::string& name, int nClientVersion)
0900 {
0901     std::ostringstream ss;
0902     ss << "/";
0903     ss << name << ":" << FormatVersion(nClientVersion);
0904     ss << "/";
0905     return ss.str();
0906 }
0907 
0908 
0909 
0910 #ifdef DEBUG_LOCKORDER
0911 //
0912 // Early deadlock detection.
0913 // Problem being solved:
0914 //    Thread 1 locks  A, then B, then C
0915 //    Thread 2 locks  D, then C, then A
0916 //     --> may result in deadlock between the two threads, depending on when they run.
0917 // Solution implemented here:
0918 // Keep track of pairs of locks: (A before B), (A before C), etc.
0919 // Complain if any thread trys to lock in a different order.
0920 //
0921 
0922 struct CLockLocation
0923 {
0924     CLockLocation(const char* pszName, const char* pszFile, int nLine)
0925     {
0926         mutexName = pszName;
0927         sourceFile = pszFile;
0928         sourceLine = nLine;
0929     }
0930 
0931     std::string ToString() const
0932     {
0933         return mutexName+"  "+sourceFile+":"+itostr(sourceLine);
0934     }
0935 
0936 private:
0937     std::string mutexName;
0938     std::string sourceFile;
0939     int sourceLine;
0940 };
0941 
0942 typedef std::vector< std::pair<CCriticalSection*, CLockLocation> > LockStack;
0943 
0944 static boost::interprocess::interprocess_mutex dd_mutex;
0945 static std::map<std::pair<CCriticalSection*, CCriticalSection*>, LockStack> lockorders;
0946 static boost::thread_specific_ptr<LockStack> lockstack;
0947 
0948 
0949 static void potential_deadlock_detected(const std::pair<CCriticalSection*, CCriticalSection*>& mismatch, const LockStack& s1, const LockStack& s2)
0950 {
0951     printf("POTENTIAL DEADLOCK DETECTED\n");
0952     printf("Previous lock order was:\n");
0953     BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, s2)
0954     {
0955         if (i.first == mismatch.first) printf(" (1)");
0956         if (i.first == mismatch.second) printf(" (2)");
0957         printf(" %s\n", i.second.ToString().c_str());
0958     }
0959     printf("Current lock order is:\n");
0960     BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, s1)
0961     {
0962         if (i.first == mismatch.first) printf(" (1)");
0963         if (i.first == mismatch.second) printf(" (2)");
0964         printf(" %s\n", i.second.ToString().c_str());
0965     }
0966 }
0967 
0968 static void push_lock(CCriticalSection* c, const CLockLocation& locklocation)
0969 {
0970     bool fOrderOK = true;
0971     if (lockstack.get() == NULL)
0972         lockstack.reset(new LockStack);
0973 
0974     if (fDebug) printf("Locking: %s\n", locklocation.ToString().c_str());
0975     dd_mutex.lock();
0976 
0977     (*lockstack).push_back(std::make_pair(c, locklocation));
0978 
0979     BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, (*lockstack))
0980     {
0981         if (i.first == c) break;
0982 
0983         std::pair<CCriticalSection*, CCriticalSection*> p1 = std::make_pair(i.first, c);
0984         if (lockorders.count(p1))
0985             continue;
0986         lockorders[p1] = (*lockstack);
0987 
0988         std::pair<CCriticalSection*, CCriticalSection*> p2 = std::make_pair(c, i.first);
0989         if (lockorders.count(p2))
0990         {
0991             potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
0992             break;
0993         }
0994     }
0995     dd_mutex.unlock();
0996 }
0997 
0998 static void pop_lock()
0999 {
1000     if (fDebug) 
1001     {
1002         const CLockLocation& locklocation = (*lockstack).rbegin()->second;
1003         printf("Unlocked: %s\n", locklocation.ToString().c_str());
1004     }
1005     dd_mutex.lock();
1006     (*lockstack).pop_back();
1007     dd_mutex.unlock();
1008 }
1009 
1010 void CCriticalSection::Enter(const char* pszName, const char* pszFile, int nLine)
1011 {
1012     push_lock(this, CLockLocation(pszName, pszFile, nLine));
1013     mutex.lock();
1014 }
1015 void CCriticalSection::Leave()
1016 {
1017     mutex.unlock();
1018     pop_lock();
1019 }
1020 bool CCriticalSection::TryEnter(const char* pszName, const char* pszFile, int nLine)
1021 {
1022     push_lock(this, CLockLocation(pszName, pszFile, nLine));
1023     bool result = mutex.try_lock();
1024     if (!result) pop_lock();
1025     return result;
1026 }
1027 
1028 #else
1029 
1030 void CCriticalSection::Enter(const char*, const char*, int)
1031 {
1032     mutex.lock();
1033 }
1034 
1035 void CCriticalSection::Leave()
1036 {
1037     mutex.unlock();
1038 }
1039 
1040 bool CCriticalSection::TryEnter(const char*, const char*, int)
1041 {
1042     bool result = mutex.try_lock();
1043     return result;
1044 }
1045 
1046 #endif /* DEBUG_LOCKORDER */