]> Git Repo - VerusCoin.git/blame - init.cpp
Updated dutch translation
[VerusCoin.git] / init.cpp
CommitLineData
0a61b0df 1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Distributed under the MIT/X11 software license, see the accompanying
3// file license.txt or http://www.opensource.org/licenses/mit-license.php.
4
5#include "headers.h"
6
7
8
9
10
11
12
0a61b0df 13//////////////////////////////////////////////////////////////////////////////
14//
15// Shutdown
16//
17
18void ExitTimeout(void* parg)
19{
20#ifdef __WXMSW__
21 Sleep(5000);
22 ExitProcess(0);
23#endif
24}
25
26void Shutdown(void* parg)
27{
28 static CCriticalSection cs_Shutdown;
29 static bool fTaken;
30 bool fFirstThread;
31 CRITICAL_BLOCK(cs_Shutdown)
32 {
33 fFirstThread = !fTaken;
34 fTaken = true;
35 }
36 static bool fExit;
37 if (fFirstThread)
38 {
39 fShutdown = true;
40 nTransactionsUpdated++;
41 DBFlush(false);
42 StopNode();
43 DBFlush(true);
44 CreateThread(ExitTimeout, NULL);
45 Sleep(50);
46 printf("Bitcoin exiting\n\n");
47 fExit = true;
48 exit(0);
49 }
50 else
51 {
52 while (!fExit)
53 Sleep(500);
54 Sleep(100);
55 ExitThread(0);
56 }
57}
58
3f647537 59void HandleSIGTERM(int)
60{
61 fRequestShutdown = true;
62}
63
0a61b0df 64
65
66
67
68
69//////////////////////////////////////////////////////////////////////////////
70//
71// Start
72//
73
74#ifndef GUI
75int main(int argc, char* argv[])
76{
dda48ccd 77 bool fRet = false;
78 fRet = AppInit(argc, argv);
0a61b0df 79
dda48ccd 80 if (fRet && fDaemon)
81 pthread_exit((void*)0);
0a61b0df 82}
83#endif
84
85bool AppInit(int argc, char* argv[])
86{
87 bool fRet = false;
88 try
89 {
90 fRet = AppInit2(argc, argv);
91 }
92 catch (std::exception& e) {
93 PrintException(&e, "AppInit()");
94 } catch (...) {
a79409af 95 PrintException(NULL, "AppInit()");
0a61b0df 96 }
97 if (!fRet)
98 Shutdown(NULL);
99 return fRet;
100}
101
102bool AppInit2(int argc, char* argv[])
103{
104#ifdef _MSC_VER
105 // Turn off microsoft heap dump noise
106 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
107 _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
108#endif
109#if _MSC_VER >= 1400
110 // Disable confusing "helpful" text message on abort, ctrl-c
111 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
112#endif
113#ifndef __WXMSW__
114 umask(077);
115#endif
3f647537 116#ifndef __WXMSW__
117 // Clean shutdown on SIGTERM
118 struct sigaction sa;
119 sa.sa_handler = HandleSIGTERM;
120 sigemptyset(&sa.sa_mask);
121 sa.sa_flags = 0;
122 sigaction(SIGTERM, &sa, NULL);
123#endif
0a61b0df 124
125 //
126 // Parameters
127 //
128 ParseParameters(argc, argv);
129
130 if (mapArgs.count("-datadir"))
131 {
132 filesystem::path pathDataDir = filesystem::system_complete(mapArgs["-datadir"]);
133 strlcpy(pszSetDataDir, pathDataDir.string().c_str(), sizeof(pszSetDataDir));
134 }
135
136 ReadConfigFile(mapArgs, mapMultiArgs); // Must be done after processing datadir
137
138 if (mapArgs.count("-?") || mapArgs.count("--help"))
139 {
5284e1b6 140 string beta = VERSION_IS_BETA ? _(" beta") : "";
0a61b0df 141 string strUsage = string() +
5284e1b6 142 _("Bitcoin version") + " " + FormatVersion(VERSION) + pszSubVer + beta + "\n\n" +
0a61b0df 143 _("Usage:") + "\t\t\t\t\t\t\t\t\t\t\n" +
144 " bitcoin [options] \t " + "\n" +
145 " bitcoin [options] <command> [params]\t " + _("Send command to -server or bitcoind\n") +
146 " bitcoin [options] help \t\t " + _("List commands\n") +
147 " bitcoin [options] help <command> \t\t " + _("Get help for a command\n") +
148 _("Options:\n") +
5cbf7532 149 " -conf=<file> \t\t " + _("Specify configuration file (default: bitcoin.conf)\n") +
150 " -gen \t\t " + _("Generate coins\n") +
151 " -gen=0 \t\t " + _("Don't generate coins\n") +
152 " -min \t\t " + _("Start minimized\n") +
153 " -datadir=<dir> \t\t " + _("Specify data directory\n") +
154 " -proxy=<ip:port> \t " + _("Connect through socks4 proxy\n") +
155 " -addnode=<ip> \t " + _("Add a node to connect to\n") +
156 " -connect=<ip> \t\t " + _("Connect only to the specified node\n") +
6665aca0 157 " -nolisten \t " + _("Don't accept connections from outside\n") +
461764cb 158 " -paytxfee=<amt> \t " + _("Fee per KB to add to transactions you send\n") +
e1205e4d 159#ifdef GUI
5cbf7532 160 " -server \t\t " + _("Accept command line and JSON-RPC commands\n") +
161 " -daemon \t\t " + _("Run in the background as a daemon and accept commands\n") +
e1205e4d 162#endif
5cbf7532 163 " -testnet \t\t " + _("Use the test network\n") +
164 " -rpcuser=<user> \t " + _("Username for JSON-RPC connections\n") +
165 " -rpcpassword=<pw>\t " + _("Password for JSON-RPC connections\n") +
10152506 166 " -rpcport=<port> \t\t " + _("Listen for JSON-RPC connections on <port> (default: 8332)\n") +
5cbf7532 167 " -rpcallowip=<ip> \t\t " + _("Allow JSON-RPC connections from specified IP address\n") +
10152506
C
168 " -rpcconnect=<ip> \t " + _("Send commands to node running on <ip> (default: 127.0.0.1)\n") +
169 " -keypool=<n> \t " + _("Set key pool size to <n> (default: 100)\n") +
05563e9e 170 " -rescan \t " + _("Rescan the block chain for missing wallet transactions\n");
0a61b0df 171
ed54768f 172#ifdef USE_SSL
173 strUsage += string() +
174 _("\nSSL options: (see the Bitcoin Wiki for SSL setup instructions)\n") +
2aadc8bb 175 " -rpcssl \t " + _("Use OpenSSL (https) for JSON-RPC connections\n") +
ab931be4
C
176 " -rpcsslcertificatechainfile=<file.cert>\t " + _("Server certificate file (default: server.cert)\n") +
177 " -rpcsslprivatekeyfile=<file.pem> \t " + _("Server private key (default: server.pem)\n") +
178 " -rpcsslciphers=<ciphers> \t " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n");
ed54768f 179#endif
180
5cbf7532 181 strUsage += string() +
182 " -? \t\t " + _("This help message\n");
183
0a61b0df 184#if defined(__WXMSW__) && defined(GUI)
185 // Tabs make the columns line up in the message box
186 wxMessageBox(strUsage, "Bitcoin", wxOK);
187#else
188 // Remove tabs
189 strUsage.erase(std::remove(strUsage.begin(), strUsage.end(), '\t'), strUsage.end());
190 fprintf(stderr, "%s", strUsage.c_str());
191#endif
192 return false;
193 }
194
bdde31d7 195 fDebug = GetBoolArg("-debug");
0a61b0df 196
dda48ccd 197 fDaemon = GetBoolArg("-daemon");
198
199 if (fDaemon)
200 fServer = true;
201 else
202 fServer = GetBoolArg("-server");
203
ea7cd317 204 /* force fServer and fDaemon when running without GUI */
dda48ccd 205#ifndef GUI
206 fServer = true;
ea7cd317 207 fDaemon = true;
dda48ccd 208#endif
209
aaac71d3 210 fPrintToConsole = GetBoolArg("-printtoconsole");
bdde31d7 211 fPrintToDebugger = GetBoolArg("-printtodebugger");
0a61b0df 212
bdde31d7 213 fTestNet = GetBoolArg("-testnet");
5f88e888 214 fNoListen = GetBoolArg("-nolisten");
e2e5f5cd 215 fLogTimestamps = GetBoolArg("-logtimestamps");
5cbf7532 216
dda48ccd 217 for (int i = 1; i < argc; i++)
218 if (!IsSwitchChar(argv[i][0]))
219 fCommandLine = true;
220
0a61b0df 221 if (fCommandLine)
222 {
223 int ret = CommandLineRPC(argc, argv);
224 exit(ret);
225 }
226
dda48ccd 227#ifndef GUI
228 if (fDaemon)
229 {
230 // Daemonize
231 pid_t pid = fork();
232 if (pid < 0)
233 {
234 fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
235 return false;
236 }
237 if (pid > 0)
238 return true;
239 }
240#endif
241
0a61b0df 242 if (!fDebug && !pszSetDataDir[0])
243 ShrinkDebugFile();
244 printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
5284e1b6 245 printf("Bitcoin version %s%s%s\n", FormatVersion(VERSION).c_str(), pszSubVer, VERSION_IS_BETA ? _(" beta") : "");
0a61b0df 246#ifdef GUI
247 printf("OS version %s\n", ((string)wxGetOsDescription()).c_str());
248 printf("System default language is %d %s\n", g_locale.GetSystemLanguage(), ((string)g_locale.GetSysName()).c_str());
249 printf("Language file %s (%s)\n", (string("locale/") + (string)g_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)g_locale.GetLocale()).c_str());
250#endif
251 printf("Default data directory %s\n", GetDefaultDataDir().c_str());
252
bdde31d7 253 if (GetBoolArg("-loadblockindextest"))
0a61b0df 254 {
255 CTxDB txdb("r");
256 txdb.LoadBlockIndex();
257 PrintBlockTree();
258 return false;
259 }
260
261 //
262 // Limit to single instance per user
263 // Required to protect the database files if we're going to keep deleting log.*
264 //
265#if defined(__WXMSW__) && defined(GUI)
d9c6b09a 266 // wxSingleInstanceChecker doesn't work on Linux
0a61b0df 267 wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH");
268 for (int i = 0; i < strMutexName.size(); i++)
269 if (!isalnum(strMutexName[i]))
270 strMutexName[i] = '.';
271 wxSingleInstanceChecker* psingleinstancechecker = new wxSingleInstanceChecker(strMutexName);
272 if (psingleinstancechecker->IsAnotherRunning())
273 {
274 printf("Existing instance found\n");
275 unsigned int nStart = GetTime();
276 loop
277 {
0a61b0df 278 // Show the previous instance and exit
279 HWND hwndPrev = FindWindowA("wxWindowClassNR", "Bitcoin");
280 if (hwndPrev)
281 {
282 if (IsIconic(hwndPrev))
283 ShowWindow(hwndPrev, SW_RESTORE);
284 SetForegroundWindow(hwndPrev);
285 return false;
286 }
287
288 if (GetTime() > nStart + 60)
289 return false;
290
291 // Resume this instance if the other exits
292 delete psingleinstancechecker;
293 Sleep(1000);
294 psingleinstancechecker = new wxSingleInstanceChecker(strMutexName);
295 if (!psingleinstancechecker->IsAnotherRunning())
296 break;
297 }
298 }
299#endif
300
d9c6b09a 301 // Make sure only a single bitcoin process is using the data directory.
302 string strLockFile = GetDataDir() + "/.lock";
303 FILE* file = fopen(strLockFile.c_str(), "a"); // empty lock file; created if it doesn't exist.
304 fclose(file);
305 static boost::interprocess::file_lock lock(strLockFile.c_str());
306 if (!lock.try_lock())
307 {
308 wxMessageBox(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().c_str()), "Bitcoin");
309 return false;
310 }
311
0a61b0df 312 // Bind to the port early so we can tell if another instance is already running.
0a61b0df 313 string strErrors;
5f88e888 314 if (!fNoListen)
0a61b0df 315 {
5f88e888
W
316 if (!BindListenPort(strErrors))
317 {
318 wxMessageBox(strErrors, "Bitcoin");
319 return false;
320 }
0a61b0df 321 }
322
323 //
324 // Load data files
325 //
326 if (fDaemon)
327 fprintf(stdout, "bitcoin server starting\n");
328 strErrors = "";
329 int64 nStart;
330
331 printf("Loading addresses...\n");
332 nStart = GetTimeMillis();
333 if (!LoadAddresses())
334 strErrors += _("Error loading addr.dat \n");
335 printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart);
336
337 printf("Loading block index...\n");
338 nStart = GetTimeMillis();
339 if (!LoadBlockIndex())
340 strErrors += _("Error loading blkindex.dat \n");
341 printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);
342
343 printf("Loading wallet...\n");
344 nStart = GetTimeMillis();
345 bool fFirstRun;
346 if (!LoadWallet(fFirstRun))
347 strErrors += _("Error loading wallet.dat \n");
348 printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
349
f1307515
GA
350 if (GetBoolArg("-rescan"))
351 {
352 nStart = GetTimeMillis();
353 ScanForWalletTransactions(pindexGenesisBlock);
354 printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart);
355 }
356
0a61b0df 357 printf("Done loading\n");
358
359 //// debug print
360 printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
361 printf("nBestHeight = %d\n", nBestHeight);
362 printf("mapKeys.size() = %d\n", mapKeys.size());
363 printf("mapPubKeys.size() = %d\n", mapPubKeys.size());
364 printf("mapWallet.size() = %d\n", mapWallet.size());
365 printf("mapAddressBook.size() = %d\n", mapAddressBook.size());
366
367 if (!strErrors.empty())
368 {
f1e1fb4b 369 wxMessageBox(strErrors, "Bitcoin", wxOK | wxICON_ERROR);
0a61b0df 370 return false;
371 }
372
373 // Add wallet transactions that aren't already in a block to mapTransactions
374 ReacceptWalletTransactions();
375
376 //
377 // Parameters
378 //
bdde31d7 379 if (GetBoolArg("-printblockindex") || GetBoolArg("-printblocktree"))
0a61b0df 380 {
381 PrintBlockTree();
382 return false;
383 }
384
385 if (mapArgs.count("-printblock"))
386 {
387 string strMatch = mapArgs["-printblock"];
388 int nFound = 0;
389 for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
390 {
391 uint256 hash = (*mi).first;
392 if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0)
393 {
394 CBlockIndex* pindex = (*mi).second;
395 CBlock block;
396 block.ReadFromDisk(pindex);
397 block.BuildMerkleTree();
398 block.print();
399 printf("\n");
400 nFound++;
401 }
402 }
403 if (nFound == 0)
404 printf("No blocks matching %s were found\n", strMatch.c_str());
405 return false;
406 }
407
bdde31d7 408 fGenerateBitcoins = GetBoolArg("-gen");
0a61b0df 409
410 if (mapArgs.count("-proxy"))
411 {
412 fUseProxy = true;
413 addrProxy = CAddress(mapArgs["-proxy"]);
414 if (!addrProxy.IsValid())
415 {
416 wxMessageBox(_("Invalid -proxy address"), "Bitcoin");
417 return false;
418 }
419 }
420
421 if (mapArgs.count("-addnode"))
422 {
423 foreach(string strAddr, mapMultiArgs["-addnode"])
424 {
425 CAddress addr(strAddr, NODE_NETWORK);
426 addr.nTime = 0; // so it won't relay unless successfully connected
427 if (addr.IsValid())
428 AddAddress(addr);
429 }
430 }
431
f684aec4
JG
432 if (mapArgs.count("-dnsseed"))
433 DNSAddressSeed();
434
0a61b0df 435 if (mapArgs.count("-paytxfee"))
436 {
437 if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee))
438 {
439 wxMessageBox(_("Invalid amount for -paytxfee=<amount>"), "Bitcoin");
440 return false;
441 }
461764cb 442 if (nTransactionFee > 0.25 * COIN)
f1e1fb4b 443 wxMessageBox(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."), "Bitcoin", wxOK | wxICON_EXCLAMATION);
0a61b0df 444 }
445
446 //
447 // Create the main window and start the node
448 //
449#ifdef GUI
450 if (!fDaemon)
451 CreateMainWindow();
452#endif
453
454 if (!CheckDiskSpace())
455 return false;
456
457 RandAddSeedPerfmon();
458
459 if (!CreateThread(StartNode, NULL))
460 wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin");
461
dda48ccd 462 if (fServer)
0a61b0df 463 CreateThread(ThreadRPCServer, NULL);
464
465#if defined(__WXMSW__) && defined(GUI)
466 if (fFirstRun)
467 SetStartOnSystemStartup(true);
468#endif
469
470 return true;
471}
This page took 0.078173 seconds and 4 git commands to generate.