Browse Source

Merge branch 'master' of github.com:ckolivas/cgminer

nfactor-troky
Con Kolivas 11 years ago
parent
commit
b445f9ce87
  1. 42
      API-README
  2. 160
      miner.php

42
API-README

@ -952,7 +952,9 @@ or in your cgminer.conf @@ -952,7 +952,9 @@ or in your cgminer.conf
And in miner.php set $mcast = true;
This will ignore the value of $rigs and overwrite it with the list of zero or
more rigs found on the network in the timout specified
more rigs found on the network in the timeout specified
A rig will not reply if the API settings would mean it would also ignore an
API request from the web server running miner.php
---------
@ -1196,6 +1198,14 @@ Set $mcast to true to look for your rigs and ignore $rigs @@ -1196,6 +1198,14 @@ Set $mcast to true to look for your rigs and ignore $rigs
---------
Default:
$mcastexpect = 0;
The minimum number of rigs expected to be found when $mcast is true
If fewer are found, an error will be included at the top of the page
---------
Default:
$mcastaddr = '224.0.0.75';
@ -1237,6 +1247,16 @@ N.B. the accuracy of the timing used to wait for the replies is @@ -1237,6 +1247,16 @@ N.B. the accuracy of the timing used to wait for the replies is
---------
Default:
$allowgen = false;
Set $allowgen to true to allow customsummarypages to use 'gen'
false means ignore any 'gen' options
This is disabled by default due to the possible security risk
of using it, see the end of this document for an explanation
---------
Default:
$rigipsecurity = true;
@ -1498,6 +1518,7 @@ The example given: @@ -1498,6 +1518,7 @@ The example given:
With cgminer 2.10.2 and later, miner.php includes an extension to
the custom pages that allows you to apply SQL style commands to
the data: where, group, and having
cgminer 3.4.2 also includes another option 'gen'
As an example, miner.php includes a more complex custom page called 'Pools'
this includes the extension:
@ -1513,6 +1534,7 @@ $poolsext = array( @@ -1513,6 +1534,7 @@ $poolsext = array(
'STATS.Bytes Sent' => 'sum',
'STATS.Times Recv' => 'sum',
'STATS.Bytes Recv' => 'sum'),
'gen' => array('AvShr', 'POOL.Difficulty Accepted/max(POOL.Accepted,1)),
'having' => array(array('STATS.Bytes Recv', '>', 0)))
);
@ -1564,3 +1586,21 @@ The first 4 are as expected - the numerical sum, average, minimum or maximum @@ -1564,3 +1586,21 @@ The first 4 are as expected - the numerical sum, average, minimum or maximum
of course any valid 'DEVS.Xyz' would give the same 'count' value
'any' is effectively random: the field value in the 1st row of the grouped data
An unrecognised 'function' uses 'any'
A 'gen' allows you to generate new fields from any php valid function of any
of the other fields
e.g. 'gen' => array('AvShr', 'POOL.Difficulty Accepted/max(POOL.Accepted,1)),
will generate a new field called GEN.AvShr that is the function shown, which
in this case is the average difficulty of each share submitted
THERE IS A SECURITY RISK WITH HOW GEN WORKS
It simply replaces all the variables with their values and then requests PHP
the execute the formula - thus if a field value returned from a cgminer API
request contained PHP code, it could be executed by your web server
Of course cgminer doesn't do this, but if you do not control the cgminer that
returns the data in the API calls, someone could modify cgminer to return a
PHP string in a field you use in 'gen'
Thus use 'gen' at your own risk
If someone feels the urge to write a mathematical interpreter in PHP to get
around this risk, feel free to write one and submit it to the API author for
consideration

160
miner.php

@ -1,17 +1,20 @@ @@ -1,17 +1,20 @@
<?php
session_start();
#
global $title, $miner, $port, $readonly, $notify, $rigs;
global $mcast, $mcastaddr, $mcastport, $mcastcode;
global $mcastlistport, $mcasttimeout;
global $doctype, $title, $miner, $port, $readonly, $notify, $rigs;
global $mcast, $mcastexpect, $mcastaddr, $mcastport, $mcastcode;
global $mcastlistport, $mcasttimeout, $allowgen;
global $rigipsecurity, $rigtotals, $forcerigtotals;
global $socksndtimeoutsec, $sockrcvtimeoutsec;
global $checklastshare, $poolinputs, $hidefields;
global $ignorerefresh, $changerefresh, $autorefresh;
global $allowcustompages, $customsummarypages;
global $miner_font_family, $miner_font_size;
global $bad_font_family, $bad_font_size;
global $colouroverride, $placebuttons, $userlist;
#
$doctype = "<!DOCTYPE html>\n";
#
# See API-README for more details of these variables and how
# to configure miner.php
#
@ -48,6 +51,9 @@ $rigs = array('127.0.0.1:4028'); @@ -48,6 +51,9 @@ $rigs = array('127.0.0.1:4028');
# Set $mcast to true to look for your rigs and ignore $rigs
$mcast = false;
#
# Set $mcastexpect to at least how many rigs you expect it to find
$mcastexpect = 0;
#
# API Multicast address all cgminers are listening on
$mcastaddr = '224.0.0.75';
#
@ -64,6 +70,10 @@ $mcastlistport = 4027; @@ -64,6 +70,10 @@ $mcastlistport = 4027;
# to wait for replies to the Multicast message
$mcasttimeout = 1.5;
#
# Set $allowgen to true to allow customsummarypages to use 'gen'
# false means ignore any 'gen' options
$allowgen = false;
#
# Set $rigipsecurity to false to show the IP/Port of the rig
# in the socket error messages and also show the full socket message
$rigipsecurity = true;
@ -139,7 +149,7 @@ $poolspage = array( @@ -139,7 +149,7 @@ $poolspage = array(
'POOL.Has GBT=GBT', 'STATS.Times Sent=TSent',
'STATS.Bytes Sent=BSent', 'STATS.Net Bytes Sent=NSent',
'STATS.Times Recv=TRecv', 'STATS.Bytes Recv=BRecv',
'STATS.Net Bytes Recv=NRecv'));
'STATS.Net Bytes Recv=NRecv', 'GEN.AvShr=AvShr'));
#
$poolssum = array(
'SUMMARY' => array('MHS av', 'Found Blocks', 'Accepted',
@ -156,7 +166,9 @@ $poolsext = array( @@ -156,7 +166,9 @@ $poolsext = array(
'calc' => array('POOL.Difficulty Accepted' => 'sum', 'POOL.Difficulty Rejected' => 'sum',
'STATS.Times Sent' => 'sum', 'STATS.Bytes Sent' => 'sum',
'STATS.Net Bytes Sent' => 'sum', 'STATS.Times Recv' => 'sum',
'STATS.Bytes Recv' => 'sum', 'STATS.Net Bytes Recv' => 'sum'),
'STATS.Bytes Recv' => 'sum', 'STATS.Net Bytes Recv' => 'sum',
'POOL.Accepted' => 'sum'),
'gen' => array('AvShr' => 'round(POOL.Difficulty Accepted/max(POOL.Accepted,1)*100)/100'),
'having' => array(array('STATS.Bytes Recv', '>', 0)))
);
@ -176,9 +188,12 @@ $warnfont = '<font color=red><b>'; @@ -176,9 +188,12 @@ $warnfont = '<font color=red><b>';
$warnoff = '</b></font>';
$dfmt = 'H:i:s j-M-Y \U\T\CP';
#
$miner_font_family = 'verdana,arial,sans';
$miner_font_family = 'Verdana, Arial, sans-serif, sans';
$miner_font_size = '13pt';
#
$bad_font_family = '"Times New Roman", Times, serif';
$bad_font_size = '18pt';
#
# Edit this or redefine it in myminer.php to change the colour scheme
# See $colourtable below for the list of names
$colouroverride = array();
@ -198,7 +213,7 @@ if (file_exists('myminer.php')) @@ -198,7 +213,7 @@ if (file_exists('myminer.php'))
# This is the system default that must always contain all necessary
# colours so it must be a constant
# You can override these values with $colouroverride
# The only one missing is in $warnfont
# The only one missing is $warnfont
# - which you can override directly anyway
global $colourtable;
$colourtable = array(
@ -210,6 +225,8 @@ $colourtable = array( @@ -210,6 +225,8 @@ $colourtable = array(
'td.h background' => '#c4ffff',
'td.err color' => 'black',
'td.err background' => '#ff3050',
'td.bad color' => 'black',
'td.bad background' => '#ff3050',
'td.warn color' => 'black',
'td.warn background' => '#ffb050',
'td.sta color' => 'green',
@ -269,9 +286,10 @@ function getdom($domname) @@ -269,9 +286,10 @@ function getdom($domname)
return getcss($domname, true);
}
#
function htmlhead($checkapi, $rig, $pg = null, $noscript = false)
function htmlhead($mcerr, $checkapi, $rig, $pg = null, $noscript = false)
{
global $title, $miner_font_family, $miner_font_size;
global $doctype, $title, $miner_font_family, $miner_font_size;
global $bad_font_family, $bad_font_size;
global $error, $readonly, $poolinputs, $here;
global $ignorerefresh, $autorefresh;
@ -300,14 +318,16 @@ function htmlhead($checkapi, $rig, $pg = null, $noscript = false) @@ -300,14 +318,16 @@ function htmlhead($checkapi, $rig, $pg = null, $noscript = false)
$readonly = true;
}
$miner_font = "font-family:$miner_font_family; font-size:$miner_font_size;";
$bad_font = "font-family:$bad_font_family; font-size:$bad_font_size;";
echo "<html><head>$refreshmeta
echo "$doctype<html><head>$refreshmeta
<title>$title</title>
<style type='text/css'>
td { $miner_font ".getcss('td')."}
td.two { $miner_font ".getcss('td.two')."}
td.h { $miner_font ".getcss('td.h')."}
td.err { $miner_font ".getcss('td.err')."}
td.bad { $bad_font ".getcss('td.bad')."}
td.warn { $miner_font ".getcss('td.warn')."}
td.sta { $miner_font ".getcss('td.sta')."}
td.tot { $miner_font ".getcss('td.tot')."}
@ -339,6 +359,14 @@ echo "</script>\n"; @@ -339,6 +359,14 @@ echo "</script>\n";
<tr><td align=center valign=top>
<table border=0 cellpadding=4 cellspacing=0 summary='Mine'>
<?php
echo $mcerr;
}
#
function minhead($mcerr = '')
{
global $readonly;
$readonly = true;
htmlhead($mcerr, false, null, null, true);
}
#
global $haderror, $error;
@ -643,9 +671,14 @@ function newrow() @@ -643,9 +671,14 @@ function newrow()
echo '<tr>';
}
#
function othrow($row)
{
return "<tr>$row</tr>";
}
#
function otherrow($row)
{
echo "<tr>$row</tr>";
echo othrow($row);
}
#
function endrow()
@ -1810,8 +1843,6 @@ function doOne($rig, $preprocess) @@ -1810,8 +1843,6 @@ function doOne($rig, $preprocess)
global $haderror, $readonly, $notify, $rigs;
global $placebuttons;
htmlhead(true, $rig);
if ($placebuttons == 'top' || $placebuttons == 'both')
pagebuttons($rig, null);
@ -2324,8 +2355,55 @@ function processcompare($which, $ext, $section, $res) @@ -2324,8 +2355,55 @@ function processcompare($which, $ext, $section, $res)
return $res;
}
#
function processext($ext, $section, $res)
function ss($a, $b)
{
$la = strlen($a);
$lb = strlen($b);
if ($la != $lb)
return $la - $lb;
return strcmp($a, $b);
}
#
function genfld($row, $calc)
{
uksort($row, "ss");
foreach ($row as $name => $value)
if (strstr($calc, $name) !== FALSE)
$calc = str_replace($name, $value, $calc);
eval("\$val = $calc;");
return $val;
}
#
function dogen($ext, $section, &$res, &$fields)
{
$gen = $ext[$section]['gen'];
foreach ($gen as $fld => $calc)
$fields[] = "GEN.$fld";
foreach ($res as $rig => $result)
foreach ($result as $sec => $row)
{
$secname = preg_replace('/\d/', '', $sec);
if (secmatch($section, $secname))
foreach ($gen as $fld => $calc)
{
$name = "GEN.$fld";
$val = genfld($row, $calc);
$res[$rig][$sec][$name] = $val;
}
}
}
#
function processext($ext, $section, $res, &$fields)
{
global $allowgen;
$res = processcompare('where', $ext, $section, $res);
if (isset($ext[$section]['group']))
@ -2393,6 +2471,10 @@ function processext($ext, $section, $res) @@ -2393,6 +2471,10 @@ function processext($ext, $section, $res)
}
}
// Generated fields (functions of other fields)
if ($allowgen === true && isset($ext[$section]['gen']))
dogen($ext, $section, $res, $fields);
return processcompare('having', $ext, $section, $res);
}
#
@ -2451,6 +2533,8 @@ function processcustompage($pagename, $sections, $sum, $ext, $namemap) @@ -2451,6 +2533,8 @@ function processcustompage($pagename, $sections, $sum, $ext, $namemap)
$results[$cmd][$num] = $process;
}
}
else
otherrow('<td class=bad>Bad "$rigs" array</td>');
}
$shownsomething = false;
@ -2487,7 +2571,8 @@ function processcustompage($pagename, $sections, $sum, $ext, $namemap) @@ -2487,7 +2571,8 @@ function processcustompage($pagename, $sections, $sum, $ext, $namemap)
if (isset($results[$sectionmap[$section]]))
{
$rigresults = processext($ext, $section, $results[$sectionmap[$section]]);
$rigresults = processext($ext, $section, $results[$sectionmap[$section]], $fields);
$showfields = array();
$showhead = array();
foreach ($fields as $field)
@ -2566,21 +2651,19 @@ function showcustompage($pagename) @@ -2566,21 +2651,19 @@ function showcustompage($pagename)
global $customsummarypages;
global $placebuttons;
htmlhead(false, null, $pagename);
if ($placebuttons == 'top' || $placebuttons == 'both')
pagebuttons(null, $pagename);
if (!isset($customsummarypages[$pagename]))
{
otherrow("<td colspan=100>Unknown custom summary page '$pagename'</td>");
otherrow("<td colspan=100 class=bad>Unknown custom summary page '$pagename'</td>");
return;
}
$c = count($customsummarypages[$pagename]);
if ($c < 2 || $c > 3)
{
$rw = "<td colspan=100>Invalid custom summary page '$pagename' (";
$rw = "<td colspan=100 class=bad>Invalid custom summary page '$pagename' (";
$rw .= count($customsummarypages[$pagename]).')</td>';
otherrow($rw);
return;
@ -2625,7 +2708,7 @@ function showcustompage($pagename) @@ -2625,7 +2708,7 @@ function showcustompage($pagename)
if (count($page) <= 1)
{
otherrow("<td colspan=100>Invalid custom summary page '$pagename' no content </td>");
otherrow("<td colspan=100 class=bad>Invalid custom summary page '$pagename' no content </td>");
return;
}
@ -2639,7 +2722,7 @@ function onlylogin() @@ -2639,7 +2722,7 @@ function onlylogin()
{
global $here;
htmlhead(false, null, null, true);
htmlhead('', false, null, null, true);
?>
<tr height=15%><td>&nbsp;</td></tr>
@ -2739,6 +2822,7 @@ function checklogin() @@ -2739,6 +2822,7 @@ function checklogin()
function display()
{
global $miner, $port;
global $mcast, $mcastexpect;
global $readonly, $notify, $rigs;
global $ignorerefresh, $autorefresh;
global $allowcustompages, $customsummarypages;
@ -2750,11 +2834,24 @@ function display() @@ -2750,11 +2834,24 @@ function display()
if ($pagesonly === 'login')
return;
$mcerr = '';
if ($rigs == null or count($rigs) == 0)
{
otherrow("<td>No rigs defined</td>");
if ($mcast === true)
$action = 'found';
else
$action = 'defined';
minhead();
otherrow("<td class=bad>No rigs $action</td>");
return;
}
else
{
if ($mcast === true && count($rigs) < $mcastexpect)
$mcerr = othrow('<td class=bad>Found '.count($rigs)." rigs but expected at least $mcastexpect</td>");
}
if ($ignorerefresh == false)
{
@ -2811,7 +2908,8 @@ function display() @@ -2811,7 +2908,8 @@ function display()
if ($pg !== null && $pg !== '')
{
showcustompage($pg);
htmlhead($mcerr, false, null, $pg);
showcustompage($pg, $mcerr);
return;
}
}
@ -2830,10 +2928,14 @@ function display() @@ -2830,10 +2928,14 @@ function display()
$miner = $parts[0];
$port = $parts[1];
htmlhead($mcerr, true, 0);
doOne(0, $preprocess);
}
else
otherrow('<td>Invalid "$rigs" array</td>');
{
minhead($mcerr);
otherrow('<td class=bad>Invalid "$rigs" array</td>');
}
return;
}
@ -2846,15 +2948,19 @@ function display() @@ -2846,15 +2948,19 @@ function display()
$miner = $parts[0];
$port = $parts[1];
htmlhead($mcerr, true, 0);
doOne($rig, $preprocess);
}
else
otherrow('<td>Invalid "$rigs" array</td>');
{
minhead($mcerr);
otherrow('<td class=bad>Invalid "$rigs" array</td>');
}
return;
}
htmlhead(false, null);
htmlhead($mcerr, false, null);
if ($placebuttons == 'top' || $placebuttons == 'both')
pagebuttons(null, null);
@ -2880,7 +2986,7 @@ function display() @@ -2880,7 +2986,7 @@ function display()
pagebuttons(null, null);
}
#
if (isset($mcast) && $mcast === true)
if ($mcast === true)
getrigs();
display();
#

Loading…
Cancel
Save