@ -157,7 +157,7 @@ static const char *COMMA = ",";
@@ -157,7 +157,7 @@ static const char *COMMA = ",";
static const char SEPARATOR = ' | ' ;
static const char GPUSEP = ' , ' ;
static const char * APIVERSION = " 1.6 " ;
static const char * APIVERSION = " 1.7 " ;
static const char * DEAD = " Dead " ;
static const char * SICK = " Sick " ;
static const char * NOSTART = " NoStart " ;
@ -337,6 +337,10 @@ static const char *JSON_PARAMETER = "parameter";
@@ -337,6 +337,10 @@ static const char *JSON_PARAMETER = "parameter";
# define MSG_PGAUNW 65
# endif
# define MSG_REMLASTP 66
# define MSG_ACTPOOL 67
# define MSG_REMPOOL 68
enum code_severity {
SEVERITY_ERR ,
SEVERITY_WARN ,
@ -456,6 +460,9 @@ struct CODES {
@@ -456,6 +460,9 @@ struct CODES {
{ 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_FAIL , 0 , 0 , NULL }
} ;
@ -483,6 +490,68 @@ extern struct device_api bitforce_api;
@@ -483,6 +490,68 @@ extern struct device_api bitforce_api;
extern struct device_api icarus_api ;
# endif
// This is only called when expected to be needed (rarely)
// i.e. strings outside of the codes control (input from the user)
static char * escape_string ( char * str , bool isjson )
{
char * buf , * ptr ;
int count ;
count = 0 ;
for ( ptr = str ; * ptr ; ptr + + ) {
switch ( * ptr ) {
case ' , ' :
case ' | ' :
case ' = ' :
if ( ! isjson )
count + + ;
break ;
case ' " ' :
if ( isjson )
count + + ;
break ;
case ' \\ ' :
count + + ;
break ;
}
}
if ( count = = 0 )
return str ;
buf = malloc ( strlen ( str ) + count + 1 ) ;
if ( unlikely ( ! buf ) )
quit ( 1 , " Failed to malloc escape buf " ) ;
ptr = buf ;
while ( * str )
switch ( * str ) {
case ' , ' :
case ' | ' :
case ' = ' :
if ( ! isjson )
* ( ptr + + ) = ' \\ ' ;
* ( ptr + + ) = * ( str + + ) ;
break ;
case ' " ' :
if ( isjson )
* ( ptr + + ) = ' \\ ' ;
* ( ptr + + ) = * ( str + + ) ;
break ;
case ' \\ ' :
* ( ptr + + ) = ' \\ ' ;
* ( ptr + + ) = * ( str + + ) ;
break ;
default :
* ( ptr + + ) = * ( str + + ) ;
break ;
}
* ptr = ' \0 ' ;
return buf ;
}
# if defined(USE_BITFORCE) || defined(USE_ICARUS)
static int numpgas ( )
{
@ -1102,6 +1171,8 @@ static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
@@ -1102,6 +1171,8 @@ static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
{
char buf [ BUFSIZ ] ;
char * status , * lp ;
char * rpc_url ;
char * rpc_user ;
int i ;
if ( total_pools = = 0 ) {
@ -1133,27 +1204,40 @@ static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
@@ -1133,27 +1204,40 @@ static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
else
lp = ( char * ) NO ;
rpc_url = escape_string ( pool - > rpc_url , isjson ) ;
rpc_user = escape_string ( pool - > rpc_user , isjson ) ;
if ( isjson )
sprintf ( buf , " %s{ \" POOL \" :%d, \" URL \" : \" %s \" , \" Status \" : \" %s \" , \" Priority \" :%d, \" Long Poll \" : \" %s \" , \" Getworks \" :%d, \" Accepted \" :%d, \" Rejected \" :%d, \" Discarded \" :%d, \" Stale \" :%d, \" Get Failures \" :%d, \" Remote Failures \" :%d} " ,
sprintf ( buf , " %s{ \" POOL \" :%d, \" URL \" : \" %s \" , \" Status \" : \" %s \" , \" Priority \" :%d, \" Long Poll \" : \" %s \" , \" Getworks \" :%d, \" Accepted \" :%d, \" Rejected \" :%d, \" Discarded \" :%d, \" Stale \" :%d, \" Get Failures \" :%d, \" Remote Failures \" :%d, \" User \" : \" %s \" } " ,
( i > 0 ) ? COMMA : " " ,
i , pool - > rpc_url , status , pool - > prio , lp ,
i , rpc_url , status , pool - > prio , lp ,
pool - > getwork_requested ,
pool - > accepted , pool - > rejected ,
pool - > discarded_work ,
pool - > stale_shares ,
pool - > getfail_occasions ,
pool - > remotefail_occasions ) ;
pool - > remotefail_occasions ,
rpc_user ) ;
else
sprintf ( buf , " POOL=%d,URL=%s,Status=%s,Priority=%d,Long Poll=%s,Getworks=%d,Accepted=%d,Rejected=%d,Discarded=%d,Stale=%d,Get Failures=%d,Remote Failures=%d%c " ,
i , pool - > rpc_url , status , pool - > prio , lp ,
sprintf ( buf , " POOL=%d,URL=%s,Status=%s,Priority=%d,Long Poll=%s,Getworks=%d,Accepted=%d,Rejected=%d,Discarded=%d,Stale=%d,Get Failures=%d,Remote Failures=%d,User=%s %c " ,
i , rpc_url , status , pool - > prio , lp ,
pool - > getwork_requested ,
pool - > accepted , pool - > rejected ,
pool - > discarded_work ,
pool - > stale_shares ,
pool - > getfail_occasions ,
pool - > remotefail_occasions , SEPARATOR ) ;
pool - > remotefail_occasions ,
rpc_user , SEPARATOR ) ;
strcat ( io_buffer , buf ) ;
if ( rpc_url ! = pool - > rpc_url )
free ( rpc_url ) ;
rpc_url = NULL ;
if ( rpc_user ! = pool - > rpc_user )
free ( rpc_user ) ;
rpc_user = NULL ;
}
if ( isjson )
@ -1443,6 +1527,7 @@ exitsama:
@@ -1443,6 +1527,7 @@ exitsama:
static void addpool ( __maybe_unused SOCKETTYPE c , char * param , bool isjson )
{
char * url , * user , * pass ;
char * ptr ;
if ( param = = NULL | | * param = = ' \0 ' ) {
strcpy ( io_buffer , message ( MSG_MISPDP , 0 , NULL , isjson ) ) ;
@ -1450,7 +1535,11 @@ static void addpool(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
@@ -1450,7 +1535,11 @@ static void addpool(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
}
if ( ! pooldetails ( param , & url , & user , & pass ) ) {
strcpy ( io_buffer , message ( MSG_INVPDP , 0 , param , isjson ) ) ;
ptr = escape_string ( param , isjson ) ;
strcpy ( io_buffer , message ( MSG_INVPDP , 0 , ptr , isjson ) ) ;
if ( ptr ! = param )
free ( ptr ) ;
ptr = NULL ;
return ;
}
@ -1459,7 +1548,11 @@ static void addpool(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
@@ -1459,7 +1548,11 @@ static void addpool(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
return ;
}
strcpy ( io_buffer , message ( MSG_ADDPOOL , 0 , url , isjson ) ) ;
ptr = escape_string ( url , isjson ) ;
strcpy ( io_buffer , message ( MSG_ADDPOOL , 0 , ptr , isjson ) ) ;
if ( ptr ! = url )
free ( ptr ) ;
ptr = NULL ;
}
static void enablepool ( __maybe_unused SOCKETTYPE c , char * param , bool isjson )
@ -1535,6 +1628,57 @@ static void disablepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
@@ -1535,6 +1628,57 @@ static void disablepool(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
strcpy ( io_buffer , message ( MSG_DISPOOL , id , NULL , isjson ) ) ;
}
static void removepool ( __maybe_unused SOCKETTYPE c , char * param , bool isjson )
{
struct pool * pool ;
char * rpc_url ;
bool dofree = false ;
int id ;
if ( total_pools = = 0 ) {
strcpy ( io_buffer , message ( MSG_NOPOOL , 0 , NULL , isjson ) ) ;
return ;
}
if ( param = = NULL | | * param = = ' \0 ' ) {
strcpy ( io_buffer , message ( MSG_MISPID , 0 , NULL , isjson ) ) ;
return ;
}
id = atoi ( param ) ;
if ( id < 0 | | id > = total_pools ) {
strcpy ( io_buffer , message ( MSG_INVPID , id , NULL , isjson ) ) ;
return ;
}
if ( total_pools < = 1 ) {
strcpy ( io_buffer , message ( MSG_REMLASTP , id , NULL , isjson ) ) ;
return ;
}
pool = pools [ id ] ;
if ( pool = = current_pool ( ) )
switch_pools ( NULL ) ;
if ( pool = = current_pool ( ) ) {
strcpy ( io_buffer , message ( MSG_ACTPOOL , id , NULL , isjson ) ) ;
return ;
}
pool - > enabled = false ;
rpc_url = escape_string ( pool - > rpc_url , isjson ) ;
if ( rpc_url ! = pool - > rpc_url )
dofree = true ;
remove_pool ( pool ) ;
strcpy ( io_buffer , message ( MSG_REMPOOL , id , rpc_url , isjson ) ) ;
if ( dofree )
free ( rpc_url ) ;
rpc_url = NULL ;
}
static bool splitgpuvalue ( char * param , int * gpu , char * * value , bool isjson )
{
int id ;
@ -1792,6 +1936,7 @@ static void notify(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool
@@ -1792,6 +1936,7 @@ static void notify(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool
void dosave ( __maybe_unused SOCKETTYPE c , char * param , bool isjson )
{
FILE * fcfg ;
char * ptr ;
if ( param = = NULL | | * param = = ' \0 ' ) {
strcpy ( io_buffer , message ( MSG_MISFN , 0 , NULL , isjson ) ) ;
@ -1800,14 +1945,22 @@ void dosave(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
@@ -1800,14 +1945,22 @@ void dosave(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
fcfg = fopen ( param , " w " ) ;
if ( ! fcfg ) {
strcpy ( io_buffer , message ( MSG_BADFN , 0 , param , isjson ) ) ;
ptr = escape_string ( param , isjson ) ;
strcpy ( io_buffer , message ( MSG_BADFN , 0 , ptr , isjson ) ) ;
if ( ptr ! = param )
free ( ptr ) ;
ptr = NULL ;
return ;
}
write_config ( fcfg ) ;
fclose ( fcfg ) ;
strcpy ( io_buffer , message ( MSG_SAVED , 0 , param , isjson ) ) ;
ptr = escape_string ( param , isjson ) ;
strcpy ( io_buffer , message ( MSG_SAVED , 0 , ptr , isjson ) ) ;
if ( ptr ! = param )
free ( ptr ) ;
ptr = NULL ;
}
struct CMDS {
@ -1839,6 +1992,7 @@ struct CMDS {
@@ -1839,6 +1992,7 @@ struct CMDS {
{ " addpool " , addpool , true } ,
{ " enablepool " , enablepool , true } ,
{ " disablepool " , disablepool , true } ,
{ " removepool " , removepool , true } ,
{ " gpuintensity " , gpuintensity , true } ,
{ " gpumem " , gpumem , true } ,
{ " gpuengine " , gpuengine , true } ,