Browse Source

json-rpc password, minor UI tweaks, removed some outdated txt files

0.8
Gavin Andresen 15 years ago
parent
commit
e96cd730d1
  1. 2
      bugs.txt
  2. 7
      changelog.txt
  3. 6
      init.cpp
  4. BIN
      locale/de/LC_MESSAGES/bitcoin.mo
  5. 2
      locale/de/LC_MESSAGES/bitcoin.po
  6. BIN
      locale/es/LC_MESSAGES/bitcoin.mo
  7. 2
      locale/es/LC_MESSAGES/bitcoin.po
  8. BIN
      locale/fr/LC_MESSAGES/bitcoin.mo
  9. 2
      locale/fr/LC_MESSAGES/bitcoin.po
  10. BIN
      locale/it/LC_MESSAGES/bitcoin.mo
  11. 2
      locale/it/LC_MESSAGES/bitcoin.po
  12. BIN
      locale/nl/LC_MESSAGES/bitcoin.mo
  13. 2
      locale/nl/LC_MESSAGES/bitcoin.po
  14. BIN
      locale/pt/LC_MESSAGES/bitcoin.mo
  15. 2
      locale/pt/LC_MESSAGES/bitcoin.po
  16. 81
      rpc.cpp
  17. 2
      serialize.h
  18. 4
      ui.cpp
  19. 3
      util.cpp

2
bugs.txt

@ -1,2 +0,0 @@
Known bugs:
- Window flickers when blocks are added (problem with repainting?)

7
changelog.txt

@ -1,7 +0,0 @@
Changes after 0.1.5:
--------------------
+ Options dialog layout changed - added the UI options panel
+ Minimize to tray feature
+ Startup on system boot feature
+ Ask before closing
+ NSIS installer

6
init.cpp

@ -389,7 +389,7 @@ bool CMyApp::OnInit2()
" bitcoin [options] \t" + "\n" + " bitcoin [options] \t" + "\n" +
" bitcoin [command] \t" + _("Send command to bitcoin running with -server or -daemon\n") + " bitcoin [command] \t" + _("Send command to bitcoin running with -server or -daemon\n") +
" bitcoin [command] -? \t" + _("Get help for a command\n") + " bitcoin [command] -? \t" + _("Get help for a command\n") +
" bitcoin help \t" + _("List commands\n") + " bitcoin help <pw> \t" + _("List commands\n") +
_("Options:\n") + _("Options:\n") +
" -gen \t " + _("Generate coins\n") + " -gen \t " + _("Generate coins\n") +
" -gen=0 \t " + _("Don't generate coins\n") + " -gen=0 \t " + _("Don't generate coins\n") +
@ -398,7 +398,7 @@ bool CMyApp::OnInit2()
" -proxy=<ip:port>\t " + _("Connect through socks4 proxy\n") + " -proxy=<ip:port>\t " + _("Connect through socks4 proxy\n") +
" -addnode=<ip> \t " + _("Add a node to connect to\n") + " -addnode=<ip> \t " + _("Add a node to connect to\n") +
" -connect=<ip> \t " + _("Connect only to the specified node\n") + " -connect=<ip> \t " + _("Connect only to the specified node\n") +
" -server \t " + _("Accept command line and JSON-RPC commands\n") + " -rpcpw=<pw> \t " + _("Accept command line and JSON-RPC commands with the given password\n") +
" -daemon \t " + _("Run in the background as a daemon and accept commands\n") + " -daemon \t " + _("Run in the background as a daemon and accept commands\n") +
" -? \t " + _("This help message\n"); " -? \t " + _("This help message\n");
@ -611,7 +611,7 @@ bool CMyApp::OnInit2()
if (!CreateThread(StartNode, NULL)) if (!CreateThread(StartNode, NULL))
wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin"); wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin");
if (mapArgs.count("-server") || fDaemon) if (mapArgs.count("-server") || mapArgs.count("-rpcpw") || fDaemon)
CreateThread(ThreadRPCServer, NULL); CreateThread(ThreadRPCServer, NULL);
if (fFirstRun) if (fFirstRun)

BIN
locale/de/LC_MESSAGES/bitcoin.mo

Binary file not shown.

2
locale/de/LC_MESSAGES/bitcoin.po

@ -216,7 +216,7 @@ msgstr "&Neue Empfangs-Adresse"
#: ../../../ui.cpp:1124 #: ../../../ui.cpp:1124
#: ../../../ui.cpp:2352 #: ../../../ui.cpp:2352
msgid "" msgid ""
"It's good policy to use a new address for each payment you receive.\n" "You should use a new address for each payment you receive.\n"
"\n" "\n"
"Label" "Label"
msgstr "" msgstr ""

BIN
locale/es/LC_MESSAGES/bitcoin.mo

Binary file not shown.

2
locale/es/LC_MESSAGES/bitcoin.po

@ -242,7 +242,7 @@ msgstr "Nueva direccion de recepcion"
#: ../../../ui.cpp:1129 #: ../../../ui.cpp:1129
#: ../../../ui.cpp:2369 #: ../../../ui.cpp:2369
msgid "" msgid ""
"It's good policy to use a new address for each payment you receive.\n" "You should use a new address for each payment you receive.\n"
"\n" "\n"
"Label" "Label"
msgstr "" msgstr ""

BIN
locale/fr/LC_MESSAGES/bitcoin.mo

Binary file not shown.

2
locale/fr/LC_MESSAGES/bitcoin.po

@ -242,7 +242,7 @@ msgstr "Nouvelle adresse de reception"
#: ../../../ui.cpp:1129 #: ../../../ui.cpp:1129
#: ../../../ui.cpp:2369 #: ../../../ui.cpp:2369
msgid "" msgid ""
"It's good policy to use a new address for each payment you receive.\n" "You should use a new address for each payment you receive.\n"
"\n" "\n"
"Label" "Label"
msgstr "" msgstr ""

BIN
locale/it/LC_MESSAGES/bitcoin.mo

Binary file not shown.

2
locale/it/LC_MESSAGES/bitcoin.po

@ -216,7 +216,7 @@ msgstr "Nuovo indirizzo ricevente"
#: ../../../ui.cpp:1124 #: ../../../ui.cpp:1124
#: ../../../ui.cpp:2352 #: ../../../ui.cpp:2352
msgid "" msgid ""
"It's good policy to use a new address for each payment you receive.\n" "You should use a new address for each payment you receive.\n"
"\n" "\n"
"Label" "Label"
msgstr "" msgstr ""

BIN
locale/nl/LC_MESSAGES/bitcoin.mo

Binary file not shown.

2
locale/nl/LC_MESSAGES/bitcoin.po

@ -216,7 +216,7 @@ msgstr "Nieuw Ontvangings Adres"
#: ../../../ui.cpp:1124 #: ../../../ui.cpp:1124
#: ../../../ui.cpp:2352 #: ../../../ui.cpp:2352
msgid "" msgid ""
"It's good policy to use a new address for each payment you receive.\n" "You should use a new address for each payment you receive.\n"
"\n" "\n"
"Label" "Label"
msgstr "" msgstr ""

BIN
locale/pt/LC_MESSAGES/bitcoin.mo

Binary file not shown.

2
locale/pt/LC_MESSAGES/bitcoin.po

@ -216,7 +216,7 @@ msgstr "Novo Endereço de Recepção"
#: ../../../ui.cpp:1124 #: ../../../ui.cpp:1124
#: ../../../ui.cpp:2352 #: ../../../ui.cpp:2352
msgid "" msgid ""
"It's good policy to use a new address for each payment you receive.\n" "You should use a new address for each payment you receive.\n"
"\n" "\n"
"Label" "Label"
msgstr "" msgstr ""

81
rpc.cpp

@ -21,6 +21,8 @@ void ThreadRPCServer2(void* parg);
typedef Value(*rpcfn_type)(const Array& params, bool fHelp); typedef Value(*rpcfn_type)(const Array& params, bool fHelp);
extern map<string, rpcfn_type> mapCallTable; extern map<string, rpcfn_type> mapCallTable;
static string strRPCPassword;
@ -37,16 +39,24 @@ Value help(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() != 0) if (fHelp || params.size() != 0)
throw runtime_error( throw runtime_error(
"help\n" "help <pw>\n"
"List commands."); "List commands.");
string strRet; string strRet;
set<rpcfn_type> setDone;
for (map<string, rpcfn_type>::iterator mi = mapCallTable.begin(); mi != mapCallTable.end(); ++mi) for (map<string, rpcfn_type>::iterator mi = mapCallTable.begin(); mi != mapCallTable.end(); ++mi)
{ {
string strMethod = (*mi).first;
// We already filter duplicates, but these deprecated screw up the sort order
if (strMethod == "getamountreceived" ||
strMethod == "getallreceived")
continue;
try try
{ {
Array params; Array params;
(*(*mi).second)(params, true); rpcfn_type pfn = (*mi).second;
if (setDone.insert(pfn).second)
(*pfn)(params, true);
} }
catch (std::exception& e) catch (std::exception& e)
{ {
@ -66,7 +76,7 @@ Value stop(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() != 0) if (fHelp || params.size() != 0)
throw runtime_error( throw runtime_error(
"stop\n" "stop <pw>\n"
"Stop bitcoin server."); "Stop bitcoin server.");
// Shutdown will take long enough that the response should get back // Shutdown will take long enough that the response should get back
@ -79,7 +89,7 @@ Value getblockcount(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() != 0) if (fHelp || params.size() != 0)
throw runtime_error( throw runtime_error(
"getblockcount\n" "getblockcount <pw>\n"
"Returns the number of blocks in the longest block chain."); "Returns the number of blocks in the longest block chain.");
return nBestHeight + 1; return nBestHeight + 1;
@ -90,7 +100,7 @@ Value getblocknumber(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() != 0) if (fHelp || params.size() != 0)
throw runtime_error( throw runtime_error(
"getblocknumber\n" "getblocknumber <pw>\n"
"Returns the block number of the latest block in the longest block chain."); "Returns the block number of the latest block in the longest block chain.");
return nBestHeight; return nBestHeight;
@ -101,7 +111,7 @@ Value getconnectioncount(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() != 0) if (fHelp || params.size() != 0)
throw runtime_error( throw runtime_error(
"getconnectioncount\n" "getconnectioncount <pw>\n"
"Returns the number of connections to other nodes."); "Returns the number of connections to other nodes.");
return (int)vNodes.size(); return (int)vNodes.size();
@ -124,7 +134,7 @@ Value getdifficulty(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() != 0) if (fHelp || params.size() != 0)
throw runtime_error( throw runtime_error(
"getdifficulty\n" "getdifficulty <pw>\n"
"Returns the proof-of-work difficulty as a multiple of the minimum difficulty."); "Returns the proof-of-work difficulty as a multiple of the minimum difficulty.");
return GetDifficulty(); return GetDifficulty();
@ -135,7 +145,7 @@ Value getbalance(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() != 0) if (fHelp || params.size() != 0)
throw runtime_error( throw runtime_error(
"getbalance\n" "getbalance <pw>\n"
"Returns the server's available balance."); "Returns the server's available balance.");
return ((double)GetBalance() / (double)COIN); return ((double)GetBalance() / (double)COIN);
@ -146,7 +156,7 @@ Value getgenerate(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() != 0) if (fHelp || params.size() != 0)
throw runtime_error( throw runtime_error(
"getgenerate\n" "getgenerate <pw>\n"
"Returns true or false."); "Returns true or false.");
return (bool)fGenerateBitcoins; return (bool)fGenerateBitcoins;
@ -157,7 +167,7 @@ Value setgenerate(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() < 1 || params.size() > 2) if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error( throw runtime_error(
"setgenerate <generate> [genproclimit]\n" "setgenerate <pw> <generate> [genproclimit]\n"
"<generate> is true or false to turn generation on or off.\n" "<generate> is true or false to turn generation on or off.\n"
"Generation is limited to [genproclimit] processors, -1 is unlimited."); "Generation is limited to [genproclimit] processors, -1 is unlimited.");
@ -183,7 +193,7 @@ Value getinfo(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() != 0) if (fHelp || params.size() != 0)
throw runtime_error( throw runtime_error(
"getinfo"); "getinfo <pw>");
Object obj; Object obj;
obj.push_back(Pair("balance", (double)GetBalance() / (double)COIN)); obj.push_back(Pair("balance", (double)GetBalance() / (double)COIN));
@ -201,7 +211,7 @@ Value getnewaddress(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() > 1) if (fHelp || params.size() > 1)
throw runtime_error( throw runtime_error(
"getnewaddress [label]\n" "getnewaddress <pw> [label]\n"
"Returns a new bitcoin address for receiving payments. " "Returns a new bitcoin address for receiving payments. "
"If [label] is specified (recommended), it is added to the address book " "If [label] is specified (recommended), it is added to the address book "
"so payments received with the address will be labeled."); "so payments received with the address will be labeled.");
@ -223,7 +233,7 @@ Value setlabel(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() < 1 || params.size() > 2) if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error( throw runtime_error(
"setlabel <bitcoinaddress> <label>\n" "setlabel <pw> <bitcoinaddress> <label>\n"
"Sets the label associated with the given address."); "Sets the label associated with the given address.");
string strAddress = params[0].get_str(); string strAddress = params[0].get_str();
@ -240,7 +250,7 @@ Value getlabel(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() != 1) if (fHelp || params.size() != 1)
throw runtime_error( throw runtime_error(
"getlabel <bitcoinaddress>\n" "getlabel <pw> <bitcoinaddress>\n"
"Returns the label associated with the given address."); "Returns the label associated with the given address.");
string strAddress = params[0].get_str(); string strAddress = params[0].get_str();
@ -260,7 +270,7 @@ Value getaddressesbylabel(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() != 1) if (fHelp || params.size() != 1)
throw runtime_error( throw runtime_error(
"getaddressesbylabel <label>\n" "getaddressesbylabel <pw> <label>\n"
"Returns the list of addresses with the given label."); "Returns the list of addresses with the given label.");
string strLabel = params[0].get_str(); string strLabel = params[0].get_str();
@ -290,7 +300,7 @@ Value sendtoaddress(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() < 2 || params.size() > 4) if (fHelp || params.size() < 2 || params.size() > 4)
throw runtime_error( throw runtime_error(
"sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to]\n" "sendtoaddress <pw> <bitcoinaddress> <amount> [comment] [comment-to]\n"
"<amount> is a real and is rounded to the nearest 0.01"); "<amount> is a real and is rounded to the nearest 0.01");
string strAddress = params[0].get_str(); string strAddress = params[0].get_str();
@ -318,7 +328,7 @@ Value listtransactions(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() > 2) if (fHelp || params.size() > 2)
throw runtime_error( throw runtime_error(
"listtransactions [count=10] [includegenerated=false]\n" "listtransactions <pw> [count=10] [includegenerated=false]\n"
"Returns up to [count] most recent transactions."); "Returns up to [count] most recent transactions.");
int64 nCount = 10; int64 nCount = 10;
@ -339,7 +349,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() < 1 || params.size() > 2) if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error( throw runtime_error(
"getreceivedbyaddress <bitcoinaddress> [minconf=1]\n" "getreceivedbyaddress <pw> <bitcoinaddress> [minconf=1]\n"
"Returns the total amount received by <bitcoinaddress> in transactions with at least [minconf] confirmations."); "Returns the total amount received by <bitcoinaddress> in transactions with at least [minconf] confirmations.");
// Bitcoin address // Bitcoin address
@ -380,7 +390,7 @@ Value getreceivedbylabel(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() < 1 || params.size() > 2) if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error( throw runtime_error(
"getreceivedbylabel <label> [minconf=1]\n" "getreceivedbylabel <pw> <label> [minconf=1]\n"
"Returns the total amount received by addresses with <label> in transactions with at least [minconf] confirmations."); "Returns the total amount received by addresses with <label> in transactions with at least [minconf] confirmations.");
// Get the set of pub keys that have the label // Get the set of pub keys that have the label
@ -543,7 +553,7 @@ Value listreceivedbyaddress(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() > 2) if (fHelp || params.size() > 2)
throw runtime_error( throw runtime_error(
"listreceivedbyaddress [minconf=1] [includeempty=false]\n" "listreceivedbyaddress <pw> [minconf=1] [includeempty=false]\n"
"[minconf] is the minimum number of confirmations before payments are included.\n" "[minconf] is the minimum number of confirmations before payments are included.\n"
"[includeempty] whether to include addresses that haven't received any payments.\n" "[includeempty] whether to include addresses that haven't received any payments.\n"
"Returns an array of objects containing:\n" "Returns an array of objects containing:\n"
@ -559,7 +569,7 @@ Value listreceivedbylabel(const Array& params, bool fHelp)
{ {
if (fHelp || params.size() > 2) if (fHelp || params.size() > 2)
throw runtime_error( throw runtime_error(
"listreceivedbylabel [minconf=1] [includeempty=false]\n" "listreceivedbylabel <pw> [minconf=1] [includeempty=false]\n"
"[minconf] is the minimum number of confirmations before payments are included.\n" "[minconf] is the minimum number of confirmations before payments are included.\n"
"[includeempty] whether to include labels that haven't received any payments.\n" "[includeempty] whether to include labels that haven't received any payments.\n"
"Returns an array of objects containing:\n" "Returns an array of objects containing:\n"
@ -603,7 +613,6 @@ pair<string, rpcfn_type> pCallTable[] =
make_pair("getlabel", &getlabel), make_pair("getlabel", &getlabel),
make_pair("getaddressesbylabel", &getaddressesbylabel), make_pair("getaddressesbylabel", &getaddressesbylabel),
make_pair("sendtoaddress", &sendtoaddress), make_pair("sendtoaddress", &sendtoaddress),
make_pair("listtransactions", &listtransactions),
make_pair("getamountreceived", &getreceivedbyaddress), // deprecated, renamed to getreceivedbyaddress make_pair("getamountreceived", &getreceivedbyaddress), // deprecated, renamed to getreceivedbyaddress
make_pair("getallreceived", &listreceivedbyaddress), // deprecated, renamed to listreceivedbyaddress make_pair("getallreceived", &listreceivedbyaddress), // deprecated, renamed to listreceivedbyaddress
make_pair("getreceivedbyaddress", &getreceivedbyaddress), make_pair("getreceivedbyaddress", &getreceivedbyaddress),
@ -742,6 +751,17 @@ void ThreadRPCServer2(void* parg)
{ {
printf("ThreadRPCServer started\n"); printf("ThreadRPCServer started\n");
if (mapArgs.count("-rpcpw"))
strRPCPassword = mapArgs["-rpcpw"];
if (strRPCPassword == "")
{
#if defined(__WXMSW__) && wxUSE_GUI
MyMessageBox("Warning: rpc password is blank, use -rpcpw=<password>\n", "Bitcoin", wxOK | wxICON_EXCLAMATION);
#else
fprintf(stdout, "Warning: rpc password is blank, use -rpcpw=<password>\n");
#endif
}
// Bind to loopback 127.0.0.1 so the socket can only be accessed locally // Bind to loopback 127.0.0.1 so the socket can only be accessed locally
boost::asio::io_service io_service; boost::asio::io_service io_service;
tcp::endpoint endpoint(boost::asio::ip::address_v4::loopback(), 8332); tcp::endpoint endpoint(boost::asio::ip::address_v4::loopback(), 8332);
@ -764,7 +784,6 @@ void ThreadRPCServer2(void* parg)
// Receive request // Receive request
string strRequest = ReadHTTP(stream); string strRequest = ReadHTTP(stream);
printf("ThreadRPCServer request=%s", strRequest.c_str());
// Handle multiple invocations per request // Handle multiple invocations per request
string::iterator begin = strRequest.begin(); string::iterator begin = strRequest.begin();
@ -787,11 +806,25 @@ void ThreadRPCServer2(void* parg)
const Array& params = find_value(request, "params").get_array(); const Array& params = find_value(request, "params").get_array();
id = find_value(request, "id"); id = find_value(request, "id");
printf("ThreadRPCServer method=%s\n", strMethod.c_str());
// Check password
if (params.size() < 1 || params[0].type() != str_type)
throw runtime_error("First parameter must be the password.");
if (params[0].get_str() != strRPCPassword)
{
if (strRPCPassword.size() < 15)
Sleep(50);
begin = strRequest.end();
printf("ThreadRPCServer incorrect password attempt\n");
throw runtime_error("Incorrect password.");
}
// Execute // Execute
map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod); map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod);
if (mi == mapCallTable.end()) if (mi == mapCallTable.end())
throw runtime_error("Method not found."); throw runtime_error("Method not found.");
Value result = (*(*mi).second)(params, false); Value result = (*(*mi).second)(Array(params.begin()+1, params.end()), false);
// Send reply // Send reply
string strReply = JSONRPCReply(result, Value::null, id); string strReply = JSONRPCReply(result, Value::null, id);

2
serialize.h

@ -20,7 +20,7 @@ class CDataStream;
class CAutoFile; class CAutoFile;
static const int VERSION = 302; static const int VERSION = 302;
static const char* pszSubVer = ""; static const char* pszSubVer = ".2";

4
ui.cpp

@ -1132,7 +1132,7 @@ void CMainFrame::OnButtonNew(wxCommandEvent& event)
// Ask name // Ask name
CGetTextFromUserDialog dialog(this, CGetTextFromUserDialog dialog(this,
_("New Receiving Address"), _("New Receiving Address"),
_("It's good policy to use a new address for each payment you receive.\n\nLabel"), _("You should use a new address for each payment you receive.\n\nLabel"),
""); "");
if (!dialog.ShowModal()) if (!dialog.ShowModal())
return; return;
@ -2372,7 +2372,7 @@ void CAddressBookDialog::OnButtonNew(wxCommandEvent& event)
// Ask name // Ask name
CGetTextFromUserDialog dialog(this, CGetTextFromUserDialog dialog(this,
_("New Receiving Address"), _("New Receiving Address"),
_("It's good policy to use a new address for each payment you receive.\n\nLabel"), _("You should use a new address for each payment you receive.\n\nLabel"),
""); "");
if (!dialog.ShowModal()) if (!dialog.ShowModal())
return; return;

3
util.cpp

@ -701,12 +701,13 @@ void AddTimeData(unsigned int ip, int64 nTime)
sort(vTimeOffsets.begin(), vTimeOffsets.end()); sort(vTimeOffsets.begin(), vTimeOffsets.end());
int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2]; int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2];
nTimeOffset = nMedian; nTimeOffset = nMedian;
if ((nMedian > 0 ? nMedian : -nMedian) > 5 * 60) if ((nMedian > 0 ? nMedian : -nMedian) > 36 * 60 * 60)
{ {
// Only let other nodes change our clock so far before we // Only let other nodes change our clock so far before we
// go to the NTP servers // go to the NTP servers
/// todo: Get time from NTP servers, then set a flag /// todo: Get time from NTP servers, then set a flag
/// to make sure it doesn't get changed again /// to make sure it doesn't get changed again
nTimeOffset = 0;
} }
foreach(int64 n, vTimeOffsets) foreach(int64 n, vTimeOffsets)
printf("%+"PRI64d" ", n); printf("%+"PRI64d" ", n);

Loading…
Cancel
Save