Commit 4185b7db394a0fd81317ba16d0b62d8ac4e7ef32

Kano 2013-09-02T22:00:18

miner.php allow formula generation of new fields

diff --git a/API-README b/API-README
index 2d7110c..0701750 100644
--- a/API-README
+++ b/API-README
@@ -1508,6 +1508,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:
@@ -1523,6 +1524,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)))
 );
 
@@ -1574,3 +1576,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
diff --git a/miner.php b/miner.php
index 89f3cba..89b6bef 100644
--- a/miner.php
+++ b/miner.php
@@ -2349,7 +2349,52 @@ 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)
 {
  $res = processcompare('where', $ext, $section, $res);
 
@@ -2418,6 +2463,10 @@ function processext($ext, $section, $res)
 	}
  }
 
+ // Generated fields (functions of other fields)
+ if (isset($ext[$section]['gen']))
+	dogen($ext, $section, $res, $fields);
+
  return processcompare('having', $ext, $section, $res);
 }
 #
@@ -2514,7 +2563,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)