From e6a72b2f781b2fbe37b8aa462fd39f204df06338 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 31 Jul 2017 16:05:16 +0300 Subject: [PATCH] #46 Added config file support. --- src/Options.cpp | 329 +++++++++++++++++++++++++++++++++------------ src/Options.h | 10 +- src/config.json | 25 ++++ src/net/Client.cpp | 4 + src/version.h | 4 +- 5 files changed, 283 insertions(+), 89 deletions(-) create mode 100644 src/config.json diff --git a/src/Options.cpp b/src/Options.cpp index 15c7750f..c1d2b505 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -113,6 +113,36 @@ static struct option const options[] = { }; +static struct option const config_options[] = { + { "algo", 1, nullptr, 'a' }, + { "av", 1, nullptr, 'v' }, + { "background", 0, nullptr, 'B' }, + { "cpu-affinity", 1, nullptr, 1020 }, + { "donate-level", 1, nullptr, 1003 }, + { "log-file", 1, nullptr, 'l' }, + { "max-cpu-usage", 1, nullptr, 1004 }, + { "print-time", 1, nullptr, 1007 }, + { "retries", 1, nullptr, 'r' }, + { "retry-pause", 1, nullptr, 'R' }, + { "safe", 0, nullptr, 1005 }, + { "syslog", 0, nullptr, 'S' }, + { "threads", 1, nullptr, 't' }, + { "colors", 0, nullptr, 2000 }, + { 0, 0, 0, 0 } +}; + + +static struct option const pool_options[] = { + { "url", 1, nullptr, 'o' }, + { "pass", 1, nullptr, 'p' }, + { "user", 1, nullptr, 'u' }, + { "userpass", 1, nullptr, 'O' }, + { "keepalive", 0, nullptr ,'k' }, + { "nicehash", 0, nullptr, 1006 }, + { 0, 0, 0, 0 } +}; + + static const char *algo_names[] = { "cryptonight", # ifndef XMRIG_NO_AEON @@ -204,11 +234,8 @@ Options::~Options() } -bool Options::parseArg(int key, char *arg) +bool Options::parseArg(int key, const char *arg) { - char *p; - int v; - switch (key) { case 'a': /* --algo */ if (!setAlgo(arg)) { @@ -216,13 +243,6 @@ bool Options::parseArg(int key, char *arg) } break; - case 'O': /* --userpass */ - if (!m_pools.back()->setUserpass(arg)) { - return false; - } - - break; - case 'o': /* --url */ if (m_pools.size() > 1 || m_pools[0]->isValid()) { Url *url = new Url(arg); @@ -240,7 +260,12 @@ bool Options::parseArg(int key, char *arg) if (!m_pools.back()->isValid()) { return false; } + break; + case 'O': /* --userpass */ + if (!m_pools.back()->setUserpass(arg)) { + return false; + } break; case 'u': /* --user */ @@ -258,52 +283,22 @@ bool Options::parseArg(int key, char *arg) break; case 'r': /* --retries */ - v = strtol(arg, nullptr, 10); - if (v < 1 || v > 1000) { - showUsage(1); - return false; - } - - m_retries = v; - break; + return parseArg(key, strtol(arg, nullptr, 10)); case 'R': /* --retry-pause */ - v = strtol(arg, nullptr, 10); - if (v < 1 || v > 3600) { - showUsage(1); - return false; - } - - m_retryPause = v; - break; + return parseArg(key, strtol(arg, nullptr, 10)); case 't': /* --threads */ - v = strtol(arg, nullptr, 10); - if (v < 1 || v > 1024) { - showUsage(1); - return false; - } - - m_threads = v; - break; + return parseArg(key, strtol(arg, nullptr, 10)); case 1004: /* --max-cpu-usage */ - v = strtol(arg, nullptr, 10); - if (v < 1 || v > 100) { - showUsage(1); - return false; - } - - m_maxCpuUsage = v; - break; + return parseArg(key, strtol(arg, nullptr, 10)); case 1005: /* --safe */ - m_safe = true; - break; + return parseBoolean(key, true); case 'k': /* --keepalive */ - m_pools.back()->setKeepAlive(true); - break; + return parseBoolean(key, true); case 'V': /* --version */ showVersion(); @@ -313,58 +308,35 @@ bool Options::parseArg(int key, char *arg) showUsage(0); return false; - case 'B': /* --background */ - m_background = true; - m_colors = false; + case 'c': /* --config */ + parseConfig(arg); break; + case 'B': /* --background */ + return parseBoolean(key, true); + case 'S': /* --syslog */ - m_syslog = true; - m_colors = false; - break; + return parseBoolean(key, true); case 'v': /* --av */ - v = strtol(arg, nullptr, 10); - if (v < 0 || v > 1000) { - showUsage(1); - return false; - } - - m_algoVariant = v; - break; - - case 1020: /* --cpu-affinity */ - p = strstr(arg, "0x"); - m_affinity = p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10); - break; + return parseArg(key, strtol(arg, nullptr, 10)); case 1002: /* --no-color */ - m_colors = false; - break; + return parseBoolean(key, false); case 1003: /* --donate-level */ - v = strtol(arg, nullptr, 10); - if (v < 1 || v > 99) { - showUsage(1); - return false; - } - - m_donateLevel = v; - break; + return parseArg(key, strtol(arg, nullptr, 10)); case 1006: /* --nicehash */ - m_pools.back()->setNicehash(true); - break; + return parseBoolean(key, true); case 1007: /* --print-time */ - v = strtol(arg, nullptr, 10); - if (v < 0 || v > 1000) { - showUsage(1); - return false; - } + return parseArg(key, strtol(arg, nullptr, 10)); - m_printTime = v; - break; + case 1020: { /* --cpu-affinity */ + const char *p = strstr(arg, "0x"); + return parseArg(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10)); + } default: showUsage(1); @@ -375,6 +347,127 @@ bool Options::parseArg(int key, char *arg) } +bool Options::parseArg(int key, uint64_t arg) +{ + switch (key) { + case 'r': /* --retries */ + if (arg < 1 || arg > 1000) { + showUsage(1); + return false; + } + + m_retries = arg; + break; + + case 'R': /* --retry-pause */ + if (arg < 1 || arg > 3600) { + showUsage(1); + return false; + } + + m_retryPause = arg; + break; + + case 't': /* --threads */ + if (arg < 1 || arg > 1024) { + showUsage(1); + return false; + } + + m_threads = arg; + break; + + case 'v': /* --av */ + if (arg > 1000) { + showUsage(1); + return false; + } + + m_algoVariant = arg; + break; + + case 1003: /* --donate-level */ + if (arg < 1 || arg > 99) { + showUsage(1); + return false; + } + + m_donateLevel = arg; + break; + + case 1004: /* --max-cpu-usage */ + if (arg < 1 || arg > 100) { + showUsage(1); + return false; + } + + m_maxCpuUsage = arg; + break; + + case 1007: /* --print-time */ + if (arg > 1000) { + showUsage(1); + return false; + } + + m_printTime = arg; + break; + + case 1020: /* --cpu-affinity */ + if (arg) { + m_affinity = arg; + } + break; + + default: + break; + } + + return true; +} + + +bool Options::parseBoolean(int key, bool enable) +{ + switch (key) { + case 'k': /* --keepalive */ + m_pools.back()->setKeepAlive(enable); + break; + + case 'B': /* --background */ + m_background = enable; + m_colors = enable ? false : m_colors; + break; + + case 'S': /* --syslog */ + m_syslog = enable; + m_colors = enable ? false : m_colors; + break; + + case 1002: /* --no-color */ + m_colors = enable; + break; + + case 1005: /* --safe */ + m_safe = enable; + break; + + case 1006: /* --nicehash */ + m_pools.back()->setNicehash(enable); + break; + + case 2000: /* colors */ + m_colors = enable; + break; + + default: + break; + } + + return true; +} + + Url *Options::parseUrl(const char *arg) const { auto url = new Url(arg); @@ -387,6 +480,72 @@ Url *Options::parseUrl(const char *arg) const } +void Options::parseConfig(const char *fileName) +{ + json_error_t err; + json_t *config = json_load_file(fileName, 0, &err); + + if (!json_is_object(config)) { + if (config) { + json_decref(config); + return; + } + + if (err.line < 0) { + fprintf(stderr, "%s\n", err.text); + } + else { + fprintf(stderr, "%s:%d: %s\n", fileName, err.line, err.text); + } + + return; + } + + for (size_t i = 0; i < ARRAY_SIZE(config_options); i++) { + parseJSON(&config_options[i], config); + } + + json_t *pools = json_object_get(config, "pools"); + if (json_is_array(pools)) { + size_t index; + json_t *value; + + json_array_foreach(pools, index, value) { + if (json_is_object(value)) { + for (size_t i = 0; i < ARRAY_SIZE(pool_options); i++) { + parseJSON(&pool_options[i], value); + } + } + } + } + + json_decref(config); +} + + +void Options::parseJSON(const struct option *option, json_t *object) +{ + if (!option->name) { + return; + } + + json_t *val = json_object_get(object, option->name); + if (!val) { + return; + } + + if (option->has_arg && json_is_string(val)) { + parseArg(option->val, json_string_value(val)); + } + else if (option->has_arg && json_is_integer(val)) { + parseArg(option->val, json_integer_value(val)); + } + else if (!option->has_arg && json_is_boolean(val)) { + parseBoolean(option->val, json_is_true(val)); + } +} + + void Options::showUsage(int status) const { if (status) { diff --git a/src/Options.h b/src/Options.h index cefca538..0b41f5c4 100644 --- a/src/Options.h +++ b/src/Options.h @@ -25,11 +25,13 @@ #define __OPTIONS_H__ -#include +#include #include +#include class Url; +struct option; class Options @@ -76,8 +78,12 @@ private: static Options *m_self; - bool parseArg(int key, char *arg); + bool parseArg(int key, const char *arg); + bool parseArg(int key, uint64_t arg); + bool parseBoolean(int key, bool enable); Url *parseUrl(const char *arg) const; + void parseConfig(const char *fileName); + void parseJSON(const struct option *option, json_t *object); void showUsage(int status) const; void showVersion(void); diff --git a/src/config.json b/src/config.json new file mode 100644 index 00000000..faa10dd1 --- /dev/null +++ b/src/config.json @@ -0,0 +1,25 @@ +{ + "algo": "cryptonight", + "av": 0, + "background": false, + "colors": true, + "cpu-affinity": null, + "donate-level": 5, + "log-file": null, + "max-cpu-usage": 75, + "print-time": 60, + "retries": 5, + "retry-pause": 5, + "safe": false, + "syslog": false, + "threads": 4, + "pools": [ + { + "url": "pool.minemonero.pro", + "user": "", + "pass": "x", + "keepalive": true, + "nicehash": false + } + ] +} \ No newline at end of file diff --git a/src/net/Client.cpp b/src/net/Client.cpp index 001415c8..bc44c7dd 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -529,6 +529,10 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) return client->close();; } + if ((size_t) nread > (kRecvBufSize - 8 - client->m_recvBufPos)) { + return client->close();; + } + client->m_recvBufPos += nread; char* end; diff --git a/src/version.h b/src/version.h index 6875f7f9..08bd362b 100644 --- a/src/version.h +++ b/src/version.h @@ -27,13 +27,13 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "Monero (XMR) CPU miner" -#define APP_VERSION "2.1.0" +#define APP_VERSION "2.2.0-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2017 xmrig.com" #define APP_VER_MAJOR 2 -#define APP_VER_MINOR 1 +#define APP_VER_MINOR 2 #define APP_VER_BUILD 0 #define APP_VER_REV 0