diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/init.cpp | 346 | ||||
-rw-r--r-- | src/init.h | 3 | ||||
-rw-r--r-- | src/irc.cpp | 5 | ||||
-rw-r--r-- | src/net.cpp | 17 | ||||
-rw-r--r-- | src/net.h | 1 | ||||
-rw-r--r-- | src/netbase.cpp | 14 | ||||
-rw-r--r-- | src/qt/bitcoin.cpp | 58 | ||||
-rw-r--r-- | src/qt/guiutil.cpp | 2 | ||||
-rw-r--r-- | src/qt/sendcoinsdialog.cpp | 10 |
9 files changed, 274 insertions, 182 deletions
diff --git a/src/init.cpp b/src/init.cpp index 38e2b6f9e6..9b12ab0aa4 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -100,14 +100,52 @@ int main(int argc, char* argv[]) return 1; } -#endif bool AppInit(int argc, char* argv[]) { bool fRet = false; try { - fRet = AppInit2(argc, argv); + // + // Parameters + // + // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main() + ParseParameters(argc, argv); + if (!boost::filesystem::is_directory(GetDataDir(false))) + { + fprintf(stderr, "Error: Specified directory does not exist\n"); + Shutdown(NULL); + } + ReadConfigFile(mapArgs, mapMultiArgs); + + if (mapArgs.count("-?") || mapArgs.count("--help")) + { + // First part of help message is specific to bitcoind / RPC client + std::string strUsage = _("Bitcoin version") + " " + FormatFullVersion() + "\n\n" + + _("Usage:") + "\n" + + " bitcoind [options] " + "\n" + + " bitcoind [options] <command> [params] " + _("Send command to -server or bitcoind") + "\n" + + " bitcoind [options] help " + _("List commands") + "\n" + + " bitcoind [options] help <command> " + _("Get help for a command") + "\n"; + + strUsage += "\n" + HelpMessage(); + + fprintf(stderr, "%s", strUsage.c_str()); + return false; + } + + // Command-line RPC + for (int i = 1; i < argc; i++) + if (!IsSwitchChar(argv[i][0]) && !(strlen(argv[i]) > 7 && strncasecmp(argv[i], "bitcoin:", 8) == 0)) + fCommandLine = true; + + if (fCommandLine) + { + int ret = CommandLineRPC(argc, argv); + exit(ret); + } + + fRet = AppInit2(); } catch (std::exception& e) { PrintException(&e, "AppInit()"); @@ -118,20 +156,114 @@ bool AppInit(int argc, char* argv[]) Shutdown(NULL); return fRet; } +#endif + +bool static InitError(const std::string &str) +{ + ThreadSafeMessageBox(str, _("Bitcoin"), wxOK | wxMODAL); + return false; + +} + +bool static InitWarning(const std::string &str) +{ + ThreadSafeMessageBox(str, _("Bitcoin"), wxOK | wxICON_EXCLAMATION | wxMODAL); + return true; +} + bool static Bind(const CService &addr) { if (IsLimited(addr)) return false; std::string strError; if (!BindListenPort(addr, strError)) - { - ThreadSafeMessageBox(strError, _("Bitcoin"), wxOK | wxMODAL); - return false; - } + return InitError(strError); return true; } -bool AppInit2(int argc, char* argv[]) +// Core-specific options shared between UI and daemon +std::string HelpMessage() +{ + string strUsage = _("Options:") + "\n" + + " -conf=<file> " + _("Specify configuration file (default: bitcoin.conf)") + "\n" + + " -pid=<file> " + _("Specify pid file (default: bitcoind.pid)") + "\n" + + " -gen " + _("Generate coins") + "\n" + + " -gen=0 " + _("Don't generate coins") + "\n" + + " -datadir=<dir> " + _("Specify data directory") + "\n" + + " -dbcache=<n> " + _("Set database cache size in megabytes (default: 25)") + "\n" + + " -dblogsize=<n> " + _("Set database disk log size in megabytes (default: 100)") + "\n" + + " -timeout=<n> " + _("Specify connection timeout (in milliseconds)") + "\n" + + " -proxy=<ip:port> " + _("Connect through socks proxy") + "\n" + + " -socks=<n> " + _("Select the version of socks proxy to use (4 or 5, 5 is default)") + "\n" + + " -noproxy=<net> " + _("Do not use proxy for connections to network <net> (IPv4 or IPv6)") + "\n" + + " -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + "\n" + + " -proxydns " + _("Pass DNS requests to (SOCKS5) proxy") + "\n" + + " -port=<port> " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)") + "\n" + + " -maxconnections=<n> " + _("Maintain at most <n> connections to peers (default: 125)") + "\n" + + " -addnode=<ip> " + _("Add a node to connect to and attempt to keep the connection open") + "\n" + + " -connect=<ip> " + _("Connect only to the specified node") + "\n" + + " -seednode=<ip> " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n" + + " -externalip=<ip> " + _("Specify your own public address") + "\n" + + " -onlynet=<net> " + _("Only connect to nodes in network <net> (IPv4 or IPv6)") + "\n" + + " -discover " + _("Try to discover public IP address (default: 1)") + "\n" + + " -irc " + _("Find peers using internet relay chat (default: 0)") + "\n" + + " -listen " + _("Accept connections from outside (default: 1)") + "\n" + + " -bind=<addr> " + _("Bind to given address. Use [host]:port notation for IPv6") + "\n" + + " -dnsseed " + _("Find peers using DNS lookup (default: 1)") + "\n" + + " -banscore=<n> " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n" + + " -bantime=<n> " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n" + + " -maxreceivebuffer=<n> " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000)") + "\n" + + " -maxsendbuffer=<n> " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 10000)") + "\n" + +#ifdef USE_UPNP +#if USE_UPNP + " -upnp " + _("Use Universal Plug and Play to map the listening port (default: 1)") + "\n" + +#else + " -upnp " + _("Use Universal Plug and Play to map the listening port (default: 0)") + "\n" + +#endif +#endif + " -detachdb " + _("Detach block and address databases. Increases shutdown time (default: 0)") + "\n" + + " -paytxfee=<amt> " + _("Fee per KB to add to transactions you send") + "\n" + +#ifdef QT_GUI + " -server " + _("Accept command line and JSON-RPC commands") + "\n" + +#endif +#if !defined(WIN32) && !defined(QT_GUI) + " -daemon " + _("Run in the background as a daemon and accept commands") + "\n" + +#endif + " -testnet " + _("Use the test network") + "\n" + + " -debug " + _("Output extra debugging information") + "\n" + + " -logtimestamps " + _("Prepend debug output with timestamp") + "\n" + + " -printtoconsole " + _("Send trace/debug info to console instead of debug.log file") + "\n" + +#ifdef WIN32 + " -printtodebugger " + _("Send trace/debug info to debugger") + "\n" + +#endif + " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n" + + " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n" + + " -rpcport=<port> " + _("Listen for JSON-RPC connections on <port> (default: 8332)") + "\n" + + " -rpcallowip=<ip> " + _("Allow JSON-RPC connections from specified IP address") + "\n" + + " -rpcconnect=<ip> " + _("Send commands to node running on <ip> (default: 127.0.0.1)") + "\n" + + " -blocknotify=<cmd> " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n" + + " -upgradewallet " + _("Upgrade wallet to latest format") + "\n" + + " -keypool=<n> " + _("Set key pool size to <n> (default: 100)") + "\n" + + " -rescan " + _("Rescan the block chain for missing wallet transactions") + "\n" + + " -checkblocks=<n> " + _("How many blocks to check at startup (default: 2500, 0 = all)") + "\n" + + " -checklevel=<n> " + _("How thorough the block verification is (0-6, default: 1)") + "\n" + + " -loadblock=<file> " + _("Imports blocks from external blk000?.dat file") + "\n" + + " -? " + _("This help message") + "\n"; + + strUsage += string() + + _("\nSSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n" + + " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n" + + " -rpcsslcertificatechainfile=<file.cert> " + _("Server certificate file (default: server.cert)") + "\n" + + " -rpcsslprivatekeyfile=<file.pem> " + _("Server private key (default: server.pem)") + "\n" + + " -rpcsslciphers=<ciphers> " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)") + "\n"; + + return strUsage; +} + +/** Initialize bitcoin. + * @pre Parameters should be parsed and config file should be read. + */ +bool AppInit2() { #ifdef _MSC_VER // Turn off microsoft heap dump noise @@ -156,120 +288,6 @@ bool AppInit2(int argc, char* argv[]) sigaction(SIGHUP, &sa, NULL); #endif - // - // Parameters - // - // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main() -#if !defined(QT_GUI) - ParseParameters(argc, argv); - if (!boost::filesystem::is_directory(GetDataDir(false))) - { - fprintf(stderr, "Error: Specified directory does not exist\n"); - Shutdown(NULL); - } - ReadConfigFile(mapArgs, mapMultiArgs); -#endif - - if (mapArgs.count("-?") || mapArgs.count("--help")) - { - string strUsage = string() + - _("Bitcoin version") + " " + FormatFullVersion() + "\n\n" + - _("Usage:") + "\t\t\t\t\t\t\t\t\t\t\n" + - " bitcoind [options] \t " + "\n" + - " bitcoind [options] <command> [params]\t " + _("Send command to -server or bitcoind") + "\n" + - " bitcoind [options] help \t\t " + _("List commands") + "\n" + - " bitcoind [options] help <command> \t\t " + _("Get help for a command") + "\n" + - _("Options:") + "\n" + - " -conf=<file> \t\t " + _("Specify configuration file (default: bitcoin.conf)") + "\n" + - " -pid=<file> \t\t " + _("Specify pid file (default: bitcoind.pid)") + "\n" + - " -gen \t\t " + _("Generate coins") + "\n" + - " -gen=0 \t\t " + _("Don't generate coins") + "\n" + - " -min \t\t " + _("Start minimized") + "\n" + - " -splash \t\t " + _("Show splash screen on startup (default: 1)") + "\n" + - " -datadir=<dir> \t\t " + _("Specify data directory") + "\n" + - " -dbcache=<n> \t\t " + _("Set database cache size in megabytes (default: 25)") + "\n" + - " -dblogsize=<n> \t\t " + _("Set database disk log size in megabytes (default: 100)") + "\n" + - " -timeout=<n> \t " + _("Specify connection timeout (in milliseconds)") + "\n" + - " -proxy=<ip:port> \t " + _("Connect through socks proxy") + "\n" + - " -socks=<n> \t " + _("Select the version of socks proxy to use (4 or 5, 5 is default)") + "\n" + - " -noproxy=<net> \t " + _("Do not use proxy for connections to network <net> (IPv4 or IPv6)") + "\n" + - " -dns \t " + _("Allow DNS lookups for -addnode, -seednode and -connect") + "\n" + - " -proxydns \t " + _("Pass DNS requests to (SOCKS5) proxy") + "\n" + - " -port=<port> \t\t " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)") + "\n" + - " -maxconnections=<n>\t " + _("Maintain at most <n> connections to peers (default: 125)") + "\n" + - " -addnode=<ip> \t " + _("Add a node to connect to and attempt to keep the connection open") + "\n" + - " -connect=<ip> \t\t " + _("Connect only to the specified node") + "\n" + - " -seednode=<ip> \t\t " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n" + - " -externalip=<ip> \t " + _("Specify your own public address") + "\n" + - " -blocknet=<net> \t " + _("Do not connect to addresses in network <net> (IPv4 or IPv6)") + "\n" + - " -discover \t " + _("Try to discover public IP address (default: 1)") + "\n" + - " -irc \t " + _("Find peers using internet relay chat (default: 0)") + "\n" + - " -listen \t " + _("Accept connections from outside (default: 1)") + "\n" + - " -bind=<addr> \t " + _("Bind to given address. Use [host]:port notation for IPv6") + "\n" + -#ifdef QT_GUI - " -lang=<lang> \t\t " + _("Set language, for example \"de_DE\" (default: system locale)") + "\n" + -#endif - " -dnsseed \t " + _("Find peers using DNS lookup (default: 1)") + "\n" + - " -banscore=<n> \t " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n" + - " -bantime=<n> \t " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n" + - " -maxreceivebuffer=<n>\t " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000)") + "\n" + - " -maxsendbuffer=<n>\t " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 10000)") + "\n" + -#ifdef USE_UPNP -#if USE_UPNP - " -upnp \t " + _("Use Universal Plug and Play to map the listening port (default: 1)") + "\n" + -#else - " -upnp \t " + _("Use Universal Plug and Play to map the listening port (default: 0)") + "\n" + -#endif - " -detachdb \t " + _("Detach block and address databases. Increases shutdown time (default: 0)") + "\n" + -#endif - " -paytxfee=<amt> \t " + _("Fee per KB to add to transactions you send") + "\n" + -#ifdef QT_GUI - " -server \t\t " + _("Accept command line and JSON-RPC commands") + "\n" + -#endif -#if !defined(WIN32) && !defined(QT_GUI) - " -daemon \t\t " + _("Run in the background as a daemon and accept commands") + "\n" + -#endif - " -testnet \t\t " + _("Use the test network") + "\n" + - " -debug \t\t " + _("Output extra debugging information") + "\n" + - " -logtimestamps \t " + _("Prepend debug output with timestamp") + "\n" + - " -printtoconsole \t " + _("Send trace/debug info to console instead of debug.log file") + "\n" + -#ifdef WIN32 - " -printtodebugger \t " + _("Send trace/debug info to debugger") + "\n" + -#endif - " -rpcuser=<user> \t " + _("Username for JSON-RPC connections") + "\n" + - " -rpcpassword=<pw>\t " + _("Password for JSON-RPC connections") + "\n" + - " -rpcport=<port> \t\t " + _("Listen for JSON-RPC connections on <port> (default: 8332)") + "\n" + - " -rpcallowip=<ip> \t\t " + _("Allow JSON-RPC connections from specified IP address") + "\n" + - " -rpcconnect=<ip> \t " + _("Send commands to node running on <ip> (default: 127.0.0.1)") + "\n" + - " -blocknotify=<cmd> " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n" + - " -upgradewallet \t " + _("Upgrade wallet to latest format") + "\n" + - " -keypool=<n> \t " + _("Set key pool size to <n> (default: 100)") + "\n" + - " -rescan \t " + _("Rescan the block chain for missing wallet transactions") + "\n" + - " -checkblocks=<n> \t\t " + _("How many blocks to check at startup (default: 2500, 0 = all)") + "\n" + - " -checklevel=<n> \t\t " + _("How thorough the block verification is (0-6, default: 1)") + "\n" + - " -loadblock=<file>\t " + _("Imports blocks from external blk000?.dat file") + "\n"; - - strUsage += string() + - _("\nSSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n" + - " -rpcssl \t " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n" + - " -rpcsslcertificatechainfile=<file.cert>\t " + _("Server certificate file (default: server.cert)") + "\n" + - " -rpcsslprivatekeyfile=<file.pem> \t " + _("Server private key (default: server.pem)") + "\n" + - " -rpcsslciphers=<ciphers> \t " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)") + "\n"; - - strUsage += string() + - " -? \t\t " + _("This help message") + "\n"; - - // Remove tabs - strUsage.erase(std::remove(strUsage.begin(), strUsage.end(), '\t'), strUsage.end()); -#if defined(QT_GUI) && defined(WIN32) - // On windows, show a message box, as there is no stderr - ThreadSafeMessageBox(strUsage, _("Usage"), wxOK | wxMODAL); -#else - fprintf(stderr, "%s", strUsage.c_str()); -#endif - return false; - } - fTestNet = GetBoolArg("-testnet"); if (fTestNet) { @@ -298,18 +316,6 @@ bool AppInit2(int argc, char* argv[]) fPrintToDebugger = GetBoolArg("-printtodebugger"); fLogTimestamps = GetBoolArg("-logtimestamps"); -#ifndef QT_GUI - for (int i = 1; i < argc; i++) - if (!IsSwitchChar(argv[i][0]) && !(strlen(argv[i]) > 7 && strncasecmp(argv[i], "bitcoin:", 8) == 0)) - fCommandLine = true; - - if (fCommandLine) - { - int ret = CommandLineRPC(argc, argv); - exit(ret); - } -#endif - #if !defined(WIN32) && !defined(QT_GUI) if (fDaemon) { @@ -352,10 +358,7 @@ bool AppInit2(int argc, char* argv[]) if (file) fclose(file); static boost::interprocess::file_lock lock(pathLockFile.string().c_str()); if (!lock.try_lock()) - { - ThreadSafeMessageBox(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().string().c_str()), _("Bitcoin"), wxOK|wxMODAL); - return false; - } + return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().string().c_str())); std::ostringstream strErrors; // @@ -414,8 +417,7 @@ bool AppInit2(int argc, char* argv[]) { strErrors << _("Wallet needed to be rewritten: restart Bitcoin to complete") << "\n"; printf("%s", strErrors.str().c_str()); - ThreadSafeMessageBox(strErrors.str(), _("Bitcoin"), wxOK | wxICON_ERROR | wxMODAL); - return false; + return InitError(strErrors.str()); } else strErrors << _("Error loading wallet.dat") << "\n"; @@ -485,10 +487,7 @@ bool AppInit2(int argc, char* argv[]) printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size()); if (!strErrors.str().empty()) - { - ThreadSafeMessageBox(strErrors.str(), _("Bitcoin"), wxOK | wxICON_ERROR | wxMODAL); - return false; - } + return InitError(strErrors.str()); // Add wallet transactions that aren't already in a block to mapTransactions pwalletMain->ReacceptWalletTransactions(); @@ -541,20 +540,15 @@ bool AppInit2(int argc, char* argv[]) fUseProxy = true; addrProxy = CService(mapArgs["-proxy"], 9050); if (!addrProxy.IsValid()) - { - ThreadSafeMessageBox(_("Invalid -proxy address"), _("Bitcoin"), wxOK | wxMODAL); - return false; - } + return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"].c_str())); } if (mapArgs.count("-noproxy")) { BOOST_FOREACH(std::string snet, mapMultiArgs["-noproxy"]) { enum Network net = ParseNetwork(snet); - if (net == NET_UNROUTABLE) { - ThreadSafeMessageBox(_("Unknown network specified in -noproxy"), _("Bitcoin"), wxOK | wxMODAL); - return false; - } + if (net == NET_UNROUTABLE) + return InitError(strprintf(_("Unknown network specified in -noproxy: '%s'"), snet.c_str())); SetNoProxy(net); } } @@ -578,14 +572,18 @@ bool AppInit2(int argc, char* argv[]) SoftSetBoolArg("-discover", false); } - if (mapArgs.count("-blocknet")) { - BOOST_FOREACH(std::string snet, mapMultiArgs["-blocknet"]) { + if (mapArgs.count("-onlynet")) { + std::set<enum Network> nets; + BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) { enum Network net = ParseNetwork(snet); - if (net == NET_UNROUTABLE) { - ThreadSafeMessageBox(_("Unknown network specified in -blocknet"), _("Bitcoin"), wxOK | wxMODAL); - return false; - } - SetLimited(net); + if (net == NET_UNROUTABLE) + return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet.c_str())); + nets.insert(net); + } + for (int n = 0; n < NET_MAX; n++) { + enum Network net = (enum Network)n; + if (!nets.count(net)) + SetLimited(net); } } @@ -595,6 +593,8 @@ bool AppInit2(int argc, char* argv[]) fNameLookup = true; fNoListen = !GetBoolArg("-listen", true); nSocksVersion = GetArg("-socks", 5); + if (nSocksVersion != 4 && nSocksVersion != 5) + return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion)); BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"]) AddOneShot(strDest); @@ -611,35 +611,41 @@ bool AppInit2(int argc, char* argv[]) std::string strError; if (mapArgs.count("-bind")) { BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) { - fBound |= Bind(CService(strBind, GetListenPort(), false)); + CService addrBind; + if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false)) + return InitError(strprintf(_("Cannot resolve -bind address: '%s'"), strBind.c_str())); + fBound |= Bind(addrBind); } } else { struct in_addr inaddr_any; inaddr_any.s_addr = INADDR_ANY; - fBound |= Bind(CService(inaddr_any, GetListenPort())); + if (!IsLimited(NET_IPV4)) + fBound |= Bind(CService(inaddr_any, GetListenPort())); #ifdef USE_IPV6 - fBound |= Bind(CService(in6addr_any, GetListenPort())); + if (!IsLimited(NET_IPV6)) + fBound |= Bind(CService(in6addr_any, GetListenPort())); #endif } if (!fBound) - return false; + return InitError(_("Not listening on any port")); } if (mapArgs.count("-externalip")) { - BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) + BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) { + CService addrLocal(strAddr, GetListenPort(), fNameLookup); + if (!addrLocal.IsValid()) + return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr.c_str())); AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL); + } } if (mapArgs.count("-paytxfee")) { if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee)) - { - ThreadSafeMessageBox(_("Invalid amount for -paytxfee=<amount>"), _("Bitcoin"), wxOK | wxMODAL); - return false; - } + return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"].c_str())); if (nTransactionFee > 0.25 * COIN) - ThreadSafeMessageBox(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."), _("Bitcoin"), wxOK | wxICON_EXCLAMATION | wxMODAL); + InitWarning(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction.")); } // @@ -651,12 +657,14 @@ bool AppInit2(int argc, char* argv[]) RandAddSeedPerfmon(); if (!CreateThread(StartNode, NULL)) - ThreadSafeMessageBox(_("Error: CreateThread(StartNode) failed"), _("Bitcoin"), wxOK | wxMODAL); + InitError(_("Error: could not start node")); if (fServer) CreateThread(ThreadRPCServer, NULL); #if !defined(QT_GUI) + // Loop until process is exit()ed from shutdown() function, + // called from ThreadRPCServer thread when a "stop" command is received. while (1) Sleep(5000); #endif diff --git a/src/init.h b/src/init.h index 0a2f0d8932..9a8f98cce9 100644 --- a/src/init.h +++ b/src/init.h @@ -11,6 +11,7 @@ extern CWallet* pwalletMain; void Shutdown(void* parg); bool AppInit(int argc, char* argv[]); -bool AppInit2(int argc, char* argv[]); +bool AppInit2(); +std::string HelpMessage(); #endif diff --git a/src/irc.cpp b/src/irc.cpp index 525bd7a8da..4baffedb54 100644 --- a/src/irc.cpp +++ b/src/irc.cpp @@ -246,11 +246,12 @@ void ThreadIRCSeed2(void* parg) return; } + CNetAddr addrIPv4("1.2.3.4"); // arbitrary IPv4 address to make GetLocal prefer IPv4 addresses CService addrLocal; string strMyName; - if (GetLocal(addrLocal, &addrConnect)) + if (GetLocal(addrLocal, &addrIPv4)) strMyName = EncodeAddress(GetLocalAddress(&addrConnect)); - else + if (strMyName == "") strMyName = strprintf("x%u", GetRand(1000000000)); Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str()); diff --git a/src/net.cpp b/src/net.cpp index c8cb17091f..e48b300953 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -211,6 +211,12 @@ bool AddLocal(const CService& addr, int nScore) if (!addr.IsRoutable()) return false; + if (!GetBoolArg("-discover", true) && nScore < LOCAL_MANUAL) + return false; + + if (IsLimited(addr)) + return false; + printf("AddLocal(%s,%i)\n", addr.ToString().c_str(), nScore); { @@ -239,14 +245,21 @@ bool AddLocal(const CNetAddr &addr, int nScore) /** Make a particular network entirely off-limits (no automatic connects to it) */ void SetLimited(enum Network net, bool fLimited) { + if (net == NET_UNROUTABLE) + return; LOCK(cs_mapLocalHost); vfLimited[net] = fLimited; } -bool IsLimited(const CNetAddr& addr) +bool IsLimited(enum Network net) { LOCK(cs_mapLocalHost); - return vfLimited[addr.GetNetwork()]; + return vfLimited[net]; +} + +bool IsLimited(const CNetAddr &addr) +{ + return IsLimited(addr.GetNetwork()); } /** vote for a local address */ @@ -57,6 +57,7 @@ enum }; void SetLimited(enum Network net, bool fLimited = true); +bool IsLimited(enum Network net); bool IsLimited(const CNetAddr& addr); bool AddLocal(const CService& addr, int nScore = LOCAL_NONE); bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE); diff --git a/src/netbase.cpp b/src/netbase.cpp index 2131bdf75b..3fe42a7a74 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -711,7 +711,19 @@ enum Network CNetAddr::GetNetwork() const std::string CNetAddr::ToStringIP() const { - if (IsIPv4()) + CService serv(*this, 0); +#ifdef USE_IPV6 + struct sockaddr_storage sockaddr; +#else + struct sockaddr sockaddr; +#endif + socklen_t socklen = sizeof(sockaddr); + if (serv.GetSockAddr((struct sockaddr*)&sockaddr, &socklen)) { + char name[1025] = ""; + if (!getnameinfo((const struct sockaddr*)&sockaddr, socklen, name, sizeof(name), NULL, 0, NI_NUMERICHOST)) + return std::string(name); + } + if (IsIPv4()) return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); else return strprintf("%x:%x:%x:%x:%x:%x:%x:%x", diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index cf115c48f1..ab0a37abff 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -129,6 +129,53 @@ static void handleRunawayException(std::exception *e) exit(1); } +/** Help message for Bitcoin-Qt, shown with --help. */ +class HelpMessageBox: public QMessageBox +{ +public: + HelpMessageBox(QWidget *parent = 0); + + void exec(); +private: + QString header; + QString coreOptions; + QString uiOptions; +}; +#include <QSpacerItem> +#include <QGridLayout> +HelpMessageBox::HelpMessageBox(QWidget *parent): + QMessageBox(parent) +{ + header = tr("Bitcoin-Qt") + " " + tr("version") + " " + + QString::fromStdString(FormatFullVersion()) + "\n\n" + + tr("Usage:") + "\n" + + " bitcoin-qt [options] " + "\n"; + coreOptions = QString::fromStdString(HelpMessage()); + uiOptions = tr("UI options") + ":\n" + + " -lang=<lang> " + tr("Set language, for example \"de_DE\" (default: system locale)") + "\n" + + " -min " + tr("Start minimized") + "\n" + + " -splash " + tr("Show splash screen on startup (default: 1)") + "\n"; + + setWindowTitle(tr("Bitcoin-Qt")); + setTextFormat(Qt::PlainText); + // setMinimumWidth is ignored for QMessageBox so put in nonbreaking spaces to make it wider. + QChar em_space(0x2003); + setText(header + QString(em_space).repeated(40)); + setDetailedText(coreOptions + "\n" + uiOptions); +} + +void HelpMessageBox::exec() +{ +#if defined(WIN32) + // On windows, show a message box, as there is no stderr in windowed applications + QMessageBox::exec(); +#else + // On other operating systems, the expected action is to print the message to the console. + QString strUsage = header + "\n" + coreOptions + "\n" + uiOptions; + fprintf(stderr, "%s", strUsage.toStdString().c_str()); +#endif +} + #ifdef WIN32 #define strncasecmp strnicmp #endif @@ -218,6 +265,15 @@ int main(int argc, char *argv[]) if (translator.load(lang_territory, ":/translations/")) app.installTranslator(&translator); + // Show help message immediately after parsing command-line options (for "-lang") and setting locale, + // but before showing splash screen. + if (mapArgs.count("-?") || mapArgs.count("--help")) + { + HelpMessageBox help; + help.exec(); + return 1; + } + QSplashScreen splash(QPixmap(":/images/splash"), 0); if (GetBoolArg("-splash", true) && !GetBoolArg("-min")) { @@ -238,7 +294,7 @@ int main(int argc, char *argv[]) BitcoinGUI window; guiref = &window; - if(AppInit2(argc, argv)) + if(AppInit2()) { { // Put this in a block, so that the Model objects are cleaned up before diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 23e6576772..22c0bfeebe 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -257,7 +257,7 @@ bool ToolTipToRichTextFilter::eventFilter(QObject *obj, QEvent *evt) { QWidget *widget = static_cast<QWidget*>(obj); QString tooltip = widget->toolTip(); - if(!Qt::mightBeRichText(tooltip) && tooltip.size() > size_threshold) + if(tooltip.size() > size_threshold && !tooltip.startsWith("<qt/>") && !Qt::mightBeRichText(tooltip)) { // Prefix <qt/> to make sure Qt detects this as rich text // Escape the current message as HTML and replace \n by <br> diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index b4029aa0d2..f6a3047a2b 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -130,28 +130,28 @@ void SendCoinsDialog::on_sendButton_clicked() break; case WalletModel::AmountExceedsBalance: QMessageBox::warning(this, tr("Send Coins"), - tr("Amount exceeds your balance"), + tr("The amount exceeds your balance."), QMessageBox::Ok, QMessageBox::Ok); break; case WalletModel::AmountWithFeeExceedsBalance: QMessageBox::warning(this, tr("Send Coins"), - tr("Total exceeds your balance when the %1 transaction fee is included"). + tr("The total exceeds your balance when the %1 transaction fee is included."). arg(BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, sendstatus.fee)), QMessageBox::Ok, QMessageBox::Ok); break; case WalletModel::DuplicateAddress: QMessageBox::warning(this, tr("Send Coins"), - tr("Duplicate address found, can only send to each address once in one send operation"), + tr("Duplicate address found, can only send to each address once per send operation."), QMessageBox::Ok, QMessageBox::Ok); break; case WalletModel::TransactionCreationFailed: QMessageBox::warning(this, tr("Send Coins"), - tr("Error: Transaction creation failed "), + tr("Error: Transaction creation failed."), QMessageBox::Ok, QMessageBox::Ok); break; case WalletModel::TransactionCommitFailed: QMessageBox::warning(this, tr("Send Coins"), - tr("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."), + tr("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."), QMessageBox::Ok, QMessageBox::Ok); break; case WalletModel::Aborted: // User aborted, nothing to do |