@ -22,7 +22,6 @@ map<string, vector<string> > mapMultiArgs;
bool fDebug = false ;
bool fDebug = false ;
bool fPrintToConsole = false ;
bool fPrintToConsole = false ;
bool fPrintToDebugger = false ;
bool fPrintToDebugger = false ;
char pszSetDataDir [ MAX_PATH ] = " " ;
bool fRequestShutdown = false ;
bool fRequestShutdown = false ;
bool fShutdown = false ;
bool fShutdown = false ;
bool fDaemon = false ;
bool fDaemon = false ;
@ -165,10 +164,8 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
if ( ! fileout )
if ( ! fileout )
{
{
char pszFile [ MAX_PATH + 100 ] ;
boost : : filesystem : : path pathDebug = GetDataDir ( ) / " debug.log " ;
GetDataDir ( pszFile ) ;
fileout = fopen ( pathDebug . string ( ) . c_str ( ) , " a " ) ;
strlcat ( pszFile , " /debug.log " , sizeof ( pszFile ) ) ;
fileout = fopen ( pszFile , " a " ) ;
if ( fileout ) setbuf ( fileout , NULL ) ; // unbuffered
if ( fileout ) setbuf ( fileout , NULL ) ; // unbuffered
}
}
if ( fileout )
if ( fileout )
@ -768,101 +765,94 @@ void PrintExceptionContinue(std::exception* pex, const char* pszThread)
}
}
# ifdef WIN32
# ifdef WIN32
string MyGetSpecialFolderPath ( int nFolder , bool fCreate )
boost : : filesystem : : path MyGetSpecialFolderPath ( int nFolder , bool fCreate )
{
{
namespace fs = boost : : filesystem ;
char pszPath [ MAX_PATH ] = " " ;
char pszPath [ MAX_PATH ] = " " ;
if ( SHGetSpecialFolderPathA ( NULL , pszPath , nFolder , fCreate ) )
if ( SHGetSpecialFolderPathA ( NULL , pszPath , nFolder , fCreate ) )
{
{
return pszPath ;
return fs : : path ( pszPath ) ;
}
}
else if ( nFolder = = CSIDL_STARTUP )
else if ( nFolder = = CSIDL_STARTUP )
{
{
return string ( getenv ( " USERPROFILE " ) ) + " \\ Start Menu \\ Programs \\ Startup " ;
return fs : : path ( getenv ( " USERPROFILE " ) ) / " Start Menu " / " Programs " / " Startup " ;
}
}
else if ( nFolder = = CSIDL_APPDATA )
else if ( nFolder = = CSIDL_APPDATA )
{
{
return getenv ( " APPDATA " ) ;
return fs : : path ( getenv ( " APPDATA " ) ) ;
}
}
return " " ;
return fs : : path ( " " ) ;
}
}
# endif
# endif
string GetDefaultDataDir ( )
boost : : filesystem : : path GetDefaultDataDir ( )
{
{
namespace fs = boost : : filesystem ;
// Windows: C:\Documents and Settings\username\Application Data\Bitcoin
// Windows: C:\Documents and Settings\username\Application Data\Bitcoin
// Mac: ~/Library/Application Support/Bitcoin
// Mac: ~/Library/Application Support/Bitcoin
// Unix: ~/.bitcoin
// Unix: ~/.bitcoin
# ifdef WIN32
# ifdef WIN32
// Windows
// Windows
return MyGetSpecialFolderPath ( CSIDL_APPDATA , true ) + " \\ Bitcoin " ;
return MyGetSpecialFolderPath ( CSIDL_APPDATA , true ) / " Bitcoin " ;
# else
# else
fs : : path pathRet ;
char * pszHome = getenv ( " HOME " ) ;
char * pszHome = getenv ( " HOME " ) ;
if ( pszHome = = NULL | | strlen ( pszHome ) = = 0 )
if ( pszHome = = NULL | | strlen ( pszHome ) = = 0 )
pszHome = ( char * ) " / " ;
pathRet = fs : : path ( " / " ) ;
string strHome = pszHome ;
else
if ( strHome [ strHome . size ( ) - 1 ] ! = ' / ' )
pathRet = fs : : path ( pszHome ) ;
strHome + = ' / ' ;
# ifdef MAC_OSX
# ifdef MAC_OSX
// Mac
// Mac
strHome + = " Library/ Application Support/ " ;
pathRet / = " Library " / " Application Support " ;
filesystem : : create_directory ( strHome . c_str ( ) ) ;
filesystem : : create_directory ( pathRet ) ;
return strHome + " Bitcoin " ;
return pathRet / " Bitcoin " ;
# else
# else
// Unix
// Unix
return strHome + " .bitcoin " ;
return pathRet / " .bitcoin " ;
# endif
# endif
# endif
# endif
}
}
void GetDataDir ( char * pszDir )
const boost : : filesystem : : path & GetDataDir ( bool fNetSpecific )
{
{
// pszDir must be at least MAX_PATH length.
namespace fs = boost : : filesystem ;
int nVariation ;
if ( pszSetDataDir [ 0 ] ! = 0 )
static fs : : path pathCached [ 2 ] ;
{
static CCriticalSection csPathCached ;
strlcpy ( pszDir , pszSetDataDir , MAX_PATH ) ;
static bool cachedPath [ 2 ] = { false , false } ;
nVariation = 0 ;
}
fs : : path & path = pathCached [ fNetSpecific ] ;
else
{
// This can be called during exceptions by printf, so we cache the
// This can be called during exceptions by printf, so we cache the
// value so we don't have to do memory allocations after that.
// value so we don't have to do memory allocations after that.
static char pszCachedDir [ MAX_PATH ] ;
if ( cachedPath [ fNetSpecific ] )
if ( pszCachedDir [ 0 ] = = 0 )
return path ;
strlcpy ( pszCachedDir , GetDefaultDataDir ( ) . c_str ( ) , sizeof ( pszCachedDir ) ) ;
strlcpy ( pszDir , pszCachedDir , MAX_PATH ) ;
LOCK ( csPathCached ) ;
nVariation = 1 ;
}
if ( mapArgs . count ( " -datadir " ) ) {
if ( fTestNet )
path = mapArgs [ " -datadir " ] ;
{
} else {
char * p = pszDir + strlen ( pszDir ) ;
path = GetDefaultDataDir ( ) ;
if ( p > pszDir & & p [ - 1 ] ! = ' / ' & & p [ - 1 ] ! = ' \\ ' )
if ( fNetSpecific & & GetBoolArg ( " -testnet " , false ) )
* p + + = ' / ' ;
path / = " testnet " ;
strcpy ( p , " testnet " ) ;
nVariation + = 2 ;
}
static bool pfMkdir [ 4 ] ;
if ( ! pfMkdir [ nVariation ] )
{
pfMkdir [ nVariation ] = true ;
boost : : filesystem : : create_directory ( pszDir ) ;
}
}
}
string GetDataDir ( )
fs : : create_directory ( path ) ;
{
char pszDir [ MAX_PATH ] ;
cachedPath [ fNetSpecific ] = true ;
GetDataDir ( pszDir ) ;
return path ;
return pszDir ;
}
}
string GetConfigFile ( )
boost : : filesystem : : path GetConfigFile ( )
{
{
namespace fs = boost : : filesystem ;
namespace fs = boost : : filesystem ;
fs : : path pathConfigFile ( GetArg ( " -conf " , " bitcoin.conf " ) ) ;
fs : : path pathConfigFile ( GetArg ( " -conf " , " bitcoin.conf " ) ) ;
if ( ! pathConfigFile . is_complete ( ) ) pathConfigFile = fs : : path ( GetDataDir ( ) ) / pathConfigFile ;
if ( ! pathConfigFile . is_complete ( ) ) pathConfigFile = GetDataDir ( false ) / pathConfigFile ;
return pathConfigFile . string ( ) ;
return pathConfigFile ;
}
}
bool ReadConfigFile ( map < string , string > & mapSettingsRet ,
bool ReadConfigFile ( map < string , string > & mapSettingsRet ,
@ -871,20 +861,6 @@ bool ReadConfigFile(map<string, string>& mapSettingsRet,
namespace fs = boost : : filesystem ;
namespace fs = boost : : filesystem ;
namespace pod = boost : : program_options : : detail ;
namespace pod = boost : : program_options : : detail ;
if ( mapSettingsRet . count ( " -datadir " ) )
{
if ( fs : : is_directory ( fs : : system_complete ( mapSettingsRet [ " -datadir " ] ) ) )
{
fs : : path pathDataDir ( fs : : system_complete ( mapSettingsRet [ " -datadir " ] ) ) ;
strlcpy ( pszSetDataDir , pathDataDir . string ( ) . c_str ( ) , sizeof ( pszSetDataDir ) ) ;
}
else
{
return false ;
}
}
fs : : ifstream streamConfig ( GetConfigFile ( ) ) ;
fs : : ifstream streamConfig ( GetConfigFile ( ) ) ;
if ( ! streamConfig . good ( ) )
if ( ! streamConfig . good ( ) )
return true ; // No bitcoin.conf file is OK
return true ; // No bitcoin.conf file is OK
@ -907,18 +883,18 @@ bool ReadConfigFile(map<string, string>& mapSettingsRet,
return true ;
return true ;
}
}
string GetPidFile ( )
boost : : filesystem : : path GetPidFile ( )
{
{
namespace fs = boost : : filesystem ;
namespace fs = boost : : filesystem ;
fs : : path pathPidFile ( GetArg ( " -pid " , " bitcoind.pid " ) ) ;
fs : : path pathPidFile ( GetArg ( " -pid " , " bitcoind.pid " ) ) ;
if ( ! pathPidFile . is_complete ( ) ) pathPidFile = fs : : path ( GetDataDir ( ) ) / pathPidFile ;
if ( ! pathPidFile . is_complete ( ) ) pathPidFile = GetDataDir ( ) / pathPidFile ;
return pathPidFile . string ( ) ;
return pathPidFile ;
}
}
void CreatePidFile ( string pidFile , pid_t pid )
void CreatePidFile ( const boost : : filesystem : : path & path , pid_t pid )
{
{
FILE * file = fopen ( pidFile . c_str ( ) , " w " ) ;
FILE * file = fopen ( path . string ( ) . c_str ( ) , " w " ) ;
if ( file )
if ( file )
{
{
fprintf ( file , " %d \n " , pid ) ;
fprintf ( file , " %d \n " , pid ) ;
@ -939,8 +915,8 @@ int GetFilesize(FILE* file)
void ShrinkDebugFile ( )
void ShrinkDebugFile ( )
{
{
// Scroll debug.log if it's getting too big
// Scroll debug.log if it's getting too big
string strFile = GetDataDir ( ) + " / debug.log" ;
boost : : filesystem : : path pathLog = GetDataDir ( ) / " debug.log " ;
FILE * file = fopen ( strFile . c_str ( ) , " r " ) ;
FILE * file = fopen ( pathLog . string ( ) . c_str ( ) , " r " ) ;
if ( file & & GetFilesize ( file ) > 10 * 1000000 )
if ( file & & GetFilesize ( file ) > 10 * 1000000 )
{
{
// Restart the file with some of the end
// Restart the file with some of the end
@ -949,7 +925,7 @@ void ShrinkDebugFile()
int nBytes = fread ( pch , 1 , sizeof ( pch ) , file ) ;
int nBytes = fread ( pch , 1 , sizeof ( pch ) , file ) ;
fclose ( file ) ;
fclose ( file ) ;
file = fopen ( strFile . c_str ( ) , " w " ) ;
file = fopen ( pathLog . string ( ) . c_str ( ) , " w " ) ;
if ( file )
if ( file )
{
{
fwrite ( pch , 1 , nBytes , file ) ;
fwrite ( pch , 1 , nBytes , file ) ;