diff options
-rw-r--r-- | bitcoin-qt.pro | 18 | ||||
-rw-r--r-- | contrib/gitian-descriptors/README | 34 | ||||
-rw-r--r-- | doc/release-notes.txt | 5 | ||||
-rw-r--r-- | src/bitcoinrpc.cpp | 2 | ||||
-rw-r--r-- | src/db.cpp | 5 | ||||
-rw-r--r-- | src/init.cpp | 15 | ||||
-rw-r--r-- | src/irc.cpp | 21 | ||||
-rw-r--r-- | src/main.cpp | 13 | ||||
-rw-r--r-- | src/main.h | 2 | ||||
-rw-r--r-- | src/makefile.linux-mingw | 5 | ||||
-rw-r--r-- | src/makefile.mingw | 5 | ||||
-rw-r--r-- | src/net.cpp | 54 | ||||
-rw-r--r-- | src/qt/bitcoingui.cpp | 5 | ||||
-rw-r--r-- | src/qt/bitcoinstrings.cpp | 1 | ||||
-rw-r--r-- | src/qt/forms/aboutdialog.ui | 19 | ||||
-rw-r--r-- | src/qt/locale/bitcoin_en.ts | 142 | ||||
-rw-r--r-- | src/qt/qtipcserver.cpp | 2 | ||||
-rw-r--r-- | src/qt/rpcconsole.cpp | 126 | ||||
-rw-r--r-- | src/rpcmining.cpp | 4 | ||||
-rw-r--r-- | src/rpcwallet.cpp | 7 | ||||
-rw-r--r-- | src/util.cpp | 12 | ||||
-rw-r--r-- | src/util.h | 53 | ||||
-rw-r--r-- | src/wallet.cpp | 12 | ||||
-rw-r--r-- | src/wallet.h | 7 |
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 &message...</source> <translation type="unfinished"></translation> </message> <message> - <location line="+48"/> - <source>Show/Hide &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>&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>&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>&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>&About Bitcoin</source> <translation type="unfinished"></translation> </message> <message> - <location line="+44"/> + <location line="+9"/> + <source>&Show / Hide</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> <source>&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: '%s'</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 <ip> (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: '%s'</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: '%s'</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=<amount>: '%s'</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); |