Back to home page

Bitcoin sources

 
 

    


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