diff --git a/configuration.c b/configuration.c index d2284eb1..af44c4fe 100644 --- a/configuration.c +++ b/configuration.c @@ -7,8 +7,48 @@ * your option) any later version. See COPYING for more details. */ +/* TODO: four-space whitespace */ + #include "configuration.h" +/* Used in config parsing, e.g. pool array. */ +static int json_array_index = -1; + +static int total_urls; + +static const char def_conf[] = "sgminer.conf"; +static char *default_config; +static int include_count; + +static struct pool *add_url(void) +{ + total_urls++; + if (total_urls > total_pools) + add_pool(); + return pools[total_urls - 1]; +} + +static void setup_url(struct pool *pool, char *arg) +{ + arg = get_proxy(arg, pool); + + if (detect_stratum(pool, arg)) + return; + + opt_set_charp(arg, &pool->rpc_url); + if (strncmp(arg, "http://", 7) && + strncmp(arg, "https://", 8)) { + char *httpinput; + + httpinput = (char *)malloc(255); + if (!httpinput) + quit(1, "Failed to malloc httpinput"); + strcpy(httpinput, "http://"); + strncat(httpinput, arg, 248); + pool->rpc_url = httpinput; + } +} + char *load_config(const char *arg, void __maybe_unused *unused) { json_error_t err; @@ -120,6 +160,273 @@ char *parse_config(json_t *config, bool fileconf, int parent_iteration) return NULL; } +/* add a mutex if this needs to be thread safe in the future */ +static struct JE { + char *buf; + struct JE *next; +} *jedata = NULL; + +static void json_escape_free() +{ + struct JE *jeptr = jedata; + struct JE *jenext; + + jedata = NULL; + + while (jeptr) { + jenext = jeptr->next; + free(jeptr->buf); + free(jeptr); + jeptr = jenext; + } +} + +static char *json_escape(char *str) +{ + struct JE *jeptr; + char *buf, *ptr; + + /* 2x is the max, may as well just allocate that */ + ptr = buf = (char *)malloc(strlen(str) * 2 + 1); + + jeptr = (struct JE *)malloc(sizeof(*jeptr)); + + jeptr->buf = buf; + jeptr->next = jedata; + jedata = jeptr; + + while (*str) { + if (*str == '\\' || *str == '"') + *(ptr++) = '\\'; + + *(ptr++) = *(str++); + } + + *ptr = '\0'; + + return buf; +} + +void write_config(FILE *fcfg) +{ + int i; + + /* Write pool values */ + fputs("{\n\"pools\" : [", fcfg); + for(i = 0; i < total_pools; i++) { + struct pool *pool = pools[i]; + + /* Using get_pool_name() here is unsafe if opt_incognito is true. */ + if (strcmp(pool->name, "") != 0) { + fprintf(fcfg, "\n\t\t\"name\" : \"%s\",", json_escape(pool->name)); + } + if (strcmp(pool->description, "") != 0) { + fprintf(fcfg, "\n\t\t\"description\" : \"%s\",", json_escape(pool->description)); + } + if (pool->quota != 1) { + fprintf(fcfg, "%s\n\t{\n\t\t\"quota\" : \"%s%s%s%d;%s\",", i > 0 ? "," : "", + pool->rpc_proxy ? json_escape((char *)proxytype(pool->rpc_proxytype)) : "", + pool->rpc_proxy ? json_escape(pool->rpc_proxy) : "", + pool->rpc_proxy ? "|" : "", + pool->quota, + json_escape(pool->rpc_url)); + } else { + fprintf(fcfg, "%s\n\t{\n\t\t\"url\" : \"%s%s%s%s\",", i > 0 ? "," : "", + pool->rpc_proxy ? json_escape((char *)proxytype(pool->rpc_proxytype)) : "", + pool->rpc_proxy ? json_escape(pool->rpc_proxy) : "", + pool->rpc_proxy ? "|" : "", + json_escape(pool->rpc_url)); + } + fprintf(fcfg, "\n\t\t\"user\" : \"%s\",", json_escape(pool->rpc_user)); + fprintf(fcfg, "\n\t\t\"pass\" : \"%s\"\n\t}", json_escape(pool->rpc_pass)); + } + fputs("\n]\n", fcfg); + + /* Write only if there are usable GPUs */ + if (nDevs) { + fputs(",\n\"intensity\" : \"", fcfg); + for(i = 0; i < nDevs; i++) + fprintf(fcfg, gpus[i].dynamic ? "%sd" : "%s%d", i > 0 ? "," : "", gpus[i].intensity); + + fputs("\",\n\"xintensity\" : \"", fcfg); + for(i = 0; i < nDevs; i++) + fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].xintensity); + + fputs("\",\n\"rawintensity\" : \"", fcfg); + for(i = 0; i < nDevs; i++) + fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].rawintensity); + + /* All current kernels only support vector=1 */ + /* fputs("\",\n\"vectors\" : \"", fcfg); */ + /* for(i = 0; i < nDevs; i++) */ + /* fprintf(fcfg, "%s%d", i > 0 ? "," : "", */ + /* gpus[i].vwidth); */ + + fputs("\",\n\"worksize\" : \"", fcfg); + for(i = 0; i < nDevs; i++) + fprintf(fcfg, "%s%d", i > 0 ? "," : "", + (int)gpus[i].work_size); + + fputs("\",\n\"kernel\" : \"", fcfg); + for(i = 0; i < nDevs; i++) { + fprintf(fcfg, "%s", i > 0 ? "," : ""); + fprintf(fcfg, "%s", gpus[i].kernelname); + } + + fputs("\",\n\"lookup-gap\" : \"", fcfg); + for(i = 0; i < nDevs; i++) + fprintf(fcfg, "%s%d", i > 0 ? "," : "", + (int)gpus[i].opt_lg); + + fputs("\",\n\"thread-concurrency\" : \"", fcfg); + for(i = 0; i < nDevs; i++) + fprintf(fcfg, "%s%d", i > 0 ? "," : "", + (int)gpus[i].opt_tc); + + fputs("\",\n\"shaders\" : \"", fcfg); + for(i = 0; i < nDevs; i++) + fprintf(fcfg, "%s%d", i > 0 ? "," : "", + (int)gpus[i].shaders); + + fputs("\",\n\"gpu-threads\" : \"", fcfg); + for(i = 0; i < nDevs; i++) + fprintf(fcfg, "%s%d", i > 0 ? "," : "", + (int)gpus[i].threads); + +#ifdef HAVE_ADL + fputs("\",\n\"gpu-engine\" : \"", fcfg); + for(i = 0; i < nDevs; i++) + fprintf(fcfg, "%s%d-%d", i > 0 ? "," : "", gpus[i].min_engine, gpus[i].gpu_engine); + + fputs("\",\n\"gpu-fan\" : \"", fcfg); + for(i = 0; i < nDevs; i++) + fprintf(fcfg, "%s%d-%d", i > 0 ? "," : "", gpus[i].min_fan, gpus[i].gpu_fan); + + fputs("\",\n\"gpu-memclock\" : \"", fcfg); + for(i = 0; i < nDevs; i++) + fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].gpu_memclock); + + fputs("\",\n\"gpu-memdiff\" : \"", fcfg); + for(i = 0; i < nDevs; i++) + fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].gpu_memdiff); + + fputs("\",\n\"gpu-powertune\" : \"", fcfg); + for(i = 0; i < nDevs; i++) + fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].gpu_powertune); + + fputs("\",\n\"gpu-vddc\" : \"", fcfg); + for(i = 0; i < nDevs; i++) + fprintf(fcfg, "%s%1.3f", i > 0 ? "," : "", gpus[i].gpu_vddc); + + fputs("\",\n\"temp-cutoff\" : \"", fcfg); + for(i = 0; i < nDevs; i++) + fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].cutofftemp); + + fputs("\",\n\"temp-overheat\" : \"", fcfg); + for(i = 0; i < nDevs; i++) + fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].adl.overtemp); + + fputs("\",\n\"temp-target\" : \"", fcfg); + for(i = 0; i < nDevs; i++) + fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].adl.targettemp); +#endif + + fputs("\"", fcfg); + } +#ifdef HAVE_ADL + if (opt_reorder) + fprintf(fcfg, ",\n\"gpu-reorder\" : true"); +#endif + + /* Simple bool and int options */ + struct opt_table *opt; + for (opt = opt_config_table; opt->type != OPT_END; opt++) { + char *p, *name = strdup(opt->names); + for (p = strtok(name, "|"); p; p = strtok(NULL, "|")) { + if (p[1] != '-') + continue; + if (opt->type & OPT_NOARG && + ((void *)opt->cb == (void *)opt_set_bool || (void *)opt->cb == (void *)opt_set_invbool) && + (*(bool *)opt->u.arg == ((void *)opt->cb == (void *)opt_set_bool))) + fprintf(fcfg, ",\n\"%s\" : true", p+2); + + if (opt->type & OPT_HASARG && + ((void *)opt->cb_arg == (void *)set_int_0_to_9999 || + (void *)opt->cb_arg == (void *)set_int_1_to_65535 || + (void *)opt->cb_arg == (void *)set_int_0_to_10 || + (void *)opt->cb_arg == (void *)set_int_1_to_10) && opt->desc != opt_hidden) + fprintf(fcfg, ",\n\"%s\" : \"%d\"", p+2, *(int *)opt->u.arg); + } + } + + /* Special case options */ + fprintf(fcfg, ",\n\"shares\" : \"%d\"", opt_shares); + if (pool_strategy == POOL_BALANCE) + fputs(",\n\"balance\" : true", fcfg); + if (pool_strategy == POOL_LOADBALANCE) + fputs(",\n\"load-balance\" : true", fcfg); + if (pool_strategy == POOL_ROUNDROBIN) + fputs(",\n\"round-robin\" : true", fcfg); + if (pool_strategy == POOL_ROTATE) + fprintf(fcfg, ",\n\"rotate\" : \"%d\"", opt_rotate_period); +#if defined(unix) || defined(__APPLE__) + if (opt_stderr_cmd && *opt_stderr_cmd) + fprintf(fcfg, ",\n\"monitor\" : \"%s\"", json_escape(opt_stderr_cmd)); +#endif // defined(unix) + if (opt_kernel_path && *opt_kernel_path) { + char *kpath = strdup(opt_kernel_path); + if (kpath[strlen(kpath)-1] == '/') + kpath[strlen(kpath)-1] = 0; + fprintf(fcfg, ",\n\"kernel-path\" : \"%s\"", json_escape(kpath)); + } + if (schedstart.enable) + fprintf(fcfg, ",\n\"sched-time\" : \"%d:%d\"", schedstart.tm.tm_hour, schedstart.tm.tm_min); + if (schedstop.enable) + fprintf(fcfg, ",\n\"stop-time\" : \"%d:%d\"", schedstop.tm.tm_hour, schedstop.tm.tm_min); + if (opt_socks_proxy && *opt_socks_proxy) + fprintf(fcfg, ",\n\"socks-proxy\" : \"%s\"", json_escape(opt_socks_proxy)); + if (opt_devs_enabled) { + fprintf(fcfg, ",\n\"device\" : \""); + bool extra_devs = false; + + for (i = 0; i < MAX_DEVICES; i++) { + if (devices_enabled[i]) { + int startd = i; + + if (extra_devs) + fprintf(fcfg, ","); + while (i < MAX_DEVICES && devices_enabled[i + 1]) + ++i; + fprintf(fcfg, "%d", startd); + if (i > startd) + fprintf(fcfg, "-%d", i); + } + } + fprintf(fcfg, "\""); + } + if (opt_removedisabled) + fprintf(fcfg, ",\n\"remove-disabled\" : true"); + if (strcmp(opt_algorithm->name, "scrypt") != 0) + fprintf(fcfg, ",\n\"algorithm\" : \"%s\"", json_escape(opt_algorithm->name)); + if (opt_api_allow) + fprintf(fcfg, ",\n\"api-allow\" : \"%s\"", json_escape(opt_api_allow)); + if (strcmp(opt_api_mcast_addr, API_MCAST_ADDR) != 0) + fprintf(fcfg, ",\n\"api-mcast-addr\" : \"%s\"", json_escape(opt_api_mcast_addr)); + if (strcmp(opt_api_mcast_code, API_MCAST_CODE) != 0) + fprintf(fcfg, ",\n\"api-mcast-code\" : \"%s\"", json_escape(opt_api_mcast_code)); + if (*opt_api_mcast_des) + fprintf(fcfg, ",\n\"api-mcast-des\" : \"%s\"", json_escape(opt_api_mcast_des)); + if (strcmp(opt_api_description, PACKAGE_STRING) != 0) + fprintf(fcfg, ",\n\"api-description\" : \"%s\"", json_escape(opt_api_description)); + if (opt_api_groups) + fprintf(fcfg, ",\n\"api-groups\" : \"%s\"", json_escape(opt_api_groups)); + + fputs("\n}\n", fcfg); + + json_escape_free(); +} + + char *set_default_config(const char *arg) { opt_set_charp(arg, &default_config); @@ -235,8 +542,6 @@ char *set_null(const char __maybe_unused *arg) return NULL; } -static char *temp_cutoff_str = NULL; - char *set_temp_cutoff(char *arg) { int val; @@ -563,6 +868,23 @@ char *enable_debug(bool *flag) return NULL; } +extern const char *opt_argv0; + +static char *opt_verusage_and_exit(const char *extra) +{ + printf("%s\n", packagename); + printf("%s", opt_usage(opt_argv0, extra)); + fflush(stdout); + exit(0); +} + +char *display_devs(int *ndevs) +{ + *ndevs = 0; + print_ndevs(ndevs); + exit(*ndevs); +} + /* These options are available from config file or commandline */ static struct opt_table opt_config_table[] = { OPT_WITH_ARG("--algorithm", @@ -894,26 +1216,8 @@ static struct opt_table opt_config_table[] = { OPT_ENDTABLE }; - -extern const char *opt_argv0; - -static char *opt_verusage_and_exit(const char *extra) -{ - printf("%s\n", packagename); - printf("%s", opt_usage(opt_argv0, extra)); - fflush(stdout); - exit(0); -} - -char *display_devs(int *ndevs) -{ - *ndevs = 0; - print_ndevs(ndevs); - exit(*ndevs); -} - /* These options are available from commandline only */ -static struct opt_table opt_cmdline_table[] = { +struct opt_table opt_cmdline_table[] = { OPT_WITH_ARG("--config|-c", load_config, NULL, NULL, "Load a JSON-format configuration file\n" diff --git a/configuration.h b/configuration.h index df4d8f5a..52dd4772 100644 --- a/configuration.h +++ b/configuration.h @@ -4,9 +4,22 @@ /* autoconf-generated definitions. */ #include "config.h" +#include +#include + /* Configuration file buffer. */ char *cnfbuf = NULL; +bool config_loaded; + +#define JSON_INCLUDE_CONF "include" +#define JSON_LOAD_ERROR "JSON decode of file '%s' failed\n %s" +#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" + +static char *temp_cutoff_str = NULL; + static int fileconf_load; char *opt_api_allow = NULL; @@ -33,7 +46,9 @@ bool opt_protocol; bool opt_compact; bool opt_incognito; +int opt_dynamic_interval = 7; const int opt_cutofftemp = 95; + int opt_log_interval = 5; int opt_queue = 1; int opt_scantime = 7; @@ -45,8 +60,18 @@ bool opt_delaynet; bool opt_disable_pool; bool opt_disable_client_reconnect = false; +struct schedtime { + bool enable; + struct tm tm; +}; + +struct schedtime schedstart; +struct schedtime schedstop; +bool sched_paused; + bool opt_fail_only; int opt_fail_switch_delay = 60; + static bool opt_fix_protocol; static bool opt_lowmem; @@ -58,8 +83,13 @@ char *opt_socks_proxy = NULL; char *opt_kernel_path; +/* TODO: see which of these have to be exposed, remove others from header + * and declare static in code. + */ + char *load_config(const char *arg, void __maybe_unused *unused); char *parse_config(json_t *config, bool fileconf, int parent_iteration); +void write_config(FILE *fcfg); char *set_default_config(const char *arg); @@ -117,4 +147,7 @@ char *set_quota(char *arg); char *enable_debug(bool *flag); +struct opt_table opt_config_table[]; +struct opt_table opt_cmdline_table[]; + #endif /* CONFIGURATION_H */ diff --git a/miner.c b/miner.c index a31dafe2..1b2ed1fe 100644 --- a/miner.c +++ b/miner.c @@ -38,8 +38,6 @@ #include #include #endif -#include -#include #ifdef HAVE_LIBCURL #include #else @@ -94,7 +92,6 @@ unsigned long global_quota_gcd = 1; time_t last_getwork; int nDevs; -int opt_dynamic_interval = 7; int opt_g_threads = -1; int gpu_threads; bool opt_restart = true; @@ -196,10 +193,6 @@ static struct pool *currentpool = NULL; int total_pools, enabled_pools; enum pool_strategy pool_strategy = POOL_FAILOVER; int opt_rotate_period; -static int total_urls; - -/* Used in config parsing, e.g. pool array. */ -static int json_array_index = -1; static #ifndef HAVE_CURSES @@ -244,16 +237,6 @@ struct stratum_share { static struct stratum_share *stratum_shares = NULL; -static const char def_conf[] = "sgminer.conf"; -static char *default_config; -static bool config_loaded; -static int include_count; -#define JSON_INCLUDE_CONF "include" -#define JSON_LOAD_ERROR "JSON decode of file '%s' failed\n %s" -#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) || defined(__APPLE__) static char *opt_stderr_cmd = NULL; static int forkpid; @@ -268,15 +251,6 @@ struct thread_q *getq; static int total_work; struct work *staged_work = NULL; -struct schedtime { - bool enable; - struct tm tm; -}; - -struct schedtime schedstart; -struct schedtime schedstop; -bool sched_paused; - static bool time_before(struct tm *tm1, struct tm *tm2) { if (tm1->tm_hour < tm2->tm_hour) @@ -583,35 +557,6 @@ bool detect_stratum(struct pool *pool, char *url) return false; } -static struct pool *add_url(void) -{ - total_urls++; - if (total_urls > total_pools) - add_pool(); - return pools[total_urls - 1]; -} - -static void setup_url(struct pool *pool, char *arg) -{ - arg = get_proxy(arg, pool); - - if (detect_stratum(pool, arg)) - return; - - opt_set_charp(arg, &pool->rpc_url); - if (strncmp(arg, "http://", 7) && - strncmp(arg, "https://", 8)) { - char *httpinput; - - httpinput = (char *)malloc(255); - if (!httpinput) - quit(1, "Failed to malloc httpinput"); - strcpy(httpinput, "http://"); - strncat(httpinput, arg, 248); - pool->rpc_url = httpinput; - } -} - static void enable_pool(struct pool *pool) { if (pool->state != POOL_ENABLED) @@ -3243,272 +3188,6 @@ static void display_pool_summary(struct pool *pool) } #endif -/* add a mutex if this needs to be thread safe in the future */ -static struct JE { - char *buf; - struct JE *next; -} *jedata = NULL; - -static void json_escape_free() -{ - struct JE *jeptr = jedata; - struct JE *jenext; - - jedata = NULL; - - while (jeptr) { - jenext = jeptr->next; - free(jeptr->buf); - free(jeptr); - jeptr = jenext; - } -} - -static char *json_escape(char *str) -{ - struct JE *jeptr; - char *buf, *ptr; - - /* 2x is the max, may as well just allocate that */ - ptr = buf = (char *)malloc(strlen(str) * 2 + 1); - - jeptr = (struct JE *)malloc(sizeof(*jeptr)); - - jeptr->buf = buf; - jeptr->next = jedata; - jedata = jeptr; - - while (*str) { - if (*str == '\\' || *str == '"') - *(ptr++) = '\\'; - - *(ptr++) = *(str++); - } - - *ptr = '\0'; - - return buf; -} - -void write_config(FILE *fcfg) -{ - int i; - - /* Write pool values */ - fputs("{\n\"pools\" : [", fcfg); - for(i = 0; i < total_pools; i++) { - struct pool *pool = pools[i]; - - /* Using get_pool_name() here is unsafe if opt_incognito is true. */ - if (strcmp(pool->name, "") != 0) { - fprintf(fcfg, "\n\t\t\"name\" : \"%s\",", json_escape(pool->name)); - } - if (strcmp(pool->description, "") != 0) { - fprintf(fcfg, "\n\t\t\"description\" : \"%s\",", json_escape(pool->description)); - } - if (pool->quota != 1) { - fprintf(fcfg, "%s\n\t{\n\t\t\"quota\" : \"%s%s%s%d;%s\",", i > 0 ? "," : "", - pool->rpc_proxy ? json_escape((char *)proxytype(pool->rpc_proxytype)) : "", - pool->rpc_proxy ? json_escape(pool->rpc_proxy) : "", - pool->rpc_proxy ? "|" : "", - pool->quota, - json_escape(pool->rpc_url)); - } else { - fprintf(fcfg, "%s\n\t{\n\t\t\"url\" : \"%s%s%s%s\",", i > 0 ? "," : "", - pool->rpc_proxy ? json_escape((char *)proxytype(pool->rpc_proxytype)) : "", - pool->rpc_proxy ? json_escape(pool->rpc_proxy) : "", - pool->rpc_proxy ? "|" : "", - json_escape(pool->rpc_url)); - } - fprintf(fcfg, "\n\t\t\"user\" : \"%s\",", json_escape(pool->rpc_user)); - fprintf(fcfg, "\n\t\t\"pass\" : \"%s\"\n\t}", json_escape(pool->rpc_pass)); - } - fputs("\n]\n", fcfg); - - /* Write only if there are usable GPUs */ - if (nDevs) { - fputs(",\n\"intensity\" : \"", fcfg); - for(i = 0; i < nDevs; i++) - fprintf(fcfg, gpus[i].dynamic ? "%sd" : "%s%d", i > 0 ? "," : "", gpus[i].intensity); - - fputs("\",\n\"xintensity\" : \"", fcfg); - for(i = 0; i < nDevs; i++) - fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].xintensity); - - fputs("\",\n\"rawintensity\" : \"", fcfg); - for(i = 0; i < nDevs; i++) - fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].rawintensity); - - /* All current kernels only support vector=1 */ - /* fputs("\",\n\"vectors\" : \"", fcfg); */ - /* for(i = 0; i < nDevs; i++) */ - /* fprintf(fcfg, "%s%d", i > 0 ? "," : "", */ - /* gpus[i].vwidth); */ - - fputs("\",\n\"worksize\" : \"", fcfg); - for(i = 0; i < nDevs; i++) - fprintf(fcfg, "%s%d", i > 0 ? "," : "", - (int)gpus[i].work_size); - - fputs("\",\n\"kernel\" : \"", fcfg); - for(i = 0; i < nDevs; i++) { - fprintf(fcfg, "%s", i > 0 ? "," : ""); - fprintf(fcfg, "%s", gpus[i].kernelname); - } - - fputs("\",\n\"lookup-gap\" : \"", fcfg); - for(i = 0; i < nDevs; i++) - fprintf(fcfg, "%s%d", i > 0 ? "," : "", - (int)gpus[i].opt_lg); - - fputs("\",\n\"thread-concurrency\" : \"", fcfg); - for(i = 0; i < nDevs; i++) - fprintf(fcfg, "%s%d", i > 0 ? "," : "", - (int)gpus[i].opt_tc); - - fputs("\",\n\"shaders\" : \"", fcfg); - for(i = 0; i < nDevs; i++) - fprintf(fcfg, "%s%d", i > 0 ? "," : "", - (int)gpus[i].shaders); - - fputs("\",\n\"gpu-threads\" : \"", fcfg); - for(i = 0; i < nDevs; i++) - fprintf(fcfg, "%s%d", i > 0 ? "," : "", - (int)gpus[i].threads); - -#ifdef HAVE_ADL - fputs("\",\n\"gpu-engine\" : \"", fcfg); - for(i = 0; i < nDevs; i++) - fprintf(fcfg, "%s%d-%d", i > 0 ? "," : "", gpus[i].min_engine, gpus[i].gpu_engine); - - fputs("\",\n\"gpu-fan\" : \"", fcfg); - for(i = 0; i < nDevs; i++) - fprintf(fcfg, "%s%d-%d", i > 0 ? "," : "", gpus[i].min_fan, gpus[i].gpu_fan); - - fputs("\",\n\"gpu-memclock\" : \"", fcfg); - for(i = 0; i < nDevs; i++) - fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].gpu_memclock); - - fputs("\",\n\"gpu-memdiff\" : \"", fcfg); - for(i = 0; i < nDevs; i++) - fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].gpu_memdiff); - - fputs("\",\n\"gpu-powertune\" : \"", fcfg); - for(i = 0; i < nDevs; i++) - fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].gpu_powertune); - - fputs("\",\n\"gpu-vddc\" : \"", fcfg); - for(i = 0; i < nDevs; i++) - fprintf(fcfg, "%s%1.3f", i > 0 ? "," : "", gpus[i].gpu_vddc); - - fputs("\",\n\"temp-cutoff\" : \"", fcfg); - for(i = 0; i < nDevs; i++) - fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].cutofftemp); - - fputs("\",\n\"temp-overheat\" : \"", fcfg); - for(i = 0; i < nDevs; i++) - fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].adl.overtemp); - - fputs("\",\n\"temp-target\" : \"", fcfg); - for(i = 0; i < nDevs; i++) - fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].adl.targettemp); -#endif - - fputs("\"", fcfg); - } -#ifdef HAVE_ADL - if (opt_reorder) - fprintf(fcfg, ",\n\"gpu-reorder\" : true"); -#endif - - /* Simple bool and int options */ - struct opt_table *opt; - for (opt = opt_config_table; opt->type != OPT_END; opt++) { - char *p, *name = strdup(opt->names); - for (p = strtok(name, "|"); p; p = strtok(NULL, "|")) { - if (p[1] != '-') - continue; - if (opt->type & OPT_NOARG && - ((void *)opt->cb == (void *)opt_set_bool || (void *)opt->cb == (void *)opt_set_invbool) && - (*(bool *)opt->u.arg == ((void *)opt->cb == (void *)opt_set_bool))) - fprintf(fcfg, ",\n\"%s\" : true", p+2); - - if (opt->type & OPT_HASARG && - ((void *)opt->cb_arg == (void *)set_int_0_to_9999 || - (void *)opt->cb_arg == (void *)set_int_1_to_65535 || - (void *)opt->cb_arg == (void *)set_int_0_to_10 || - (void *)opt->cb_arg == (void *)set_int_1_to_10) && opt->desc != opt_hidden) - fprintf(fcfg, ",\n\"%s\" : \"%d\"", p+2, *(int *)opt->u.arg); - } - } - - /* Special case options */ - fprintf(fcfg, ",\n\"shares\" : \"%d\"", opt_shares); - if (pool_strategy == POOL_BALANCE) - fputs(",\n\"balance\" : true", fcfg); - if (pool_strategy == POOL_LOADBALANCE) - fputs(",\n\"load-balance\" : true", fcfg); - if (pool_strategy == POOL_ROUNDROBIN) - fputs(",\n\"round-robin\" : true", fcfg); - if (pool_strategy == POOL_ROTATE) - fprintf(fcfg, ",\n\"rotate\" : \"%d\"", opt_rotate_period); -#if defined(unix) || defined(__APPLE__) - if (opt_stderr_cmd && *opt_stderr_cmd) - fprintf(fcfg, ",\n\"monitor\" : \"%s\"", json_escape(opt_stderr_cmd)); -#endif // defined(unix) - if (opt_kernel_path && *opt_kernel_path) { - char *kpath = strdup(opt_kernel_path); - if (kpath[strlen(kpath)-1] == '/') - kpath[strlen(kpath)-1] = 0; - fprintf(fcfg, ",\n\"kernel-path\" : \"%s\"", json_escape(kpath)); - } - if (schedstart.enable) - fprintf(fcfg, ",\n\"sched-time\" : \"%d:%d\"", schedstart.tm.tm_hour, schedstart.tm.tm_min); - if (schedstop.enable) - fprintf(fcfg, ",\n\"stop-time\" : \"%d:%d\"", schedstop.tm.tm_hour, schedstop.tm.tm_min); - if (opt_socks_proxy && *opt_socks_proxy) - fprintf(fcfg, ",\n\"socks-proxy\" : \"%s\"", json_escape(opt_socks_proxy)); - if (opt_devs_enabled) { - fprintf(fcfg, ",\n\"device\" : \""); - bool extra_devs = false; - - for (i = 0; i < MAX_DEVICES; i++) { - if (devices_enabled[i]) { - int startd = i; - - if (extra_devs) - fprintf(fcfg, ","); - while (i < MAX_DEVICES && devices_enabled[i + 1]) - ++i; - fprintf(fcfg, "%d", startd); - if (i > startd) - fprintf(fcfg, "-%d", i); - } - } - fprintf(fcfg, "\""); - } - if (opt_removedisabled) - fprintf(fcfg, ",\n\"remove-disabled\" : true"); - if (strcmp(opt_algorithm->name, "scrypt") != 0) - fprintf(fcfg, ",\n\"algorithm\" : \"%s\"", json_escape(opt_algorithm->name)); - if (opt_api_allow) - fprintf(fcfg, ",\n\"api-allow\" : \"%s\"", json_escape(opt_api_allow)); - if (strcmp(opt_api_mcast_addr, API_MCAST_ADDR) != 0) - fprintf(fcfg, ",\n\"api-mcast-addr\" : \"%s\"", json_escape(opt_api_mcast_addr)); - if (strcmp(opt_api_mcast_code, API_MCAST_CODE) != 0) - fprintf(fcfg, ",\n\"api-mcast-code\" : \"%s\"", json_escape(opt_api_mcast_code)); - if (*opt_api_mcast_des) - fprintf(fcfg, ",\n\"api-mcast-des\" : \"%s\"", json_escape(opt_api_mcast_des)); - if (strcmp(opt_api_description, PACKAGE_STRING) != 0) - fprintf(fcfg, ",\n\"api-description\" : \"%s\"", json_escape(opt_api_description)); - if (opt_api_groups) - fprintf(fcfg, ",\n\"api-groups\" : \"%s\"", json_escape(opt_api_groups)); - - fputs("\n}\n", fcfg); - - json_escape_free(); -} - void zero_bestshare(void) { int i;