mirror of
https://github.com/GOSTSec/sgminer
synced 2025-01-08 22:08:02 +00:00
Updated API functionality
Fixed addpool to specify a profile or algorithm and sets defaults if nothing specified. Also added a new API function to change multipool strategy. Conflicts (resolved): sgminer.c
This commit is contained in:
parent
4c3352b8a0
commit
832ac82bf6
@ -32,7 +32,7 @@ sgminer_CPPFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
sgminer_SOURCES := sgminer.c
|
sgminer_SOURCES := sgminer.c
|
||||||
sgminer_SOURCES += api.c
|
sgminer_SOURCES += api.c api.h
|
||||||
sgminer_SOURCES += elist.h miner.h compat.h bench_block.h
|
sgminer_SOURCES += elist.h miner.h compat.h bench_block.h
|
||||||
sgminer_SOURCES += util.c util.h uthash.h
|
sgminer_SOURCES += util.c util.h uthash.h
|
||||||
sgminer_SOURCES += logging.c logging.h
|
sgminer_SOURCES += logging.c logging.h
|
||||||
|
548
api.c
548
api.c
@ -26,6 +26,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
#include "api.h"
|
||||||
#include "miner.h"
|
#include "miner.h"
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@ -33,72 +34,9 @@
|
|||||||
|
|
||||||
#include "config_parser.h"
|
#include "config_parser.h"
|
||||||
|
|
||||||
// BUFSIZ varies on Windows and Linux
|
#ifdef WIN32
|
||||||
#define TMPBUFSIZ 8192
|
|
||||||
|
|
||||||
// Number of requests to queue - normally would be small
|
|
||||||
#define QUEUE 100
|
|
||||||
|
|
||||||
#if defined WIN32
|
|
||||||
static char WSAbuf[1024];
|
static char WSAbuf[1024];
|
||||||
|
|
||||||
struct WSAERRORS {
|
|
||||||
int id;
|
|
||||||
char *code;
|
|
||||||
} WSAErrors[] = {
|
|
||||||
{ 0, "No error" },
|
|
||||||
{ WSAEINTR, "Interrupted system call" },
|
|
||||||
{ WSAEBADF, "Bad file number" },
|
|
||||||
{ WSAEACCES, "Permission denied" },
|
|
||||||
{ WSAEFAULT, "Bad address" },
|
|
||||||
{ WSAEINVAL, "Invalid argument" },
|
|
||||||
{ WSAEMFILE, "Too many open sockets" },
|
|
||||||
{ WSAEWOULDBLOCK, "Operation would block" },
|
|
||||||
{ WSAEINPROGRESS, "Operation now in progress" },
|
|
||||||
{ WSAEALREADY, "Operation already in progress" },
|
|
||||||
{ WSAENOTSOCK, "Socket operation on non-socket" },
|
|
||||||
{ WSAEDESTADDRREQ, "Destination address required" },
|
|
||||||
{ WSAEMSGSIZE, "Message too long" },
|
|
||||||
{ WSAEPROTOTYPE, "Protocol wrong type for socket" },
|
|
||||||
{ WSAENOPROTOOPT, "Bad protocol option" },
|
|
||||||
{ WSAEPROTONOSUPPORT, "Protocol not supported" },
|
|
||||||
{ WSAESOCKTNOSUPPORT, "Socket type not supported" },
|
|
||||||
{ WSAEOPNOTSUPP, "Operation not supported on socket" },
|
|
||||||
{ WSAEPFNOSUPPORT, "Protocol family not supported" },
|
|
||||||
{ WSAEAFNOSUPPORT, "Address family not supported" },
|
|
||||||
{ WSAEADDRINUSE, "Address already in use" },
|
|
||||||
{ WSAEADDRNOTAVAIL, "Can't assign requested address" },
|
|
||||||
{ WSAENETDOWN, "Network is down" },
|
|
||||||
{ WSAENETUNREACH, "Network is unreachable" },
|
|
||||||
{ WSAENETRESET, "Net connection reset" },
|
|
||||||
{ WSAECONNABORTED, "Software caused connection abort" },
|
|
||||||
{ WSAECONNRESET, "Connection reset by peer" },
|
|
||||||
{ WSAENOBUFS, "No buffer space available" },
|
|
||||||
{ WSAEISCONN, "Socket is already connected" },
|
|
||||||
{ WSAENOTCONN, "Socket is not connected" },
|
|
||||||
{ WSAESHUTDOWN, "Can't send after socket shutdown" },
|
|
||||||
{ WSAETOOMANYREFS, "Too many references, can't splice" },
|
|
||||||
{ WSAETIMEDOUT, "Connection timed out" },
|
|
||||||
{ WSAECONNREFUSED, "Connection refused" },
|
|
||||||
{ WSAELOOP, "Too many levels of symbolic links" },
|
|
||||||
{ WSAENAMETOOLONG, "File name too long" },
|
|
||||||
{ WSAEHOSTDOWN, "Host is down" },
|
|
||||||
{ WSAEHOSTUNREACH, "No route to host" },
|
|
||||||
{ WSAENOTEMPTY, "Directory not empty" },
|
|
||||||
{ WSAEPROCLIM, "Too many processes" },
|
|
||||||
{ WSAEUSERS, "Too many users" },
|
|
||||||
{ WSAEDQUOT, "Disc quota exceeded" },
|
|
||||||
{ WSAESTALE, "Stale NFS file handle" },
|
|
||||||
{ WSAEREMOTE, "Too many levels of remote in path" },
|
|
||||||
{ WSASYSNOTREADY, "Network system is unavailable" },
|
|
||||||
{ WSAVERNOTSUPPORTED, "Winsock version out of range" },
|
|
||||||
{ WSANOTINITIALISED, "WSAStartup not yet called" },
|
|
||||||
{ WSAEDISCON, "Graceful shutdown in progress" },
|
|
||||||
{ WSAHOST_NOT_FOUND, "Host not found" },
|
|
||||||
{ WSANO_DATA, "No host data of that type was found" },
|
|
||||||
{ -1, "Unknown error code" }
|
|
||||||
};
|
|
||||||
|
|
||||||
char *WSAErrorMsg(void) {
|
char *WSAErrorMsg(void) {
|
||||||
int i;
|
int i;
|
||||||
int id = WSAGetLastError();
|
int id = WSAGetLastError();
|
||||||
@ -114,21 +52,15 @@ char *WSAErrorMsg(void) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static const char *UNAVAILABLE = " - API will not be available";
|
static const char *UNAVAILABLE = " - API will not be available";
|
||||||
static const char *MUNAVAILABLE = " - API multicast listener will not be available";
|
static const char *MUNAVAILABLE = " - API multicast listener will not be available";
|
||||||
|
|
||||||
static const char *BLANK = "";
|
static const char *BLANK = "";
|
||||||
static const char *COMMA = ",";
|
static const char *COMMA = ",";
|
||||||
#define COMSTR ","
|
|
||||||
static const char SEPARATOR = '|';
|
static const char SEPARATOR = '|';
|
||||||
#define SEPSTR "|"
|
|
||||||
static const char GPUSEP = ',';
|
static const char GPUSEP = ',';
|
||||||
|
static const char *APIVERSION = "4.0";
|
||||||
#define CMDJOIN '+'
|
|
||||||
#define JOIN_CMD "CMD="
|
|
||||||
#define BETWEEN_JOIN SEPSTR
|
|
||||||
|
|
||||||
static const char *APIVERSION = "3.2";
|
|
||||||
static const char *DEAD = "Dead";
|
static const char *DEAD = "Dead";
|
||||||
static const char *SICK = "Sick";
|
static const char *SICK = "Sick";
|
||||||
static const char *NOSTART = "NoStart";
|
static const char *NOSTART = "NoStart";
|
||||||
@ -137,7 +69,6 @@ static const char *DISABLED = "Disabled";
|
|||||||
static const char *ALIVE = "Alive";
|
static const char *ALIVE = "Alive";
|
||||||
static const char *REJECTING = "Rejecting";
|
static const char *REJECTING = "Rejecting";
|
||||||
static const char *UNKNOWN = "Unknown";
|
static const char *UNKNOWN = "Unknown";
|
||||||
#define _DYNAMIC "D"
|
|
||||||
static const char *DYNAMIC = _DYNAMIC;
|
static const char *DYNAMIC = _DYNAMIC;
|
||||||
|
|
||||||
static __maybe_unused const char *NONE = "None";
|
static __maybe_unused const char *NONE = "None";
|
||||||
@ -166,270 +97,9 @@ static const char *OSINFO =
|
|||||||
"Unknown";
|
"Unknown";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define _DEVS "DEVS"
|
|
||||||
#define _POOLS "POOLS"
|
|
||||||
#define _SUMMARY "SUMMARY"
|
|
||||||
#define _STATUS "STATUS"
|
|
||||||
#define _VERSION "VERSION"
|
|
||||||
#define _MINECONFIG "CONFIG"
|
|
||||||
#define _GPU "GPU"
|
|
||||||
|
|
||||||
#define _GPUS "GPUS"
|
|
||||||
#define _NOTIFY "NOTIFY"
|
|
||||||
#define _DEVDETAILS "DEVDETAILS"
|
|
||||||
#define _BYE "BYE"
|
|
||||||
#define _RESTART "RESTART"
|
|
||||||
#define _MINESTATS "STATS"
|
|
||||||
#define _CHECK "CHECK"
|
|
||||||
#define _MINECOIN "COIN"
|
|
||||||
#define _DEBUGSET "DEBUG"
|
|
||||||
#define _SETCONFIG "SETCONFIG"
|
|
||||||
|
|
||||||
static const char ISJSON = '{';
|
|
||||||
#define JSON0 "{"
|
|
||||||
#define JSON1 "\""
|
|
||||||
#define JSON2 "\":["
|
|
||||||
#define JSON3 "]"
|
|
||||||
#define JSON4 ",\"id\":1"
|
|
||||||
// If anyone cares, id=0 for truncated output
|
|
||||||
#define JSON4_TRUNCATED ",\"id\":0"
|
|
||||||
#define JSON5 "}"
|
|
||||||
|
|
||||||
#define JSON_START JSON0
|
|
||||||
#define JSON_DEVS JSON1 _DEVS JSON2
|
|
||||||
#define JSON_POOLS JSON1 _POOLS JSON2
|
|
||||||
#define JSON_SUMMARY JSON1 _SUMMARY JSON2
|
|
||||||
#define JSON_STATUS JSON1 _STATUS JSON2
|
|
||||||
#define JSON_VERSION JSON1 _VERSION JSON2
|
|
||||||
#define JSON_MINECONFIG JSON1 _MINECONFIG JSON2
|
|
||||||
#define JSON_GPU JSON1 _GPU JSON2
|
|
||||||
|
|
||||||
#define JSON_GPUS JSON1 _GPUS JSON2
|
|
||||||
#define JSON_NOTIFY JSON1 _NOTIFY JSON2
|
|
||||||
#define JSON_DEVDETAILS JSON1 _DEVDETAILS JSON2
|
|
||||||
#define JSON_CLOSE JSON3
|
|
||||||
#define JSON_MINESTATS JSON1 _MINESTATS JSON2
|
|
||||||
#define JSON_CHECK JSON1 _CHECK JSON2
|
|
||||||
#define JSON_MINECOIN JSON1 _MINECOIN JSON2
|
|
||||||
#define JSON_DEBUGSET JSON1 _DEBUGSET JSON2
|
|
||||||
#define JSON_SETCONFIG JSON1 _SETCONFIG JSON2
|
|
||||||
|
|
||||||
#define JSON_END JSON4 JSON5
|
|
||||||
#define JSON_END_TRUNCATED JSON4_TRUNCATED JSON5
|
|
||||||
#define JSON_BETWEEN_JOIN ","
|
|
||||||
|
|
||||||
static const char *JSON_COMMAND = "command";
|
static const char *JSON_COMMAND = "command";
|
||||||
static const char *JSON_PARAMETER = "parameter";
|
static const char *JSON_PARAMETER = "parameter";
|
||||||
|
static const char ISJSON = '{';
|
||||||
#define MSG_INVGPU 1
|
|
||||||
#define MSG_ALRENA 2
|
|
||||||
#define MSG_ALRDIS 3
|
|
||||||
#define MSG_GPUMRE 4
|
|
||||||
#define MSG_GPUREN 5
|
|
||||||
#define MSG_GPUNON 6
|
|
||||||
#define MSG_POOL 7
|
|
||||||
#define MSG_NOPOOL 8
|
|
||||||
#define MSG_DEVS 9
|
|
||||||
#define MSG_NODEVS 10
|
|
||||||
#define MSG_SUMM 11
|
|
||||||
#define MSG_GPUDIS 12
|
|
||||||
#define MSG_GPUREI 13
|
|
||||||
#define MSG_INVCMD 14
|
|
||||||
#define MSG_MISID 15
|
|
||||||
#define MSG_GPUDEV 17
|
|
||||||
|
|
||||||
#define MSG_NUMGPU 20
|
|
||||||
|
|
||||||
#define MSG_VERSION 22
|
|
||||||
#define MSG_INVJSON 23
|
|
||||||
#define MSG_MISCMD 24
|
|
||||||
#define MSG_MISPID 25
|
|
||||||
#define MSG_INVPID 26
|
|
||||||
#define MSG_SWITCHP 27
|
|
||||||
#define MSG_MISVAL 28
|
|
||||||
#define MSG_NOADL 29
|
|
||||||
#define MSG_NOGPUADL 30
|
|
||||||
#define MSG_INVINT 31
|
|
||||||
#define MSG_GPUINT 32
|
|
||||||
#define MSG_MINECONFIG 33
|
|
||||||
#define MSG_GPUMERR 34
|
|
||||||
#define MSG_GPUMEM 35
|
|
||||||
#define MSG_GPUEERR 36
|
|
||||||
#define MSG_GPUENG 37
|
|
||||||
#define MSG_GPUVERR 38
|
|
||||||
#define MSG_GPUVDDC 39
|
|
||||||
#define MSG_GPUFERR 40
|
|
||||||
#define MSG_GPUFAN 41
|
|
||||||
#define MSG_MISFN 42
|
|
||||||
#define MSG_BADFN 43
|
|
||||||
#define MSG_SAVED 44
|
|
||||||
#define MSG_ACCDENY 45
|
|
||||||
#define MSG_ACCOK 46
|
|
||||||
#define MSG_ENAPOOL 47
|
|
||||||
#define MSG_DISPOOL 48
|
|
||||||
#define MSG_ALRENAP 49
|
|
||||||
#define MSG_ALRDISP 50
|
|
||||||
#define MSG_MISPDP 52
|
|
||||||
#define MSG_INVPDP 53
|
|
||||||
#define MSG_TOOMANYP 54
|
|
||||||
#define MSG_ADDPOOL 55
|
|
||||||
|
|
||||||
#define MSG_NOTIFY 60
|
|
||||||
|
|
||||||
#define MSG_REMLASTP 66
|
|
||||||
#define MSG_ACTPOOL 67
|
|
||||||
#define MSG_REMPOOL 68
|
|
||||||
#define MSG_DEVDETAILS 69
|
|
||||||
#define MSG_MINESTATS 70
|
|
||||||
#define MSG_MISCHK 71
|
|
||||||
#define MSG_CHECK 72
|
|
||||||
#define MSG_POOLPRIO 73
|
|
||||||
#define MSG_DUPPID 74
|
|
||||||
#define MSG_MISBOOL 75
|
|
||||||
#define MSG_INVBOOL 76
|
|
||||||
#define MSG_FOO 77
|
|
||||||
#define MSG_MINECOIN 78
|
|
||||||
#define MSG_DEBUGSET 79
|
|
||||||
#define MSG_SETCONFIG 82
|
|
||||||
#define MSG_UNKCON 83
|
|
||||||
#define MSG_INVNUM 84
|
|
||||||
#define MSG_CONPAR 85
|
|
||||||
#define MSG_CONVAL 86
|
|
||||||
|
|
||||||
#define MSG_NOUSTA 88
|
|
||||||
|
|
||||||
#define MSG_ZERMIS 94
|
|
||||||
#define MSG_ZERINV 95
|
|
||||||
#define MSG_ZERSUM 96
|
|
||||||
#define MSG_ZERNOSUM 97
|
|
||||||
|
|
||||||
#define MSG_BYE 0x101
|
|
||||||
|
|
||||||
#define MSG_INVNEG 121
|
|
||||||
#define MSG_SETQUOTA 122
|
|
||||||
#define MSG_LOCKOK 123
|
|
||||||
#define MSG_LOCKDIS 124
|
|
||||||
|
|
||||||
enum code_severity {
|
|
||||||
SEVERITY_ERR,
|
|
||||||
SEVERITY_WARN,
|
|
||||||
SEVERITY_INFO,
|
|
||||||
SEVERITY_SUCC,
|
|
||||||
SEVERITY_FAIL
|
|
||||||
};
|
|
||||||
|
|
||||||
enum code_parameters {
|
|
||||||
PARAM_GPU,
|
|
||||||
PARAM_PID,
|
|
||||||
PARAM_GPUMAX,
|
|
||||||
PARAM_PMAX,
|
|
||||||
PARAM_POOLMAX,
|
|
||||||
|
|
||||||
// Single generic case: have the code resolve it - see below
|
|
||||||
PARAM_DMAX,
|
|
||||||
|
|
||||||
PARAM_CMD,
|
|
||||||
PARAM_POOL,
|
|
||||||
PARAM_STR,
|
|
||||||
PARAM_BOTH,
|
|
||||||
PARAM_BOOL,
|
|
||||||
PARAM_SET,
|
|
||||||
PARAM_INT,
|
|
||||||
PARAM_NONE
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CODES {
|
|
||||||
const enum code_severity severity;
|
|
||||||
const int code;
|
|
||||||
const enum code_parameters params;
|
|
||||||
const char *description;
|
|
||||||
} codes[] = {
|
|
||||||
{ SEVERITY_ERR, MSG_INVGPU, PARAM_GPUMAX, "Invalid GPU id %d - range is 0 - %d" },
|
|
||||||
{ SEVERITY_INFO, MSG_ALRENA, PARAM_GPU, "GPU %d already enabled" },
|
|
||||||
{ SEVERITY_INFO, MSG_ALRDIS, PARAM_GPU, "GPU %d already disabled" },
|
|
||||||
{ SEVERITY_WARN, MSG_GPUMRE, PARAM_GPU, "GPU %d must be restarted first" },
|
|
||||||
{ SEVERITY_INFO, MSG_GPUREN, PARAM_GPU, "GPU %d sent enable message" },
|
|
||||||
{ SEVERITY_ERR, MSG_GPUNON, PARAM_NONE, "No GPUs" },
|
|
||||||
{ SEVERITY_SUCC, MSG_POOL, PARAM_PMAX, "%d Pool(s)" },
|
|
||||||
{ SEVERITY_ERR, MSG_NOPOOL, PARAM_NONE, "No pools" },
|
|
||||||
|
|
||||||
{ SEVERITY_SUCC, MSG_DEVS, PARAM_DMAX, "%d GPU(s)" },
|
|
||||||
{ SEVERITY_ERR, MSG_NODEVS, PARAM_NONE, "No GPUs"
|
|
||||||
},
|
|
||||||
|
|
||||||
{ SEVERITY_SUCC, MSG_SUMM, PARAM_NONE, "Summary" },
|
|
||||||
{ SEVERITY_INFO, MSG_GPUDIS, PARAM_GPU, "GPU %d set disable flag" },
|
|
||||||
{ SEVERITY_INFO, MSG_GPUREI, PARAM_GPU, "GPU %d restart attempted" },
|
|
||||||
{ SEVERITY_ERR, MSG_INVCMD, PARAM_NONE, "Invalid command" },
|
|
||||||
{ SEVERITY_ERR, MSG_MISID, PARAM_NONE, "Missing device id parameter" },
|
|
||||||
{ SEVERITY_SUCC, MSG_GPUDEV, PARAM_GPU, "GPU%d" },
|
|
||||||
{ SEVERITY_SUCC, MSG_NUMGPU, PARAM_NONE, "GPU count" },
|
|
||||||
{ SEVERITY_SUCC, MSG_VERSION, PARAM_NONE, "SGMiner versions" },
|
|
||||||
{ SEVERITY_ERR, MSG_INVJSON, PARAM_NONE, "Invalid JSON" },
|
|
||||||
{ SEVERITY_ERR, MSG_MISCMD, PARAM_CMD, "Missing JSON '%s'" },
|
|
||||||
{ SEVERITY_ERR, MSG_MISPID, PARAM_NONE, "Missing pool id parameter" },
|
|
||||||
{ SEVERITY_ERR, MSG_INVPID, PARAM_POOLMAX, "Invalid pool id %d - range is 0 - %d" },
|
|
||||||
{ SEVERITY_SUCC, MSG_SWITCHP, PARAM_POOL, "Switching to pool %d:'%s'" },
|
|
||||||
{ SEVERITY_ERR, MSG_MISVAL, PARAM_NONE, "Missing comma after GPU number" },
|
|
||||||
{ SEVERITY_ERR, MSG_NOADL, PARAM_NONE, "ADL is not available" },
|
|
||||||
{ SEVERITY_ERR, MSG_NOGPUADL,PARAM_GPU, "GPU %d does not have ADL" },
|
|
||||||
{ SEVERITY_ERR, MSG_INVINT, PARAM_STR, "Invalid intensity (%s) - must be '" _DYNAMIC "' or range " MIN_INTENSITY_STR " - " MAX_INTENSITY_STR },
|
|
||||||
{ SEVERITY_INFO, MSG_GPUINT, PARAM_BOTH, "GPU %d set new intensity to %s" },
|
|
||||||
{ SEVERITY_SUCC, MSG_MINECONFIG,PARAM_NONE, "sgminer config" },
|
|
||||||
{ SEVERITY_ERR, MSG_GPUMERR, PARAM_BOTH, "Setting GPU %d memoryclock to (%s) reported failure" },
|
|
||||||
{ SEVERITY_SUCC, MSG_GPUMEM, PARAM_BOTH, "Setting GPU %d memoryclock to (%s) reported success" },
|
|
||||||
{ SEVERITY_ERR, MSG_GPUEERR, PARAM_BOTH, "Setting GPU %d clock to (%s) reported failure" },
|
|
||||||
{ SEVERITY_SUCC, MSG_GPUENG, PARAM_BOTH, "Setting GPU %d clock to (%s) reported success" },
|
|
||||||
{ SEVERITY_ERR, MSG_GPUVERR, PARAM_BOTH, "Setting GPU %d vddc to (%s) reported failure" },
|
|
||||||
{ SEVERITY_SUCC, MSG_GPUVDDC, PARAM_BOTH, "Setting GPU %d vddc to (%s) reported success" },
|
|
||||||
{ SEVERITY_ERR, MSG_GPUFERR, PARAM_BOTH, "Setting GPU %d fan to (%s) reported failure" },
|
|
||||||
{ SEVERITY_SUCC, MSG_GPUFAN, PARAM_BOTH, "Setting GPU %d fan to (%s) reported success" },
|
|
||||||
{ SEVERITY_ERR, MSG_MISFN, PARAM_NONE, "Missing save filename parameter" },
|
|
||||||
{ SEVERITY_ERR, MSG_BADFN, PARAM_STR, "Can't open or create save file '%s'" },
|
|
||||||
{ SEVERITY_SUCC, MSG_SAVED, PARAM_STR, "Configuration saved to file '%s'" },
|
|
||||||
{ SEVERITY_ERR, MSG_ACCDENY, PARAM_STR, "Access denied to '%s' command" },
|
|
||||||
{ SEVERITY_SUCC, MSG_ACCOK, PARAM_NONE, "Privileged access OK" },
|
|
||||||
{ SEVERITY_SUCC, MSG_ENAPOOL, PARAM_POOL, "Enabling pool %d:'%s'" },
|
|
||||||
{ SEVERITY_SUCC, MSG_POOLPRIO,PARAM_NONE, "Changed pool priorities" },
|
|
||||||
{ SEVERITY_ERR, MSG_DUPPID, PARAM_PID, "Duplicate pool specified %d" },
|
|
||||||
{ SEVERITY_SUCC, MSG_DISPOOL, PARAM_POOL, "Disabling pool %d:'%s'" },
|
|
||||||
{ SEVERITY_INFO, MSG_ALRENAP, PARAM_POOL, "Pool %d:'%s' already enabled" },
|
|
||||||
{ SEVERITY_INFO, MSG_ALRDISP, PARAM_POOL, "Pool %d:'%s' already disabled" },
|
|
||||||
{ SEVERITY_ERR, MSG_MISPDP, PARAM_NONE, "Missing addpool details" },
|
|
||||||
{ SEVERITY_ERR, MSG_INVPDP, PARAM_STR, "Invalid addpool details '%s'" },
|
|
||||||
{ SEVERITY_ERR, MSG_TOOMANYP,PARAM_NONE, "Reached maximum number of pools (%d)" },
|
|
||||||
{ SEVERITY_SUCC, MSG_ADDPOOL, PARAM_STR, "Added pool '%s'" },
|
|
||||||
{ SEVERITY_ERR, MSG_REMLASTP,PARAM_POOL, "Cannot remove last pool %d:'%s'" },
|
|
||||||
{ SEVERITY_ERR, MSG_ACTPOOL, PARAM_POOL, "Cannot remove active pool %d:'%s'" },
|
|
||||||
{ SEVERITY_SUCC, MSG_REMPOOL, PARAM_BOTH, "Removed pool %d:'%s'" },
|
|
||||||
{ SEVERITY_SUCC, MSG_NOTIFY, PARAM_NONE, "Notify" },
|
|
||||||
{ SEVERITY_SUCC, MSG_DEVDETAILS,PARAM_NONE, "Device Details" },
|
|
||||||
{ SEVERITY_SUCC, MSG_MINESTATS,PARAM_NONE, "sgminer stats" },
|
|
||||||
{ SEVERITY_ERR, MSG_MISCHK, PARAM_NONE, "Missing check cmd" },
|
|
||||||
{ SEVERITY_SUCC, MSG_CHECK, PARAM_NONE, "Check command" },
|
|
||||||
{ SEVERITY_ERR, MSG_MISBOOL, PARAM_NONE, "Missing parameter: true/false" },
|
|
||||||
{ SEVERITY_ERR, MSG_INVBOOL, PARAM_NONE, "Invalid parameter should be true or false" },
|
|
||||||
{ SEVERITY_SUCC, MSG_FOO, PARAM_BOOL, "Failover-Only set to %s" },
|
|
||||||
{ SEVERITY_SUCC, MSG_MINECOIN,PARAM_NONE, "sgminer coin" },
|
|
||||||
{ SEVERITY_SUCC, MSG_DEBUGSET,PARAM_NONE, "Debug settings" },
|
|
||||||
{ SEVERITY_SUCC, MSG_SETCONFIG,PARAM_SET, "Set config '%s' to %d" },
|
|
||||||
{ SEVERITY_ERR, MSG_UNKCON, PARAM_STR, "Unknown config '%s'" },
|
|
||||||
{ SEVERITY_ERR, MSG_INVNUM, PARAM_BOTH, "Invalid number (%d) for '%s' range is 0-9999" },
|
|
||||||
{ SEVERITY_ERR, MSG_INVNEG, PARAM_BOTH, "Invalid negative number (%d) for '%s'" },
|
|
||||||
{ SEVERITY_SUCC, MSG_SETQUOTA,PARAM_SET, "Set pool '%s' to quota %d'" },
|
|
||||||
{ SEVERITY_ERR, MSG_CONPAR, PARAM_NONE, "Missing config parameters 'name,N'" },
|
|
||||||
{ SEVERITY_ERR, MSG_CONVAL, PARAM_STR, "Missing config value N for '%s,N'" },
|
|
||||||
{ SEVERITY_INFO, MSG_NOUSTA, PARAM_NONE, "No USB Statistics" },
|
|
||||||
{ SEVERITY_ERR, MSG_ZERMIS, PARAM_NONE, "Missing zero parameters" },
|
|
||||||
{ SEVERITY_ERR, MSG_ZERINV, PARAM_STR, "Invalid zero parameter '%s'" },
|
|
||||||
{ SEVERITY_SUCC, MSG_ZERSUM, PARAM_STR, "Zeroed %s stats with summary" },
|
|
||||||
{ SEVERITY_SUCC, MSG_ZERNOSUM, PARAM_STR, "Zeroed %s stats without summary" },
|
|
||||||
{ SEVERITY_SUCC, MSG_LOCKOK, PARAM_NONE, "Lock stats created" },
|
|
||||||
{ SEVERITY_WARN, MSG_LOCKDIS, PARAM_NONE, "Lock stats not enabled" },
|
|
||||||
{ SEVERITY_SUCC, MSG_BYE, PARAM_STR, "%s" },
|
|
||||||
{ SEVERITY_FAIL, 0, (enum code_parameters)0, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *localaddr = "127.0.0.1";
|
static const char *localaddr = "127.0.0.1";
|
||||||
|
|
||||||
static int my_thr_id = 0;
|
static int my_thr_id = 0;
|
||||||
@ -443,50 +113,11 @@ static bool do_a_restart;
|
|||||||
|
|
||||||
static time_t when = 0; // when the request occurred
|
static time_t when = 0; // when the request occurred
|
||||||
|
|
||||||
struct IP4ACCESS {
|
|
||||||
in_addr_t ip;
|
|
||||||
in_addr_t mask;
|
|
||||||
char group;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define GROUP(g) (toupper(g))
|
|
||||||
#define PRIVGROUP GROUP('W')
|
|
||||||
#define NOPRIVGROUP GROUP('R')
|
|
||||||
#define ISPRIVGROUP(g) (GROUP(g) == PRIVGROUP)
|
|
||||||
#define GROUPOFFSET(g) (GROUP(g) - GROUP('A'))
|
|
||||||
#define VALIDGROUP(g) (GROUP(g) >= GROUP('A') && GROUP(g) <= GROUP('Z'))
|
|
||||||
#define COMMANDS(g) (apigroups[GROUPOFFSET(g)].commands)
|
|
||||||
#define DEFINEDGROUP(g) (ISPRIVGROUP(g) || COMMANDS(g) != NULL)
|
|
||||||
|
|
||||||
struct APIGROUPS {
|
|
||||||
// This becomes a string like: "|cmd1|cmd2|cmd3|" so it's quick to search
|
|
||||||
char *commands;
|
|
||||||
} apigroups['Z' - 'A' + 1]; // only A=0 to Z=25 (R: noprivs, W: allprivs)
|
|
||||||
|
|
||||||
static struct IP4ACCESS *ipaccess = NULL;
|
static struct IP4ACCESS *ipaccess = NULL;
|
||||||
static int ips = 0;
|
static int ips = 0;
|
||||||
|
|
||||||
struct io_data {
|
|
||||||
size_t siz;
|
|
||||||
char *ptr;
|
|
||||||
char *cur;
|
|
||||||
bool sock;
|
|
||||||
bool close;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct io_list {
|
|
||||||
struct io_data *io_data;
|
|
||||||
struct io_list *prev;
|
|
||||||
struct io_list *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct io_list *io_head = NULL;
|
static struct io_list *io_head = NULL;
|
||||||
|
|
||||||
#define SOCKBUFALLOCSIZ 65536
|
|
||||||
|
|
||||||
#define io_new(init) _io_new(init, false)
|
|
||||||
#define sock_io_new() _io_new(SOCKBUFALLOCSIZ, true)
|
|
||||||
|
|
||||||
static void io_reinit(struct io_data *io_data)
|
static void io_reinit(struct io_data *io_data)
|
||||||
{
|
{
|
||||||
io_data->cur = io_data->ptr;
|
io_data->cur = io_data->ptr;
|
||||||
@ -1047,7 +678,7 @@ static struct api_data *print_data(struct api_data *root, char *buf, bool isjson
|
|||||||
// All replies (except BYE and RESTART) start with a message
|
// All replies (except BYE and RESTART) start with a message
|
||||||
// thus for JSON, message() inserts JSON_START at the front
|
// thus for JSON, message() inserts JSON_START at the front
|
||||||
// and send_result() adds JSON_END at the end
|
// and send_result() adds JSON_END at the end
|
||||||
static void message(struct io_data *io_data, int messageid, int paramid, char *param2, bool isjson)
|
void message(struct io_data *io_data, int messageid, int paramid, char *param2, bool isjson)
|
||||||
{
|
{
|
||||||
struct api_data *root = NULL;
|
struct api_data *root = NULL;
|
||||||
char buf[TMPBUFSIZ];
|
char buf[TMPBUFSIZ];
|
||||||
@ -1149,49 +780,6 @@ static void message(struct io_data *io_data, int messageid, int paramid, char *p
|
|||||||
|
|
||||||
#if LOCK_TRACKING
|
#if LOCK_TRACKING
|
||||||
|
|
||||||
#define LOCK_FMT_FFL " - called from %s %s():%d"
|
|
||||||
|
|
||||||
#define LOCKMSG(fmt, ...) fprintf(stderr, "APILOCK: " fmt "\n", ##__VA_ARGS__)
|
|
||||||
#define LOCKMSGMORE(fmt, ...) fprintf(stderr, " " fmt "\n", ##__VA_ARGS__)
|
|
||||||
#define LOCKMSGFFL(fmt, ...) fprintf(stderr, "APILOCK: " fmt LOCK_FMT_FFL "\n", ##__VA_ARGS__, file, func, linenum)
|
|
||||||
#define LOCKMSGFLUSH() fflush(stderr)
|
|
||||||
|
|
||||||
typedef struct lockstat {
|
|
||||||
uint64_t lock_id;
|
|
||||||
const char *file;
|
|
||||||
const char *func;
|
|
||||||
int linenum;
|
|
||||||
struct timeval tv;
|
|
||||||
} LOCKSTAT;
|
|
||||||
|
|
||||||
typedef struct lockline {
|
|
||||||
struct lockline *prev;
|
|
||||||
struct lockstat *stat;
|
|
||||||
struct lockline *next;
|
|
||||||
} LOCKLINE;
|
|
||||||
|
|
||||||
typedef struct lockinfo {
|
|
||||||
void *lock;
|
|
||||||
enum cglock_typ typ;
|
|
||||||
const char *file;
|
|
||||||
const char *func;
|
|
||||||
int linenum;
|
|
||||||
uint64_t gets;
|
|
||||||
uint64_t gots;
|
|
||||||
uint64_t tries;
|
|
||||||
uint64_t dids;
|
|
||||||
uint64_t didnts; // should be tries - dids
|
|
||||||
uint64_t unlocks;
|
|
||||||
LOCKSTAT lastgot;
|
|
||||||
LOCKLINE *lockgets;
|
|
||||||
LOCKLINE *locktries;
|
|
||||||
} LOCKINFO;
|
|
||||||
|
|
||||||
typedef struct locklist {
|
|
||||||
LOCKINFO *info;
|
|
||||||
struct locklist *next;
|
|
||||||
} LOCKLIST;
|
|
||||||
|
|
||||||
static uint64_t lock_id = 1;
|
static uint64_t lock_id = 1;
|
||||||
|
|
||||||
static LOCKLIST *lockhead;
|
static LOCKLIST *lockhead;
|
||||||
@ -1534,6 +1122,23 @@ void show_locks()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void copyadvanceafter(char ch, char **param, char **buf)
|
||||||
|
{
|
||||||
|
#define src_p (*param)
|
||||||
|
#define dst_b (*buf)
|
||||||
|
|
||||||
|
while (*src_p && *src_p != ch) {
|
||||||
|
if (*src_p == '\\' && *(src_p+1) != '\0')
|
||||||
|
src_p++;
|
||||||
|
|
||||||
|
*(dst_b++) = *(src_p++);
|
||||||
|
}
|
||||||
|
if (*src_p)
|
||||||
|
src_p++;
|
||||||
|
|
||||||
|
*(dst_b++) = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
static void lockstats(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
static void lockstats(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
#if LOCK_TRACKING
|
#if LOCK_TRACKING
|
||||||
@ -1824,6 +1429,7 @@ static void poolstatus(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __m
|
|||||||
root = api_add_string(root, "Name", get_pool_name(pool), true);
|
root = api_add_string(root, "Name", get_pool_name(pool), true);
|
||||||
mutex_unlock(&pool->stratum_lock);
|
mutex_unlock(&pool->stratum_lock);
|
||||||
root = api_add_escape(root, "URL", pool->rpc_url, false);
|
root = api_add_escape(root, "URL", pool->rpc_url, false);
|
||||||
|
root = api_add_string(root, "Profile", pool->profile, false);
|
||||||
root = api_add_string(root, "Algorithm", pool->algorithm.name, false);
|
root = api_add_string(root, "Algorithm", pool->algorithm.name, false);
|
||||||
root = api_add_string(root, "Description", pool->description, false);
|
root = api_add_string(root, "Description", pool->description, false);
|
||||||
root = api_add_string(root, "Status", status, false);
|
root = api_add_string(root, "Status", status, false);
|
||||||
@ -2101,25 +1707,74 @@ static void switchpool(struct io_data *io_data, __maybe_unused SOCKETTYPE c, cha
|
|||||||
message(io_data, MSG_SWITCHP, id, NULL, isjson);
|
message(io_data, MSG_SWITCHP, id, NULL, isjson);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void copyadvanceafter(char ch, char **param, char **buf)
|
static void api_pool_strategy(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
#define src_p (*param)
|
char *p;
|
||||||
#define dst_b (*buf)
|
int strategy;
|
||||||
|
|
||||||
while (*src_p && *src_p != ch) {
|
if (total_pools == 0)
|
||||||
if (*src_p == '\\' && *(src_p+1) != '\0')
|
{
|
||||||
src_p++;
|
message(io_data, MSG_NOPOOL, 0, NULL, isjson);
|
||||||
|
return;
|
||||||
*(dst_b++) = *(src_p++);
|
|
||||||
}
|
}
|
||||||
if (*src_p)
|
|
||||||
src_p++;
|
|
||||||
|
|
||||||
*(dst_b++) = '\0';
|
if (param == NULL || *param == '\0')
|
||||||
|
{
|
||||||
|
message(io_data, MSG_MISSTRAT, 0, NULL, isjson);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//get strategy in parameter 1
|
||||||
|
if(!(p = strtok(param, ",")))
|
||||||
|
{
|
||||||
|
message(io_data, MSG_MISSTRAT, 0, NULL, isjson);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
strategy = atoi(p);
|
||||||
|
|
||||||
|
//invalid strategy
|
||||||
|
if(strategy < 0 || strategy > TOP_STRATEGY)
|
||||||
|
{
|
||||||
|
message(io_data, MSG_INVSTRAT, strategy, NULL, isjson);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if set to rotate, get second param
|
||||||
|
if(strategy == POOL_ROTATE)
|
||||||
|
{
|
||||||
|
//if second param is missing then invalid
|
||||||
|
if(!(p = strtok(NULL, ",")))
|
||||||
|
{
|
||||||
|
message(io_data, MSG_MISSTRATINT, 0, NULL, isjson);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//get interval in parameter 2
|
||||||
|
int interval;
|
||||||
|
interval = atoi(p);
|
||||||
|
|
||||||
|
//interval can only be between 0 and 9999
|
||||||
|
if(interval < 0 || interval > 9999)
|
||||||
|
{
|
||||||
|
message(io_data, MSG_INVNUM, interval, "interval", isjson);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//set interval
|
||||||
|
opt_rotate_period = interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
//set pool strategy
|
||||||
|
pool_strategy = (enum pool_strategy)strategy;
|
||||||
|
//initiate new strategy
|
||||||
|
switch_pools(NULL);
|
||||||
|
|
||||||
|
message(io_data, MSG_CHSTRAT, 0, (char *)strategies[strategy].s, isjson);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool pooldetails(char *param, char **url, char **user, char **pass,
|
static bool pooldetails(char *param, char **url, char **user, char **pass,
|
||||||
char **name, char **desc, char **algo)
|
char **name, char **desc, char **profile, char **algo)
|
||||||
{
|
{
|
||||||
char *ptr, *buf;
|
char *ptr, *buf;
|
||||||
|
|
||||||
@ -2134,23 +1789,28 @@ static bool pooldetails(char *param, char **url, char **user, char **pass,
|
|||||||
|
|
||||||
*user = buf;
|
*user = buf;
|
||||||
copyadvanceafter(',', ¶m, &buf);
|
copyadvanceafter(',', ¶m, &buf);
|
||||||
if (!*param) // missing pass
|
if (!(*param)) // missing pass
|
||||||
goto exitsama;
|
goto exitsama;
|
||||||
|
|
||||||
*pass = buf;
|
*pass = buf;
|
||||||
copyadvanceafter(',', ¶m, &buf);
|
copyadvanceafter(',', ¶m, &buf);
|
||||||
if (!*param) // missing name (allowed)
|
if (!(*param)) // missing name (allowed)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
*name = buf;
|
*name = buf;
|
||||||
copyadvanceafter(',', ¶m, &buf);
|
copyadvanceafter(',', ¶m, &buf);
|
||||||
if (!*param) // missing desc
|
if (!(*param)) // missing desc
|
||||||
goto exitsama;
|
return true;
|
||||||
|
|
||||||
*desc = buf;
|
*desc = buf;
|
||||||
copyadvanceafter(',', ¶m, &buf);
|
copyadvanceafter(',', ¶m, &buf);
|
||||||
if (!*param) // missing algo
|
if (!(*param)) // missing profile
|
||||||
goto exitsama;
|
return true;
|
||||||
|
|
||||||
|
*profile = buf;
|
||||||
|
copyadvanceafter(',', ¶m, &buf);
|
||||||
|
if (!(*param)) // missing algo
|
||||||
|
return true;
|
||||||
|
|
||||||
*algo = buf;
|
*algo = buf;
|
||||||
copyadvanceafter(',', ¶m, &buf);
|
copyadvanceafter(',', ¶m, &buf);
|
||||||
@ -2165,7 +1825,7 @@ exitsama:
|
|||||||
static void addpool(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
static void addpool(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
char *url, *user, *pass;
|
char *url, *user, *pass;
|
||||||
char *name = NULL, *desc = NULL, *algo = NULL;
|
char *name = NULL, *desc = NULL, *algo = NULL, *profile = NULL;
|
||||||
struct pool *pool;
|
struct pool *pool;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
|
||||||
@ -2175,7 +1835,7 @@ static void addpool(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!pooldetails(param, &url, &user, &pass,
|
if (!pooldetails(param, &url, &user, &pass,
|
||||||
&name, &desc, &algo)) {
|
&name, &desc, &profile, &algo)) {
|
||||||
ptr = escape_string(param, isjson);
|
ptr = escape_string(param, isjson);
|
||||||
message(io_data, MSG_INVPDP, 0, ptr, isjson);
|
message(io_data, MSG_INVPDP, 0, ptr, isjson);
|
||||||
if (ptr != param)
|
if (ptr != param)
|
||||||
@ -2185,13 +1845,14 @@ static void addpool(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If API client is old, it might not have provided all fields. */
|
/* If API client is old, it might not have provided all fields. */
|
||||||
if (name == NULL) name = strdup("");
|
name = ((name == NULL)?strdup(""):name);
|
||||||
if (desc == NULL) desc = strdup("");
|
desc = ((desc == NULL)?strdup(""):desc);
|
||||||
if (algo == NULL) algo = strdup("scrypt"); // FIXME?
|
profile = ((profile == NULL)?strdup(""):profile);
|
||||||
|
algo = ((algo == NULL)?strdup(""):algo);
|
||||||
|
|
||||||
pool = add_pool();
|
pool = add_pool();
|
||||||
detect_stratum(pool, url);
|
detect_stratum(pool, url);
|
||||||
add_pool_details(pool, true, url, user, pass, name, desc, algo);
|
add_pool_details(pool, true, url, user, pass, name, desc, profile, algo);
|
||||||
|
|
||||||
ptr = escape_string(url, isjson);
|
ptr = escape_string(url, isjson);
|
||||||
message(io_data, MSG_ADDPOOL, 0, ptr, isjson);
|
message(io_data, MSG_ADDPOOL, 0, ptr, isjson);
|
||||||
@ -2729,7 +2390,7 @@ static void devdetails(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __m
|
|||||||
void dosave(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
void dosave(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
|
||||||
{
|
{
|
||||||
char filename[PATH_MAX];
|
char filename[PATH_MAX];
|
||||||
FILE *fcfg;
|
// FILE *fcfg;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
|
||||||
if (param == NULL || *param == '\0') {
|
if (param == NULL || *param == '\0') {
|
||||||
@ -3071,6 +2732,7 @@ struct CMDS {
|
|||||||
{ "gpu", gpudev, false, false },
|
{ "gpu", gpudev, false, false },
|
||||||
{ "gpucount", gpucount, false, true },
|
{ "gpucount", gpucount, false, true },
|
||||||
{ "switchpool", switchpool, true, false },
|
{ "switchpool", switchpool, true, false },
|
||||||
|
{ "changestrategy", api_pool_strategy, true, false },
|
||||||
{ "addpool", addpool, true, false },
|
{ "addpool", addpool, true, false },
|
||||||
{ "poolpriority", poolpriority, true, false },
|
{ "poolpriority", poolpriority, true, false },
|
||||||
{ "poolquota", poolquota, true, false },
|
{ "poolquota", poolquota, true, false },
|
||||||
|
436
api.h
Normal file
436
api.h
Normal file
@ -0,0 +1,436 @@
|
|||||||
|
#ifndef API_H
|
||||||
|
#define API_H
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "miner.h"
|
||||||
|
|
||||||
|
// BUFSIZ varies on Windows and Linux
|
||||||
|
#define TMPBUFSIZ 8192
|
||||||
|
|
||||||
|
// Number of requests to queue - normally would be small
|
||||||
|
#define QUEUE 100
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
struct WSAERRORS {
|
||||||
|
int id;
|
||||||
|
char *code;
|
||||||
|
} WSAErrors[] = {
|
||||||
|
{ 0, "No error" },
|
||||||
|
{ WSAEINTR, "Interrupted system call" },
|
||||||
|
{ WSAEBADF, "Bad file number" },
|
||||||
|
{ WSAEACCES, "Permission denied" },
|
||||||
|
{ WSAEFAULT, "Bad address" },
|
||||||
|
{ WSAEINVAL, "Invalid argument" },
|
||||||
|
{ WSAEMFILE, "Too many open sockets" },
|
||||||
|
{ WSAEWOULDBLOCK, "Operation would block" },
|
||||||
|
{ WSAEINPROGRESS, "Operation now in progress" },
|
||||||
|
{ WSAEALREADY, "Operation already in progress" },
|
||||||
|
{ WSAENOTSOCK, "Socket operation on non-socket" },
|
||||||
|
{ WSAEDESTADDRREQ, "Destination address required" },
|
||||||
|
{ WSAEMSGSIZE, "Message too long" },
|
||||||
|
{ WSAEPROTOTYPE, "Protocol wrong type for socket" },
|
||||||
|
{ WSAENOPROTOOPT, "Bad protocol option" },
|
||||||
|
{ WSAEPROTONOSUPPORT, "Protocol not supported" },
|
||||||
|
{ WSAESOCKTNOSUPPORT, "Socket type not supported" },
|
||||||
|
{ WSAEOPNOTSUPP, "Operation not supported on socket" },
|
||||||
|
{ WSAEPFNOSUPPORT, "Protocol family not supported" },
|
||||||
|
{ WSAEAFNOSUPPORT, "Address family not supported" },
|
||||||
|
{ WSAEADDRINUSE, "Address already in use" },
|
||||||
|
{ WSAEADDRNOTAVAIL, "Can't assign requested address" },
|
||||||
|
{ WSAENETDOWN, "Network is down" },
|
||||||
|
{ WSAENETUNREACH, "Network is unreachable" },
|
||||||
|
{ WSAENETRESET, "Net connection reset" },
|
||||||
|
{ WSAECONNABORTED, "Software caused connection abort" },
|
||||||
|
{ WSAECONNRESET, "Connection reset by peer" },
|
||||||
|
{ WSAENOBUFS, "No buffer space available" },
|
||||||
|
{ WSAEISCONN, "Socket is already connected" },
|
||||||
|
{ WSAENOTCONN, "Socket is not connected" },
|
||||||
|
{ WSAESHUTDOWN, "Can't send after socket shutdown" },
|
||||||
|
{ WSAETOOMANYREFS, "Too many references, can't splice" },
|
||||||
|
{ WSAETIMEDOUT, "Connection timed out" },
|
||||||
|
{ WSAECONNREFUSED, "Connection refused" },
|
||||||
|
{ WSAELOOP, "Too many levels of symbolic links" },
|
||||||
|
{ WSAENAMETOOLONG, "File name too long" },
|
||||||
|
{ WSAEHOSTDOWN, "Host is down" },
|
||||||
|
{ WSAEHOSTUNREACH, "No route to host" },
|
||||||
|
{ WSAENOTEMPTY, "Directory not empty" },
|
||||||
|
{ WSAEPROCLIM, "Too many processes" },
|
||||||
|
{ WSAEUSERS, "Too many users" },
|
||||||
|
{ WSAEDQUOT, "Disc quota exceeded" },
|
||||||
|
{ WSAESTALE, "Stale NFS file handle" },
|
||||||
|
{ WSAEREMOTE, "Too many levels of remote in path" },
|
||||||
|
{ WSASYSNOTREADY, "Network system is unavailable" },
|
||||||
|
{ WSAVERNOTSUPPORTED, "Winsock version out of range" },
|
||||||
|
{ WSANOTINITIALISED, "WSAStartup not yet called" },
|
||||||
|
{ WSAEDISCON, "Graceful shutdown in progress" },
|
||||||
|
{ WSAHOST_NOT_FOUND, "Host not found" },
|
||||||
|
{ WSANO_DATA, "No host data of that type was found" },
|
||||||
|
{ -1, "Unknown error code" }
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define COMSTR ","
|
||||||
|
#define SEPSTR "|"
|
||||||
|
|
||||||
|
#define CMDJOIN '+'
|
||||||
|
#define JOIN_CMD "CMD="
|
||||||
|
#define BETWEEN_JOIN SEPSTR
|
||||||
|
#define _DYNAMIC "D"
|
||||||
|
|
||||||
|
#define _DEVS "DEVS"
|
||||||
|
#define _POOLS "POOLS"
|
||||||
|
#define _SUMMARY "SUMMARY"
|
||||||
|
#define _STATUS "STATUS"
|
||||||
|
#define _VERSION "VERSION"
|
||||||
|
#define _MINECONFIG "CONFIG"
|
||||||
|
#define _GPU "GPU"
|
||||||
|
|
||||||
|
#define _GPUS "GPUS"
|
||||||
|
#define _NOTIFY "NOTIFY"
|
||||||
|
#define _DEVDETAILS "DEVDETAILS"
|
||||||
|
#define _BYE "BYE"
|
||||||
|
#define _RESTART "RESTART"
|
||||||
|
#define _MINESTATS "STATS"
|
||||||
|
#define _CHECK "CHECK"
|
||||||
|
#define _MINECOIN "COIN"
|
||||||
|
#define _DEBUGSET "DEBUG"
|
||||||
|
#define _SETCONFIG "SETCONFIG"
|
||||||
|
|
||||||
|
#define JSON0 "{"
|
||||||
|
#define JSON1 "\""
|
||||||
|
#define JSON2 "\":["
|
||||||
|
#define JSON3 "]"
|
||||||
|
#define JSON4 ",\"id\":1"
|
||||||
|
// If anyone cares, id=0 for truncated output
|
||||||
|
#define JSON4_TRUNCATED ",\"id\":0"
|
||||||
|
#define JSON5 "}"
|
||||||
|
|
||||||
|
#define JSON_START JSON0
|
||||||
|
#define JSON_DEVS JSON1 _DEVS JSON2
|
||||||
|
#define JSON_POOLS JSON1 _POOLS JSON2
|
||||||
|
#define JSON_SUMMARY JSON1 _SUMMARY JSON2
|
||||||
|
#define JSON_STATUS JSON1 _STATUS JSON2
|
||||||
|
#define JSON_VERSION JSON1 _VERSION JSON2
|
||||||
|
#define JSON_MINECONFIG JSON1 _MINECONFIG JSON2
|
||||||
|
#define JSON_GPU JSON1 _GPU JSON2
|
||||||
|
|
||||||
|
#define JSON_GPUS JSON1 _GPUS JSON2
|
||||||
|
#define JSON_NOTIFY JSON1 _NOTIFY JSON2
|
||||||
|
#define JSON_DEVDETAILS JSON1 _DEVDETAILS JSON2
|
||||||
|
#define JSON_CLOSE JSON3
|
||||||
|
#define JSON_MINESTATS JSON1 _MINESTATS JSON2
|
||||||
|
#define JSON_CHECK JSON1 _CHECK JSON2
|
||||||
|
#define JSON_MINECOIN JSON1 _MINECOIN JSON2
|
||||||
|
#define JSON_DEBUGSET JSON1 _DEBUGSET JSON2
|
||||||
|
#define JSON_SETCONFIG JSON1 _SETCONFIG JSON2
|
||||||
|
|
||||||
|
#define JSON_END JSON4 JSON5
|
||||||
|
#define JSON_END_TRUNCATED JSON4_TRUNCATED JSON5
|
||||||
|
#define JSON_BETWEEN_JOIN ","
|
||||||
|
|
||||||
|
#define MSG_INVGPU 1
|
||||||
|
#define MSG_ALRENA 2
|
||||||
|
#define MSG_ALRDIS 3
|
||||||
|
#define MSG_GPUMRE 4
|
||||||
|
#define MSG_GPUREN 5
|
||||||
|
#define MSG_GPUNON 6
|
||||||
|
#define MSG_POOL 7
|
||||||
|
#define MSG_NOPOOL 8
|
||||||
|
#define MSG_DEVS 9
|
||||||
|
#define MSG_NODEVS 10
|
||||||
|
#define MSG_SUMM 11
|
||||||
|
#define MSG_GPUDIS 12
|
||||||
|
#define MSG_GPUREI 13
|
||||||
|
#define MSG_INVCMD 14
|
||||||
|
#define MSG_MISID 15
|
||||||
|
#define MSG_GPUDEV 17
|
||||||
|
|
||||||
|
#define MSG_NUMGPU 20
|
||||||
|
|
||||||
|
#define MSG_VERSION 22
|
||||||
|
#define MSG_INVJSON 23
|
||||||
|
#define MSG_MISCMD 24
|
||||||
|
#define MSG_MISPID 25
|
||||||
|
#define MSG_INVPID 26
|
||||||
|
#define MSG_SWITCHP 27
|
||||||
|
#define MSG_MISVAL 28
|
||||||
|
#define MSG_NOADL 29
|
||||||
|
#define MSG_NOGPUADL 30
|
||||||
|
#define MSG_INVINT 31
|
||||||
|
#define MSG_GPUINT 32
|
||||||
|
#define MSG_MINECONFIG 33
|
||||||
|
#define MSG_GPUMERR 34
|
||||||
|
#define MSG_GPUMEM 35
|
||||||
|
#define MSG_GPUEERR 36
|
||||||
|
#define MSG_GPUENG 37
|
||||||
|
#define MSG_GPUVERR 38
|
||||||
|
#define MSG_GPUVDDC 39
|
||||||
|
#define MSG_GPUFERR 40
|
||||||
|
#define MSG_GPUFAN 41
|
||||||
|
#define MSG_MISFN 42
|
||||||
|
#define MSG_BADFN 43
|
||||||
|
#define MSG_SAVED 44
|
||||||
|
#define MSG_ACCDENY 45
|
||||||
|
#define MSG_ACCOK 46
|
||||||
|
#define MSG_ENAPOOL 47
|
||||||
|
#define MSG_DISPOOL 48
|
||||||
|
#define MSG_ALRENAP 49
|
||||||
|
#define MSG_ALRDISP 50
|
||||||
|
#define MSG_MISPDP 52
|
||||||
|
#define MSG_INVPDP 53
|
||||||
|
#define MSG_TOOMANYP 54
|
||||||
|
#define MSG_ADDPOOL 55
|
||||||
|
|
||||||
|
#define MSG_NOTIFY 60
|
||||||
|
|
||||||
|
#define MSG_REMLASTP 66
|
||||||
|
#define MSG_ACTPOOL 67
|
||||||
|
#define MSG_REMPOOL 68
|
||||||
|
#define MSG_DEVDETAILS 69
|
||||||
|
#define MSG_MINESTATS 70
|
||||||
|
#define MSG_MISCHK 71
|
||||||
|
#define MSG_CHECK 72
|
||||||
|
#define MSG_POOLPRIO 73
|
||||||
|
#define MSG_DUPPID 74
|
||||||
|
#define MSG_MISBOOL 75
|
||||||
|
#define MSG_INVBOOL 76
|
||||||
|
#define MSG_FOO 77
|
||||||
|
#define MSG_MINECOIN 78
|
||||||
|
#define MSG_DEBUGSET 79
|
||||||
|
#define MSG_SETCONFIG 82
|
||||||
|
#define MSG_UNKCON 83
|
||||||
|
#define MSG_INVNUM 84
|
||||||
|
#define MSG_CONPAR 85
|
||||||
|
#define MSG_CONVAL 86
|
||||||
|
|
||||||
|
#define MSG_NOUSTA 88
|
||||||
|
|
||||||
|
#define MSG_ZERMIS 94
|
||||||
|
#define MSG_ZERINV 95
|
||||||
|
#define MSG_ZERSUM 96
|
||||||
|
#define MSG_ZERNOSUM 97
|
||||||
|
|
||||||
|
#define MSG_BYE 0x101
|
||||||
|
|
||||||
|
#define MSG_INVNEG 121
|
||||||
|
#define MSG_SETQUOTA 122
|
||||||
|
#define MSG_LOCKOK 123
|
||||||
|
#define MSG_LOCKDIS 124
|
||||||
|
|
||||||
|
#define MSG_CHSTRAT 125
|
||||||
|
#define MSG_MISSTRAT 126
|
||||||
|
#define MSG_INVSTRAT 127
|
||||||
|
#define MSG_MISSTRATINT 128
|
||||||
|
|
||||||
|
enum code_severity {
|
||||||
|
SEVERITY_ERR,
|
||||||
|
SEVERITY_WARN,
|
||||||
|
SEVERITY_INFO,
|
||||||
|
SEVERITY_SUCC,
|
||||||
|
SEVERITY_FAIL
|
||||||
|
};
|
||||||
|
|
||||||
|
enum code_parameters {
|
||||||
|
PARAM_GPU,
|
||||||
|
PARAM_PID,
|
||||||
|
PARAM_GPUMAX,
|
||||||
|
PARAM_PMAX,
|
||||||
|
PARAM_POOLMAX,
|
||||||
|
|
||||||
|
// Single generic case: have the code resolve it - see below
|
||||||
|
PARAM_DMAX,
|
||||||
|
|
||||||
|
PARAM_CMD,
|
||||||
|
PARAM_POOL,
|
||||||
|
PARAM_STR,
|
||||||
|
PARAM_BOTH,
|
||||||
|
PARAM_BOOL,
|
||||||
|
PARAM_SET,
|
||||||
|
PARAM_INT,
|
||||||
|
PARAM_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CODES {
|
||||||
|
const enum code_severity severity;
|
||||||
|
const int code;
|
||||||
|
const enum code_parameters params;
|
||||||
|
const char *description;
|
||||||
|
} codes[] = {
|
||||||
|
{ SEVERITY_ERR, MSG_INVGPU, PARAM_GPUMAX, "Invalid GPU id %d - range is 0 - %d" },
|
||||||
|
{ SEVERITY_INFO, MSG_ALRENA, PARAM_GPU, "GPU %d already enabled" },
|
||||||
|
{ SEVERITY_INFO, MSG_ALRDIS, PARAM_GPU, "GPU %d already disabled" },
|
||||||
|
{ SEVERITY_WARN, MSG_GPUMRE, PARAM_GPU, "GPU %d must be restarted first" },
|
||||||
|
{ SEVERITY_INFO, MSG_GPUREN, PARAM_GPU, "GPU %d sent enable message" },
|
||||||
|
{ SEVERITY_ERR, MSG_GPUNON, PARAM_NONE, "No GPUs" },
|
||||||
|
{ SEVERITY_SUCC, MSG_POOL, PARAM_PMAX, "%d Pool(s)" },
|
||||||
|
{ SEVERITY_ERR, MSG_NOPOOL, PARAM_NONE, "No pools" },
|
||||||
|
|
||||||
|
{ SEVERITY_SUCC, MSG_DEVS, PARAM_DMAX, "%d GPU(s)" },
|
||||||
|
{ SEVERITY_ERR, MSG_NODEVS, PARAM_NONE, "No GPUs"
|
||||||
|
},
|
||||||
|
|
||||||
|
{ SEVERITY_SUCC, MSG_SUMM, PARAM_NONE, "Summary" },
|
||||||
|
{ SEVERITY_INFO, MSG_GPUDIS, PARAM_GPU, "GPU %d set disable flag" },
|
||||||
|
{ SEVERITY_INFO, MSG_GPUREI, PARAM_GPU, "GPU %d restart attempted" },
|
||||||
|
{ SEVERITY_ERR, MSG_INVCMD, PARAM_NONE, "Invalid command" },
|
||||||
|
{ SEVERITY_ERR, MSG_MISID, PARAM_NONE, "Missing device id parameter" },
|
||||||
|
{ SEVERITY_SUCC, MSG_GPUDEV, PARAM_GPU, "GPU%d" },
|
||||||
|
{ SEVERITY_SUCC, MSG_NUMGPU, PARAM_NONE, "GPU count" },
|
||||||
|
{ SEVERITY_SUCC, MSG_VERSION, PARAM_NONE, "SGMiner versions" },
|
||||||
|
{ SEVERITY_ERR, MSG_INVJSON, PARAM_NONE, "Invalid JSON" },
|
||||||
|
{ SEVERITY_ERR, MSG_MISCMD, PARAM_CMD, "Missing JSON '%s'" },
|
||||||
|
{ SEVERITY_ERR, MSG_MISPID, PARAM_NONE, "Missing pool id parameter" },
|
||||||
|
{ SEVERITY_ERR, MSG_INVPID, PARAM_POOLMAX, "Invalid pool id %d - range is 0 - %d" },
|
||||||
|
{ SEVERITY_SUCC, MSG_SWITCHP, PARAM_POOL, "Switching to pool %d:'%s'" },
|
||||||
|
{ SEVERITY_ERR, MSG_MISVAL, PARAM_NONE, "Missing comma after GPU number" },
|
||||||
|
{ SEVERITY_ERR, MSG_NOADL, PARAM_NONE, "ADL is not available" },
|
||||||
|
{ SEVERITY_ERR, MSG_NOGPUADL,PARAM_GPU, "GPU %d does not have ADL" },
|
||||||
|
{ SEVERITY_ERR, MSG_INVINT, PARAM_STR, "Invalid intensity (%s) - must be '" _DYNAMIC "' or range " MIN_INTENSITY_STR " - " MAX_INTENSITY_STR },
|
||||||
|
{ SEVERITY_INFO, MSG_GPUINT, PARAM_BOTH, "GPU %d set new intensity to %s" },
|
||||||
|
{ SEVERITY_SUCC, MSG_MINECONFIG,PARAM_NONE, "sgminer config" },
|
||||||
|
{ SEVERITY_ERR, MSG_GPUMERR, PARAM_BOTH, "Setting GPU %d memoryclock to (%s) reported failure" },
|
||||||
|
{ SEVERITY_SUCC, MSG_GPUMEM, PARAM_BOTH, "Setting GPU %d memoryclock to (%s) reported success" },
|
||||||
|
{ SEVERITY_ERR, MSG_GPUEERR, PARAM_BOTH, "Setting GPU %d clock to (%s) reported failure" },
|
||||||
|
{ SEVERITY_SUCC, MSG_GPUENG, PARAM_BOTH, "Setting GPU %d clock to (%s) reported success" },
|
||||||
|
{ SEVERITY_ERR, MSG_GPUVERR, PARAM_BOTH, "Setting GPU %d vddc to (%s) reported failure" },
|
||||||
|
{ SEVERITY_SUCC, MSG_GPUVDDC, PARAM_BOTH, "Setting GPU %d vddc to (%s) reported success" },
|
||||||
|
{ SEVERITY_ERR, MSG_GPUFERR, PARAM_BOTH, "Setting GPU %d fan to (%s) reported failure" },
|
||||||
|
{ SEVERITY_SUCC, MSG_GPUFAN, PARAM_BOTH, "Setting GPU %d fan to (%s) reported success" },
|
||||||
|
{ SEVERITY_ERR, MSG_MISFN, PARAM_NONE, "Missing save filename parameter" },
|
||||||
|
{ SEVERITY_ERR, MSG_BADFN, PARAM_STR, "Can't open or create save file '%s'" },
|
||||||
|
{ SEVERITY_SUCC, MSG_SAVED, PARAM_STR, "Configuration saved to file '%s'" },
|
||||||
|
{ SEVERITY_ERR, MSG_ACCDENY, PARAM_STR, "Access denied to '%s' command" },
|
||||||
|
{ SEVERITY_SUCC, MSG_ACCOK, PARAM_NONE, "Privileged access OK" },
|
||||||
|
{ SEVERITY_SUCC, MSG_ENAPOOL, PARAM_POOL, "Enabling pool %d:'%s'" },
|
||||||
|
{ SEVERITY_SUCC, MSG_POOLPRIO,PARAM_NONE, "Changed pool priorities" },
|
||||||
|
{ SEVERITY_ERR, MSG_DUPPID, PARAM_PID, "Duplicate pool specified %d" },
|
||||||
|
{ SEVERITY_SUCC, MSG_DISPOOL, PARAM_POOL, "Disabling pool %d:'%s'" },
|
||||||
|
{ SEVERITY_INFO, MSG_ALRENAP, PARAM_POOL, "Pool %d:'%s' already enabled" },
|
||||||
|
{ SEVERITY_INFO, MSG_ALRDISP, PARAM_POOL, "Pool %d:'%s' already disabled" },
|
||||||
|
{ SEVERITY_ERR, MSG_MISPDP, PARAM_NONE, "Missing addpool details" },
|
||||||
|
{ SEVERITY_ERR, MSG_INVPDP, PARAM_STR, "Invalid addpool details '%s'" },
|
||||||
|
{ SEVERITY_ERR, MSG_TOOMANYP,PARAM_NONE, "Reached maximum number of pools (%d)" },
|
||||||
|
{ SEVERITY_SUCC, MSG_ADDPOOL, PARAM_STR, "Added pool '%s'" },
|
||||||
|
{ SEVERITY_ERR, MSG_REMLASTP,PARAM_POOL, "Cannot remove last pool %d:'%s'" },
|
||||||
|
{ SEVERITY_ERR, MSG_ACTPOOL, PARAM_POOL, "Cannot remove active pool %d:'%s'" },
|
||||||
|
{ SEVERITY_SUCC, MSG_REMPOOL, PARAM_BOTH, "Removed pool %d:'%s'" },
|
||||||
|
{ SEVERITY_SUCC, MSG_NOTIFY, PARAM_NONE, "Notify" },
|
||||||
|
{ SEVERITY_SUCC, MSG_DEVDETAILS,PARAM_NONE, "Device Details" },
|
||||||
|
{ SEVERITY_SUCC, MSG_MINESTATS,PARAM_NONE, "sgminer stats" },
|
||||||
|
{ SEVERITY_ERR, MSG_MISCHK, PARAM_NONE, "Missing check cmd" },
|
||||||
|
{ SEVERITY_SUCC, MSG_CHECK, PARAM_NONE, "Check command" },
|
||||||
|
{ SEVERITY_ERR, MSG_MISBOOL, PARAM_NONE, "Missing parameter: true/false" },
|
||||||
|
{ SEVERITY_ERR, MSG_INVBOOL, PARAM_NONE, "Invalid parameter should be true or false" },
|
||||||
|
{ SEVERITY_SUCC, MSG_FOO, PARAM_BOOL, "Failover-Only set to %s" },
|
||||||
|
{ SEVERITY_SUCC, MSG_MINECOIN,PARAM_NONE, "sgminer coin" },
|
||||||
|
{ SEVERITY_SUCC, MSG_DEBUGSET,PARAM_NONE, "Debug settings" },
|
||||||
|
{ SEVERITY_SUCC, MSG_SETCONFIG,PARAM_SET, "Set config '%s' to %d" },
|
||||||
|
{ SEVERITY_ERR, MSG_UNKCON, PARAM_STR, "Unknown config '%s'" },
|
||||||
|
{ SEVERITY_ERR, MSG_INVNUM, PARAM_BOTH, "Invalid number (%d) for '%s' range is 0-9999" },
|
||||||
|
{ SEVERITY_ERR, MSG_INVNEG, PARAM_BOTH, "Invalid negative number (%d) for '%s'" },
|
||||||
|
{ SEVERITY_SUCC, MSG_SETQUOTA,PARAM_SET, "Set pool '%s' to quota %d'" },
|
||||||
|
{ SEVERITY_ERR, MSG_CONPAR, PARAM_NONE, "Missing config parameters 'name,N'" },
|
||||||
|
{ SEVERITY_ERR, MSG_CONVAL, PARAM_STR, "Missing config value N for '%s,N'" },
|
||||||
|
{ SEVERITY_INFO, MSG_NOUSTA, PARAM_NONE, "No USB Statistics" },
|
||||||
|
{ SEVERITY_ERR, MSG_ZERMIS, PARAM_NONE, "Missing zero parameters" },
|
||||||
|
{ SEVERITY_ERR, MSG_ZERINV, PARAM_STR, "Invalid zero parameter '%s'" },
|
||||||
|
{ SEVERITY_SUCC, MSG_ZERSUM, PARAM_STR, "Zeroed %s stats with summary" },
|
||||||
|
{ SEVERITY_SUCC, MSG_ZERNOSUM, PARAM_STR, "Zeroed %s stats without summary" },
|
||||||
|
{ SEVERITY_SUCC, MSG_LOCKOK, PARAM_NONE, "Lock stats created" },
|
||||||
|
{ SEVERITY_WARN, MSG_LOCKDIS, PARAM_NONE, "Lock stats not enabled" },
|
||||||
|
{ SEVERITY_SUCC, MSG_CHSTRAT, PARAM_STR, "Multipool strategy changed to '%s'" },
|
||||||
|
{ SEVERITY_ERR, MSG_MISSTRAT, PARAM_NONE, "Missing multipool strategy" },
|
||||||
|
{ SEVERITY_ERR, MSG_INVSTRAT, PARAM_NONE, "Invalid multipool strategy %d" },
|
||||||
|
{ SEVERITY_ERR, MSG_MISSTRATINT, PARAM_NONE, "Missing rotate interval" },
|
||||||
|
{ SEVERITY_SUCC, MSG_BYE, PARAM_STR, "%s" },
|
||||||
|
{ SEVERITY_FAIL, 0, (enum code_parameters)0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IP4ACCESS {
|
||||||
|
in_addr_t ip;
|
||||||
|
in_addr_t mask;
|
||||||
|
char group;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GROUP(g) (toupper(g))
|
||||||
|
#define PRIVGROUP GROUP('W')
|
||||||
|
#define NOPRIVGROUP GROUP('R')
|
||||||
|
#define ISPRIVGROUP(g) (GROUP(g) == PRIVGROUP)
|
||||||
|
#define GROUPOFFSET(g) (GROUP(g) - GROUP('A'))
|
||||||
|
#define VALIDGROUP(g) (GROUP(g) >= GROUP('A') && GROUP(g) <= GROUP('Z'))
|
||||||
|
#define COMMANDS(g) (apigroups[GROUPOFFSET(g)].commands)
|
||||||
|
#define DEFINEDGROUP(g) (ISPRIVGROUP(g) || COMMANDS(g) != NULL)
|
||||||
|
|
||||||
|
struct APIGROUPS {
|
||||||
|
// This becomes a string like: "|cmd1|cmd2|cmd3|" so it's quick to search
|
||||||
|
char *commands;
|
||||||
|
} apigroups['Z' - 'A' + 1]; // only A=0 to Z=25 (R: noprivs, W: allprivs)
|
||||||
|
|
||||||
|
struct io_data {
|
||||||
|
size_t siz;
|
||||||
|
char *ptr;
|
||||||
|
char *cur;
|
||||||
|
bool sock;
|
||||||
|
bool close;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct io_list {
|
||||||
|
struct io_data *io_data;
|
||||||
|
struct io_list *prev;
|
||||||
|
struct io_list *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void message(struct io_data *io_data, int messageid, int paramid, char *param2, bool isjson);
|
||||||
|
|
||||||
|
#define SOCKBUFALLOCSIZ 65536
|
||||||
|
|
||||||
|
#define io_new(init) _io_new(init, false)
|
||||||
|
#define sock_io_new() _io_new(SOCKBUFALLOCSIZ, true)
|
||||||
|
|
||||||
|
#if LOCK_TRACKING
|
||||||
|
|
||||||
|
#define LOCK_FMT_FFL " - called from %s %s():%d"
|
||||||
|
#define LOCKMSG(fmt, ...) fprintf(stderr, "APILOCK: " fmt "\n", ##__VA_ARGS__)
|
||||||
|
#define LOCKMSGMORE(fmt, ...) fprintf(stderr, " " fmt "\n", ##__VA_ARGS__)
|
||||||
|
#define LOCKMSGFFL(fmt, ...) fprintf(stderr, "APILOCK: " fmt LOCK_FMT_FFL "\n", ##__VA_ARGS__, file, func, linenum)
|
||||||
|
#define LOCKMSGFLUSH() fflush(stderr)
|
||||||
|
|
||||||
|
typedef struct lockstat {
|
||||||
|
uint64_t lock_id;
|
||||||
|
const char *file;
|
||||||
|
const char *func;
|
||||||
|
int linenum;
|
||||||
|
struct timeval tv;
|
||||||
|
} LOCKSTAT;
|
||||||
|
|
||||||
|
typedef struct lockline {
|
||||||
|
struct lockline *prev;
|
||||||
|
struct lockstat *stat;
|
||||||
|
struct lockline *next;
|
||||||
|
} LOCKLINE;
|
||||||
|
|
||||||
|
typedef struct lockinfo {
|
||||||
|
void *lock;
|
||||||
|
enum cglock_typ typ;
|
||||||
|
const char *file;
|
||||||
|
const char *func;
|
||||||
|
int linenum;
|
||||||
|
uint64_t gets;
|
||||||
|
uint64_t gots;
|
||||||
|
uint64_t tries;
|
||||||
|
uint64_t dids;
|
||||||
|
uint64_t didnts; // should be tries - dids
|
||||||
|
uint64_t unlocks;
|
||||||
|
LOCKSTAT lastgot;
|
||||||
|
LOCKLINE *lockgets;
|
||||||
|
LOCKLINE *locktries;
|
||||||
|
} LOCKINFO;
|
||||||
|
|
||||||
|
typedef struct locklist {
|
||||||
|
LOCKINFO *info;
|
||||||
|
struct locklist *next;
|
||||||
|
} LOCKLIST;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* API_H */
|
2880
config_parser.c
2880
config_parser.c
File diff suppressed because it is too large
Load Diff
@ -8,34 +8,34 @@
|
|||||||
|
|
||||||
//helper to check for empty or NULL strings
|
//helper to check for empty or NULL strings
|
||||||
#ifndef empty_string
|
#ifndef empty_string
|
||||||
#define empty_string(str) ((str && str[0] != '\0')?0:1)
|
#define empty_string(str) ((str && str[0] != '\0')?0:1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//helper function to get a gpu option value
|
//helper function to get a gpu option value
|
||||||
#ifndef gpu_opt
|
#ifndef gpu_opt
|
||||||
#define gpu_opt(i,optname) gpus[i].optname
|
#define gpu_opt(i,optname) gpus[i].optname
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//profile structure
|
//profile structure
|
||||||
struct profile {
|
struct profile {
|
||||||
int profile_no;
|
int profile_no;
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
algorithm_t algorithm;
|
algorithm_t algorithm;
|
||||||
const char *devices;
|
const char *devices;
|
||||||
const char *intensity;
|
const char *intensity;
|
||||||
const char *xintensity;
|
const char *xintensity;
|
||||||
const char *rawintensity;
|
const char *rawintensity;
|
||||||
const char *lookup_gap;
|
const char *lookup_gap;
|
||||||
const char *gpu_engine;
|
const char *gpu_engine;
|
||||||
const char *gpu_memclock;
|
const char *gpu_memclock;
|
||||||
const char *gpu_threads;
|
const char *gpu_threads;
|
||||||
const char *gpu_fan;
|
const char *gpu_fan;
|
||||||
const char *gpu_powertune;
|
const char *gpu_powertune;
|
||||||
const char *gpu_vddc;
|
const char *gpu_vddc;
|
||||||
const char *shaders;
|
const char *shaders;
|
||||||
const char *thread_concurrency;
|
const char *thread_concurrency;
|
||||||
const char *worksize;
|
const char *worksize;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* globals needed outside */
|
/* globals needed outside */
|
||||||
@ -57,12 +57,12 @@ extern char *set_default_xintensity(const char *arg);
|
|||||||
extern char *set_default_rawintensity(const char *arg);
|
extern char *set_default_rawintensity(const char *arg);
|
||||||
extern char *set_default_thread_concurrency(const char *arg);
|
extern char *set_default_thread_concurrency(const char *arg);
|
||||||
#ifdef HAVE_ADL
|
#ifdef HAVE_ADL
|
||||||
extern char *set_default_gpu_engine(const char *arg);
|
extern char *set_default_gpu_engine(const char *arg);
|
||||||
extern char *set_default_gpu_memclock(const char *arg);
|
extern char *set_default_gpu_memclock(const char *arg);
|
||||||
extern char *set_default_gpu_threads(const char *arg);
|
extern char *set_default_gpu_threads(const char *arg);
|
||||||
extern char *set_default_gpu_fan(const char *arg);
|
extern char *set_default_gpu_fan(const char *arg);
|
||||||
extern char *set_default_gpu_powertune(const char *arg);
|
extern char *set_default_gpu_powertune(const char *arg);
|
||||||
extern char *set_default_gpu_vddc(const char *arg);
|
extern char *set_default_gpu_vddc(const char *arg);
|
||||||
#endif
|
#endif
|
||||||
extern char *set_default_profile(char *arg);
|
extern char *set_default_profile(char *arg);
|
||||||
extern char *set_default_shaders(const char *arg);
|
extern char *set_default_shaders(const char *arg);
|
||||||
@ -77,12 +77,12 @@ extern char *set_profile_xintensity(const char *arg);
|
|||||||
extern char *set_profile_rawintensity(const char *arg);
|
extern char *set_profile_rawintensity(const char *arg);
|
||||||
extern char *set_profile_thread_concurrency(const char *arg);
|
extern char *set_profile_thread_concurrency(const char *arg);
|
||||||
#ifdef HAVE_ADL
|
#ifdef HAVE_ADL
|
||||||
extern char *set_profile_gpu_engine(const char *arg);
|
extern char *set_profile_gpu_engine(const char *arg);
|
||||||
extern char *set_profile_gpu_memclock(const char *arg);
|
extern char *set_profile_gpu_memclock(const char *arg);
|
||||||
extern char *set_profile_gpu_threads(const char *arg);
|
extern char *set_profile_gpu_threads(const char *arg);
|
||||||
extern char *set_profile_gpu_fan(const char *arg);
|
extern char *set_profile_gpu_fan(const char *arg);
|
||||||
extern char *set_profile_gpu_powertune(const char *arg);
|
extern char *set_profile_gpu_powertune(const char *arg);
|
||||||
extern char *set_profile_gpu_vddc(const char *arg);
|
extern char *set_profile_gpu_vddc(const char *arg);
|
||||||
#endif
|
#endif
|
||||||
extern char *set_profile_nfactor(const char *arg);
|
extern char *set_profile_nfactor(const char *arg);
|
||||||
extern char *set_profile_shaders(const char *arg);
|
extern char *set_profile_shaders(const char *arg);
|
||||||
@ -98,6 +98,7 @@ extern void load_default_config(void);
|
|||||||
extern void load_default_profile();
|
extern void load_default_profile();
|
||||||
extern void apply_defaults();
|
extern void apply_defaults();
|
||||||
extern void apply_pool_profiles();
|
extern void apply_pool_profiles();
|
||||||
|
extern void apply_pool_profile(struct pool *pool);
|
||||||
|
|
||||||
/* config writer */
|
/* config writer */
|
||||||
extern void write_config(const char *filename);
|
extern void write_config(const char *filename);
|
||||||
|
@ -207,13 +207,13 @@ The list of requests - a (*) means it requires privileged access - and replies:
|
|||||||
stating the results of enabling pool N
|
stating the results of enabling pool N
|
||||||
The Msg includes the pool URL
|
The Msg includes the pool URL
|
||||||
|
|
||||||
addpool|URL,USR,PASS[,NAME,DESC,ALGO] (*)
|
addpool|URL,USR,PASS[,NAME,DESC,PROFILE,ALGO] (*)
|
||||||
none There is no reply section just the STATUS section
|
none There is no reply section just the STATUS section
|
||||||
stating the results of attempting to add pool N
|
stating the results of attempting to add pool N
|
||||||
The Msg includes the pool URL
|
The Msg includes the pool URL
|
||||||
Use '\\' to get a '\' and '\,' to include a comma
|
Use '\\' to get a '\' and '\,' to include a comma
|
||||||
inside URL, USR or PASS
|
inside URL, USR or PASS
|
||||||
Name, description and algorithm are optional
|
Name, description, profile and algorithm are optional
|
||||||
|
|
||||||
poolpriority|N,... (*)
|
poolpriority|N,... (*)
|
||||||
none There is no reply section just the STATUS section
|
none There is no reply section just the STATUS section
|
||||||
@ -235,6 +235,13 @@ The list of requests - a (*) means it requires privileged access - and replies:
|
|||||||
The Msg includes the pool URL
|
The Msg includes the pool URL
|
||||||
N.B. all details for the pool will be lost
|
N.B. all details for the pool will be lost
|
||||||
|
|
||||||
|
changestrategy|STRAT,INT (*)
|
||||||
|
none There is no reply section just the STATUS section
|
||||||
|
stating the results of changing multipool strategy
|
||||||
|
to STRAT. If the strategy requested is "rotate",
|
||||||
|
the interval INT must be specified as a number
|
||||||
|
between 0 and 9999 seconds. INT is not required
|
||||||
|
otherwise.
|
||||||
gpuenable|N (*)
|
gpuenable|N (*)
|
||||||
none There is no reply section just the STATUS section
|
none There is no reply section just the STATUS section
|
||||||
stating the results of the enable request
|
stating the results of the enable request
|
6
miner.h
6
miner.h
@ -253,7 +253,6 @@ enum alive {
|
|||||||
LIFE_INIT,
|
LIFE_INIT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum pool_strategy {
|
enum pool_strategy {
|
||||||
POOL_FAILOVER,
|
POOL_FAILOVER,
|
||||||
POOL_ROUNDROBIN,
|
POOL_ROUNDROBIN,
|
||||||
@ -268,6 +267,9 @@ struct strategies {
|
|||||||
const char *s;
|
const char *s;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern enum pool_strategy pool_strategy;
|
||||||
|
extern struct strategies strategies[];
|
||||||
|
|
||||||
struct cgpu_info;
|
struct cgpu_info;
|
||||||
|
|
||||||
#ifdef HAVE_ADL
|
#ifdef HAVE_ADL
|
||||||
@ -1044,7 +1046,7 @@ extern bool detect_stratum(struct pool *pool, char *url);
|
|||||||
extern void print_summary(void);
|
extern void print_summary(void);
|
||||||
extern void adjust_quota_gcd(void);
|
extern void adjust_quota_gcd(void);
|
||||||
extern struct pool *add_pool(void);
|
extern struct pool *add_pool(void);
|
||||||
extern bool add_pool_details(struct pool *pool, bool live, char *url, char *user, char *pass, char *name, char *desc, char *algo);
|
extern bool add_pool_details(struct pool *pool, bool live, char *url, char *user, char *pass, char *name, char *desc, char *profile, char *algo);
|
||||||
|
|
||||||
#define MAX_GPUDEVICES 16
|
#define MAX_GPUDEVICES 16
|
||||||
#define MAX_DEVICES 4096
|
#define MAX_DEVICES 4096
|
||||||
|
57
sgminer.c
57
sgminer.c
@ -71,14 +71,6 @@ char *curly = ":D";
|
|||||||
#define VERSION GIT_VERSION
|
#define VERSION GIT_VERSION
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct strategies strategies[] = {
|
|
||||||
{ "Failover" },
|
|
||||||
{ "Round Robin" },
|
|
||||||
{ "Rotate" },
|
|
||||||
{ "Load Balance" },
|
|
||||||
{ "Balance" },
|
|
||||||
};
|
|
||||||
|
|
||||||
static char packagename[256];
|
static char packagename[256];
|
||||||
|
|
||||||
bool opt_work_update;
|
bool opt_work_update;
|
||||||
@ -230,6 +222,14 @@ unsigned int total_go, total_ro;
|
|||||||
struct pool **pools;
|
struct pool **pools;
|
||||||
static struct pool *currentpool = NULL;
|
static struct pool *currentpool = NULL;
|
||||||
|
|
||||||
|
struct strategies strategies[] = {
|
||||||
|
{ "Failover" },
|
||||||
|
{ "Round Robin" },
|
||||||
|
{ "Rotate" },
|
||||||
|
{ "Load Balance" },
|
||||||
|
{ "Balance" },
|
||||||
|
};
|
||||||
|
|
||||||
int total_pools, enabled_pools;
|
int total_pools, enabled_pools;
|
||||||
enum pool_strategy pool_strategy = POOL_FAILOVER;
|
enum pool_strategy pool_strategy = POOL_FAILOVER;
|
||||||
int opt_rotate_period;
|
int opt_rotate_period;
|
||||||
@ -1390,6 +1390,16 @@ struct opt_table opt_config_table[] = {
|
|||||||
OPT_WITHOUT_ARG("--more-notices",
|
OPT_WITHOUT_ARG("--more-notices",
|
||||||
opt_set_bool, &opt_morenotices,
|
opt_set_bool, &opt_morenotices,
|
||||||
"Shows work restart and new block notices, hidden by default"),
|
"Shows work restart and new block notices, hidden by default"),
|
||||||
|
OPT_WITH_ARG("--intensity|-I",
|
||||||
|
set_default_intensity, NULL, NULL,
|
||||||
|
"Intensity of GPU scanning (d or " MIN_INTENSITY_STR
|
||||||
|
" -> " MAX_INTENSITY_STR
|
||||||
|
",default: d to maintain desktop interactivity), overridden by --xintensity or --rawintensity."),
|
||||||
|
OPT_WITH_ARG("--xintensity|-X",
|
||||||
|
// set_xintensity, NULL, NULL,
|
||||||
|
set_default_xintensity, NULL, NULL,
|
||||||
|
"Shader based intensity of GPU scanning (" MIN_XINTENSITY_STR " to "
|
||||||
|
MAX_XINTENSITY_STR "), overridden --xintensity|-X and --rawintensity."),
|
||||||
OPT_WITH_ARG("--xintensity|-X",
|
OPT_WITH_ARG("--xintensity|-X",
|
||||||
// set_xintensity, NULL, NULL,
|
// set_xintensity, NULL, NULL,
|
||||||
set_default_xintensity, NULL, NULL,
|
set_default_xintensity, NULL, NULL,
|
||||||
@ -1449,7 +1459,7 @@ struct opt_table opt_config_table[] = {
|
|||||||
OPT_WITHOUT_ARG("--no-submit-stale",
|
OPT_WITHOUT_ARG("--no-submit-stale",
|
||||||
opt_set_invbool, &opt_submit_stale,
|
opt_set_invbool, &opt_submit_stale,
|
||||||
"Don't submit shares if they are detected as stale"),
|
"Don't submit shares if they are detected as stale"),
|
||||||
OPT_WITHOUT_ARG("--no-extranonce-subscribe",
|
OPT_WITHOUT_ARG("--no-extranonce|--pool-no-extranonce",
|
||||||
set_no_extranonce_subscribe, NULL,
|
set_no_extranonce_subscribe, NULL,
|
||||||
"Disable 'extranonce' stratum subscribe for pool"),
|
"Disable 'extranonce' stratum subscribe for pool"),
|
||||||
OPT_WITH_ARG("--pass|--pool-pass|-p",
|
OPT_WITH_ARG("--pass|--pool-pass|-p",
|
||||||
@ -1628,7 +1638,7 @@ struct opt_table opt_config_table[] = {
|
|||||||
OPT_WITHOUT_ARG("--show-coindiff",
|
OPT_WITHOUT_ARG("--show-coindiff",
|
||||||
opt_set_bool, &opt_show_coindiff,
|
opt_set_bool, &opt_show_coindiff,
|
||||||
"Show coin difficulty rather than hash value of a share"),
|
"Show coin difficulty rather than hash value of a share"),
|
||||||
OPT_WITH_ARG("--state",
|
OPT_WITH_ARG("--state|--pool-state",
|
||||||
set_pool_state, NULL, NULL,
|
set_pool_state, NULL, NULL,
|
||||||
"Specify pool state at startup (default: enabled)"),
|
"Specify pool state at startup (default: enabled)"),
|
||||||
#ifdef HAVE_SYSLOG_H
|
#ifdef HAVE_SYSLOG_H
|
||||||
@ -1689,7 +1699,7 @@ struct opt_table opt_config_table[] = {
|
|||||||
OPT_WITH_ARG("--worksize|-w",
|
OPT_WITH_ARG("--worksize|-w",
|
||||||
set_default_worksize, NULL, NULL,
|
set_default_worksize, NULL, NULL,
|
||||||
"Override detected optimal worksize - one value or comma separated list"),
|
"Override detected optimal worksize - one value or comma separated list"),
|
||||||
OPT_WITH_ARG("--userpass|-O",
|
OPT_WITH_ARG("--userpass|--pool-userpass|-O",
|
||||||
set_userpass, NULL, NULL,
|
set_userpass, NULL, NULL,
|
||||||
"Username:Password pair for bitcoin JSON-RPC server"),
|
"Username:Password pair for bitcoin JSON-RPC server"),
|
||||||
OPT_WITHOUT_ARG("--worktime",
|
OPT_WITHOUT_ARG("--worktime",
|
||||||
@ -7200,7 +7210,7 @@ static void *test_pool_thread(void *arg)
|
|||||||
/* Always returns true that the pool details were added unless we are not
|
/* Always returns true that the pool details were added unless we are not
|
||||||
* live, implying this is the only pool being added, so if no pools are
|
* live, implying this is the only pool being added, so if no pools are
|
||||||
* active it returns false. */
|
* active it returns false. */
|
||||||
bool add_pool_details(struct pool *pool, bool live, char *url, char *user, char *pass, char *name, char *desc, char *algo)
|
bool add_pool_details(struct pool *pool, bool live, char *url, char *user, char *pass, char *name, char *desc, char *profile, char *algo)
|
||||||
{
|
{
|
||||||
size_t siz;
|
size_t siz;
|
||||||
|
|
||||||
@ -7211,7 +7221,20 @@ bool add_pool_details(struct pool *pool, bool live, char *url, char *user, char
|
|||||||
pool->rpc_pass = pass;
|
pool->rpc_pass = pass;
|
||||||
pool->name = name;
|
pool->name = name;
|
||||||
pool->description = desc;
|
pool->description = desc;
|
||||||
set_algorithm(&pool->algorithm, algo);
|
pool->profile = profile;
|
||||||
|
|
||||||
|
//if a profile was supplied, apply pool properties from profile
|
||||||
|
if(!empty_string(profile))
|
||||||
|
apply_pool_profile(pool); //remove profile if was invalid
|
||||||
|
|
||||||
|
//if profile is empty, assign algorithm or default algorithm
|
||||||
|
if(empty_string(pool->profile))
|
||||||
|
{
|
||||||
|
if(!empty_string(algo))
|
||||||
|
set_algorithm(&pool->algorithm, algo);
|
||||||
|
else
|
||||||
|
set_algorithm(&pool->algorithm, default_profile.algorithm.name);
|
||||||
|
}
|
||||||
|
|
||||||
siz = strlen(pool->rpc_user) + strlen(pool->rpc_pass) + 2;
|
siz = strlen(pool->rpc_user) + strlen(pool->rpc_pass) + 2;
|
||||||
pool->rpc_userpass = (char *)malloc(siz);
|
pool->rpc_userpass = (char *)malloc(siz);
|
||||||
@ -7236,7 +7259,7 @@ bool add_pool_details(struct pool *pool, bool live, char *url, char *user, char
|
|||||||
static bool input_pool(bool live)
|
static bool input_pool(bool live)
|
||||||
{
|
{
|
||||||
char *url = NULL, *user = NULL, *pass = NULL;
|
char *url = NULL, *user = NULL, *pass = NULL;
|
||||||
char *name = NULL, *desc = NULL, *algo = NULL;
|
char *name = NULL, *desc = NULL, *profile = NULL, *algo = NULL;
|
||||||
struct pool *pool;
|
struct pool *pool;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
@ -7254,8 +7277,10 @@ static bool input_pool(bool live)
|
|||||||
if (strcmp(name, "-1") == 0) strcpy(name, "");
|
if (strcmp(name, "-1") == 0) strcpy(name, "");
|
||||||
desc = curses_input("Description (optional)");
|
desc = curses_input("Description (optional)");
|
||||||
if (strcmp(desc, "-1") == 0) strcpy(desc, "");
|
if (strcmp(desc, "-1") == 0) strcpy(desc, "");
|
||||||
|
algo = curses_input("Profile (optional)");
|
||||||
|
if (strcmp(profile, "-1") == 0) profile[0] = '\0';
|
||||||
algo = curses_input("Algorithm (optional)");
|
algo = curses_input("Algorithm (optional)");
|
||||||
if (strcmp(algo, "-1") == 0) strcpy(algo, opt_algorithm.name);
|
if (strcmp(algo, "-1") == 0) algo[0] = '\0';
|
||||||
|
|
||||||
pool = add_pool();
|
pool = add_pool();
|
||||||
|
|
||||||
@ -7273,7 +7298,7 @@ static bool input_pool(bool live)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = add_pool_details(pool, live, url, user, pass,
|
ret = add_pool_details(pool, live, url, user, pass,
|
||||||
name, desc, algo);
|
name, desc, profile, algo);
|
||||||
out:
|
out:
|
||||||
immedok(logwin, false);
|
immedok(logwin, false);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user