Browse Source

Merge pull request #131 from kanoi/master

Allow configuration file to include another recursively
Con Kolivas 14 years ago
parent
commit
4dd6b649d5
2 changed files with 36 additions and 8 deletions
  1. 10 5
      README
  2. 26 3
      cgminer.c

+ 10 - 5
README

@@ -224,6 +224,11 @@ EXECUTIVE SUMMARY ON USAGE:
 After saving configuration from the menu, you do not need to give cgminer any
 After saving configuration from the menu, you do not need to give cgminer any
 arguments and it will load your configuration.
 arguments and it will load your configuration.
 
 
+Any configuration file may also contain a single
+	"include" : "filename"
+to recursively include another configuration file.
+Writing the configuration will save all settings from all files in the output.
+
 
 
 Single pool, regular desktop:
 Single pool, regular desktop:
 
 
@@ -543,10 +548,10 @@ network attached computer.
 
 
 You can only access the comands that reply with data in this mode.
 You can only access the comands that reply with data in this mode.
 By default, you cannot access any privileged command that affects the miner -
 By default, you cannot access any privileged command that affects the miner -
-you will receive an access denied status message see --api-access below.
+you will receive an access denied status message see --api-allow below.
 
 
 You can specify IP addresses/prefixes that are only allowed to access the API
 You can specify IP addresses/prefixes that are only allowed to access the API
-with the "--api-access" option e.g. --api-access W:192.168.0.1,10.0.0/24
+with the "--api-allow" option e.g. --api-allow W:192.168.0.1,10.0.0/24
 will allow 192.168.0.1 or any address matching 10.0.0.*, but nothing else
 will allow 192.168.0.1 or any address matching 10.0.0.*, but nothing else
 IP addresses are automatically padded with extra '.0's as needed
 IP addresses are automatically padded with extra '.0's as needed
 Without a /prefix is the same as specifying /32
 Without a /prefix is the same as specifying /32
@@ -555,11 +560,11 @@ The 'W:' on the front gives that address/subnet privileged access to commands
 that modify cgminer.
 that modify cgminer.
 Without it those commands return an access denied status.
 Without it those commands return an access denied status.
 Privileged access is checked in the order the IP addresses were supplied to
 Privileged access is checked in the order the IP addresses were supplied to
-"--api-access"
+"--api-allow"
 The first match determines the privilege level.
 The first match determines the privilege level.
-Using the "--api-access" option overides the "--api-network" option if they
+Using the "--api-allow" option overides the "--api-network" option if they
 are both specified
 are both specified
-With "--api-access", 127.0.0.1 is not by default given access unless specified
+With "--api-allow", 127.0.0.1 is not by default given access unless specified
 
 
 The RPC API request can be either simple text or JSON.
 The RPC API request can be either simple text or JSON.
 
 

+ 26 - 3
cgminer.c

@@ -197,6 +197,12 @@ char *opt_socks_proxy = NULL;
 
 
 static const char def_conf[] = "cgminer.conf";
 static const char def_conf[] = "cgminer.conf";
 static bool config_loaded = false;
 static bool config_loaded = false;
+static int include_count = 0;
+#define JSON_INCLUDE_CONF "include"
+#define JSON_LOAD_ERROR "JSON decode of file '%s' failed"
+#define JSON_LOAD_ERROR_LEN strlen(JSON_LOAD_ERROR)
+#define JSON_MAX_DEPTH 10
+#define JSON_MAX_DEPTH_ERR "Too many levels of JSON includes (limit 10) or a loop"
 
 
 #if defined(unix)
 #if defined(unix)
 	static char *opt_stderr_cmd = NULL;
 	static char *opt_stderr_cmd = NULL;
@@ -850,6 +856,8 @@ static struct opt_table opt_config_table[] = {
 	OPT_ENDTABLE
 	OPT_ENDTABLE
 };
 };
 
 
+static char *load_config(const char *arg, void __maybe_unused *unused);
+
 static char *parse_config(json_t *config, bool fileconf)
 static char *parse_config(json_t *config, bool fileconf)
 {
 {
 	static char err_buf[200];
 	static char err_buf[200];
@@ -905,6 +913,11 @@ static char *parse_config(json_t *config, bool fileconf)
 		}
 		}
 		free(name);
 		free(name);
 	}
 	}
+
+	val = json_object_get(config, JSON_INCLUDE_CONF);
+	if (val && json_is_string(val))
+		return load_config(json_string_value(val), NULL);
+
 	return NULL;
 	return NULL;
 }
 }
 
 
@@ -912,14 +925,24 @@ static char *load_config(const char *arg, void __maybe_unused *unused)
 {
 {
 	json_error_t err;
 	json_error_t err;
 	json_t *config;
 	json_t *config;
+	char *json_error;
+
+	if(++include_count > JSON_MAX_DEPTH)
+		return JSON_MAX_DEPTH_ERR;
 
 
 #if JANSSON_MAJOR_VERSION > 1
 #if JANSSON_MAJOR_VERSION > 1
 	config = json_load_file(arg, 0, &err);
 	config = json_load_file(arg, 0, &err);
 #else
 #else
 	config = json_load_file(arg, &err);
 	config = json_load_file(arg, &err);
 #endif
 #endif
-	if (!json_is_object(config))
-		return "JSON decode of file failed";
+	if (!json_is_object(config)) {
+		json_error = malloc(JSON_LOAD_ERROR_LEN + strlen(arg));
+		if (!json_error)
+			quit(1, "Malloc failure in json error");
+
+		sprintf(json_error, JSON_LOAD_ERROR, arg);
+		return json_error;
+	}
 
 
 	config_loaded = true;
 	config_loaded = true;
 	/* Parse the config now, so we can override it.  That can keep pointers
 	/* Parse the config now, so we can override it.  That can keep pointers
@@ -2451,7 +2474,7 @@ void write_config(FILE *fcfg)
 		for (i = 0; i < nDevs; i++)
 		for (i = 0; i < nDevs; i++)
 			if (gpus[i].deven != DEV_DISABLED)
 			if (gpus[i].deven != DEV_DISABLED)
 				fprintf(fcfg, ",\n\"device\" : \"%d\"", i);
 				fprintf(fcfg, ",\n\"device\" : \"%d\"", i);
-	if (opt_api_allow != NULL)
+	if (opt_api_allow)
 		fprintf(fcfg, ",\n\"api-allow\" : \"%s\"", opt_api_allow);
 		fprintf(fcfg, ",\n\"api-allow\" : \"%s\"", opt_api_allow);
 	if (strcmp(opt_api_description, PACKAGE_STRING) != 0)
 	if (strcmp(opt_api_description, PACKAGE_STRING) != 0)
 		fprintf(fcfg, ",\n\"api-description\" : \"%s\"", opt_api_description);
 		fprintf(fcfg, ",\n\"api-description\" : \"%s\"", opt_api_description);