allow url based config files
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
diff --git a/cgminer.c b/cgminer.c
index 902b0bf..6497067 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -363,6 +363,7 @@ static int include_count;
#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"
+#define JSON_WEB_ERROR "WEB config err"
#if defined(unix) || defined(__APPLE__)
static char *opt_stderr_cmd = NULL;
@@ -1648,6 +1649,33 @@ static char *parse_config(json_t *config, bool fileconf)
char *cnfbuf = NULL;
+char conf_web1[] = "http://";
+char conf_web2[] = "https://";
+
+static char *load_web_config(const char *arg)
+{
+ json_t *val;
+ CURL *curl;
+
+ curl = curl_easy_init();
+ if (unlikely(!curl))
+ quithere(1, "CURL initialisation failed");
+
+ val = json_web_config(curl, arg);
+
+ curl_easy_cleanup(curl);
+
+ if (!val || !json_is_object(val))
+ return JSON_WEB_ERROR;
+
+ if (!cnfbuf)
+ cnfbuf = strdup(arg);
+
+ config_loaded = true;
+
+ return parse_config(val, true);
+}
+
static char *load_config(const char *arg, void __maybe_unused *unused)
{
json_error_t err;
@@ -1655,6 +1683,12 @@ static char *load_config(const char *arg, void __maybe_unused *unused)
char *json_error;
size_t siz;
+#ifdef HAVE_LIBCURL
+ if (strncasecmp(arg, conf_web1, sizeof(conf_web1)-1) == 0 ||
+ strncasecmp(arg, conf_web2, sizeof(conf_web2)-1) == 0)
+ return load_web_config(arg);
+#endif
+
if (!cnfbuf)
cnfbuf = strdup(arg);
diff --git a/miner.h b/miner.h
index 1910fe8..1d79c0e 100644
--- a/miner.h
+++ b/miner.h
@@ -1027,6 +1027,7 @@ extern pthread_rwlock_t netacc_lock;
extern const uint32_t sha256_init_state[];
#ifdef HAVE_LIBCURL
+extern json_t *json_web_config(CURL *curl, const char *url);
extern json_t *json_rpc_call(CURL *curl, const char *url, const char *userpass,
const char *rpc_req, bool, bool, int *,
struct pool *pool, bool);
diff --git a/util.c b/util.c
index f6a3ecb..921aa75 100644
--- a/util.c
+++ b/util.c
@@ -296,6 +296,60 @@ static int curl_debug_cb(__maybe_unused CURL *handle, curl_infotype type,
return 0;
}
+json_t *json_web_config(CURL *curl, const char *url)
+{
+ struct data_buffer all_data = {NULL, 0};
+ char curl_err_str[CURL_ERROR_SIZE];
+ json_error_t err;
+ long timeout = 60;
+ json_t *val;
+ int rc;
+
+ memset(&err, 0, sizeof(err));
+
+ /* it is assumed that 'curl' is freshly [re]initialized at this pt */
+
+ curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
+
+ curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ curl_easy_setopt(curl, CURLOPT_ENCODING, "");
+ curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
+
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, all_data_cb);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &all_data);
+ curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_err_str);
+ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
+ curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_TRY);
+
+ val = NULL;
+ rc = curl_easy_perform(curl);
+ if (rc) {
+ applog(LOG_ERR, "HTTP config request of '%s' failed: %s",
+ url, curl_err_str);
+ goto c_out;
+ }
+
+ if (!all_data.buf) {
+ applog(LOG_ERR, "Empty config data received from '%s'",
+ url);
+ goto c_out;
+ }
+
+ val = JSON_LOADS(all_data.buf, &err);
+ if (!val) {
+ applog(LOG_ERR, "JSON config decode of '%s' failed(%d): %s",
+ url, err.line, err.text);
+ goto c_out;
+ }
+
+c_out:
+ databuf_free(&all_data);
+ curl_easy_reset(curl);
+ curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1);
+ return val;
+}
+
json_t *json_rpc_call(CURL *curl, const char *url,
const char *userpass, const char *rpc_req,
bool probe, bool longpoll, int *rolltime,