Browse Source

Add support for JSON-format configuration file

Jeff Garzik 15 years ago
parent
commit
6d2882937f
3 changed files with 75 additions and 5 deletions
  1. 2 0
      Makefile.am
  2. 61 5
      cpu-miner.c
  3. 12 0
      example-cfg.json

+ 2 - 0
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)

+ 61 - 5
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);
 

+ 12 - 0
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
+}