diff --git a/build-msw.txt b/build-msw.txt index cdb264f5e..7a58aaa6e 100644 --- a/build-msw.txt +++ b/build-msw.txt @@ -12,12 +12,8 @@ WINDOWS BUILD NOTES Compilers Supported ------------------- MinGW GCC (recommended) - -MSVC 6.0 SP6: You'll need Boost version 1.34 because they dropped support -for MSVC 6.0 after that. However, they didn't add Asio until 1.35. -You should still be able to build with MSVC 6.0 by adding Asio to 1.34 by -unpacking boost_asio_*.zip into the boost directory: -http://sourceforge.net/projects/asio/files/asio +http://tdm-gcc.tdragon.net/ has an easy installer. Go back a few versions +for a little older gcc like gcc 4.4.?. MSVC 8.0 (2005) SP1 has been tested. Note: MSVC 7.0 and up have a habit of linking to runtime DLLs that are not installed on XP by default. diff --git a/headers.h b/headers.h index e5499464b..a12392d18 100644 --- a/headers.h +++ b/headers.h @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include diff --git a/init.cpp b/init.cpp index 98410d188..b10e22a32 100644 --- a/init.cpp +++ b/init.cpp @@ -244,8 +244,7 @@ bool AppInit2(int argc, char* argv[]) // Required to protect the database files if we're going to keep deleting log.* // #if defined(__WXMSW__) && defined(GUI) - // todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file - // maybe should go by whether successfully bind port 8333 instead + // wxSingleInstanceChecker doesn't work on Linux wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH"); for (int i = 0; i < strMutexName.size(); i++) if (!isalnum(strMutexName[i])) @@ -257,7 +256,6 @@ bool AppInit2(int argc, char* argv[]) unsigned int nStart = GetTime(); loop { - // TODO: find out how to do this in Linux, or replace with wxWidgets commands // Show the previous instance and exit HWND hwndPrev = FindWindowA("wxWindowClassNR", "Bitcoin"); if (hwndPrev) @@ -281,8 +279,18 @@ bool AppInit2(int argc, char* argv[]) } #endif + // Make sure only a single bitcoin process is using the data directory. + string strLockFile = GetDataDir() + "/.lock"; + FILE* file = fopen(strLockFile.c_str(), "a"); // empty lock file; created if it doesn't exist. + fclose(file); + static boost::interprocess::file_lock lock(strLockFile.c_str()); + if (!lock.try_lock()) + { + wxMessageBox(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().c_str()), "Bitcoin"); + return false; + } + // Bind to the port early so we can tell if another instance is already running. - // This is a backup to wxSingleInstanceChecker, which doesn't work on Linux. string strErrors; if (!BindListenPort(strErrors)) { diff --git a/net.cpp b/net.cpp index 82def0b40..06a12d4fb 100644 --- a/net.cpp +++ b/net.cpp @@ -20,7 +20,7 @@ bool OpenNetworkConnection(const CAddress& addrConnect); // bool fClient = false; uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); -CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices); +CAddress addrLocalHost(0, 0, nLocalServices); CNode* pnodeLocalHost = NULL; uint64 nLocalHostNonce = 0; array vnThreadsRunning; @@ -1006,7 +1006,7 @@ void ThreadOpenConnections2(void* parg) // Randomize the order in a deterministic way, putting the standard port first int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60); - if (addr.port != DEFAULT_PORT) + if (addr.port != GetDefaultPort()) nRandomizer += 2 * 60 * 60; // Last seen Base retry frequency @@ -1185,6 +1185,7 @@ bool BindListenPort(string& strError) { strError = ""; int nOne = 1; + addrLocalHost.port = GetDefaultPort(); #ifdef __WXMSW__ // Initialize Windows Sockets @@ -1236,12 +1237,12 @@ bool BindListenPort(string& strError) memset(&sockaddr, 0, sizeof(sockaddr)); sockaddr.sin_family = AF_INET; sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer - sockaddr.sin_port = DEFAULT_PORT; + sockaddr.sin_port = GetDefaultPort(); if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) { int nErr = WSAGetLastError(); if (nErr == WSAEADDRINUSE) - strError = strprintf("Unable to bind to port %d on this computer. Bitcoin is probably already running.", ntohs(sockaddr.sin_port)); + strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port)); else strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr); printf("%s\n", strError.c_str()); @@ -1278,7 +1279,7 @@ void StartNode(void* parg) printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str()); for (int i = 0; phostent->h_addr_list[i] != NULL; i++) { - CAddress addr(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices); + CAddress addr(*(unsigned int*)phostent->h_addr_list[i], GetDefaultPort(), nLocalServices); if (addr.IsValid() && addr.GetByte(3) != 127) { addrLocalHost = addr; @@ -1306,7 +1307,7 @@ void StartNode(void* parg) printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP); // Take the first IP that isn't loopback 127.x.x.x - CAddress addr(*(unsigned int*)&s4->sin_addr, DEFAULT_PORT, nLocalServices); + CAddress addr(*(unsigned int*)&s4->sin_addr, GetDefaultPort(), nLocalServices); if (addr.IsValid() && addr.GetByte(3) != 127) { addrLocalHost = addr; diff --git a/net.h b/net.h index 698bd0b2a..33c59147b 100644 --- a/net.h +++ b/net.h @@ -12,7 +12,7 @@ extern int nBestHeight; -static const unsigned short DEFAULT_PORT = 0x8d20; // htons(8333) +inline unsigned short GetDefaultPort() { return fTestNet ? htons(18333) : htons(8333); } static const unsigned int PUBLISH_HOPS = 5; enum { @@ -150,11 +150,11 @@ public: Init(); } - CAddress(unsigned int ipIn, unsigned short portIn=DEFAULT_PORT, uint64 nServicesIn=NODE_NETWORK) + CAddress(unsigned int ipIn, unsigned short portIn=0, uint64 nServicesIn=NODE_NETWORK) { Init(); ip = ipIn; - port = portIn; + port = (portIn == 0 ? GetDefaultPort() : portIn); nServices = nServicesIn; } @@ -185,7 +185,7 @@ public: nServices = NODE_NETWORK; memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); ip = INADDR_NONE; - port = DEFAULT_PORT; + port = GetDefaultPort(); nTime = GetAdjustedTime(); nLastTry = 0; } @@ -193,7 +193,7 @@ public: bool SetAddress(const char* pszIn) { ip = INADDR_NONE; - port = DEFAULT_PORT; + port = GetDefaultPort(); char psz[100]; strlcpy(psz, pszIn, sizeof(psz)); unsigned int a=0, b=0, c=0, d=0, e=0; diff --git a/rpc.cpp b/rpc.cpp index 88e44cc47..81d36b378 100644 --- a/rpc.cpp +++ b/rpc.cpp @@ -654,7 +654,28 @@ Value backupwallet(const Array& params, bool fHelp) return Value::null; } +Value validateaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "validateaddress \n" + "Return information about ."); + string strAddress = params[0].get_str(); + uint160 hash160; + bool isValid = AddressToHash160(strAddress, hash160); + + Object ret; + ret.push_back(Pair("isvalid", isValid)); + if (isValid) + { + // Call Hash160ToAddress() so we always return current ADDRESSVERSION + // version of the address: + ret.push_back(Pair("address", Hash160ToAddress(hash160))); + ret.push_back(Pair("ismine", (mapPubKeys.count(hash160) > 0))); + } + return ret; +} @@ -695,6 +716,7 @@ pair pCallTable[] = make_pair("listreceivedbyaddress", &listreceivedbyaddress), make_pair("listreceivedbylabel", &listreceivedbylabel), make_pair("backupwallet", &backupwallet), + make_pair("validateaddress", &validateaddress), }; map mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0])); @@ -715,6 +737,7 @@ string pAllowInSafeMode[] = "getlabel", "getaddressesbylabel", "backupwallet", + "validateaddress", }; set setAllowInSafeMode(pAllowInSafeMode, pAllowInSafeMode + sizeof(pAllowInSafeMode)/sizeof(pAllowInSafeMode[0])); diff --git a/serialize.h b/serialize.h index 44b647f1e..0268c750b 100644 --- a/serialize.h +++ b/serialize.h @@ -22,7 +22,7 @@ class CDataStream; class CAutoFile; static const unsigned int MAX_SIZE = 0x02000000; -static const int VERSION = 31305; +static const int VERSION = 31306; static const char* pszSubVer = "";