Browse Source

Allow configuration file to include another recursively

Kano 14 years ago
parent
commit
915c72d8e7
2 changed files with 37 additions and 3 deletions
  1. 4 0
      README
  2. 33 3
      cgminer.c

+ 4 - 0
README

@@ -224,6 +224,10 @@ 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.
+
 
 
 Single pool, regular desktop:
 Single pool, regular desktop:
 
 

+ 33 - 3
cgminer.c

@@ -197,6 +197,13 @@ 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 char *include_conf = NULL;
+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 +857,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 +914,15 @@ 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)) {
+		if (include_conf == NULL)
+			include_conf = (char *)json_string_value(val);
+
+		return load_config(json_string_value(val), NULL);
+	}
+
 	return NULL;
 	return NULL;
 }
 }
 
 
@@ -912,14 +930,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
@@ -2449,10 +2477,12 @@ 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);
+	if (include_conf)
+		fprintf(fcfg, ",\n\"%s\" : \"%s\"", JSON_INCLUDE_CONF, include_conf);
 	fputs("\n}", fcfg);
 	fputs("\n}", fcfg);
 }
 }