]> Git Repo - VerusCoin.git/blame - src/bitcoin-cli.cpp
Merge pull request #4326
[VerusCoin.git] / src / bitcoin-cli.cpp
CommitLineData
2a03a390
WL
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-2013 The Bitcoin developers
3// Distributed under the MIT/X11 software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include "util.h"
7#include "init.h"
fb78cc23 8#include "rpcclient.h"
a7199038 9#include "rpcprotocol.h"
2a03a390 10#include "ui_interface.h" /* for _(...) */
9d2b73d1 11#include "chainparams.h"
2a03a390 12
51ed9ec9
BD
13#include <boost/filesystem/operations.hpp>
14
b750cf1f
WL
15using namespace boost;
16using namespace boost::asio;
17using namespace json_spirit;
18
19std::string HelpMessageCli()
20{
21 string strUsage;
22 strUsage += _("Options:") + "\n";
23 strUsage += " -? " + _("This help message") + "\n";
24 strUsage += " -conf=<file> " + _("Specify configuration file (default: bitcoin.conf)") + "\n";
25 strUsage += " -datadir=<dir> " + _("Specify data directory") + "\n";
26 strUsage += " -testnet " + _("Use the test network") + "\n";
27 strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be "
28 "solved instantly. This is intended for regression testing tools and app development.") + "\n";
29 strUsage += " -rpcconnect=<ip> " + _("Send commands to node running on <ip> (default: 127.0.0.1)") + "\n";
30 strUsage += " -rpcport=<port> " + _("Connect to JSON-RPC on <port> (default: 8332 or testnet: 18332)") + "\n";
31 strUsage += " -rpcwait " + _("Wait for RPC server to start") + "\n";
32 strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n";
33 strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n";
34
35 strUsage += "\n" + _("SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n";
36 strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n";
37
38 return strUsage;
39}
40
2a03a390
WL
41//////////////////////////////////////////////////////////////////////////////
42//
43// Start
44//
45static bool AppInitRPC(int argc, char* argv[])
46{
47 //
48 // Parameters
49 //
50 ParseParameters(argc, argv);
51 if (!boost::filesystem::is_directory(GetDataDir(false)))
52 {
53 fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str());
54 return false;
55 }
4ae5e721
WL
56 try {
57 ReadConfigFile(mapArgs, mapMultiArgs);
58 } catch(std::exception &e) {
59 fprintf(stderr,"Error reading configuration file: %s\n", e.what());
60 return false;
61 }
a3d946eb 62 // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
9d2b73d1
WL
63 if (!SelectParamsFromCommandLine()) {
64 fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
65 return false;
66 }
2a03a390 67
96b733e9 68 if (argc<2 || mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version"))
2a03a390 69 {
96b733e9
WL
70 std::string strUsage = _("Bitcoin Core RPC client version") + " " + FormatFullVersion() + "\n";
71 if (!mapArgs.count("-version"))
72 {
73 strUsage += "\n" + _("Usage:") + "\n" +
74 " bitcoin-cli [options] <command> [params] " + _("Send command to Bitcoin Core") + "\n" +
75 " bitcoin-cli [options] help " + _("List commands") + "\n" +
76 " bitcoin-cli [options] help <command> " + _("Get help for a command") + "\n";
2a03a390 77
b750cf1f 78 strUsage += "\n" + HelpMessageCli();
96b733e9 79 }
2a03a390
WL
80
81 fprintf(stdout, "%s", strUsage.c_str());
82 return false;
83 }
84 return true;
85}
86
b750cf1f
WL
87Object CallRPC(const string& strMethod, const Array& params)
88{
89 if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
90 throw runtime_error(strprintf(
91 _("You must set rpcpassword=<password> in the configuration file:\n%s\n"
92 "If the file does not exist, create it with owner-readable-only file permissions."),
93 GetConfigFile().string().c_str()));
94
95 // Connect to localhost
96 bool fUseSSL = GetBoolArg("-rpcssl", false);
97 asio::io_service io_service;
98 ssl::context context(io_service, ssl::context::sslv23);
99 context.set_options(ssl::context::no_sslv2);
100 asio::ssl::stream<asio::ip::tcp::socket> sslStream(io_service, context);
101 SSLIOStreamDevice<asio::ip::tcp> d(sslStream, fUseSSL);
102 iostreams::stream< SSLIOStreamDevice<asio::ip::tcp> > stream(d);
103
104 bool fWait = GetBoolArg("-rpcwait", false); // -rpcwait means try until server has started
105 do {
106 bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(Params().RPCPort())));
107 if (fConnected) break;
108 if (fWait)
109 MilliSleep(1000);
110 else
111 throw runtime_error("couldn't connect to server");
112 } while (fWait);
113
114 // HTTP basic authentication
115 string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]);
116 map<string, string> mapRequestHeaders;
117 mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64;
118
119 // Send request
120 string strRequest = JSONRPCRequest(strMethod, params, 1);
121 string strPost = HTTPPost(strRequest, mapRequestHeaders);
122 stream << strPost << std::flush;
123
124 // Receive HTTP reply status
125 int nProto = 0;
126 int nStatus = ReadHTTPStatus(stream, nProto);
127
128 // Receive HTTP reply message headers and body
129 map<string, string> mapHeaders;
130 string strReply;
131 ReadHTTPMessage(stream, mapHeaders, strReply, nProto);
132
133 if (nStatus == HTTP_UNAUTHORIZED)
134 throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
135 else if (nStatus >= 400 && nStatus != HTTP_BAD_REQUEST && nStatus != HTTP_NOT_FOUND && nStatus != HTTP_INTERNAL_SERVER_ERROR)
136 throw runtime_error(strprintf("server returned HTTP error %d", nStatus));
137 else if (strReply.empty())
138 throw runtime_error("no response from server");
139
140 // Parse reply
141 Value valReply;
142 if (!read_string(strReply, valReply))
143 throw runtime_error("couldn't parse reply from server");
144 const Object& reply = valReply.get_obj();
145 if (reply.empty())
146 throw runtime_error("expected reply to have result, error and id properties");
147
148 return reply;
149}
150
151int CommandLineRPC(int argc, char *argv[])
152{
153 string strPrint;
154 int nRet = 0;
155 try
156 {
157 // Skip switches
158 while (argc > 1 && IsSwitchChar(argv[1][0]))
159 {
160 argc--;
161 argv++;
162 }
163
164 // Method
165 if (argc < 2)
166 throw runtime_error("too few parameters");
167 string strMethod = argv[1];
168
169 // Parameters default to strings
170 std::vector<std::string> strParams(&argv[2], &argv[argc]);
171 Array params = RPCConvertValues(strMethod, strParams);
172
173 // Execute
174 Object reply = CallRPC(strMethod, params);
175
176 // Parse reply
177 const Value& result = find_value(reply, "result");
178 const Value& error = find_value(reply, "error");
179
180 if (error.type() != null_type)
181 {
182 // Error
183 strPrint = "error: " + write_string(error, false);
184 int code = find_value(error.get_obj(), "code").get_int();
185 nRet = abs(code);
186 }
187 else
188 {
189 // Result
190 if (result.type() == null_type)
191 strPrint = "";
192 else if (result.type() == str_type)
193 strPrint = result.get_str();
194 else
195 strPrint = write_string(result, true);
196 }
197 }
198 catch (boost::thread_interrupted) {
199 throw;
200 }
201 catch (std::exception& e) {
202 strPrint = string("error: ") + e.what();
203 nRet = EXIT_FAILURE;
204 }
205 catch (...) {
206 PrintExceptionContinue(NULL, "CommandLineRPC()");
207 throw;
208 }
209
210 if (strPrint != "")
211 {
212 fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
213 }
214 return nRet;
215}
216
2a03a390
WL
217int main(int argc, char* argv[])
218{
5248ff40
SC
219 SetupEnvironment();
220
2a03a390
WL
221 try
222 {
223 if(!AppInitRPC(argc, argv))
0cafb630 224 return EXIT_FAILURE;
2a03a390
WL
225 }
226 catch (std::exception& e) {
227 PrintExceptionContinue(&e, "AppInitRPC()");
0cafb630 228 return EXIT_FAILURE;
2a03a390
WL
229 } catch (...) {
230 PrintExceptionContinue(NULL, "AppInitRPC()");
0cafb630 231 return EXIT_FAILURE;
2a03a390
WL
232 }
233
0cafb630 234 int ret = EXIT_FAILURE;
2a03a390
WL
235 try
236 {
a7199038 237 ret = CommandLineRPC(argc, argv);
2a03a390
WL
238 }
239 catch (std::exception& e) {
240 PrintExceptionContinue(&e, "CommandLineRPC()");
241 } catch (...) {
242 PrintExceptionContinue(NULL, "CommandLineRPC()");
243 }
a7199038 244 return ret;
2a03a390 245}
This page took 0.061092 seconds and 4 git commands to generate.