aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bitcoin-qt.pro18
-rw-r--r--contrib/gitian-descriptors/README34
-rw-r--r--doc/release-notes.txt5
-rw-r--r--src/bitcoinrpc.cpp2
-rw-r--r--src/db.cpp5
-rw-r--r--src/init.cpp15
-rw-r--r--src/irc.cpp21
-rw-r--r--src/main.cpp13
-rw-r--r--src/main.h2
-rw-r--r--src/makefile.linux-mingw5
-rw-r--r--src/makefile.mingw5
-rw-r--r--src/net.cpp54
-rw-r--r--src/qt/bitcoingui.cpp5
-rw-r--r--src/qt/bitcoinstrings.cpp1
-rw-r--r--src/qt/forms/aboutdialog.ui19
-rw-r--r--src/qt/locale/bitcoin_en.ts142
-rw-r--r--src/qt/qtipcserver.cpp2
-rw-r--r--src/qt/rpcconsole.cpp126
-rw-r--r--src/rpcmining.cpp4
-rw-r--r--src/rpcwallet.cpp7
-rw-r--r--src/util.cpp12
-rw-r--r--src/util.h53
-rw-r--r--src/wallet.cpp12
-rw-r--r--src/wallet.h7
24 files changed, 336 insertions, 233 deletions
diff --git a/bitcoin-qt.pro b/bitcoin-qt.pro
index 0711ae1c91..1d2b1dbdc3 100644
--- a/bitcoin-qt.pro
+++ b/bitcoin-qt.pro
@@ -75,12 +75,12 @@ contains(FIRST_CLASS_MESSAGING, 1) {
# or: qmake "USE_IPV6=0" (disabled by default)
# or: qmake "USE_IPV6=-" (not supported)
contains(USE_IPV6, -) {
- message(Building without IPv6 support)
+ message(Building without IPv6 support)
} else {
- count(USE_IPV6, 0) {
- USE_IPV6=1
- }
- DEFINES += USE_IPV6=$$USE_IPV6
+ count(USE_IPV6, 0) {
+ USE_IPV6=1
+ }
+ DEFINES += USE_IPV6=$$USE_IPV6
}
contains(BITCOIN_NEED_QT_PLUGINS, 1) {
@@ -92,7 +92,7 @@ contains(BITCOIN_NEED_QT_PLUGINS, 1) {
# for extra security against potential buffer overflows
QMAKE_CXXFLAGS += -fstack-protector
QMAKE_LFLAGS += -fstack-protector
- # do not enable this on windows, as it will result in a non-working executable!
+ # do not enable this on windows cross compile with mingw 4.2.x, as it will result in a non-working executable!
}
# regenerate src/build.h
@@ -177,7 +177,8 @@ HEADERS += src/qt/bitcoingui.h \
src/allocators.h \
src/ui_interface.h \
src/qt/rpcconsole.h \
- src/version.h
+ src/version.h \
+ src/netbase.h
SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
src/qt/transactiontablemodel.cpp \
@@ -204,9 +205,6 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
src/addrman.cpp \
src/db.cpp \
src/walletdb.cpp \
- src/json/json_spirit_writer.cpp \
- src/json/json_spirit_value.cpp \
- src/json/json_spirit_reader.cpp \
src/qt/clientmodel.cpp \
src/qt/guiutil.cpp \
src/qt/transactionrecord.cpp \
diff --git a/contrib/gitian-descriptors/README b/contrib/gitian-descriptors/README
index a2d902e210..8a304eb349 100644
--- a/contrib/gitian-descriptors/README
+++ b/contrib/gitian-descriptors/README
@@ -1,31 +1,55 @@
-Gavin's notes on getting gitian builds up and running:
+Gavin's notes on getting gitian builds up and running using KVM:
+
+These instructions distilled from:
+ https://help.ubuntu.com/community/KVM/Installation
+... see there for complete details.
You need the right hardware: you need a 64-bit-capable CPU with hardware virtualization support (Intel VT-x or AMD-V). Not all modern CPUs support hardware virtualization.
You probably need to enable hardware virtualization in your machine's BIOS.
You need to be running a recent version of 64-bit-Ubuntu, and you need to install several prerequisites:
- sudo apt-get install apache2 git apt-cacher-ng python-vm-builder qemu-kvm
+ sudo apt-get install ruby apache2 git apt-cacher-ng python-vm-builder qemu-kvm
Sanity checks:
sudo service apt-cacher-ng status # Should return apt-cacher-ng is running
ls -l /dev/kvm # Should show a /dev/kvm device
+
Once you've got the right hardware and software:
git clone git://github.com/bitcoin/bitcoin.git
git clone git://github.com/devrandom/gitian-builder.git
mkdir gitian-builder/inputs
- wget 'http://miniupnp.tuxfamily.org/files/download.php?file=miniupnpc-1.6.tar.gz' -O gitian-builder/inputs/miniupnpc-1.6.tar.gz
+ cd gitian-builder/inputs
+ # Inputs for Linux and Win32:
+ wget 'http://miniupnp.tuxfamily.org/files/download.php?file=miniupnpc-1.6.tar.gz'
+ wget 'http://fukuchi.org/works/qrencode/qrencode-3.2.0.tar.bz2'
+ # Inputs for Win32: (Linux has packages for these)
+ wget 'https://downloads.sourceforge.net/project/boost/boost/1.50.0/boost_1_50_0.tar.bz2'
+ wget 'http://www.openssl.org/source/openssl-1.0.1b.tar.gz'
+ wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz'
+ wget 'https://downloads.sourceforge.net/project/libpng/zlib/1.2.6/zlib-1.2.6.tar.gz'
+ wget 'https://downloads.sourceforge.net/project/libpng/libpng15/older-releases/1.5.9/libpng-1.5.9.tar.gz'
+ wget 'ftp://ftp.trolltech.com/qt/source/qt-everywhere-opensource-src-4.7.4.tar.gz'
+ cd ../..
cd gitian-builder
bin/make-base-vm --arch i386
bin/make-base-vm --arch amd64
cd ..
- # To build
+ # Build Linux release:
cd bitcoin
git pull
cd ../gitian-builder
git pull
- ./bin/gbuild --commit bitcoin=HEAD ../bitcoin/contrib/gitian.yml
+ ./bin/gbuild --commit bitcoin=HEAD ../bitcoin/contrib/gitian-descriptors/gitian.yml
+
+ # Build Win32 dependencies:
+ ./bin/gbuild --commit bitcoin=HEAD ../bitcoin/contrib/gitian-descriptors/boost-win32.yml
+ ./bin/gbuild --commit bitcoin=HEAD ../bitcoin/contrib/gitian-descriptors/deps-win32.yml
+ ./bin/gbuild --commit bitcoin=HEAD ../bitcoin/contrib/gitian-descriptors/qt-win32.yml
+
+ # Build Win32 release:
+ ./bin/gbuild --commit bitcoin=HEAD ../bitcoin/contrib/gitian-descriptors/gitian-win32.yml
diff --git a/doc/release-notes.txt b/doc/release-notes.txt
index 796ba3a356..babc56ff81 100644
--- a/doc/release-notes.txt
+++ b/doc/release-notes.txt
@@ -43,6 +43,7 @@ JSON-RPC API
* Rework gettransaction, getblock calls. 'gettransaction' responds for
non-wallet TXs now.
* Remove deprecated RPC 'getblocknumber'
+* Remove superceded RPC 'getmemorypool' (see BIP 22, above)
* New blockchain checkpoint at block 193,000
* listtransactions output now displays "smart" times for transactions,
and 'blocktime' and 'timereceived' fields were added
@@ -57,8 +58,8 @@ P2P networking
file containing peer address data.
* Lower default send buffer from 10MB to 1MB
* proxy: SOCKS5 by default
-* Support connecting by hostnames passed to proxy (-proxydns)
-* Add -seednode connections, and use this for -dnsseed + -proxydns
+* Support connecting by hostnames passed to proxy
+* Add -seednode connections, and use this instead of DNS seeds when proxied
* Added -externalip and -discover
* Add -onlynet to connect only to a given network (IPv4, IPv6, or Tor)
* Separate listening sockets, -bind=<addr>
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
index 2271ff07c4..84a6d6f896 100644
--- a/src/bitcoinrpc.cpp
+++ b/src/bitcoinrpc.cpp
@@ -697,7 +697,7 @@ static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol,
}
// start HTTP client thread
- else if (!CreateThread(ThreadRPCServer3, conn)) {
+ else if (!NewThread(ThreadRPCServer3, conn)) {
printf("Failed to create RPC server client thread\n");
delete conn;
}
diff --git a/src/db.cpp b/src/db.cpp
index 5671993d37..015e7ec2de 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -195,10 +195,7 @@ CDB::CDB(const char *pszFile, const char* pszMode) :
{
delete pdb;
pdb = NULL;
- {
- LOCK(bitdb.cs_db);
- --bitdb.mapFileUseCount[strFile];
- }
+ --bitdb.mapFileUseCount[strFile];
strFile = "";
throw runtime_error(strprintf("CDB() : can't open database file %s, error %d", pszFile, ret));
}
diff --git a/src/init.cpp b/src/init.cpp
index 25756c4e6f..21d8cadf23 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -46,7 +46,7 @@ void StartShutdown()
uiInterface.QueueShutdown();
#else
// Without UI, Shutdown() can simply be started in a new thread
- CreateThread(Shutdown, NULL);
+ NewThread(Shutdown, NULL);
#endif
}
@@ -78,7 +78,7 @@ void Shutdown(void* parg)
boost::filesystem::remove(GetPidFile());
UnregisterWallet(pwalletMain);
delete pwalletMain;
- CreateThread(ExitTimeout, NULL);
+ NewThread(ExitTimeout, NULL);
Sleep(50);
printf("Bitcoin exited\n\n");
fExit = true;
@@ -225,7 +225,7 @@ std::string HelpMessage()
" -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" +
+ " -timeout=<n> " + _("Specify connection timeout in milliseconds (default: 5000))") + "\n" +
" -proxy=<ip:port> " + _("Connect through socks proxy") + "\n" +
" -socks=<n> " + _("Select the version of socks proxy to use (4-5, default: 5)") + "\n" +
" -tor=<ip:port> " + _("Use proxy to reach tor hidden services (default: same as -proxy)") + "\n"
@@ -469,7 +469,8 @@ bool AppInit2()
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
printf("Bitcoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str());
printf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
- printf("Startup time: %s\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
+ if (!fLogTimestamps)
+ printf("Startup time: %s\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
printf("Default data directory %s\n", GetDefaultDataDir().string().c_str());
printf("Used data directory %s\n", GetDataDir().string().c_str());
std::ostringstream strErrors;
@@ -645,7 +646,7 @@ bool AppInit2()
uiInterface.InitMessage(_("Loading wallet..."));
printf("Loading wallet...\n");
nStart = GetTimeMillis();
- bool fFirstRun;
+ bool fFirstRun = true;
pwalletMain = new CWallet("wallet.dat");
int nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun);
if (nLoadWalletRet != DB_LOAD_OK)
@@ -759,11 +760,11 @@ bool AppInit2()
printf("mapWallet.size() = %d\n", pwalletMain->mapWallet.size());
printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size());
- if (!CreateThread(StartNode, NULL))
+ if (!NewThread(StartNode, NULL))
InitError(_("Error: could not start node"));
if (fServer)
- CreateThread(ThreadRPCServer, NULL);
+ NewThread(ThreadRPCServer, NULL);
// ********************************************************* Step 11: finished
diff --git a/src/irc.cpp b/src/irc.cpp
index 50c6a5b4db..6991e6ee7e 100644
--- a/src/irc.cpp
+++ b/src/irc.cpp
@@ -207,16 +207,22 @@ void ThreadIRCSeed(void* parg)
void ThreadIRCSeed2(void* parg)
{
- /* Don't advertise on IRC if we don't allow incoming connections */
- if (mapArgs.count("-connect") || fNoListen)
+ // Don't connect to IRC if we won't use IPv4 connections.
+ if (IsLimited(NET_IPV4))
return;
+ // ... or if we won't make outbound connections and won't accept inbound ones.
+ if (mapArgs.count("-connect") && fNoListen)
+ return;
+
+ // ... or if IRC is not enabled.
if (!GetBoolArg("-irc", false))
return;
printf("ThreadIRCSeed started\n");
int nErrorWait = 10;
int nRetryWait = 10;
+ int nNameRetry = 0;
while (!fShutdown)
{
@@ -251,7 +257,9 @@ void ThreadIRCSeed2(void* parg)
CNetAddr addrIPv4("1.2.3.4"); // arbitrary IPv4 address to make GetLocal prefer IPv4 addresses
CService addrLocal;
string strMyName;
- if (GetLocal(addrLocal, &addrIPv4))
+ // Don't use our IP as our nick if we're not listening
+ // or if it keeps failing because the nick is already in use.
+ if (!fNoListen && GetLocal(addrLocal, &addrIPv4) && nNameRetry<3)
strMyName = EncodeAddress(GetLocalAddress(&addrConnect));
if (strMyName == "")
strMyName = strprintf("x%u", GetRand(1000000000));
@@ -267,6 +275,7 @@ void ThreadIRCSeed2(void* parg)
if (nRet == 2)
{
printf("IRC name already in use\n");
+ nNameRetry++;
Wait(10);
continue;
}
@@ -276,6 +285,7 @@ void ThreadIRCSeed2(void* parg)
else
return;
}
+ nNameRetry = 0;
Sleep(500);
// Get our external IP from the IRC server and re-nick before joining the channel
@@ -283,7 +293,8 @@ void ThreadIRCSeed2(void* parg)
if (GetIPFromIRC(hSocket, strMyName, addrFromIRC))
{
printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToString().c_str());
- if (addrFromIRC.IsRoutable())
+ // Don't use our IP as our nick if we're not listening
+ if (!fNoListen && addrFromIRC.IsRoutable())
{
// IRC lets you to re-nick
AddLocal(addrFromIRC, LOCAL_IRC);
@@ -291,7 +302,7 @@ void ThreadIRCSeed2(void* parg)
Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
}
}
-
+
if (fTestNet) {
Send(hSocket, "JOIN #bitcoinTEST3\r");
Send(hSocket, "WHO #bitcoinTEST3\r");
diff --git a/src/main.cpp b/src/main.cpp
index 010db0c1e9..302292ee29 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1992,11 +1992,17 @@ bool CheckDiskSpace(uint64 nAdditionalBytes)
return true;
}
+static filesystem::path BlockFilePath(unsigned int nFile)
+{
+ string strBlockFn = strprintf("blk%04u.dat", nFile);
+ return GetDataDir() / strBlockFn;
+}
+
FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode)
{
if ((nFile < 1) || (nFile == (unsigned int) -1))
return NULL;
- FILE* file = fopen((GetDataDir() / strprintf("blk%04d.dat", nFile)).string().c_str(), pszMode);
+ FILE* file = fopen(BlockFilePath(nFile).string().c_str(), pszMode);
if (!file)
return NULL;
if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w'))
@@ -2595,7 +2601,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
// In case we are on a very long side-chain, it is possible that we already have
// the last block in an inv bundle sent in response to getblocks. Try to detect
// this situation and push another getblocks to continue.
- std::vector<CInv> vGetData(1,inv);
pfrom->PushGetBlocks(mapBlockIndex[inv.hash], uint256(0));
if (fDebug)
printf("force request: %s\n", inv.ToString().c_str());
@@ -3941,8 +3946,8 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet)
printf("Starting %d BitcoinMiner threads\n", nAddThreads);
for (int i = 0; i < nAddThreads; i++)
{
- if (!CreateThread(ThreadBitcoinMiner, pwallet))
- printf("Error: CreateThread(ThreadBitcoinMiner) failed\n");
+ if (!NewThread(ThreadBitcoinMiner, pwallet))
+ printf("Error: NewThread(ThreadBitcoinMiner) failed\n");
Sleep(10);
}
}
diff --git a/src/main.h b/src/main.h
index 294024b4f3..e61cbdd46b 100644
--- a/src/main.h
+++ b/src/main.h
@@ -1174,7 +1174,7 @@ public:
std::string ToString() const
{
- return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
+ return strprintf("CBlockIndex(pprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
pprev, pnext, nFile, nBlockPos, nHeight,
hashMerkleRoot.ToString().substr(0,10).c_str(),
GetBlockHash().ToString().substr(0,20).c_str());
diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw
index c46c876d25..4ba0cf06f0 100644
--- a/src/makefile.linux-mingw
+++ b/src/makefile.linux-mingw
@@ -33,6 +33,7 @@ LIBS= \
DEFS=-D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE
DEBUGFLAGS=-g
CFLAGS=-O2 -w -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
+LDFLAGS=-Wl,--dynamicbase -Wl,--nxcompat
TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data)
@@ -94,7 +95,7 @@ obj/%.o: %.cpp $(HEADERS)
i586-mingw32msvc-g++ -c $(CFLAGS) -o $@ $<
bitcoind.exe: $(OBJS:obj/%=obj/%)
- i586-mingw32msvc-g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
+ i586-mingw32msvc-g++ $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp))
@@ -102,7 +103,7 @@ obj-test/%.o: test/%.cpp $(HEADERS)
i586-mingw32msvc-g++ -c $(TESTDEFS) $(CFLAGS) -o $@ $<
test_bitcoin.exe: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%))
- i586-mingw32msvc-g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework-mt-s $(LIBS)
+ i586-mingw32msvc-g++ $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework-mt-s $(LIBS)
clean:
diff --git a/src/makefile.mingw b/src/makefile.mingw
index 5dadda826c..55c5b7e387 100644
--- a/src/makefile.mingw
+++ b/src/makefile.mingw
@@ -28,6 +28,7 @@ LIBS= \
DEFS=-DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE
DEBUGFLAGS=-g
CFLAGS=-mthreads -O2 -w -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
+LDFLAGS=-Wl,--dynamicbase -Wl,--nxcompat
TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data)
@@ -86,7 +87,7 @@ obj/%.o: %.cpp $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
bitcoind.exe: $(OBJS:obj/%=obj/%)
- g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
+ g++ $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS)
TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp))
@@ -94,7 +95,7 @@ obj-test/%.o: test/%.cpp $(HEADERS)
g++ -c $(TESTDEFS) $(CFLAGS) -o $@ $<
test_bitcoin.exe: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%))
- g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework $(LIBS)
+ g++ $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework $(LIBS)
clean:
-del /Q bitcoind test_bitcoin
diff --git a/src/net.cpp b/src/net.cpp
index aaf7883e51..76e44a6cf8 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -233,8 +233,8 @@ bool AddLocal(const CService& addr, int nScore)
bool fAlready = mapLocalHost.count(addr) > 0;
LocalServiceInfo &info = mapLocalHost[addr];
if (!fAlready || nScore >= info.nScore) {
- info.nScore = nScore;
- info.nPort = addr.GetPort() + (fAlready ? 1 : 0);
+ info.nScore = nScore + (fAlready ? 1 : 0);
+ info.nPort = addr.GetPort();
}
SetReachable(addr.GetNetwork());
}
@@ -1020,9 +1020,7 @@ void ThreadMapPort2(void* parg)
{
printf("ThreadMapPort started\n");
- char port[6];
- sprintf(port, "%d", GetListenPort());
-
+ std::string port = strprintf("%d", GetListenPort());
const char * multicastif = 0;
const char * minissdpdpath = 0;
struct UPNPDev * devlist = 0;
@@ -1065,23 +1063,23 @@ void ThreadMapPort2(void* parg)
#ifndef UPNPDISCOVER_SUCCESS
/* miniupnpc 1.5 */
r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
- port, port, lanaddr, strDesc.c_str(), "TCP", 0);
+ port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
#else
/* miniupnpc 1.6 */
r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
- port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
+ port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
#endif
if(r!=UPNPCOMMAND_SUCCESS)
printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
- port, port, lanaddr, r, strupnperror(r));
+ port.c_str(), port.c_str(), lanaddr, r, strupnperror(r));
else
printf("UPnP Port Mapping successful.\n");
int i = 1;
loop {
if (fShutdown || !fUseUPnP)
{
- r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
+ r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
printf("UPNP_DeletePortMapping() returned : %d\n", r);
freeUPNPDevlist(devlist); devlist = 0;
FreeUPNPUrls(&urls);
@@ -1092,16 +1090,16 @@ void ThreadMapPort2(void* parg)
#ifndef UPNPDISCOVER_SUCCESS
/* miniupnpc 1.5 */
r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
- port, port, lanaddr, strDesc.c_str(), "TCP", 0);
+ port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
#else
/* miniupnpc 1.6 */
r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
- port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
+ port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
#endif
if(r!=UPNPCOMMAND_SUCCESS)
printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
- port, port, lanaddr, r, strupnperror(r));
+ port.c_str(), port.c_str(), lanaddr, r, strupnperror(r));
else
printf("UPnP Port Mapping successful.\n");;
}
@@ -1125,7 +1123,7 @@ void MapPort()
{
if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
{
- if (!CreateThread(ThreadMapPort, NULL))
+ if (!NewThread(ThreadMapPort, NULL))
printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
}
}
@@ -1887,7 +1885,7 @@ void static Discover()
// Don't use external IPv4 discovery, when -onlynet="IPv6"
if (!IsLimited(NET_IPV4))
- CreateThread(ThreadGetMyExternalIP, NULL);
+ NewThread(ThreadGetMyExternalIP, NULL);
}
void StartNode(void* parg)
@@ -1913,36 +1911,36 @@ void StartNode(void* parg)
if (!GetBoolArg("-dnsseed", true))
printf("DNS seeding disabled\n");
else
- if (!CreateThread(ThreadDNSAddressSeed, NULL))
- printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
+ if (!NewThread(ThreadDNSAddressSeed, NULL))
+ printf("Error: NewThread(ThreadDNSAddressSeed) failed\n");
// Map ports with UPnP
if (fUseUPnP)
MapPort();
// Get addresses from IRC and advertise ours
- if (!CreateThread(ThreadIRCSeed, NULL))
- printf("Error: CreateThread(ThreadIRCSeed) failed\n");
+ if (!NewThread(ThreadIRCSeed, NULL))
+ printf("Error: NewThread(ThreadIRCSeed) failed\n");
// Send and receive from sockets, accept connections
- if (!CreateThread(ThreadSocketHandler, NULL))
- printf("Error: CreateThread(ThreadSocketHandler) failed\n");
+ if (!NewThread(ThreadSocketHandler, NULL))
+ printf("Error: NewThread(ThreadSocketHandler) failed\n");
// Initiate outbound connections from -addnode
- if (!CreateThread(ThreadOpenAddedConnections, NULL))
- printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
+ if (!NewThread(ThreadOpenAddedConnections, NULL))
+ printf("Error: NewThread(ThreadOpenAddedConnections) failed\n");
// Initiate outbound connections
- if (!CreateThread(ThreadOpenConnections, NULL))
- printf("Error: CreateThread(ThreadOpenConnections) failed\n");
+ if (!NewThread(ThreadOpenConnections, NULL))
+ printf("Error: NewThread(ThreadOpenConnections) failed\n");
// Process messages
- if (!CreateThread(ThreadMessageHandler, NULL))
- printf("Error: CreateThread(ThreadMessageHandler) failed\n");
+ if (!NewThread(ThreadMessageHandler, NULL))
+ printf("Error: NewThread(ThreadMessageHandler) failed\n");
// Dump network addresses
- if (!CreateThread(ThreadDumpAddress, NULL))
- printf("Error; CreateThread(ThreadDumpAddress) failed\n");
+ if (!NewThread(ThreadDumpAddress, NULL))
+ printf("Error; NewThread(ThreadDumpAddress) failed\n");
// Generate coins in the background
GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 1bdc313da8..27b974b5c6 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -273,8 +273,7 @@ void BitcoinGUI::createActions()
optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this);
optionsAction->setToolTip(tr("Modify configuration options for Bitcoin"));
optionsAction->setMenuRole(QAction::PreferencesRole);
- toggleHideAction = new QAction(QIcon(":/icons/bitcoin"), tr("Show/Hide &Bitcoin"), this);
- toggleHideAction->setToolTip(tr("Show or hide the Bitcoin window"));
+ toggleHideAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Show / Hide"), this);
exportAction = new QAction(QIcon(":/icons/export"), tr("&Export..."), this);
exportAction->setToolTip(tr("Export the data in the current tab to a file"));
encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this);
@@ -463,7 +462,7 @@ void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
{
if(reason == QSystemTrayIcon::Trigger)
{
- // Click on system tray icon triggers "show/hide Bitcoin"
+ // Click on system tray icon triggers show/hide of the main window
toggleHideAction->trigger();
}
}
diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp
index 5fe9e5218a..92b3352866 100644
--- a/src/qt/bitcoinstrings.cpp
+++ b/src/qt/bitcoinstrings.cpp
@@ -92,6 +92,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins"),
QT_TRANSLATE_NOOP("bitcoin-core", "Get help for a command"),
QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: 2500, 0 = all)"),
QT_TRANSLATE_NOOP("bitcoin-core", "How thorough the block verification is (0-6, default: 1)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Importing blocks..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000?.dat file"),
QT_TRANSLATE_NOOP("bitcoin-core", "Insufficient funds"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address: '%s'"),
diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui
index 6632e311d0..b59c2445de 100644
--- a/src/qt/forms/aboutdialog.ui
+++ b/src/qt/forms/aboutdialog.ui
@@ -65,9 +65,6 @@
<property name="text">
<string notr="true">0.3.666-beta</string>
</property>
- <property name="textFormat">
- <enum>Qt::RichText</enum>
- </property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
@@ -89,13 +86,25 @@
</layout>
</item>
<item>
+ <widget class="QLabel" name="copyrightLabel">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>Copyright © 2009-2012 The Bitcoin developers</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QLabel" name="label_2">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
<property name="text">
- <string>Copyright © 2009-2012 Bitcoin Developers
-
+ <string>
This is experimental software.
Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php.
diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts
index 849ff47a52..2ac97a532b 100644
--- a/src/qt/locale/bitcoin_en.ts
+++ b/src/qt/locale/bitcoin_en.ts
@@ -15,9 +15,13 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+44"/>
- <source>Copyright © 2009-2012 Bitcoin Developers
-
+ <location line="+41"/>
+ <source>Copyright © 2009-2012 The Bitcoin developers</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>
This is experimental software.
Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -286,22 +290,17 @@ This product includes software developed by the OpenSSL Project for use in the O
<context>
<name>BitcoinGUI</name>
<message>
- <location filename="../bitcoingui.cpp" line="+218"/>
+ <location filename="../bitcoingui.cpp" line="+228"/>
<source>Sign &amp;message...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+48"/>
- <source>Show/Hide &amp;Bitcoin</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+248"/>
+ <location line="+295"/>
<source>Synchronizing with network...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-326"/>
+ <location line="-325"/>
<source>&amp;Overview</source>
<translation type="unfinished"></translation>
</message>
@@ -376,7 +375,7 @@ This product includes software developed by the OpenSSL Project for use in the O
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+7"/>
+ <location line="+6"/>
<source>&amp;Encrypt Wallet...</source>
<translation type="unfinished"></translation>
</message>
@@ -409,7 +408,7 @@ This product includes software developed by the OpenSSL Project for use in the O
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-55"/>
+ <location line="-54"/>
<source>Send coins to a Bitcoin address</source>
<translation type="unfinished"></translation>
</message>
@@ -434,12 +433,7 @@ This product includes software developed by the OpenSSL Project for use in the O
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
- <source>Show or hide the Bitcoin window</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+2"/>
+ <location line="+4"/>
<source>Export the data in the current tab to a file</source>
<translation type="unfinished"></translation>
</message>
@@ -469,12 +463,12 @@ This product includes software developed by the OpenSSL Project for use in the O
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-56"/>
+ <location line="-55"/>
<source>&amp;Verify message...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-151"/>
+ <location line="-160"/>
<source>Bitcoin</source>
<translation type="unfinished"></translation>
</message>
@@ -484,12 +478,17 @@ This product includes software developed by the OpenSSL Project for use in the O
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+186"/>
+ <location line="+195"/>
<source>&amp;About Bitcoin</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+44"/>
+ <location line="+9"/>
+ <source>&amp;Show / Hide</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+34"/>
<source>&amp;File</source>
<translation type="unfinished"></translation>
</message>
@@ -657,7 +656,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoin.cpp" line="+112"/>
+ <location filename="../bitcoin.cpp" line="+109"/>
<source>A fatal error occurred. Bitcoin can no longer continue safely and will quit.</source>
<translation type="unfinished"></translation>
</message>
@@ -741,7 +740,7 @@ Address: %4
<context>
<name>GUIUtil::HelpMessageBox</name>
<message>
- <location filename="../guiutil.cpp" line="+425"/>
+ <location filename="../guiutil.cpp" line="+419"/>
<location line="+12"/>
<source>Bitcoin-Qt</source>
<translation type="unfinished"></translation>
@@ -960,7 +959,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+134"/>
+ <location line="+147"/>
<location line="+9"/>
<source>Warning</source>
<translation type="unfinished"></translation>
@@ -1256,7 +1255,7 @@ Address: %4
<name>SendCoinsDialog</name>
<message>
<location filename="../forms/sendcoinsdialog.ui" line="+14"/>
- <location filename="../sendcoinsdialog.cpp" line="+123"/>
+ <location filename="../sendcoinsdialog.cpp" line="+124"/>
<location line="+5"/>
<location line="+5"/>
<location line="+5"/>
@@ -2106,7 +2105,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+81"/>
+ <location line="+82"/>
<source>Usage:</source>
<translation type="unfinished"></translation>
</message>
@@ -2121,12 +2120,12 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-9"/>
+ <location line="-10"/>
<source>Get help for a command</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+19"/>
+ <location line="+20"/>
<source>Options:</source>
<translation type="unfinished"></translation>
</message>
@@ -2141,7 +2140,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-46"/>
+ <location line="-47"/>
<source>Generate coins</source>
<translation type="unfinished"></translation>
</message>
@@ -2151,7 +2150,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+59"/>
+ <location line="+60"/>
<source>Specify data directory</source>
<translation type="unfinished"></translation>
</message>
@@ -2181,27 +2180,27 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-32"/>
+ <location line="-33"/>
<source>Connect to a node to retrieve peer addresses, and disconnect</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+63"/>
+ <location line="+64"/>
<source>Specify your own public address</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-74"/>
+ <location line="-75"/>
<source>Bind to given address. Use [host]:port notation for IPv6</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+76"/>
+ <location line="+77"/>
<source>Threshold for disconnecting misbehaving peers (default: 100)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-104"/>
+ <location line="-105"/>
<source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source>
<translation type="unfinished"></translation>
</message>
@@ -2216,7 +2215,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+60"/>
+ <location line="+61"/>
<source>Run in the background as a daemon and accept commands</source>
<translation type="unfinished"></translation>
</message>
@@ -2226,7 +2225,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-92"/>
+ <location line="-93"/>
<source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
<translation type="unfinished"></translation>
</message>
@@ -2281,7 +2280,12 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+9"/>
+ <location line="+6"/>
+ <source>Importing blocks...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
<source>Invalid -tor address: &apos;%s&apos;</source>
<translation type="unfinished"></translation>
</message>
@@ -2391,22 +2395,22 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-40"/>
+ <location line="-41"/>
<source>Allow JSON-RPC connections from specified IP address</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+60"/>
+ <location line="+61"/>
<source>Send commands to node running on &lt;ip&gt; (default: 127.0.0.1)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-89"/>
+ <location line="-90"/>
<source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+112"/>
+ <location line="+113"/>
<source>Upgrade wallet to latest format</source>
<translation type="unfinished"></translation>
</message>
@@ -2421,7 +2425,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-23"/>
+ <location line="-24"/>
<source>How many blocks to check at startup (default: 2500, 0 = all)</source>
<translation type="unfinished"></translation>
</message>
@@ -2431,7 +2435,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+1"/>
+ <location line="+2"/>
<source>Imports blocks from external blk000?.dat file</source>
<translation type="unfinished"></translation>
</message>
@@ -2451,17 +2455,17 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-109"/>
+ <location line="-110"/>
<source>Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+121"/>
+ <location line="+122"/>
<source>This help message</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-118"/>
+ <location line="-119"/>
<source>Cannot obtain a lock on data directory %s. Bitcoin is probably already running.</source>
<translation type="unfinished"></translation>
</message>
@@ -2471,12 +2475,12 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+76"/>
+ <location line="+77"/>
<source>Unable to bind to %s on this computer (bind returned error %d, %s)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-68"/>
+ <location line="-69"/>
<source>Connect through socks proxy</source>
<translation type="unfinished"></translation>
</message>
@@ -2486,12 +2490,12 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+43"/>
+ <location line="+44"/>
<source>Loading addresses...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-25"/>
+ <location line="-26"/>
<source>Error loading blkindex.dat</source>
<translation type="unfinished"></translation>
</message>
@@ -2506,17 +2510,17 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+71"/>
+ <location line="+72"/>
<source>Wallet needed to be rewritten: restart Bitcoin to complete</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-73"/>
+ <location line="-74"/>
<source>Error loading wallet.dat</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+17"/>
+ <location line="+18"/>
<source>Invalid -proxy address: &apos;%s&apos;</source>
<translation type="unfinished"></translation>
</message>
@@ -2531,7 +2535,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-73"/>
+ <location line="-74"/>
<source>Cannot resolve -bind address: &apos;%s&apos;</source>
<translation type="unfinished"></translation>
</message>
@@ -2541,12 +2545,12 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+28"/>
+ <location line="+29"/>
<source>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-13"/>
+ <location line="-14"/>
<source>Error: could not start node</source>
<translation type="unfinished"></translation>
</message>
@@ -2566,17 +2570,17 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+41"/>
+ <location line="+42"/>
<source>Sending...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-99"/>
+ <location line="-100"/>
<source>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.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+74"/>
+ <location line="+75"/>
<source>Invalid amount</source>
<translation type="unfinished"></translation>
</message>
@@ -2591,7 +2595,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-45"/>
+ <location line="-46"/>
<source>Add a node to connect to and attempt to keep the connection open</source>
<translation type="unfinished"></translation>
</message>
@@ -2611,12 +2615,12 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+18"/>
+ <location line="+19"/>
<source>Loading wallet...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-38"/>
+ <location line="-39"/>
<source>Cannot downgrade wallet</source>
<translation type="unfinished"></translation>
</message>
@@ -2631,22 +2635,22 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+45"/>
+ <location line="+46"/>
<source>Rescanning...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-39"/>
+ <location line="-40"/>
<source>Done loading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+63"/>
+ <location line="+64"/>
<source>To use the %s option</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-132"/>
+ <location line="-133"/>
<source>%s, you must set a rpcpassword in the configuration file:
%s
It is recommended you use the following random password:
diff --git a/src/qt/qtipcserver.cpp b/src/qt/qtipcserver.cpp
index a2fe866e29..ec2d56b9e3 100644
--- a/src/qt/qtipcserver.cpp
+++ b/src/qt/qtipcserver.cpp
@@ -152,7 +152,7 @@ void ipcInit(int argc, char *argv[])
return;
}
- if (!CreateThread(ipcThread, mq))
+ if (!NewThread(ipcThread, mq))
{
delete mq;
return;
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 08f936e719..7d5b6fed53 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -13,7 +13,6 @@
#include <QUrl>
#include <QScrollBar>
-#include <boost/tokenizer.hpp>
#include <openssl/crypto.h>
// TODO: make it possible to filter out categories (esp debug messages when implemented)
@@ -54,34 +53,108 @@ void RPCExecutor::start()
// Nothing to do
}
-void RPCExecutor::request(const QString &command)
+/**
+ * Split shell command line into a list of arguments. Aims to emulate \c bash and friends.
+ *
+ * - Arguments are delimited with whitespace
+ * - Extra whitespace at the beginning and end and between arguments will be ignored
+ * - Text can be "double" or 'single' quoted
+ * - The backslash \c \ is used as escape character
+ * - Outside quotes, any character can be escaped
+ * - Within double quotes, only escape \c " and backslashes before a \c " or another backslash
+ * - Within single quotes, no escaping is possible and no special interpretation takes place
+ *
+ * @param[out] args Parsed arguments will be appended to this list
+ * @param[in] strCommand Command line to split
+ */
+bool parseCommandLine(std::vector<std::string> &args, const std::string &strCommand)
{
- // Parse shell-like command line into separate arguments
- std::string strMethod;
- std::vector<std::string> strParams;
- try {
- boost::escaped_list_separator<char> els('\\',' ','\"');
- std::string strCommand = command.toStdString();
- boost::tokenizer<boost::escaped_list_separator<char> > tok(strCommand, els);
-
- int n = 0;
- for(boost::tokenizer<boost::escaped_list_separator<char> >::iterator beg=tok.begin(); beg!=tok.end();++beg,++n)
+ enum CmdParseState
+ {
+ STATE_EATING_SPACES,
+ STATE_ARGUMENT,
+ STATE_SINGLEQUOTED,
+ STATE_DOUBLEQUOTED,
+ STATE_ESCAPE_OUTER,
+ STATE_ESCAPE_DOUBLEQUOTED
+ } state = STATE_EATING_SPACES;
+ std::string curarg;
+ foreach(char ch, strCommand)
+ {
+ switch(state)
{
- if(n == 0) // First parameter is the command
- strMethod = *beg;
- else
- strParams.push_back(*beg);
+ case STATE_ARGUMENT: // In or after argument
+ case STATE_EATING_SPACES: // Handle runs of whitespace
+ switch(ch)
+ {
+ case '"': state = STATE_DOUBLEQUOTED; break;
+ case '\'': state = STATE_SINGLEQUOTED; break;
+ case '\\': state = STATE_ESCAPE_OUTER; break;
+ case ' ': case '\n': case '\t':
+ if(state == STATE_ARGUMENT) // Space ends argument
+ {
+ args.push_back(curarg);
+ curarg.clear();
+ }
+ state = STATE_EATING_SPACES;
+ break;
+ default: curarg += ch; state = STATE_ARGUMENT;
+ }
+ break;
+ case STATE_SINGLEQUOTED: // Single-quoted string
+ switch(ch)
+ {
+ case '\'': state = STATE_ARGUMENT; break;
+ default: curarg += ch;
+ }
+ break;
+ case STATE_DOUBLEQUOTED: // Double-quoted string
+ switch(ch)
+ {
+ case '"': state = STATE_ARGUMENT; break;
+ case '\\': state = STATE_ESCAPE_DOUBLEQUOTED; break;
+ default: curarg += ch;
+ }
+ break;
+ case STATE_ESCAPE_OUTER: // '\' outside quotes
+ curarg += ch; state = STATE_ARGUMENT;
+ break;
+ case STATE_ESCAPE_DOUBLEQUOTED: // '\' in double-quoted text
+ if(ch != '"' && ch != '\\') curarg += '\\'; // keep '\' for everything but the quote and '\' itself
+ curarg += ch; state = STATE_DOUBLEQUOTED;
+ break;
}
}
- catch(boost::escaped_list_error &e)
+ switch(state) // final state
{
- emit reply(RPCConsole::CMD_ERROR, QString("Parse error"));
- return;
+ case STATE_EATING_SPACES:
+ return true;
+ case STATE_ARGUMENT:
+ args.push_back(curarg);
+ return true;
+ default: // ERROR to end in one of the other states
+ return false;
}
+}
- try {
+void RPCExecutor::request(const QString &command)
+{
+ std::vector<std::string> args;
+ if(!parseCommandLine(args, command.toStdString()))
+ {
+ emit reply(RPCConsole::CMD_ERROR, QString("Parse error: unbalanced ' or \""));
+ return;
+ }
+ if(args.empty())
+ return; // Nothing to do
+ try
+ {
std::string strPrint;
- json_spirit::Value result = tableRPC.execute(strMethod, RPCConvertValues(strMethod, strParams));
+ // Convert argument list to JSON objects in method-dependent way,
+ // and pass it along with the method name to the dispatcher.
+ json_spirit::Value result = tableRPC.execute(
+ args[0],
+ RPCConvertValues(args[0], std::vector<std::string>(args.begin() + 1, args.end())));
// Format result reply
if (result.type() == json_spirit::null_type)
@@ -95,7 +168,16 @@ void RPCExecutor::request(const QString &command)
}
catch (json_spirit::Object& objError)
{
- emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(write_string(json_spirit::Value(objError), false)));
+ try // Nice formatting for standard-format error
+ {
+ int code = find_value(objError, "code").get_int();
+ std::string message = find_value(objError, "message").get_str();
+ emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(message) + " (code " + QString::number(code) + ")");
+ }
+ catch(std::runtime_error &) // raised when converting to invalid type, i.e. missing code or message
+ { // Show raw JSON object
+ emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(write_string(json_spirit::Value(objError), false)));
+ }
}
catch (std::exception& e)
{
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
index d2cb31f51d..2954b9ee57 100644
--- a/src/rpcmining.cpp
+++ b/src/rpcmining.cpp
@@ -225,6 +225,10 @@ Value getblocktemplate(const Array& params, bool fHelp)
const Value& modeval = find_value(oparam, "mode");
if (modeval.type() == str_type)
strMode = modeval.get_str();
+ else if (modeval.type() == null_type)
+ {
+ /* Do nothing */
+ }
else
throw JSONRPCError(-8, "Invalid mode");
}
diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp
index be83b85c15..929dde9c15 100644
--- a/src/rpcwallet.cpp
+++ b/src/rpcwallet.cpp
@@ -1006,7 +1006,8 @@ Value listtransactions(const Array& params, bool fHelp)
Array ret;
- CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(strAccount);
+ std::list<CAccountingEntry> acentries;
+ CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(acentries, strAccount);
// iterate backwards until we have nCount items to return:
for (CWallet::TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
@@ -1302,9 +1303,9 @@ Value walletpassphrase(const Array& params, bool fHelp)
"walletpassphrase <passphrase> <timeout>\n"
"Stores the wallet decryption key in memory for <timeout> seconds.");
- CreateThread(ThreadTopUpKeyPool, NULL);
+ NewThread(ThreadTopUpKeyPool, NULL);
int64* pnSleepTime = new int64(params[1].get_int64());
- CreateThread(ThreadCleanWalletPassphrase, pnSleepTime);
+ NewThread(ThreadCleanWalletPassphrase, pnSleepTime);
return Value::null;
}
diff --git a/src/util.cpp b/src/util.cpp
index 461f42d177..d1270348e0 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -1299,3 +1299,15 @@ void RenameThread(const char* name)
(void)name;
#endif
}
+
+bool NewThread(void(*pfn)(void*), void* parg)
+{
+ try
+ {
+ boost::thread(pfn, parg); // thread detaches when out of scope
+ } catch(boost::thread_resource_error &e) {
+ printf("Error creating thread: %s\n", e.what());
+ return false;
+ }
+ return true;
+}
diff --git a/src/util.h b/src/util.h
index 709b0e05bd..65923e68a3 100644
--- a/src/util.h
+++ b/src/util.h
@@ -539,65 +539,14 @@ public:
}
};
+bool NewThread(void(*pfn)(void*), void* parg);
-
-
-
-
-
-
-
-
-// Note: It turns out we might have been able to use boost::thread
-// by using TerminateThread(boost::thread.native_handle(), 0);
#ifdef WIN32
-typedef HANDLE pthread_t;
-
-inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false)
-{
- DWORD nUnused = 0;
- HANDLE hthread =
- CreateThread(
- NULL, // default security
- 0, // inherit stack size from parent
- (LPTHREAD_START_ROUTINE)pfn, // function pointer
- parg, // argument
- 0, // creation option, start immediately
- &nUnused); // thread identifier
- if (hthread == NULL)
- {
- printf("Error: CreateThread() returned %d\n", GetLastError());
- return (pthread_t)0;
- }
- if (!fWantHandle)
- {
- CloseHandle(hthread);
- return (pthread_t)-1;
- }
- return hthread;
-}
-
inline void SetThreadPriority(int nPriority)
{
SetThreadPriority(GetCurrentThread(), nPriority);
}
#else
-inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false)
-{
- pthread_t hthread = 0;
- int ret = pthread_create(&hthread, NULL, (void*(*)(void*))pfn, parg);
- if (ret != 0)
- {
- printf("Error: pthread_create() returned %d\n", ret);
- return (pthread_t)0;
- }
- if (!fWantHandle)
- {
- pthread_detach(hthread);
- return (pthread_t)-1;
- }
- return hthread;
-}
#define THREAD_PRIORITY_LOWEST PRIO_MAX
#define THREAD_PRIORITY_BELOW_NORMAL 2
diff --git a/src/wallet.cpp b/src/wallet.cpp
index dc019d4924..f88a0e1413 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -291,8 +291,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
return true;
}
-CWallet::TxItems
-CWallet::OrderedTxItems(std::string strAccount)
+CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount)
{
CWalletDB walletdb(strWalletFile);
@@ -306,7 +305,7 @@ CWallet::OrderedTxItems(std::string strAccount)
CWalletTx* wtx = &((*it).second);
txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0)));
}
- list<CAccountingEntry> acentries;
+ acentries.clear();
walletdb.ListAccountCreditDebit(strAccount, acentries);
BOOST_FOREACH(CAccountingEntry& entry, acentries)
{
@@ -375,7 +374,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
{
// Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
int64 latestTolerated = latestNow + 300;
- TxItems txOrdered = OrderedTxItems();
+ std::list<CAccountingEntry> acentries;
+ TxItems txOrdered = OrderedTxItems(acentries);
for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
{
CWalletTx *const pwtx = (*it).second.first;
@@ -1367,7 +1367,7 @@ string CWallet::SendMoneyToDestination(const CTxDestination& address, int64 nVal
int CWallet::LoadWallet(bool& fFirstRunRet)
{
if (!fFileBacked)
- return false;
+ return DB_LOAD_OK;
fFirstRunRet = false;
int nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
if (nLoadWalletRet == DB_NEED_REWRITE)
@@ -1385,7 +1385,7 @@ int CWallet::LoadWallet(bool& fFirstRunRet)
return nLoadWalletRet;
fFirstRunRet = !vchDefaultKey.IsValid();
- CreateThread(ThreadFlushWalletDB, &strWalletFile);
+ NewThread(ThreadFlushWalletDB, &strWalletFile);
return DB_LOAD_OK;
}
diff --git a/src/wallet.h b/src/wallet.h
index 44f8a17d37..7fd33629fe 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -146,7 +146,12 @@ public:
typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair;
typedef std::multimap<int64, TxPair > TxItems;
- TxItems OrderedTxItems(std::string strAccount = "");
+
+ /** Get the wallet's activity log
+ @return multimap of ordered transactions and accounting entries
+ @warning Returned pointers are *only* valid within the scope of passed acentries
+ */
+ TxItems OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount = "");
void MarkDirty();
bool AddToWallet(const CWalletTx& wtxIn);