aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/init.cpp346
-rw-r--r--src/init.h3
-rw-r--r--src/irc.cpp5
-rw-r--r--src/net.cpp17
-rw-r--r--src/net.h1
-rw-r--r--src/netbase.cpp14
-rw-r--r--src/qt/bitcoin.cpp58
-rw-r--r--src/qt/guiutil.cpp2
-rw-r--r--src/qt/sendcoinsdialog.cpp10
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 */
diff --git a/src/net.h b/src/net.h
index 3755c765d3..cb90ef6e72 100644
--- a/src/net.h
+++ b/src/net.h
@@ -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