Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto 2 : // Copyright (c) 2009-2014 The Bitcoin developers 3 : // Copyright (c) 2014-2015 The Dash developers 4 : // Copyright (c) 2015-2022 The PIVX Core developers 5 : // Distributed under the MIT/X11 software license, see the accompanying 6 : // file COPYING or https://www.opensource.org/licenses/mit-license.php. 7 : 8 : #if defined(HAVE_CONFIG_H) 9 : #include "config/pivx-config.h" 10 : #endif 11 : 12 : #include "chainparams.h" 13 : #include "clientversion.h" 14 : #include "fs.h" 15 : #include "init.h" 16 : #include "masternodeconfig.h" 17 : #include "noui.h" 18 : #include "shutdown.h" 19 : #include "util/system.h" 20 : 21 : #include <stdio.h> 22 : 23 : /* Introduction text for doxygen: */ 24 : 25 : /*! \mainpage Developer documentation 26 : * 27 : * \section intro_sec Introduction 28 : * 29 : * This is the developer documentation of the reference client for an experimental new digital currency called PIVX (http://www.pivx.org), 30 : * which enables instant payments to anyone, anywhere in the world. PIVX uses peer-to-peer technology to operate 31 : * with no central authority: managing transactions and issuing money are carried out collectively by the network. 32 : * 33 : * The software is a community-driven open source project, released under the MIT license. 34 : * 35 : * \section Navigation 36 : * Use the buttons <code>Namespaces</code>, <code>Classes</code> or <code>Files</code> at the top of the page to start navigating the code. 37 : */ 38 : 39 355 : void WaitForShutdown() 40 : { 41 95507 : while (!ShutdownRequested()) { 42 95152 : MilliSleep(200); 43 : } 44 355 : Interrupt(); 45 355 : } 46 : 47 : ////////////////////////////////////////////////////////////////////////////// 48 : // 49 : // Start 50 : // 51 391 : bool AppInit(int argc, char* argv[]) 52 : { 53 391 : bool fRet = false; 54 : 55 : // 56 : // Parameters 57 : // 58 : // If Qt is used, parameters/pivx.conf are parsed in qt/pivx.cpp's main() 59 391 : gArgs.ParseParameters(argc, argv); 60 : 61 : // Process help and version before taking care about datadir 62 1562 : if (gArgs.IsArgSet("-?") || gArgs.IsArgSet("-h") || gArgs.IsArgSet("-help") || gArgs.IsArgSet("-version")) { 63 6 : std::string strUsage = PACKAGE_NAME " Daemon version " + FormatFullVersion() + "\n"; 64 : 65 2 : if (gArgs.IsArgSet("-version")) { 66 3 : strUsage += LicenseInfo(); 67 : } else { 68 1 : strUsage += "\nUsage: pivxd [options] Start " PACKAGE_NAME " Daemon\n"; 69 3 : strUsage += "\n" + HelpMessage(HMM_BITCOIND); 70 : } 71 : 72 2 : fprintf(stdout, "%s", strUsage.c_str()); 73 2 : return true; 74 : } 75 : 76 389 : try { 77 389 : if (!CheckDataDirOption()) { 78 2 : fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "").c_str()); 79 1 : return false; 80 : } 81 388 : try { 82 777 : gArgs.ReadConfigFile(gArgs.GetArg("-conf", PIVX_CONF_FILENAME)); 83 1 : } catch (const std::exception& e) { 84 1 : fprintf(stderr, "Error reading configuration file: %s\n", e.what()); 85 1 : return false; 86 : } 87 : // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause) 88 387 : try { 89 387 : SelectParams(gArgs.GetChainName()); 90 0 : } catch(const std::exception& e) { 91 0 : fprintf(stderr, "Error: %s\n", e.what()); 92 0 : return false; 93 : } 94 : 95 : // Error out when loose non-argument tokens are encountered on command line 96 4023 : for (int i = 1; i < argc; i++) { 97 3636 : if (!IsSwitchChar(argv[i][0])) { 98 0 : fprintf(stderr, "Error: Command line contains unexpected token '%s', see pivxd -h for a list of options.\n", argv[i]); 99 : return false; 100 : } 101 : } 102 : 103 : // -server defaults to true for pivxd but not for the GUI so do this here 104 387 : gArgs.SoftSetBoolArg("-server", true); 105 : // Set this early so that parameter interactions go to console 106 387 : InitLogging(); 107 387 : InitParameterInteraction(); 108 387 : if (!AppInitBasicSetup()) { 109 : // UIError will have been called with detailed error, which ends up on console 110 : return false; 111 : } 112 387 : if (!AppInitParameterInteraction()) { 113 : // UIError will have been called with detailed error, which ends up on console 114 : return false; 115 : } 116 379 : if (!AppInitSanityChecks()) { 117 : // UIError will have been called with detailed error, which ends up on console 118 : return false; 119 : } 120 : 121 : #ifndef WIN32 122 378 : if (gArgs.GetBoolArg("-daemon", false)) { 123 0 : fprintf(stdout, "PIVX server starting\n"); 124 : 125 : // Daemonize 126 0 : pid_t pid = fork(); 127 0 : if (pid < 0) { 128 391 : fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno); 129 : return false; 130 : } 131 0 : if (pid > 0) // Parent process, pid is child process id 132 : { 133 : return true; 134 : } 135 : // Child process falls through to rest of initialization 136 : 137 0 : pid_t sid = setsid(); 138 0 : if (sid < 0) 139 0 : fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno); 140 : } 141 : #endif 142 : 143 : // Set this early so that parameter interactions go to console 144 378 : fRet = AppInitMain(); 145 2 : } catch (const std::exception& e) { 146 2 : PrintExceptionContinue(&e, "AppInit()"); 147 0 : } catch (...) { 148 0 : PrintExceptionContinue(nullptr, "AppInit()"); 149 : } 150 : 151 378 : if (!fRet) { 152 23 : Interrupt(); 153 : } else { 154 355 : WaitForShutdown(); 155 : } 156 378 : Shutdown(); 157 : 158 378 : return fRet; 159 : } 160 : 161 391 : int main(int argc, char* argv[]) 162 : { 163 : #ifdef WIN32 164 : util::WinCmdLineArgs winArgs; 165 : std::tie(argc, argv) = winArgs.get(); 166 : #endif 167 391 : SetupEnvironment(); 168 : 169 : // Connect pivxd signal handlers 170 391 : noui_connect(); 171 : 172 391 : return (AppInit(argc, argv) ? 0 : 1); 173 : }