]>
Commit | Line | Data |
---|---|---|
c862d2ff | 1 | // Copyright (c) 2009-2010 Satoshi Nakamoto |
f914f1a7 | 2 | // Copyright (c) 2009-2013 The Bitcoin Core developers |
78253fcb | 3 | // Distributed under the MIT software license, see the accompanying |
bc909a7a | 4 | // file COPYING or https://www.opensource.org/licenses/mit-license.php . |
c862d2ff | 5 | |
71697f97 | 6 | #include "clientversion.h" |
4519a766 | 7 | #include "rpc/server.h" |
c862d2ff | 8 | #include "init.h" |
722fa283 | 9 | #include "main.h" |
51ed9ec9 | 10 | #include "noui.h" |
ddd0acd3 | 11 | #include "scheduler.h" |
51ed9ec9 | 12 | #include "util.h" |
afd64f76 WL |
13 | #include "httpserver.h" |
14 | #include "httprpc.h" | |
51ed9ec9 | 15 | |
c862d2ff | 16 | #include <boost/algorithm/string/predicate.hpp> |
51ed9ec9 | 17 | #include <boost/filesystem.hpp> |
ad49c256 | 18 | #include <boost/thread.hpp> |
c862d2ff | 19 | |
afd64f76 WL |
20 | #include <stdio.h> |
21 | ||
0e165b97 WL |
22 | /* Introduction text for doxygen: */ |
23 | ||
24 | /*! \mainpage Developer documentation | |
25 | * | |
26 | * \section intro_sec Introduction | |
27 | * | |
447d37e7 | 28 | * This is the developer documentation of the reference client for an experimental new digital currency called Bitcoin (https://www.bitcoin.org/), |
0e165b97 WL |
29 | * which enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate |
30 | * with no central authority: managing transactions and issuing money are carried out collectively by the network. | |
31 | * | |
32 | * The software is a community-driven open source project, released under the MIT license. | |
33 | * | |
34 | * \section Navigation | |
35 | * Use the buttons <code>Namespaces</code>, <code>Classes</code> or <code>Files</code> at the top of the page to start navigating the code. | |
36 | */ | |
37 | ||
8b9adca4 WL |
38 | static bool fDaemon; |
39 | ||
28ee7e8b | 40 | void WaitForShutdown(boost::thread_group* threadGroup) |
c862d2ff | 41 | { |
c55d1600 | 42 | bool fShutdown = ShutdownRequested(); |
c862d2ff | 43 | // Tell the main threads to shutdown. |
c55d1600 | 44 | while (!fShutdown) |
c862d2ff CF |
45 | { |
46 | MilliSleep(200); | |
c55d1600 | 47 | fShutdown = ShutdownRequested(); |
c862d2ff CF |
48 | } |
49 | if (threadGroup) | |
c55d1600 | 50 | { |
afd64f76 | 51 | Interrupt(*threadGroup); |
c55d1600 PK |
52 | threadGroup->join_all(); |
53 | } | |
c862d2ff CF |
54 | } |
55 | ||
56 | ////////////////////////////////////////////////////////////////////////////// | |
57 | // | |
58 | // Start | |
59 | // | |
60 | bool AppInit(int argc, char* argv[]) | |
61 | { | |
62 | boost::thread_group threadGroup; | |
ddd0acd3 | 63 | CScheduler scheduler; |
c862d2ff CF |
64 | |
65 | bool fRet = false; | |
3d0a1ce1 PJ |
66 | |
67 | // | |
68 | // Parameters | |
69 | // | |
3d0a1ce1 PJ |
70 | ParseParameters(argc, argv); |
71 | ||
72 | // Process help and version before taking care about datadir | |
af6edac0 | 73 | if (mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version")) |
3d0a1ce1 | 74 | { |
f0d1accb | 75 | std::string strUsage = _("Zcash Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n" + PrivacyInfo(); |
3d0a1ce1 PJ |
76 | |
77 | if (mapArgs.count("-version")) | |
78 | { | |
79 | strUsage += LicenseInfo(); | |
80 | } | |
81 | else | |
82 | { | |
83 | strUsage += "\n" + _("Usage:") + "\n" + | |
a1de76c7 | 84 | " zcashd [options] " + _("Start Zcash Daemon") + "\n"; |
3d0a1ce1 PJ |
85 | |
86 | strUsage += "\n" + HelpMessage(HMM_BITCOIND); | |
87 | } | |
88 | ||
89 | fprintf(stdout, "%s", strUsage.c_str()); | |
fadbbe1e | 90 | return true; |
3d0a1ce1 PJ |
91 | } |
92 | ||
c862d2ff CF |
93 | try |
94 | { | |
c862d2ff CF |
95 | if (!boost::filesystem::is_directory(GetDataDir(false))) |
96 | { | |
a2189fba PK |
97 | fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str()); |
98 | return false; | |
c862d2ff | 99 | } |
4ae5e721 WL |
100 | try |
101 | { | |
102 | ReadConfigFile(mapArgs, mapMultiArgs); | |
24f4e336 JG |
103 | } catch (const missing_zcash_conf& e) { |
104 | fprintf(stderr, | |
105 | (_("Before starting zcashd, you need to create a configuration file:\n" | |
106 | "%s\n" | |
107 | "It can be completely empty! That indicates you are happy with the default\n" | |
108 | "configuration of zcashd. But requiring a configuration file to start ensures\n" | |
109 | "that zcashd won't accidentally compromise your privacy if there was a default\n" | |
110 | "option you needed to change.\n" | |
111 | "\n" | |
112 | "You can look at the example configuration file for suggestions of default\n" | |
113 | "options that you may want to change. It should be in one of these locations,\n" | |
114 | "depending on how you installed Zcash:\n") + | |
115 | _("- Source code: %s\n" | |
116 | "- .deb package: %s\n")).c_str(), | |
117 | GetConfigFile().string().c_str(), | |
82c754f6 | 118 | "contrib/debian/examples/zcash.conf", |
24f4e336 JG |
119 | "/usr/share/doc/zcash/examples/zcash.conf"); |
120 | return false; | |
27df4123 | 121 | } catch (const std::exception& e) { |
4ae5e721 WL |
122 | fprintf(stderr,"Error reading configuration file: %s\n", e.what()); |
123 | return false; | |
124 | } | |
a3d946eb | 125 | // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause) |
a2189fba PK |
126 | if (!SelectParamsFromCommandLine()) { |
127 | fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n"); | |
128 | return false; | |
129 | } | |
c862d2ff | 130 | |
c862d2ff | 131 | // Command-line RPC |
917ac1dc | 132 | bool fCommandLine = false; |
c862d2ff | 133 | for (int i = 1; i < argc; i++) |
a1de76c7 | 134 | if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "zcash:")) |
c862d2ff CF |
135 | fCommandLine = true; |
136 | ||
137 | if (fCommandLine) | |
138 | { | |
b3e712a4 | 139 | fprintf(stderr, "Error: There is no RPC client functionality in zcashd. Use the zcash-cli utility instead.\n"); |
c06245c1 | 140 | exit(EXIT_FAILURE); |
c862d2ff | 141 | } |
a034c7eb | 142 | #ifndef WIN32 |
c862d2ff CF |
143 | fDaemon = GetBoolArg("-daemon", false); |
144 | if (fDaemon) | |
145 | { | |
a1de76c7 | 146 | fprintf(stdout, "Zcash server starting\n"); |
8b9adca4 | 147 | |
c862d2ff CF |
148 | // Daemonize |
149 | pid_t pid = fork(); | |
150 | if (pid < 0) | |
151 | { | |
152 | fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno); | |
153 | return false; | |
154 | } | |
155 | if (pid > 0) // Parent process, pid is child process id | |
156 | { | |
c862d2ff CF |
157 | return true; |
158 | } | |
159 | // Child process falls through to rest of initialization | |
160 | ||
161 | pid_t sid = setsid(); | |
162 | if (sid < 0) | |
163 | fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno); | |
164 | } | |
165 | #endif | |
8b9adca4 | 166 | SoftSetBoolArg("-server", true); |
c862d2ff | 167 | |
ddd0acd3 | 168 | fRet = AppInit2(threadGroup, scheduler); |
c862d2ff | 169 | } |
27df4123 | 170 | catch (const std::exception& e) { |
c862d2ff CF |
171 | PrintExceptionContinue(&e, "AppInit()"); |
172 | } catch (...) { | |
173 | PrintExceptionContinue(NULL, "AppInit()"); | |
174 | } | |
c55d1600 PK |
175 | |
176 | if (!fRet) | |
177 | { | |
afd64f76 | 178 | Interrupt(threadGroup); |
c55d1600 PK |
179 | // threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of |
180 | // the startup-failure cases to make sure they don't result in a hang due to some | |
181 | // thread-blocking-waiting-for-another-thread-during-startup case | |
28ee7e8b WL |
182 | } else { |
183 | WaitForShutdown(&threadGroup); | |
c862d2ff CF |
184 | } |
185 | Shutdown(); | |
186 | ||
187 | return fRet; | |
188 | } | |
189 | ||
c862d2ff CF |
190 | int main(int argc, char* argv[]) |
191 | { | |
5248ff40 SC |
192 | SetupEnvironment(); |
193 | ||
c862d2ff CF |
194 | // Connect bitcoind signal handlers |
195 | noui_connect(); | |
196 | ||
c06245c1 | 197 | return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE); |
c862d2ff | 198 | } |