From 6f8d38ee11bf5afc9e097fe960ff12cc86c1f9d5 Mon Sep 17 00:00:00 2001 From: ystarnaud Date: Tue, 1 Jul 2014 00:51:54 -0400 Subject: [PATCH] Remote config files Config parser can now read config files stored remotely via https/http/ftp. Requires libcurl. --- config_parser.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/config_parser.c b/config_parser.c index 0d5c1bd4..1ddf952b 100644 --- a/config_parser.c +++ b/config_parser.c @@ -52,6 +52,10 @@ #include #endif +#ifdef HAVE_LIBCURL +#include +#endif + char *cnfbuf = NULL; //config file loaded int fileconf_load; //config file load status const char def_conf[] = "sgminer.conf"; @@ -490,6 +494,82 @@ static struct opt_table *opt_find(struct opt_table *tbl, char *optname) return NULL; } +/************************************** + * Remote Config Functions (Curl Only) + **************************************/ +#ifdef HAVE_LIBCURL + struct remote_config { + const char *filename; + FILE *stream; + }; + + //curl file data write callback + static size_t fetch_remote_config_cb(void *buffer, size_t size, size_t nmemb, void *stream) + { + struct remote_config *out = (struct remote_config *)stream; + + //create file if not created + if(out && !out->stream) + { + if(!(out->stream = fopen(out->filename, "w+"))) + return -1; + } + + return fwrite(buffer, size, nmemb, out->stream); + } + + //download remote config file - return filename on success or NULL on failure + static char *fetch_remote_config(const char *url) + { + CURL *curl; + CURLcode res; + char *p; + struct remote_config file = { "", NULL }; + + //get filename out of url + if((p = strrchr(url, '/')) == NULL) + { + applog(LOG_ERR, "Fetch remote file failed: Invalid URL"); + return NULL; + } + + file.filename = p+1; + + //check for empty filename + if(file.filename[0] == '\0') + { + applog(LOG_ERR, "Fetch remote file failed: Invalid Filename"); + return NULL; + } + + //init curl + if((curl = curl_easy_init()) == NULL) + { + applog(LOG_ERR, "Fetch remote file failed: curl init failed."); + return NULL; + } + + //https stuff - skip verification we just want the data + if(strstr(url, "https") != NULL) + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + + //set url + curl_easy_setopt(curl, CURLOPT_URL, url); + //set write callback and fileinfo + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fetch_remote_config_cb); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &file); + + if((res = curl_easy_perform(curl)) != CURLE_OK) + applog(LOG_ERR, "Fetch remote file failed: %s", curl_easy_strerror(res)); + + if(file.stream) + fclose(file.stream); + + curl_easy_cleanup(curl); + + return (char *)((res == CURLE_OK)?file.filename:NULL); + } +#endif /*************************************** * Config Parsing Functions @@ -633,6 +713,16 @@ char *load_config(const char *arg, const char *parentkey, void __maybe_unused *u json_error_t err; json_t *config; + #ifdef HAVE_LIBCURL + //if detected as url + if((strstr(arg, "http://") != NULL) || (strstr(arg, "https://") != NULL) || (strstr(arg, "ftp://") != NULL)) + { + //download config file locally and reset arg to it so we can parse it + if((arg = fetch_remote_config(arg)) == NULL) + return NULL; + } + #endif + //most likely useless but leaving it here for now... if(!cnfbuf) cnfbuf = strdup(arg);