Add support for JSON-format configuration file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
diff --git a/Makefile.am b/Makefile.am
index 5c84e75..3cf7c00 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,6 +5,8 @@ else
JANSSON_INCLUDES=
endif
+EXTRA_DIST = example-cfg.json
+
SUBDIRS = compat
INCLUDES = $(PTHREAD_FLAGS) -fno-strict-aliasing $(JANSSON_INCLUDES)
diff --git a/cpu-miner.c b/cpu-miner.c
index e78c48f..3486b20 100644
--- a/cpu-miner.c
+++ b/cpu-miner.c
@@ -59,11 +59,12 @@ static bool opt_quiet = false;
static int opt_retries = 10;
static int opt_fail_pause = 30;
static int opt_scantime = 5;
+static json_t *opt_config;
static const bool opt_time = true;
static enum sha256_algos opt_algo = ALGO_C;
static int opt_n_threads = 1;
-static char *rpc_url = DEF_RPC_URL;
-static char *userpass = DEF_RPC_USERPASS;
+static char *rpc_url;
+static char *userpass;
struct option_help {
@@ -75,6 +76,10 @@ static struct option_help options_help[] = {
{ "help",
"(-h) Display this help text" },
+ { "config FILE",
+ "(-c FILE) JSON-format configuration file (default: none)\n"
+ "See example-cfg.json for an example configuration." },
+
{ "algo XXX",
"(-a XXX) Specify sha256 implementation:\n"
"\tc\t\tLinux kernel sha256, implemented in C (default)"
@@ -126,6 +131,7 @@ static struct option_help options_help[] = {
static struct option options[] = {
{ "help", 0, NULL, 'h' },
{ "algo", 1, NULL, 'a' },
+ { "config", 1, NULL, 'c' },
{ "quiet", 0, NULL, 'q' },
{ "debug", 0, NULL, 'D' },
{ "protocol-dump", 0, NULL, 'P' },
@@ -419,6 +425,17 @@ static void parse_arg (int key, char *arg)
if (i == ARRAY_SIZE(algo_names))
show_usage();
break;
+ case 'c': {
+ json_error_t err;
+ if (opt_config)
+ json_decref(opt_config);
+ opt_config = json_load_file(arg, &err);
+ if (!json_is_object(opt_config)) {
+ fprintf(stderr, "JSON decode of %s failed\n", arg);
+ show_usage();
+ }
+ break;
+ }
case 'q':
opt_quiet = true;
break;
@@ -461,30 +478,66 @@ static void parse_arg (int key, char *arg)
strncmp(arg, "https://", 8))
show_usage();
- rpc_url = arg;
+ free(rpc_url);
+ rpc_url = strdup(arg);
break;
case 1002: /* --userpass */
if (!strchr(arg, ':'))
show_usage();
- userpass = arg;
+ free(userpass);
+ userpass = strdup(arg);
break;
default:
show_usage();
}
}
+static void parse_config(void)
+{
+ int i;
+ json_t *val;
+
+ if (!json_is_object(opt_config))
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(options); i++) {
+ if (!options[i].name)
+ break;
+ if (!strcmp(options[i].name, "config"))
+ continue;
+
+ val = json_object_get(opt_config, options[i].name);
+ if (!val)
+ continue;
+
+ if (options[i].has_arg && json_is_string(val)) {
+ char *s = strdup(json_string_value(val));
+ if (!s)
+ break;
+ parse_arg(options[i].val, s);
+ free(s);
+ } else if (!options[i].has_arg && json_is_true(val))
+ parse_arg(options[i].val, "");
+ else
+ fprintf(stderr, "JSON option %s invalid\n",
+ options[i].name);
+ }
+}
+
static void parse_cmdline(int argc, char *argv[])
{
int key;
while (1) {
- key = getopt_long(argc, argv, "a:qDPr:s:t:h?", options, NULL);
+ key = getopt_long(argc, argv, "a:c:qDPr:s:t:h?", options, NULL);
if (key < 0)
break;
parse_arg(key, optarg);
}
+
+ parse_config();
}
int main (int argc, char *argv[])
@@ -492,6 +545,9 @@ int main (int argc, char *argv[])
int i;
pthread_t *t_all;
+ rpc_url = strdup(DEF_RPC_URL);
+ userpass = strdup(DEF_RPC_USERPASS);
+
/* parse command line */
parse_cmdline(argc, argv);
diff --git a/example-cfg.json b/example-cfg.json
new file mode 100644
index 0000000..9742bb5
--- /dev/null
+++ b/example-cfg.json
@@ -0,0 +1,12 @@
+{
+ "_comment" : "Any command line argument may be used in this file",
+
+ "url" : "http://127.0.0.1:8332",
+ "userpass" : "rpcuser:rpcpass",
+
+ "algo" : "4way",
+ "threads" : "4",
+
+ "quiet" : true,
+ "debug" : true
+}