/ miner.php
miner.php
1 <?php 2 session_start(); 3 # 4 global $doctype, $title, $miner, $port, $readonly, $notify; 5 global $rigport, $rigs, $rignames, $rigbuttons; 6 global $mcast, $mcastexpect, $mcastaddr, $mcastport, $mcastcode; 7 global $mcastlistport, $mcasttimeout, $mcastretries, $allowgen; 8 global $rigipsecurity, $rigtotals, $forcerigtotals; 9 global $socksndtimeoutsec, $sockrcvtimeoutsec; 10 global $checklastshare, $poolinputs, $hidefields; 11 global $ignorerefresh, $changerefresh, $autorefresh; 12 global $allowcustompages, $customsummarypages, $user_pages; 13 global $miner_font_family, $miner_font_size; 14 global $bad_font_family, $bad_font_size, $add_css_names; 15 global $colouroverride, $placebuttons, $userlist; 16 # 17 $doctype = "<!DOCTYPE html>\n"; 18 # 19 # See API-README for more details of these variables and how 20 # to configure miner.php 21 # 22 # Web page title 23 $title = 'Mine'; 24 # 25 # Set $readonly to true to force miner.php to be readonly 26 # Set $readonly to false then it will check cgminer 'privileged' 27 $readonly = false; 28 # 29 # Set $userlist to null to allow anyone access or read API-README 30 $userlist = null; 31 # 32 # Set $notify to false to NOT attempt to display the notify command 33 # Set $notify to true to attempt to display the notify command 34 $notify = true; 35 # 36 # Set $checklastshare to true to do the following checks: 37 # If a device's last share is 12x expected ago then display as an error 38 # If a device's last share is 8x expected ago then display as a warning 39 # If either of the above is true, also display the whole line highlighted 40 # This assumes shares are 1 difficulty shares 41 $checklastshare = true; 42 # 43 # Set $poolinputs to true to show the input fields for adding a pool 44 # and changing the pool priorities 45 # N.B. also if $readonly is true, it will not display the fields 46 $poolinputs = false; 47 # 48 # Default port to use if any $rigs entries don't specify the port number 49 $rigport = 4028; 50 # 51 # Set $rigs to an array of your cgminer rigs that are running 52 # format: 'IP' or 'Host' or 'IP:Port' or 'Host:Port' or 'Host:Port:Name' 53 $rigs = array('127.0.0.1:4028'); 54 # 55 # Set $rignames to false, or one of 'ip' or 'ipx' 56 # this says what to use if $rigs doesn't have a 'name' 57 $rignames = false; 58 # 59 # Set $rigbuttons to false to display a link rather than a button 60 $rigbuttons = true; 61 # 62 # Set $mcast to true to look for your rigs and ignore $rigs 63 $mcast = false; 64 # 65 # Set $mcastexpect to at least how many rigs you expect it to find 66 $mcastexpect = 0; 67 # 68 # API Multicast address all cgminers are listening on 69 $mcastaddr = '224.0.0.75'; 70 # 71 # API Multicast UDP port all cgminers are listening on 72 $mcastport = 4028; 73 # 74 # The code all cgminers expect in the Multicast message sent 75 $mcastcode = 'FTW'; 76 # 77 # UDP port cgminers are to reply on (by request) 78 $mcastlistport = 4027; 79 # 80 # Set $mcasttimeout to the number of seconds (floating point) 81 # to wait for replies to the Multicast message 82 $mcasttimeout = 1.5; 83 # 84 # Set $mcastretries to the number of times to retry the multicast 85 $mcastretries = 0; 86 # 87 # Set $allowgen to true to allow customsummarypages to use 'gen' 88 # false means ignore any 'gen' options 89 $allowgen = false; 90 # 91 # Set $rigipsecurity to false to show the IP/Port of the rig 92 # in the socket error messages and also show the full socket message 93 $rigipsecurity = true; 94 # 95 # Set $rigtotals to true to display totals on the single rig page 96 # 'false' means no totals (and ignores $forcerigtotals) 97 # You can force it to always show rig totals when there is only 98 # one line by setting $forcerigtotals = true; 99 $rigtotals = true; 100 $forcerigtotals = false; 101 # 102 # These should be OK for most cases 103 $socksndtimeoutsec = 10; 104 $sockrcvtimeoutsec = 40; 105 # 106 # List of fields NOT to be displayed 107 # This example would hide the slightly more sensitive pool information 108 #$hidefields = array('POOL.URL' => 1, 'POOL.User' => 1); 109 $hidefields = array(); 110 # 111 # Auto-refresh of the page (in seconds) - integers only 112 # $ignorerefresh = true/false always ignore refresh parameters 113 # $changerefresh = true/false show buttons to change the value 114 # $autorefresh = default value, 0 means dont auto-refresh 115 $ignorerefresh = false; 116 $changerefresh = true; 117 $autorefresh = 0; 118 # 119 # Should we allow custom pages? 120 # (or just completely ignore them and don't display the buttons) 121 $allowcustompages = true; 122 # 123 # OK this is a bit more complex item: Custom Summary Pages 124 # As mentioned above, see API-README 125 # see the example below (if there is no matching data, no total will show) 126 $mobilepage = array( 127 'DATE' => null, 128 'RIGS' => null, 129 'SUMMARY' => array('Elapsed', 'MHS av', 'MHS 5m', 'Found Blocks=Blks', 130 'Difficulty Accepted=DiffA', 131 'Difficulty Rejected=DiffR', 132 'Hardware Errors=HW', 133 'Work Utility=WU'), 134 'DEVS+NOTIFY' => array('DEVS.Name=Name', 'DEVS.ID=ID', 'DEVS.Status=Status', 135 'DEVS.Temperature=Temp', 'DEVS.MHS av=MHS av', 136 'DEVS.MHS 5m=MHS 5m', 'DEVS.Difficulty Accepted=DiffA', 137 'DEVS.Difficulty Rejected=DiffR', 138 'DEVS.Work Utility=WU', 139 'NOTIFY.Last Not Well=Not Well'), 140 'POOL' => array('POOL', 'Status', 'Difficulty Accepted=DiffA', 141 'Difficulty Rejected=DiffR', 'Last Share Time=LST')); 142 $mobilesum = array( 143 'SUMMARY' => array('MHS av', 'MHS 5m', 'Found Blocks', 'Difficulty Accepted', 144 'Difficulty Rejected', 'Hardware Errors', 145 'Work Utility'), 146 'DEVS+NOTIFY' => array('DEVS.MHS av', 'DEVS.Difficulty Accepted', 147 'DEVS.Difficulty Rejected'), 148 'POOL' => array('Difficulty Accepted', 'Difficulty Rejected')); 149 # 150 $statspage = array( 151 'DATE' => null, 152 'RIGS' => null, 153 'SUMMARY' => array('Elapsed', 'MHS av', 'MHS 5m', 'Found Blocks=Blks', 154 'Difficulty Accepted=DiffA', 155 'Difficulty Rejected=DiffR', 156 'Work Utility=WU', 'Hardware Errors=HW Errs', 157 'Network Blocks=Net Blks'), 158 'COIN' => array('*'), 159 'STATS' => array('*')); 160 # 161 $statssum = array( 162 'SUMMARY' => array('MHS av', 'MHS 5m', 'Found Blocks', 163 'Difficulty Accepted', 'Difficulty Rejected', 164 'Work Utility', 'Hardware Errors')); 165 # 166 $poolspage = array( 167 'DATE' => null, 168 'RIGS' => null, 169 'SUMMARY' => array('Elapsed', 'MHS av', 'MHS 5m', 'Found Blocks=Blks', 170 'Difficulty Accepted=DiffA', 171 'Difficulty Rejected=DiffR', 172 'Work Utility', 'Hardware Errors=HW', 173 'Network Blocks=Net Blks', 'Best Share'), 174 'POOL+STATS' => array('STATS.ID=ID', 'POOL.URL=URL', 175 'POOL.Difficulty Accepted=DiffA', 176 'POOL.Difficulty Rejected=DiffR', 177 'POOL.Has Stratum=Stratum', 178 'POOL.Stratum Active=StrAct', 179 'POOL.Has GBT=GBT', 'STATS.Times Sent=TSent', 180 'STATS.Bytes Sent=BSent', 'STATS.Net Bytes Sent=NSent', 181 'STATS.Times Recv=TRecv', 'STATS.Bytes Recv=BRecv', 182 'STATS.Net Bytes Recv=NRecv', 'GEN.AvShr=AvShr')); 183 # 184 $poolssum = array( 185 'SUMMARY' => array('MHS av', 'MHS 5m', 'Found Blocks', 186 'Difficulty Accepted', 'Difficulty Rejected', 187 'Work Utility', 'Hardware Errors'), 188 'POOL+STATS' => array('POOL.Difficulty Accepted', 'POOL.Difficulty Rejected', 189 'STATS.Times Sent', 'STATS.Bytes Sent', 190 'STATS.Net Bytes Sent', 'STATS.Times Recv', 191 'STATS.Bytes Recv', 'STATS.Net Bytes Recv')); 192 # 193 $poolsext = array( 194 'POOL+STATS' => array( 195 'where' => null, 196 'group' => array('POOL.URL', 'POOL.Has Stratum', 197 'POOL.Stratum Active', 'POOL.Has GBT'), 198 'calc' => array('POOL.Difficulty Accepted' => 'sum', 199 'POOL.Difficulty Rejected' => 'sum', 200 'STATS.Times Sent' => 'sum', 201 'STATS.Bytes Sent' => 'sum', 202 'STATS.Net Bytes Sent' => 'sum', 203 'STATS.Times Recv' => 'sum', 204 'STATS.Bytes Recv' => 'sum', 205 'STATS.Net Bytes Recv' => 'sum', 206 'POOL.Accepted' => 'sum'), 207 'gen' => array('AvShr' => 208 'round(POOL.Difficulty Accepted/'. 209 'max(POOL.Accepted,1)*100)/100'), 210 'having' => array(array('STATS.Bytes Recv', '>', 0))) 211 ); 212 # 213 $devnotpage = array( 214 'DATE' => null, 215 'RIGS' => null, 216 'DEVS+NOTIFY' => array('DEVS.Name=Name', 'DEVS.ID=ID', 217 'DEVS.Temperature=Temp', 'DEVS.MHS av=MHS av', 218 'DEVS.Difficulty Accepted=DiffA', 219 'DEVS.Difficulty Rejected=DiffR', 220 'NOTIFY.Last Not Well=Last Not Well')); 221 $devnotsum = array( 222 'DEVS+NOTIFY' => array('DEVS.MHS av', 'DEVS.Difficulty Accepted', 223 'DEVS.Difficulty Rejected')); 224 # 225 $devdetpage = array( 226 'DATE' => null, 227 'RIGS' => null, 228 'DEVS+DEVDETAILS' => array('DEVS.Name=Name', 'DEVS.ID=ID', 229 'DEVS.Temperature=Temp', 230 'DEVS.MHS av=MHS av', 231 'DEVS.Difficulty Accepted=DiffA', 232 'DEVS.Difficulty Rejected=DiffR', 233 'DEVDETAILS.Device Path=Device')); 234 $devdetsum = array( 235 'DEVS+DEVDETAILS' => array('DEVS.MHS av', 'DEVS.Difficulty Accepted', 236 'DEVS.Difficulty Rejected')); 237 # 238 $protopage = array( 239 'DATE' => null, 240 'RIGS' => null, 241 'CONFIG' => array('ASC Count=ASCs', 'PGA Count=PGAs', 'Pool Count=Pools', 242 'Strategy', 'Device Code', 'OS', 'Failover-Only'), 243 'SUMMARY' => array('Elapsed', 'MHS av', 'Found Blocks=Blks', 244 'Difficulty Accepted=Diff Acc', 245 'Difficulty Rejected=Diff Rej', 246 'Hardware Errors=HW Errs', 247 'Network Blocks=Net Blks', 'Utility', 'Work Utility'), 248 'POOL+STATS' => array('STATS.ID=ID', 'POOL.URL=URL', 'POOL.Accepted=Acc', 249 'POOL.Difficulty Accepted=DiffA', 250 'POOL.Difficulty Rejected=DiffR', 'POOL.Has GBT=GBT', 251 'STATS.Max Diff=Max Work Diff', 252 'STATS.Times Sent=#Sent', 'STATS.Bytes Sent=Byte Sent', 253 'STATS.Net Bytes Sent=Net Sent', 254 'STATS.Times Recv=#Recv', 255 'STATS.Bytes Recv=Byte Recv', 256 'STATS.Net Bytes Recv=Net Recv')); 257 $protosum = array( 258 'SUMMARY' => array('MHS av', 'Found Blocks', 'Difficulty Accepted', 259 'Difficulty Rejected', 'Hardware Errors', 260 'Utility', 'Work Utility'), 261 'POOL+STATS' => array('POOL.Accepted', 'POOL.Difficulty Accepted', 262 'POOL.Difficulty Rejected', 263 'STATS.Times Sent', 'STATS.Bytes Sent', 264 'STATS.Net Bytes Sent', 'STATS.Times Recv', 265 'STATS.Bytes Recv', 'STATS.Net Bytes Recv')); 266 $protoext = array( 267 'POOL+STATS' => array( 268 'where' => null, 269 'group' => array('POOL.URL', 'POOL.Has GBT'), 270 'calc' => array('POOL.Accepted' => 'sum', 271 'POOL.Difficulty Accepted' => 'sum', 272 'POOL.Difficulty Rejected' => 'sum', 273 'STATS.Max Diff' => 'max', 274 'STATS.Times Sent' => 'sum', 275 'STATS.Bytes Sent' => 'sum', 276 'STATS.Net Bytes Sent' => 'sum', 277 'STATS.Times Recv' => 'sum', 278 'STATS.Bytes Recv' => 'sum', 279 'STATS.Net Bytes Recv' => 'sum'), 280 'having' => array(array('STATS.Bytes Recv', '>', 0))) 281 ); 282 # 283 # If 'gen' isn't enabled, the 'GEN' fields won't show but 284 # where present, will be replaced with the ||SUMMARY fields 285 $kanogenpage = array( 286 'DATE' => null, 287 'RIGS' => null, 288 'SUMMARY+COIN' => array('SUMMARY.Elapsed=Elapsed', 289 'GEN.Mined=Block%', 'GEN.GHS Acc=GH/s Acc', 290 'GEN.GHS av=GH/s av||SUMMARY.MHS av=MHS av', 291 'GEN.GHS 5m=GH/s 5m||SUMMARY.MHS 5m=MHS 5m', 292 'GEN.GHS WU=GH/s WU||SUMMARY.Work Utility=WU', 293 'SUMMARY.Found Blocks=Blks', 294 'SUMMARY.Difficulty Accepted=DiffA', 295 'SUMMARY.Difficulty Rejected=DiffR', 296 'SUMMARY.Hardware Errors=HW', 297 'SUMMARY.Difficulty Stale=DiffS', 298 'SUMMARY.Best Share=Best Share', 299 'SUMMARY.Device Hardware%=Dev HW%', 300 'SUMMARY.Device Rejected%=Dev Rej%', 301 'SUMMARY.Pool Rejected%=Pool Rej%', 302 'SUMMARY.Pool Stale%=Pool Stale%'), 303 'POOL' => array('URL', 'Diff1 Shares=Diff Work', 304 'Difficulty Accepted=DiffA', 305 'Difficulty Rejected=DiffR', 306 'Difficulty Stale=DiffS', 307 'Best Share', 'GEN.Acc=Pool Acc%', 'GEN.Rej=Pool Rej%') 308 ); 309 # sum should list all fields seperately including GEN/BGEN || replacements 310 $kanogensum = array( 311 'SUMMARY+COIN' => array('GEN.Mined', 'GEN.GHS Acc', 'GEN.GHS av', 312 'GEN.GHS 5m', 'GEN.GHS WU', 313 'SUMMARY.MHS av', 'SUMMARY.MHS 5m', 314 'SUMMARY.Work Utility', 315 'SUMMARY.Found Blocks', 316 'SUMMARY.Difficulty Accepted', 317 'SUMMARY.Difficulty Rejected', 318 'SUMMARY.Hardware Errors', 319 'SUMMARY.Difficulty Stale'), 320 'POOL' => array('Diff1 Shares', 'Difficulty Accepted', 321 'Difficulty Rejected', 'Difficulty Stale') 322 ); 323 # 'where', 'calc' and 'having' should list GEN/BGEN || replacements seperately 324 # 'group' must use the 'name1||name2' format for GEN/BGEN fields 325 $kanogenext = array( 326 'SUMMARY+COIN' => array( 327 'gen' => array('GHS Acc' => 328 'round(pow(2,32) * SUMMARY.Difficulty Accepted / '. 329 'SUMMARY.Elapsed / 10000000) / 100', 330 'Mined' => 331 'SUMMARY.Elapsed * SUMMARY.Work Utility / 60 / '. 332 'COIN.Network Difficulty', 333 'GHS av' => 334 'SUMMARY.MHS av / 1000.0', 335 'GHS 5m' => 336 'SUMMARY.MHS 5m / 1000.0', 337 'GHS WU' => 338 'round(pow(2,32) * SUMMARY.Work Utility / 60 / '. 339 '10000000 ) / 100')), 340 'POOL' => array( 341 'group' => array('URL'), 342 'calc' => array('Diff1 Shares' => 'sum', 'Difficulty Accepted' => 'sum', 343 'Difficulty Rejected' => 'sum', 344 'Difficulty Stale' => 'sum', 'Best Share' => 'max'), 345 'gen' => array('Rej' => 'Difficulty Rejected / '. 346 'max(1,Difficulty Accepted+Difficulty Rejected)', 347 'Acc' => 'Difficulty Accepted / '. 348 'max(1,Difficulty Accepted+Difficulty Rejected)')) 349 ); 350 # 351 $syspage = array( 352 'DATE' => null, 353 'RIGS' => null, 354 'SUMMARY' => array('#', 'Elapsed', 'MHS av', 'MHS 5m', 'Found Blocks=Blks', 355 'Difficulty Accepted=DiffA', 356 'Difficulty Rejected=DiffR', 357 'Difficulty Stale=DiffS', 'Hardware Errors=HW', 358 'Work Utility', 'Network Blocks=Net Blks', 'Total MH', 359 'Best Share', 'Device Hardware%=Dev HW%', 360 'Device Rejected%=Dev Rej%', 361 'Pool Rejected%=Pool Rej%', 'Pool Stale%', 362 'Last getwork'), 363 'DEVS' => array('#', 'ID', 'Name', 'ASC', 'Device Elapsed', 'Enabled', 364 'Status', 'No Device', 'Temperature=Temp', 365 'MHS av', 'MHS 5s', 'MHS 5m', 'Diff1 Work', 366 'Difficulty Accepted=DiffA', 367 'Difficulty Rejected=DiffR', 368 'Hardware Errors=HW', 'Work Utility', 369 'Last Valid Work', 'Last Share Pool', 370 'Last Share Time', 'Total MH', 371 'Device Hardware%=Dev HW%', 372 'Device Rejected%=Dev Rej%'), 373 'POOL' => array('POOL', 'URL', 'Status', 'Priority', 'Quota', 374 'Getworks', 'Diff1 Shares', 375 'Difficulty Accepted=DiffA', 376 'Difficulty Rejected=DiffR', 377 'Difficulty Stale=DiffS', 378 'Last Share Difficulty', 379 'Last Share Time', 380 'Best Share', 'Pool Rejected%=Pool Rej%', 381 'Pool Stale%') 382 ); 383 $syssum = array( 384 'SUMMARY' => array('MHS av', 'MHS 5m', 'Found Blocks', 385 'Difficulty Accepted', 'Difficulty Rejected', 386 'Difficulty Stale', 'Hardware Errors', 387 'Work Utility', 'Total MH'), 388 'DEVS' => array('MHS av', 'MHS 5s', 'MHS 5m', 'Diff1 Work', 389 'Difficulty Accepted', 'Difficulty Rejected', 390 'Hardware Errors', 'Total MH'), 391 'POOL' => array('Getworks', 'Diff1 Shares', 'Difficulty Accepted', 392 'Difficulty Rejected', 'Difficulty Stale') 393 ); 394 # 395 # $customsummarypages is an array of these Custom Summary Pages 396 # that you can override in myminer.php 397 # It can be 'Name' => 1 with 'Name' in any of $user_pages or $sys_pages 398 # and it can be a fully defined 'Name' => array(...) like in $sys_pages below 399 $customsummarypages = array( 400 'Kano' => 1, 401 'Mobile' => 1, 402 'Stats' => 1, 403 'Pools' => 1 404 ); 405 # 406 # $user_pages are the myminer.php definable version of $sys_pages 407 # It should contain a set of 'Name' => array(...) like in $sys_pages 408 # that $customsummarypages can refer to by 'Name' 409 # If a 'Name' is in both $user_pages and $sys_pages, then the one 410 # in $user_pages will override the one in $sys_pages 411 $user_pages = array(); 412 # 413 $here = $_SERVER['PHP_SELF']; 414 # 415 global $tablebegin, $tableend, $warnfont, $warnoff, $dfmt; 416 # 417 $tablebegin = '<tr><td><table border=1 cellpadding=5 cellspacing=0>'; 418 $tableend = '</table></td></tr>'; 419 $warnfont = '<font color=red><b>'; 420 $warnoff = '</b></font>'; 421 $dfmt = 'H:i:s j-M-Y \U\T\CP'; 422 # 423 $miner_font_family = 'Verdana, Arial, sans-serif, sans'; 424 $miner_font_size = '13pt'; 425 # 426 $bad_font_family = '"Times New Roman", Times, serif'; 427 $bad_font_size = '18pt'; 428 # 429 # List of css names to add to the css style object 430 # e.g. array('td.cool' => false); 431 # true/false to not include the default $miner_font 432 # The css name/value pairs must be defined in $colouroverride below 433 $add_css_names = array(); 434 # 435 # Edit this or redefine it in myminer.php to change the colour scheme 436 # See $colourtable below for the list of names 437 $colouroverride = array(); 438 # 439 # Where to place the buttons: 'top' 'bot' 'both' 440 # anything else means don't show them - case sensitive 441 $placebuttons = 'top'; 442 # 443 # This below allows you to put your own settings into a seperate file 444 # so you don't need to update miner.php with your preferred settings 445 # every time a new version is released 446 # Just create the file 'myminer.php' in the same directory as 447 # 'miner.php' - and put your own settings in there 448 if (file_exists('myminer.php')) 449 include_once('myminer.php'); 450 # 451 # This is the system default that must always contain all necessary 452 # colours so it must be a constant 453 # You can override these values with $colouroverride 454 # The only one missing is $warnfont 455 # - which you can override directly anyway 456 global $colourtable; 457 $colourtable = array( 458 'body bgcolor' => '#ecffff', 459 'td color' => 'blue', 460 'td.two color' => 'blue', 461 'td.two background' => '#ecffff', 462 'td.h color' => 'blue', 463 'td.h background' => '#c4ffff', 464 'td.err color' => 'black', 465 'td.err background' => '#ff3050', 466 'td.bad color' => 'black', 467 'td.bad background' => '#ff3050', 468 'td.warn color' => 'black', 469 'td.warn background' => '#ffb050', 470 'td.sta color' => 'green', 471 'td.tot color' => 'blue', 472 'td.tot background' => '#fff8f2', 473 'td.lst color' => 'blue', 474 'td.lst background' => '#ffffdd', 475 'td.hi color' => 'blue', 476 'td.hi background' => '#f6ffff', 477 'td.lo color' => 'blue', 478 'td.lo background' => '#deffff' 479 ); 480 # 481 # A list of system default summary pages (defined further above) 482 # that you can use by 'Name' in $customsummarypages 483 global $sys_pages; 484 $sys_pages = array( 485 'Mobile' => array($mobilepage, $mobilesum), 486 'Stats' => array($statspage, $statssum), 487 'Pools' => array($poolspage, $poolssum, $poolsext), 488 'DevNot' => array($devnotpage, $devnotsum), 489 'DevDet' => array($devdetpage, $devdetsum), 490 'Proto' => array($protopage, $protosum, $protoext), 491 'Kano' => array($kanogenpage, $kanogensum, $kanogenext), 492 'Summary' => array($syspage, $syssum) 493 ); 494 # 495 # Don't touch these 2 496 $miner = null; 497 $port = null; 498 # 499 global $rigips; 500 $rigips = array(); 501 # 502 # Ensure it is only ever shown once 503 global $showndate; 504 $showndate = false; 505 # 506 global $rownum; 507 $rownum = 0; 508 # 509 // Login 510 global $ses; 511 $ses = 'rutroh'; 512 # 513 function getcsp($name, $systempage = false) 514 { 515 global $customsummarypages, $user_pages, $sys_pages; 516 517 if ($systempage === false) 518 { 519 if (!isset($customsummarypages[$name])) 520 return false; 521 522 $csp = $customsummarypages[$name]; 523 if (is_array($csp)) 524 { 525 if (count($csp) < 2 || count($csp) > 3) 526 return false; 527 else 528 return $csp; 529 } 530 } 531 532 if (isset($user_pages[$name])) 533 { 534 $csp = $user_pages[$name]; 535 if (!is_array($csp) || count($csp) < 2 || count($csp) > 3) 536 return false; 537 else 538 return $csp; 539 } 540 541 if (isset($sys_pages[$name])) 542 { 543 $csp = $sys_pages[$name]; 544 if (!is_array($csp) || count($csp) < 2 || count($csp) > 3) 545 return false; 546 else 547 return $csp; 548 } 549 550 return false; 551 } 552 # 553 function degenfields(&$sec, $name, $fields) 554 { 555 global $allowgen; 556 557 if (!is_array($fields)) 558 return; 559 560 foreach ($fields as $num => $fld) 561 if (substr($fld, 0, 5) == 'BGEN.' || substr($fld, 0, 4) == 'GEN.') 562 { 563 $opts = explode('||', $fld, 2); 564 if ($allowgen) 565 { 566 if (count($opts) > 1) 567 $sec[$name][$num] = $opts[0]; 568 } 569 else 570 { 571 if (count($opts) > 1) 572 $sec[$name][$num] = $opts[1]; 573 else 574 unset($sec[$name][$num]); 575 } 576 } 577 } 578 # 579 # Allow BGEN/GEN fields to have a '||' replacement when gen is disabled 580 # N.B. if gen is disabled and all page fields are GBEN/GEN without '||' then 581 # the table will disappear 582 # Replacements can be in the page fields and then also the ext group fields 583 # All other $csp sections should list both separately 584 function degen(&$csp) 585 { 586 $page = 0; 587 if (isset($csp[$page]) && is_array($csp[$page])) 588 foreach ($csp[$page] as $sec => $fields) 589 degenfields($csp[$page], $sec, $fields); 590 591 $ext = 2; 592 if (isset($csp[$ext]) && is_array($csp[$ext])) 593 foreach ($csp[$ext] as $sec => $types) 594 if (is_array($types) && isset($types['group'])) 595 degenfields($types, 'group', $types['group']); 596 } 597 # 598 function getcss($cssname, $dom = false) 599 { 600 global $colourtable, $colouroverride; 601 602 $css = ''; 603 foreach ($colourtable as $cssdata => $value) 604 { 605 $cssobj = explode(' ', $cssdata, 2); 606 if ($cssobj[0] == $cssname) 607 { 608 if (isset($colouroverride[$cssdata])) 609 $value = $colouroverride[$cssdata]; 610 611 if ($dom == true) 612 $css .= ' '.$cssobj[1].'='.$value; 613 else 614 $css .= $cssobj[1].':'.$value.'; '; 615 } 616 } 617 return $css; 618 } 619 # 620 function getdom($domname) 621 { 622 return getcss($domname, true); 623 } 624 # 625 # N.B. don't call this before calling htmlhead() 626 function php_pr($cmd) 627 { 628 global $here, $autorefresh; 629 630 return "$here?ref=$autorefresh$cmd"; 631 } 632 # 633 function htmlhead($mcerr, $checkapi, $rig, $pg = null, $noscript = false) 634 { 635 global $doctype, $title, $miner_font_family, $miner_font_size; 636 global $bad_font_family, $bad_font_size, $add_css_names; 637 global $error, $readonly, $poolinputs, $here; 638 global $ignorerefresh, $autorefresh; 639 640 $extraparams = ''; 641 if ($rig != null && $rig != '') 642 $extraparams = "&rig=$rig"; 643 else 644 if ($pg != null && $pg != '') 645 $extraparams = "&pg=$pg"; 646 647 if ($ignorerefresh == true || $autorefresh == 0) 648 $refreshmeta = ''; 649 else 650 { 651 $url = "$here?ref=$autorefresh$extraparams"; 652 $refreshmeta = "\n<meta http-equiv='refresh' content='$autorefresh;url=$url'>"; 653 } 654 655 if ($readonly === false && $checkapi === true) 656 { 657 $error = null; 658 $access = api($rig, 'privileged'); 659 if ($error != null 660 || !isset($access['STATUS']['STATUS']) 661 || $access['STATUS']['STATUS'] != 'S') 662 $readonly = true; 663 } 664 $miner_font = "font-family:$miner_font_family; font-size:$miner_font_size;"; 665 $bad_font = "font-family:$bad_font_family; font-size:$bad_font_size;"; 666 667 echo "$doctype<html><head>$refreshmeta 668 <title>$title</title> 669 <style type='text/css'> 670 td { $miner_font ".getcss('td')."} 671 td.two { $miner_font ".getcss('td.two')."} 672 td.h { $miner_font ".getcss('td.h')."} 673 td.err { $miner_font ".getcss('td.err')."} 674 td.bad { $bad_font ".getcss('td.bad')."} 675 td.warn { $miner_font ".getcss('td.warn')."} 676 td.sta { $miner_font ".getcss('td.sta')."} 677 td.tot { $miner_font ".getcss('td.tot')."} 678 td.lst { $miner_font ".getcss('td.lst')."} 679 td.hi { $miner_font ".getcss('td.hi')."} 680 td.lo { $miner_font ".getcss('td.lo')."}\n"; 681 if (isset($add_css_names)) 682 foreach ($add_css_names as $css_name => $no_miner_font) 683 { 684 echo "$css_name { "; 685 if ($no_miner_font !== true) 686 echo "$miner_font "; 687 echo getcss("$css_name")."}\n"; 688 } 689 echo "</style> 690 </head><body".getdom('body').">\n"; 691 if ($noscript === false) 692 { 693 echo "<script type='text/javascript'> 694 function pr(a,m){if(m!=null){if(!confirm(m+'?'))return}window.location='$here?ref=$autorefresh'+a}\n"; 695 696 if ($ignorerefresh == false) 697 echo "function prr(a){if(a){v=document.getElementById('refval').value}else{v=0}window.location='$here?ref='+v+'$extraparams'}\n"; 698 699 if ($readonly === false && $checkapi === true) 700 { 701 echo "function prc(a,m){pr('&arg='+a,m)} 702 function prs(a,r){var c=a.substr(3);var z=c.split('|',2);var m=z[0].substr(0,1).toUpperCase()+z[0].substr(1)+' GPU '+z[1];prc(a+'&rig='+r,m)} 703 function prs2(a,n,r){var v=document.getElementById('gi'+n).value;var c=a.substr(3);var z=c.split('|',2);var m='Set GPU '+z[1]+' '+z[0].substr(0,1).toUpperCase()+z[0].substr(1)+' to '+v;prc(a+','+v+'&rig='+r,m)}\n"; 704 if ($poolinputs === true) 705 echo "function cbs(s){var t=s.replace(/\\\\/g,'\\\\\\\\'); return t.replace(/,/g, '\\\\,')}\nfunction pla(r){var u=document.getElementById('purl').value;var w=document.getElementById('pwork').value;var p=document.getElementById('ppass').value;pr('&rig='+r+'&arg=addpool|'+cbs(u)+','+cbs(w)+','+cbs(p),'Add Pool '+u)}\nfunction psp(r){var p=document.getElementById('prio').value;pr('&rig='+r+'&arg=poolpriority|'+p,'Set Pool Priorities to '+p)}\n"; 706 } 707 echo "</script>\n"; 708 } 709 ?> 710 <table width=100% height=100% border=0 cellpadding=0 cellspacing=0 summary='Mine'> 711 <tr><td align=center valign=top> 712 <table border=0 cellpadding=4 cellspacing=0 summary='Mine'> 713 <?php 714 echo $mcerr; 715 } 716 # 717 function minhead($mcerr = '') 718 { 719 global $readonly; 720 $readonly = true; 721 htmlhead($mcerr, false, null, null, true); 722 } 723 # 724 global $haderror, $error; 725 $haderror = false; 726 $error = null; 727 # 728 function mcastrigs() 729 { 730 global $rigs, $mcastexpect, $mcastaddr, $mcastport, $mcastcode; 731 global $mcastlistport, $mcasttimeout, $mcastretries, $error; 732 733 $listname = "0.0.0.0"; 734 735 $rigs = array(); 736 737 $rep_soc = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); 738 if ($rep_soc === false || $rep_soc == null) 739 { 740 $msg = "ERR: mcast listen socket create(UDP) failed"; 741 if ($rigipsecurity === false) 742 { 743 $error = socket_strerror(socket_last_error()); 744 $error = "$msg '$error'\n"; 745 } 746 else 747 $error = "$msg\n"; 748 749 return; 750 } 751 752 $res = socket_bind($rep_soc, $listname, $mcastlistport); 753 if ($res === false) 754 { 755 $msg1 = "ERR: mcast listen socket bind("; 756 $msg2 = ") failed"; 757 if ($rigipsecurity === false) 758 { 759 $error = socket_strerror(socket_last_error()); 760 $error = "$msg1$listname,$mcastlistport$msg2 '$error'\n"; 761 } 762 else 763 $error = "$msg1$msg2\n"; 764 765 socket_close($rep_soc); 766 return; 767 } 768 769 $retries = $mcastretries; 770 $doretry = ($retries > 0); 771 do 772 { 773 $mcast_soc = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); 774 if ($mcast_soc === false || $mcast_soc == null) 775 { 776 $msg = "ERR: mcast send socket create(UDP) failed"; 777 if ($rigipsecurity === false) 778 { 779 $error = socket_strerror(socket_last_error()); 780 $error = "$msg '$error'\n"; 781 } 782 else 783 $error = "$msg\n"; 784 785 socket_close($rep_soc); 786 return; 787 } 788 789 $buf = "cgminer-$mcastcode-$mcastlistport"; 790 socket_sendto($mcast_soc, $buf, strlen($buf), 0, $mcastaddr, $mcastport); 791 socket_close($mcast_soc); 792 793 $stt = microtime(true); 794 while (true) 795 { 796 $got = @socket_recvfrom($rep_soc, $buf, 32, MSG_DONTWAIT, $ip, $p); 797 if ($got !== false && $got > 0) 798 { 799 $ans = explode('-', $buf, 4); 800 if (count($ans) >= 3 && $ans[0] == 'cgm' && $ans[1] == 'FTW') 801 { 802 $rp = intval($ans[2]); 803 804 if (count($ans) > 3) 805 $mdes = str_replace("\0", '', $ans[3]); 806 else 807 $mdes = ''; 808 809 if (strlen($mdes) > 0) 810 $rig = "$ip:$rp:$mdes"; 811 else 812 $rig = "$ip:$rp"; 813 814 if (!in_array($rig, $rigs)) 815 $rigs[] = $rig; 816 } 817 } 818 if ((microtime(true) - $stt) >= $mcasttimeout) 819 break; 820 821 usleep(100000); 822 } 823 824 if ($mcastexpect > 0 && count($rigs) >= $mcastexpect) 825 $doretry = false; 826 827 } while ($doretry && --$retries > 0); 828 829 socket_close($rep_soc); 830 } 831 # 832 function getrigs() 833 { 834 global $rigs; 835 836 mcastrigs(); 837 838 sort($rigs); 839 } 840 # 841 function getsock($rig, $addr, $port) 842 { 843 global $rigport, $rigips, $rignames, $rigipsecurity; 844 global $haderror, $error, $socksndtimeoutsec, $sockrcvtimeoutsec; 845 846 $port = trim($port); 847 if (strlen($port) == 0) 848 $port = $rigport; 849 $error = null; 850 $socket = null; 851 $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); 852 if ($socket === false || $socket === null) 853 { 854 $haderror = true; 855 if ($rigipsecurity === false) 856 { 857 $error = socket_strerror(socket_last_error()); 858 $msg = "socket create(TCP) failed"; 859 $error = "ERR: $msg '$error'\n"; 860 } 861 else 862 $error = "ERR: socket create(TCP) failed\n"; 863 864 return null; 865 } 866 867 // Ignore if this fails since the socket connect may work anyway 868 // and nothing is gained by aborting if the option cannot be set 869 // since we don't know in advance if it can connect 870 socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array('sec' => $socksndtimeoutsec, 'usec' => 0)); 871 socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => $sockrcvtimeoutsec, 'usec' => 0)); 872 873 $res = socket_connect($socket, $addr, $port); 874 if ($res === false) 875 { 876 $haderror = true; 877 if ($rigipsecurity === false) 878 { 879 $error = socket_strerror(socket_last_error()); 880 $msg = "socket connect($addr,$port) failed"; 881 $error = "ERR: $msg '$error'\n"; 882 } 883 else 884 $error = "ERR: socket connect($rig) failed\n"; 885 886 socket_close($socket); 887 return null; 888 } 889 if ($rignames !== false && !isset($rigips[$addr])) 890 if (socket_getpeername($socket, $ip) == true) 891 $rigips[$addr] = $ip; 892 return $socket; 893 } 894 # 895 function readsockline($socket) 896 { 897 $line = ''; 898 while (true) 899 { 900 $byte = socket_read($socket, 1); 901 if ($byte === false || $byte === '') 902 break; 903 if ($byte === "\0") 904 break; 905 $line .= $byte; 906 } 907 return $line; 908 } 909 # 910 function api_convert_escape($str) 911 { 912 $res = ''; 913 $len = strlen($str); 914 for ($i = 0; $i < $len; $i++) 915 { 916 $ch = substr($str, $i, 1); 917 if ($ch != '\\' || $i == ($len-1)) 918 $res .= $ch; 919 else 920 { 921 $i++; 922 $ch = substr($str, $i, 1); 923 switch ($ch) 924 { 925 case '|': 926 $res .= "\1"; 927 break; 928 case '\\': 929 $res .= "\2"; 930 break; 931 case '=': 932 $res .= "\3"; 933 break; 934 case ',': 935 $res .= "\4"; 936 break; 937 default: 938 $res .= $ch; 939 } 940 } 941 } 942 return $res; 943 } 944 # 945 function revert($str) 946 { 947 return str_replace(array("\1", "\2", "\3", "\4"), array("|", "\\", "=", ","), $str); 948 } 949 # 950 function api($rig, $cmd) 951 { 952 global $haderror, $error; 953 global $miner, $port, $hidefields; 954 955 $socket = getsock($rig, $miner, $port); 956 if ($socket != null) 957 { 958 socket_write($socket, $cmd, strlen($cmd)); 959 $line = readsockline($socket); 960 socket_close($socket); 961 962 if (strlen($line) == 0) 963 { 964 $haderror = true; 965 $error = "WARN: '$cmd' returned nothing\n"; 966 return $line; 967 } 968 969 # print "$cmd returned '$line'\n"; 970 971 $line = api_convert_escape($line); 972 973 $data = array(); 974 975 $objs = explode('|', $line); 976 foreach ($objs as $obj) 977 { 978 if (strlen($obj) > 0) 979 { 980 $items = explode(',', $obj); 981 $item = $items[0]; 982 $id = explode('=', $items[0], 2); 983 if (count($id) == 1 or !ctype_digit($id[1])) 984 $name = $id[0]; 985 else 986 $name = $id[0].$id[1]; 987 988 if (strlen($name) == 0) 989 $name = 'null'; 990 991 $sectionname = preg_replace('/\d/', '', $name); 992 993 if (isset($data[$name])) 994 { 995 $num = 1; 996 while (isset($data[$name.$num])) 997 $num++; 998 $name .= $num; 999 } 1000 1001 $counter = 0; 1002 foreach ($items as $item) 1003 { 1004 $id = explode('=', $item, 2); 1005 1006 if (isset($hidefields[$sectionname.'.'.$id[0]])) 1007 continue; 1008 1009 if (count($id) == 2) 1010 $data[$name][$id[0]] = revert($id[1]); 1011 else 1012 $data[$name][$counter] = $id[0]; 1013 1014 $counter++; 1015 } 1016 } 1017 } 1018 return $data; 1019 } 1020 return null; 1021 } 1022 # 1023 function getparam($name, $both = false) 1024 { 1025 $a = null; 1026 if (isset($_POST[$name])) 1027 $a = $_POST[$name]; 1028 1029 if (($both === true) and ($a === null)) 1030 { 1031 if (isset($_GET[$name])) 1032 $a = $_GET[$name]; 1033 } 1034 1035 if ($a == '' || $a == null) 1036 return null; 1037 1038 // limit to 1K just to be safe 1039 return substr($a, 0, 1024); 1040 } 1041 # 1042 function newtable() 1043 { 1044 global $tablebegin, $rownum; 1045 echo $tablebegin; 1046 $rownum = 0; 1047 } 1048 # 1049 function newrow() 1050 { 1051 echo '<tr>'; 1052 } 1053 # 1054 function othrow($row) 1055 { 1056 return "<tr>$row</tr>"; 1057 } 1058 # 1059 function otherrow($row) 1060 { 1061 echo othrow($row); 1062 } 1063 # 1064 function endrow() 1065 { 1066 global $rownum; 1067 echo '</tr>'; 1068 $rownum++; 1069 } 1070 # 1071 function endtable() 1072 { 1073 global $tableend; 1074 echo $tableend; 1075 } 1076 # 1077 function classlastshare($when, $alldata, $warnclass, $errorclass) 1078 { 1079 global $checklastshare; 1080 1081 if ($checklastshare === false) 1082 return ''; 1083 1084 if ($when == 0) 1085 return ''; 1086 1087 if (!isset($alldata['MHS av'])) 1088 return ''; 1089 1090 if ($alldata['MHS av'] == 0) 1091 return ''; 1092 1093 if (!isset($alldata['Last Share Time'])) 1094 return ''; 1095 1096 if (!isset($alldata['Last Share Difficulty'])) 1097 return ''; 1098 1099 $expected = pow(2, 32) / ($alldata['MHS av'] * pow(10, 6)); 1100 1101 // If the share difficulty changes while waiting on a share, 1102 // this calculation will of course be incorrect 1103 $expected *= $alldata['Last Share Difficulty']; 1104 1105 $howlong = $when - $alldata['Last Share Time']; 1106 if ($howlong < 1) 1107 $howlong = 1; 1108 1109 if ($howlong > ($expected * 12)) 1110 return $errorclass; 1111 1112 if ($howlong > ($expected * 8)) 1113 return $warnclass; 1114 1115 return ''; 1116 } 1117 # 1118 function endzero($num) 1119 { 1120 $rep = preg_replace('/0*$/', '', $num); 1121 if ($rep === '') 1122 $rep = '0'; 1123 return $rep; 1124 } 1125 # 1126 function fmt($section, $name, $value, $when, $alldata, $cf = NULL) 1127 { 1128 global $dfmt, $rownum; 1129 1130 if ($alldata == null) 1131 $alldata = array(); 1132 1133 $errorclass = 'err'; 1134 $warnclass = 'warn'; 1135 $lstclass = 'lst'; 1136 $hiclass = 'hi'; 1137 $loclass = 'lo'; 1138 $c2class = 'two'; 1139 $totclass = 'tot'; 1140 $b = ' '; 1141 1142 $class = ''; 1143 1144 $nams = explode('.', $name); 1145 if (count($nams) > 1) 1146 $name = $nams[count($nams)-1]; 1147 1148 $done = false; 1149 if ($value === null) 1150 { 1151 $ret = $b; 1152 $done = true; 1153 } 1154 else 1155 if ($cf != NULL and function_exists($cf)) 1156 { 1157 list($ret, $class) = $cf($section, $name, $value, $when, $alldata, 1158 $warnclass, $errorclass, $hiclass, $loclass, $totclass); 1159 if ($ret !== '') 1160 $done = true; 1161 } 1162 1163 if ($done === false) 1164 { 1165 $ret = $value; 1166 /* 1167 * To speed up the PHP, the case statement is just $name 1168 * It used to be $section.'.'.$name 1169 * If any names clash, the case code will need to check the value of 1170 * $section to resolve the clash - as with 'Last Share Time' below 1171 * If the code picks up a field that you wish to format differently, 1172 * then you'll need a customsummarypage 'fmt' extension 1173 */ 1174 switch ($name) 1175 { 1176 case '0': 1177 break; 1178 case 'Last Share Time': 1179 if ($section == 'total') 1180 break; 1181 if ($section == 'POOL') 1182 { 1183 if ($value == 0) 1184 $ret = 'Never'; 1185 else 1186 $ret = date('H:i:s d-M', $value); 1187 } 1188 else 1189 { 1190 if ($value == 0 1191 || (isset($alldata['Last Share Pool']) && $alldata['Last Share Pool'] == -1)) 1192 { 1193 $ret = 'Never'; 1194 $class = $warnclass; 1195 } 1196 else 1197 { 1198 $ret = date('H:i:s', $value); 1199 $class = classlastshare($when, $alldata, $warnclass, $errorclass); 1200 } 1201 } 1202 break; 1203 case 'Last getwork': 1204 case 'Last Valid Work': 1205 if ($section == 'total') 1206 break; 1207 if ($value == 0) 1208 $ret = 'Never'; 1209 else 1210 $ret = ($value - $when) . 's'; 1211 break; 1212 case 'Last Share Pool': 1213 if ($section == 'total') 1214 break; 1215 if ($value == -1) 1216 { 1217 $ret = 'None'; 1218 $class = $warnclass; 1219 } 1220 break; 1221 case 'Elapsed': 1222 case 'Device Elapsed': 1223 if ($section == 'total') 1224 break; 1225 $s = $value % 60; 1226 $value -= $s; 1227 $value /= 60; 1228 if ($value == 0) 1229 $ret = $s.'s'; 1230 else 1231 { 1232 $m = $value % 60; 1233 $value -= $m; 1234 $value /= 60; 1235 if ($value == 0) 1236 $ret = sprintf("%dm$b%02ds", $m, $s); 1237 else 1238 { 1239 $h = $value % 24; 1240 $value -= $h; 1241 $value /= 24; 1242 if ($value == 0) 1243 $ret = sprintf("%dh$b%02dm$b%02ds", $h, $m, $s); 1244 else 1245 { 1246 if ($value == 1) 1247 $days = ''; 1248 else 1249 $days = 's'; 1250 1251 $ret = sprintf("%dday$days$b%02dh$b%02dm$b%02ds", $value, $h, $m, $s); 1252 } 1253 } 1254 } 1255 break; 1256 case 'Last Well': 1257 if ($section == 'total') 1258 break; 1259 if ($value == '0') 1260 { 1261 $ret = 'Never'; 1262 $class = $warnclass; 1263 } 1264 else 1265 $ret = date('H:i:s', $value); 1266 break; 1267 case 'Last Not Well': 1268 if ($section == 'total') 1269 break; 1270 if ($value == '0') 1271 $ret = 'Never'; 1272 else 1273 { 1274 $ret = date('H:i:s', $value); 1275 $class = $errorclass; 1276 } 1277 break; 1278 case 'Reason Not Well': 1279 if ($section == 'total') 1280 break; 1281 if ($value != 'None') 1282 $class = $errorclass; 1283 break; 1284 case 'Utility': 1285 $ret = number_format($value, 2).'/m'; 1286 if ($value == 0) 1287 $class = $errorclass; 1288 else 1289 if (isset($alldata['Difficulty Accepted']) 1290 && isset($alldata['Accepted']) 1291 && isset($alldata['MHS av']) 1292 && ($alldata['Difficulty Accepted'] > 0) 1293 && ($alldata['Accepted'] > 0)) 1294 { 1295 $expected = 60 * $alldata['MHS av'] * (pow(10, 6) / pow(2, 32)); 1296 if ($expected == 0) 1297 $expected = 0.000001; // 1 H/s 1298 1299 $da = $alldata['Difficulty Accepted']; 1300 $a = $alldata['Accepted']; 1301 $expected /= ($da / $a); 1302 1303 $ratio = $value / $expected; 1304 if ($ratio < 0.9) 1305 $class = $loclass; 1306 else 1307 if ($ratio > 1.1) 1308 $class = $hiclass; 1309 } 1310 break; 1311 case 'Work Utility': 1312 $ret = number_format($value, 2).'/m'; 1313 break; 1314 case 'Temperature': 1315 if ($section == 'total') 1316 break; 1317 $ret = $value.'°C'; 1318 if ($value == 0) 1319 $ret = ' '; 1320 break; 1321 case 'Fan Percent': 1322 if ($section == 'total') 1323 break; 1324 if ($value == 0) 1325 $class = $warnclass; 1326 else 1327 { 1328 if ($value == 100) 1329 $class = $errorclass; 1330 else 1331 if ($value > 85) 1332 $class = $warnclass; 1333 } 1334 break; 1335 case 'Fan Speed': 1336 if ($section == 'total') 1337 break; 1338 if ($value == 0) 1339 $class = $warnclass; 1340 else 1341 if (isset($alldata['Fan Percent'])) 1342 { 1343 $test = $alldata['Fan Percent']; 1344 if ($test == 100) 1345 $class = $errorclass; 1346 else 1347 if ($test > 85) 1348 $class = $warnclass; 1349 } 1350 break; 1351 case 'MHS av': 1352 case 'MHS 5s': 1353 case 'MHS 1m': 1354 case 'MHS 5m': 1355 case 'MHS 15m': 1356 $parts = explode('.', $value, 2); 1357 if (count($parts) == 1) 1358 $dec = ''; 1359 else 1360 $dec = '.'.$parts[1]; 1361 $ret = number_format((float)$parts[0]).$dec; 1362 1363 if ($value == 0) 1364 $class = $errorclass; 1365 else 1366 if (isset($alldata['Difficulty Accepted']) 1367 && isset($alldata['Accepted']) 1368 && isset($alldata['Utility']) 1369 && ($alldata['Difficulty Accepted'] > 0) 1370 && ($alldata['Accepted'] > 0)) 1371 { 1372 $expected = 60 * $value * (pow(10, 6) / pow(2, 32)); 1373 if ($expected == 0) 1374 $expected = 0.000001; // 1 H/s 1375 1376 $da = $alldata['Difficulty Accepted']; 1377 $a = $alldata['Accepted']; 1378 $expected /= ($da / $a); 1379 1380 $ratio = $alldata['Utility'] / $expected; 1381 if ($ratio < 0.9) 1382 $class = $hiclass; 1383 else 1384 if ($ratio > 1.1) 1385 $class = $loclass; 1386 } 1387 break; 1388 case 'Total MH': 1389 case 'Getworks': 1390 case 'Works': 1391 case 'Accepted': 1392 case 'Rejected': 1393 case 'Local Work': 1394 case 'Discarded': 1395 case 'Diff1 Shares': 1396 case 'Diff1 Work': 1397 case 'Times Sent': 1398 case 'Bytes Sent': 1399 case 'Net Bytes Sent': 1400 case 'Times Recv': 1401 case 'Bytes Recv': 1402 case 'Net Bytes Recv': 1403 $parts = explode('.', $value, 2); 1404 if (count($parts) == 1) 1405 $dec = ''; 1406 else 1407 $dec = '.'.$parts[1]; 1408 $ret = number_format((float)$parts[0]).$dec; 1409 break; 1410 case 'Hs': 1411 case 'W': 1412 case 'history_time': 1413 case 'Pool Wait': 1414 case 'Pool Max': 1415 case 'Pool Min': 1416 case 'Pool Av': 1417 case 'Min Diff': 1418 case 'Max Diff': 1419 case 'Work Diff': 1420 $parts = explode('.', $value, 2); 1421 if (count($parts) == 1) 1422 $dec = ''; 1423 else 1424 $dec = '.'.endzero($parts[1]); 1425 $ret = number_format((float)$parts[0]).$dec; 1426 break; 1427 case 'Status': 1428 if ($section == 'total') 1429 break; 1430 if ($value != 'Alive') 1431 $class = $errorclass; 1432 break; 1433 case 'Enabled': 1434 if ($section == 'total') 1435 break; 1436 if ($value != 'Y') 1437 $class = $warnclass; 1438 break; 1439 case 'No Device': 1440 if ($section == 'total') 1441 break; 1442 if ($value != 'false') 1443 $class = $errorclass; 1444 break; 1445 case 'When': 1446 case 'Current Block Time': 1447 if ($section == 'total') 1448 break; 1449 $ret = date($dfmt, $value); 1450 break; 1451 case 'Last Share Difficulty': 1452 if ($section == 'total') 1453 break; 1454 case 'Difficulty Accepted': 1455 case 'Difficulty Rejected': 1456 case 'Difficulty Stale': 1457 if ($value != '') 1458 $ret = number_format((float)$value, 2); 1459 break; 1460 case 'Device Hardware%': 1461 case 'Device Rejected%': 1462 case 'Pool Rejected%': 1463 case 'Pool Stale%': 1464 if ($section == 'total') 1465 break; 1466 if ($value != '') 1467 $ret = number_format((float)$value, 2) . '%'; 1468 break; 1469 case 'Best Share': 1470 if ($section == 'total') 1471 break; 1472 case 'Hardware Errors': 1473 if ($value != '') 1474 $ret = number_format((float)$value); 1475 break; 1476 // BUTTON. 1477 case 'Rig': 1478 case 'Pool': 1479 // Sample GEN fields 1480 case 'Mined': 1481 if ($value != '') 1482 $ret = number_format((float)$value * 100.0, 3) . '%'; 1483 break; 1484 case 'Acc': 1485 case 'Rej': 1486 if ($value != '') 1487 $ret = number_format((float)$value * 100.0, 2) . '%'; 1488 break; 1489 case 'GHS av': 1490 case 'GHS 5m': 1491 case 'GHS WU': 1492 case 'GHS Acc': 1493 if ($value != '') 1494 $ret = number_format((float)$value, 2); 1495 break; 1496 case 'AvShr': 1497 if ($section == 'total') 1498 break; 1499 if ($value != '') 1500 $ret = number_format((float)$value, 2); 1501 if ($value == 0) 1502 $class = $warnclass; 1503 break; 1504 } 1505 } 1506 1507 if ($section == 'NOTIFY' && substr($name, 0, 1) == '*' && $value != '0') 1508 $class = $errorclass; 1509 1510 if ($class == '' && $section != 'POOL') 1511 $class = classlastshare($when, $alldata, $lstclass, $lstclass); 1512 1513 if ($class == '' && $section == 'total') 1514 $class = $totclass; 1515 1516 if ($class == '' && ($rownum % 2) == 0) 1517 $class = $c2class; 1518 1519 if ($ret === '') 1520 $ret = $b; 1521 1522 if ($class !== '') 1523 $class = " class=$class"; 1524 1525 return array($ret, $class); 1526 } 1527 # 1528 global $poolcmd; 1529 $poolcmd = array( 'Switch to' => 'switchpool', 1530 'Enable' => 'enablepool', 1531 'Disable' => 'disablepool', 1532 'Remove' => 'removepool' ); 1533 # 1534 function showhead($cmd, $values, $justnames = false) 1535 { 1536 global $poolcmd, $readonly; 1537 1538 newrow(); 1539 1540 foreach ($values as $name => $value) 1541 { 1542 if ($name == '0' or $name == '') 1543 $name = ' '; 1544 echo "<td valign=bottom class=h>$name</td>"; 1545 } 1546 1547 if ($justnames === false && $cmd == 'pools' && $readonly === false) 1548 foreach ($poolcmd as $name => $pcmd) 1549 echo "<td valign=bottom class=h>$name</td>"; 1550 1551 endrow(); 1552 } 1553 # 1554 function showdatetime() 1555 { 1556 global $dfmt; 1557 1558 otherrow('<td class=sta>Date: '.date($dfmt).'</td>'); 1559 } 1560 # 1561 global $singlerigsum; 1562 $singlerigsum = array( 1563 'devs' => array('MHS av' => 1, 'MHS 5s' => 1, 'MHS 1m' => 1, 'MHS 5m' => 1, 1564 'MHS 15m' => 1, 'Accepted' => 1, 'Rejected' => 1, 1565 'Hardware Errors' => 1, 'Utility' => 1, 'Total MH' => 1, 1566 'Diff1 Shares' => 1, 'Diff1 Work' => 1, 1567 'Difficulty Accepted' => 1, 'Difficulty Rejected' => 1), 1568 'pools' => array('Getworks' => 1, 'Accepted' => 1, 'Rejected' => 1, 'Discarded' => 1, 1569 'Stale' => 1, 'Get Failures' => 1, 'Remote Failures' => 1, 1570 'Diff1 Shares' => 1, 'Diff1 Work' => 1, 1571 'Difficulty Accepted' => 1, 'Difficulty Rejected' => 1, 1572 'Difficulty Stale' => 1), 1573 'notify' => array('*' => 1)); 1574 # 1575 function showtotal($total, $when, $oldvalues) 1576 { 1577 global $rigtotals; 1578 1579 list($showvalue, $class) = fmt('total', '', 'Total:', $when, null); 1580 echo "<td$class align=right>$showvalue</td>"; 1581 1582 $skipfirst = true; 1583 foreach ($oldvalues as $name => $value) 1584 { 1585 if ($skipfirst === true) 1586 { 1587 $skipfirst = false; 1588 continue; 1589 } 1590 1591 if (isset($total[$name])) 1592 $newvalue = $total[$name]; 1593 else 1594 $newvalue = ''; 1595 1596 list($showvalue, $class) = fmt('total', $name, $newvalue, $when, null); 1597 echo "<td$class"; 1598 if ($rigtotals === true) 1599 echo ' align=right'; 1600 echo ">$showvalue</td>"; 1601 } 1602 } 1603 # 1604 function details($cmd, $list, $rig) 1605 { 1606 global $dfmt, $poolcmd, $readonly, $showndate; 1607 global $rownum, $rigtotals, $forcerigtotals, $singlerigsum; 1608 1609 $when = 0; 1610 1611 $stas = array('S' => 'Success', 'W' => 'Warning', 'I' => 'Informational', 'E' => 'Error', 'F' => 'Fatal'); 1612 1613 newtable(); 1614 1615 if ($showndate === false) 1616 { 1617 showdatetime(); 1618 1619 endtable(); 1620 newtable(); 1621 1622 $showndate = true; 1623 } 1624 1625 if (isset($list['STATUS'])) 1626 { 1627 newrow(); 1628 echo '<td>Computer: '.$list['STATUS']['Description'].'</td>'; 1629 if (isset($list['STATUS']['When'])) 1630 { 1631 echo '<td>When: '.date($dfmt, $list['STATUS']['When']).'</td>'; 1632 $when = $list['STATUS']['When']; 1633 } 1634 $sta = $list['STATUS']['STATUS']; 1635 echo '<td>Status: '.$stas[$sta].'</td>'; 1636 echo '<td>Message: '.$list['STATUS']['Msg'].'</td>'; 1637 endrow(); 1638 } 1639 1640 if ($rigtotals === true && isset($singlerigsum[$cmd])) 1641 $dototal = $singlerigsum[$cmd]; 1642 else 1643 $dototal = array(); 1644 1645 $total = array(); 1646 1647 $section = ''; 1648 $oldvalues = null; 1649 foreach ($list as $item => $values) 1650 { 1651 if ($item == 'STATUS') 1652 continue; 1653 1654 $sectionname = preg_replace('/\d/', '', $item); 1655 1656 // Handle 'devs' possibly containing >1 table 1657 if ($sectionname != $section) 1658 { 1659 if ($oldvalues != null && count($total) > 0 1660 && ($rownum > 2 || $forcerigtotals === true)) 1661 showtotal($total, $when, $oldvalues); 1662 1663 endtable(); 1664 newtable(); 1665 showhead($cmd, $values); 1666 $section = $sectionname; 1667 } 1668 1669 newrow(); 1670 1671 foreach ($values as $name => $value) 1672 { 1673 list($showvalue, $class) = fmt($section, $name, $value, $when, $values); 1674 echo "<td$class"; 1675 if ($rigtotals === true) 1676 echo ' align=right'; 1677 echo ">$showvalue</td>"; 1678 1679 if (isset($dototal[$name]) 1680 || (isset($dototal['*']) and substr($name, 0, 1) == '*')) 1681 { 1682 if (isset($total[$name])) 1683 $total[$name] += $value; 1684 else 1685 $total[$name] = $value; 1686 } 1687 } 1688 1689 if ($cmd == 'pools' && $readonly === false) 1690 { 1691 reset($values); 1692 $pool = current($values); 1693 foreach ($poolcmd as $name => $pcmd) 1694 { 1695 list($ignore, $class) = fmt('BUTTON', 'Pool', '', $when, $values); 1696 echo "<td$class>"; 1697 if ($pool === false) 1698 echo ' '; 1699 else 1700 { 1701 echo "<input type=button value='Pool $pool'"; 1702 echo " onclick='prc(\"$pcmd|$pool&rig=$rig\",\"$name Pool $pool\")'>"; 1703 } 1704 echo '</td>'; 1705 } 1706 } 1707 endrow(); 1708 1709 $oldvalues = $values; 1710 } 1711 1712 if ($oldvalues != null && count($total) > 0 1713 && ($rownum > 2 || $forcerigtotals === true)) 1714 showtotal($total, $when, $oldvalues); 1715 1716 endtable(); 1717 } 1718 # 1719 global $devs; 1720 $devs = null; 1721 # 1722 function showpoolinputs($rig, $ans) 1723 { 1724 global $readonly, $poolinputs; 1725 1726 if ($readonly === true || $poolinputs === false) 1727 return; 1728 1729 newtable(); 1730 newrow(); 1731 1732 $inps = array('Pool URL' => array('purl', 20), 1733 'Worker Name' => array('pwork', 10), 1734 'Worker Password' => array('ppass', 10)); 1735 $b = ' '; 1736 1737 echo "<td align=right class=h> Add a pool: </td><td>"; 1738 1739 foreach ($inps as $text => $name) 1740 echo "$text: <input name='".$name[0]."' id='".$name[0]."' value='' type=text size=".$name[1]."> "; 1741 1742 echo "</td><td align=middle><input type=button value='Add' onclick='pla($rig)'></td>"; 1743 1744 endrow(); 1745 1746 if (count($ans) > 1) 1747 { 1748 newrow(); 1749 1750 echo '<td align=right class=h> Set pool priorities: </td>'; 1751 echo "<td> Comma list of pool numbers: <input type=text name=prio id=prio size=20>"; 1752 echo "</td><td align=middle><input type=button value='Set' onclick='psp($rig)'></td>"; 1753 1754 endrow(); 1755 } 1756 endtable(); 1757 } 1758 # 1759 function process($cmds, $rig) 1760 { 1761 global $error, $devs; 1762 global $warnfont, $warnoff; 1763 1764 $count = count($cmds); 1765 foreach ($cmds as $cmd => $des) 1766 { 1767 $process = api($rig, $cmd); 1768 1769 if ($error != null) 1770 { 1771 otherrow("<td colspan=100>Error getting $des: $warnfont$error$warnoff</td>"); 1772 break; 1773 } 1774 else 1775 { 1776 details($cmd, $process, $rig); 1777 1778 if ($cmd == 'devs') 1779 $devs = $process; 1780 1781 if ($cmd == 'pools') 1782 showpoolinputs($rig, $process); 1783 1784 # Not after the last one 1785 if (--$count > 0) 1786 otherrow('<td><br><br></td>'); 1787 } 1788 } 1789 } 1790 # 1791 function rigname($rig, $rigname) 1792 { 1793 global $rigs, $rignames, $rigips; 1794 1795 if (isset($rigs[$rig])) 1796 { 1797 $parts = explode(':', $rigs[$rig], 3); 1798 if (count($parts) == 3) 1799 $rigname = $parts[2]; 1800 else 1801 if ($rignames !== false) 1802 { 1803 switch ($rignames) 1804 { 1805 case 'ip': 1806 if (isset($parts[0]) && isset($rigips[$parts[0]])) 1807 { 1808 $ip = explode('.', $rigips[$parts[0]]); 1809 if (count($ip) == 4) 1810 $rigname = intval($ip[3]); 1811 } 1812 break; 1813 case 'ipx': 1814 if (isset($parts[0]) && isset($rigips[$parts[0]])) 1815 { 1816 $ip = explode('.', $rigips[$parts[0]]); 1817 if (count($ip) == 4) 1818 $rigname = intval($ip[3], 16); 1819 } 1820 break; 1821 } 1822 } 1823 } 1824 1825 return $rigname; 1826 } 1827 # 1828 function riginput($rig, $rigname, $usebuttons) 1829 { 1830 $rigname = rigname($rig, $rigname); 1831 1832 if ($usebuttons === true) 1833 return "<input type=button value='$rigname' onclick='pr(\"&rig=$rig\",null)'>"; 1834 else 1835 return "<a href='".php_pr("&rig=$rig")."'>$rigname</a>"; 1836 } 1837 # 1838 function rigbutton($rig, $rigname, $when, $row, $usebuttons) 1839 { 1840 list($value, $class) = fmt('BUTTON', 'Rig', '', $when, $row); 1841 1842 if ($rig === '') 1843 $ri = ' '; 1844 else 1845 $ri = riginput($rig, $rigname, $usebuttons); 1846 1847 return "<td align=middle$class>$ri</td>"; 1848 } 1849 # 1850 function showrigs($anss, $headname, $rigname) 1851 { 1852 global $rigbuttons; 1853 1854 $dthead = array($headname => 1, 'STATUS' => 1, 'Description' => 1, 'When' => 1, 'API' => 1, 'CGMiner' => 1); 1855 showhead('', $dthead); 1856 1857 foreach ($anss as $rig => $ans) 1858 { 1859 if ($ans == null) 1860 continue; 1861 1862 newrow(); 1863 1864 $when = 0; 1865 if (isset($ans['STATUS']['When'])) 1866 $when = $ans['STATUS']['When']; 1867 1868 foreach ($ans as $item => $row) 1869 { 1870 if ($item != 'STATUS' && $item != 'VERSION') 1871 continue; 1872 1873 foreach ($dthead as $name => $x) 1874 { 1875 if ($item == 'STATUS' && $name == $headname) 1876 echo rigbutton($rig, $rigname.$rig, $when, null, $rigbuttons); 1877 else 1878 { 1879 if (isset($row[$name])) 1880 { 1881 list($showvalue, $class) = fmt('STATUS', $name, $row[$name], $when, null); 1882 echo "<td$class align=right>$showvalue</td>"; 1883 } 1884 } 1885 } 1886 } 1887 endrow(); 1888 } 1889 } 1890 # 1891 function refreshbuttons() 1892 { 1893 global $ignorerefresh, $changerefresh, $autorefresh; 1894 1895 if ($ignorerefresh == false && $changerefresh == true) 1896 { 1897 echo ' '; 1898 echo "<input type=button value='Auto Refresh:' onclick='prr(true)'>"; 1899 echo "<input type=text name='refval' id='refval' size=2 value='$autorefresh'>"; 1900 echo "<input type=button value='Off' onclick='prr(false)'>"; 1901 } 1902 } 1903 # 1904 function pagebuttons($rig, $pg) 1905 { 1906 global $readonly, $rigs, $rigbuttons, $userlist, $ses; 1907 global $allowcustompages, $customsummarypages; 1908 1909 if ($rig === null) 1910 { 1911 $prev = null; 1912 $next = null; 1913 1914 if ($pg === null) 1915 $refresh = ''; 1916 else 1917 $refresh = "&pg=$pg"; 1918 } 1919 else 1920 { 1921 switch (count($rigs)) 1922 { 1923 case 0: 1924 case 1: 1925 $prev = null; 1926 $next = null; 1927 break; 1928 case 2: 1929 $prev = null; 1930 $next = ($rig + 1) % count($rigs); 1931 break; 1932 default: 1933 $prev = ($rig - 1) % count($rigs); 1934 $next = ($rig + 1) % count($rigs); 1935 break; 1936 } 1937 1938 $refresh = "&rig=$rig"; 1939 } 1940 1941 echo '<tr><td><table cellpadding=0 cellspacing=0 border=0><tr><td nowrap>'; 1942 if ($userlist === null || isset($_SESSION[$ses])) 1943 { 1944 if ($prev !== null) 1945 echo riginput($prev, 'Prev', true).' '; 1946 1947 echo "<input type=button value='Refresh' onclick='pr(\"$refresh\",null)'> "; 1948 1949 if ($next !== null) 1950 echo riginput($next, 'Next', true).' '; 1951 echo ' '; 1952 if (count($rigs) > 1 and getcsp('Summary', true) !== false) 1953 echo "<input type=button value='Summary' onclick='pr(\"\",null)'> "; 1954 } 1955 1956 if ($allowcustompages === true) 1957 { 1958 if ($userlist === null || isset($_SESSION[$ses])) 1959 $list = $customsummarypages; 1960 else 1961 { 1962 if ($userlist !== null && isset($userlist['def'])) 1963 $list = array_flip($userlist['def']); 1964 else 1965 $list = array(); 1966 } 1967 1968 foreach ($list as $pagename => $data) 1969 if (getcsp($pagename) !== false) 1970 echo "<input type=button value='$pagename' onclick='pr(\"&pg=$pagename\",null)'> "; 1971 } 1972 1973 echo '</td><td width=100%> </td><td nowrap>'; 1974 if ($rig !== null && $readonly === false) 1975 { 1976 $rg = ''; 1977 if (count($rigs) > 1) 1978 $rg = " Rig $rig"; 1979 echo "<input type=button value='Restart' onclick='prc(\"restart&rig=$rig\",\"Restart CGMiner$rg\")'>"; 1980 echo " <input type=button value='Quit' onclick='prc(\"quit&rig=$rig\",\"Quit CGMiner$rg\")'>"; 1981 } 1982 refreshbuttons(); 1983 if (isset($_SESSION[$ses])) 1984 echo " <input type=button value='Logout' onclick='pr(\"&logout=1\",null)'>"; 1985 else 1986 if ($userlist !== null) 1987 echo " <input type=button value='Login' onclick='pr(\"&login=1\",null)'>"; 1988 1989 echo "</td></tr></table></td></tr>"; 1990 } 1991 # 1992 function doOne($rig, $preprocess) 1993 { 1994 global $haderror, $readonly, $notify, $rigs; 1995 global $placebuttons; 1996 1997 if ($placebuttons == 'top' || $placebuttons == 'both') 1998 pagebuttons($rig, null); 1999 2000 if ($preprocess != null) 2001 process(array($preprocess => $preprocess), $rig); 2002 2003 $cmds = array( 'devs' => 'device list', 2004 'summary' => 'summary information', 2005 'pools' => 'pool list'); 2006 2007 if ($notify) 2008 $cmds['notify'] = 'device status'; 2009 2010 $cmds['config'] = 'cgminer config'; 2011 2012 process($cmds, $rig); 2013 2014 if ($placebuttons == 'bot' || $placebuttons == 'both') 2015 pagebuttons($rig, null); 2016 } 2017 # 2018 global $sectionmap; 2019 # map sections to their api command 2020 # DEVS is a special case that will match PGA or ASC 2021 # so you can have a single table with both in it 2022 # DATE is hard coded so not in here 2023 $sectionmap = array( 2024 'RIGS' => 'version', 2025 'SUMMARY' => 'summary', 2026 'POOL' => 'pools', 2027 'DEVS' => 'devs', 2028 'EDEVS' => 'edevs', 2029 'PGA' => 'devs', // You would normally use DEVS 2030 'ASC' => 'devs', // You would normally use DEVS 2031 'NOTIFY' => 'notify', 2032 'DEVDETAILS' => 'devdetails', 2033 'STATS' => 'stats', 2034 'ESTATS' => 'estats', 2035 'CONFIG' => 'config', 2036 'COIN' => 'coin', 2037 'USBSTATS' => 'usbstats'); 2038 # 2039 function joinfields($section1, $section2, $join, $results) 2040 { 2041 global $sectionmap; 2042 2043 $name1 = $sectionmap[$section1]; 2044 $name2 = $sectionmap[$section2]; 2045 $newres = array(); 2046 2047 // foreach rig in section1 2048 foreach ($results[$name1] as $rig => $result) 2049 { 2050 $status = null; 2051 2052 // foreach answer section in the rig api call 2053 foreach ($result as $name1b => $fields1b) 2054 { 2055 if ($name1b == 'STATUS') 2056 { 2057 // remember the STATUS from section1 2058 $status = $result[$name1b]; 2059 continue; 2060 } 2061 2062 // foreach answer section in the rig api call (for the other api command) 2063 foreach ($results[$name2][$rig] as $name2b => $fields2b) 2064 { 2065 if ($name2b == 'STATUS') 2066 continue; 2067 2068 // If match the same field values of fields in $join 2069 $match = true; 2070 foreach ($join as $field) 2071 if ($fields1b[$field] != $fields2b[$field]) 2072 { 2073 $match = false; 2074 break; 2075 } 2076 2077 if ($match === true) 2078 { 2079 if ($status != null) 2080 { 2081 $newres[$rig]['STATUS'] = $status; 2082 $status = null; 2083 } 2084 2085 $subsection = $section1.'+'.$section2; 2086 $subsection .= preg_replace('/[^0-9]/', '', $name1b.$name2b); 2087 2088 foreach ($fields1b as $nam => $val) 2089 $newres[$rig][$subsection]["$section1.$nam"] = $val; 2090 foreach ($fields2b as $nam => $val) 2091 $newres[$rig][$subsection]["$section2.$nam"] = $val; 2092 } 2093 } 2094 } 2095 } 2096 return $newres; 2097 } 2098 # 2099 function joinlr($section1, $section2, $join, $results) 2100 { 2101 global $sectionmap; 2102 2103 $name1 = $sectionmap[$section1]; 2104 $name2 = $sectionmap[$section2]; 2105 $newres = array(); 2106 2107 // foreach rig in section1 2108 foreach ($results[$name1] as $rig => $result) 2109 { 2110 $status = null; 2111 2112 // foreach answer section in the rig api call 2113 foreach ($result as $name1b => $fields1b) 2114 { 2115 if ($name1b == 'STATUS') 2116 { 2117 // remember the STATUS from section1 2118 $status = $result[$name1b]; 2119 continue; 2120 } 2121 2122 // Build L string to be matched 2123 // : means a string constant otherwise it's a field name 2124 $Lval = ''; 2125 foreach ($join['L'] as $field) 2126 { 2127 if (substr($field, 0, 1) == ':') 2128 $Lval .= substr($field, 1); 2129 else 2130 $Lval .= $fields1b[$field]; 2131 } 2132 2133 // foreach answer section in the rig api call (for the other api command) 2134 foreach ($results[$name2][$rig] as $name2b => $fields2b) 2135 { 2136 if ($name2b == 'STATUS') 2137 continue; 2138 2139 // Build R string and compare 2140 // : means a string constant otherwise it's a field name 2141 $Rval = ''; 2142 foreach ($join['R'] as $field) 2143 { 2144 if (substr($field, 0, 1) == ':') 2145 $Rval .= substr($field, 1); 2146 else 2147 $Rval .= $fields2b[$field]; 2148 } 2149 2150 if ($Lval === $Rval) 2151 { 2152 if ($status != null) 2153 { 2154 $newres[$rig]['STATUS'] = $status; 2155 $status = null; 2156 } 2157 2158 $subsection = $section1.'+'.$section2; 2159 $subsection .= preg_replace('/[^0-9]/', '', $name1b.$name2b); 2160 2161 foreach ($fields1b as $nam => $val) 2162 $newres[$rig][$subsection]["$section1.$nam"] = $val; 2163 foreach ($fields2b as $nam => $val) 2164 $newres[$rig][$subsection]["$section2.$nam"] = $val; 2165 } 2166 } 2167 } 2168 } 2169 return $newres; 2170 } 2171 # 2172 function joinall($section1, $section2, $results) 2173 { 2174 global $sectionmap; 2175 2176 $name1 = $sectionmap[$section1]; 2177 $name2 = $sectionmap[$section2]; 2178 $newres = array(); 2179 2180 // foreach rig in section1 2181 foreach ($results[$name1] as $rig => $result) 2182 { 2183 // foreach answer section in the rig api call 2184 foreach ($result as $name1b => $fields1b) 2185 { 2186 if ($name1b == 'STATUS') 2187 { 2188 // copy the STATUS from section1 2189 $newres[$rig][$name1b] = $result[$name1b]; 2190 continue; 2191 } 2192 2193 // foreach answer section in the rig api call (for the other api command) 2194 foreach ($results[$name2][$rig] as $name2b => $fields2b) 2195 { 2196 if ($name2b == 'STATUS') 2197 continue; 2198 2199 $subsection = $section1.'+'.$section2; 2200 $subsection .= preg_replace('/[^0-9]/', '', $name1b.$name2b); 2201 2202 foreach ($fields1b as $nam => $val) 2203 $newres[$rig][$subsection]["$section1.$nam"] = $val; 2204 foreach ($fields2b as $nam => $val) 2205 $newres[$rig][$subsection]["$section2.$nam"] = $val; 2206 } 2207 } 2208 } 2209 return $newres; 2210 } 2211 # 2212 function joinsections($sections, $results, $errors) 2213 { 2214 global $sectionmap; 2215 2216 foreach ($sections as $section => $fields) 2217 if ($section != 'DATE' && !isset($sectionmap[$section])) 2218 { 2219 $both = explode('+', $section, 2); 2220 if (count($both) > 1) 2221 { 2222 switch($both[0]) 2223 { 2224 case 'SUMMARY': 2225 switch($both[1]) 2226 { 2227 case 'POOL': 2228 case 'DEVS': 2229 case 'EDEVS': 2230 case 'CONFIG': 2231 case 'COIN': 2232 $sectionmap[$section] = $section; 2233 $results[$section] = joinall($both[0], $both[1], $results); 2234 break; 2235 default: 2236 $errors[] = "Error: Invalid section '$section'"; 2237 break; 2238 } 2239 break; 2240 case 'DEVS': 2241 case 'EDEVS': 2242 switch($both[1]) 2243 { 2244 case 'NOTIFY': 2245 case 'DEVDETAILS': 2246 case 'USBSTATS': 2247 $join = array('Name', 'ID'); 2248 $sectionmap[$section] = $section; 2249 $results[$section] = joinfields($both[0], $both[1], $join, $results); 2250 break; 2251 case 'STATS': 2252 case 'ESTATS': 2253 $join = array('L' => array('Name','ID'), 'R' => array('ID')); 2254 $sectionmap[$section] = $section; 2255 $results[$section] = joinlr($both[0], $both[1], $join, $results); 2256 break; 2257 default: 2258 $errors[] = "Error: Invalid section '$section'"; 2259 break; 2260 } 2261 break; 2262 case 'POOL': 2263 switch($both[1]) 2264 { 2265 case 'STATS': 2266 $join = array('L' => array(':POOL','POOL'), 'R' => array('ID')); 2267 $sectionmap[$section] = $section; 2268 $results[$section] = joinlr($both[0], $both[1], $join, $results); 2269 break; 2270 default: 2271 $errors[] = "Error: Invalid section '$section'"; 2272 break; 2273 } 2274 break; 2275 default: 2276 $errors[] = "Error: Invalid section '$section'"; 2277 break; 2278 } 2279 } 2280 else 2281 $errors[] = "Error: Invalid section '$section'"; 2282 } 2283 2284 return array($results, $errors); 2285 } 2286 # 2287 function secmatch($section, $field) 2288 { 2289 if ($section == $field) 2290 return true; 2291 2292 if (($section == 'DEVS' || $section == 'EDEVS') 2293 && ($field == 'PGA' || $field == 'ASC')) 2294 return true; 2295 2296 return false; 2297 } 2298 # 2299 function customset($showfields, $sum, $section, $rig, $isbutton, $result, $total, $cf = NULL) 2300 { 2301 global $rigbuttons; 2302 2303 $rn = 0; 2304 foreach ($result as $sec => $row) 2305 { 2306 $secname = preg_replace('/\d/', '', $sec); 2307 2308 if ($sec != 'total') 2309 if (!secmatch($section, $secname)) 2310 continue; 2311 2312 newrow(); 2313 2314 $when = 0; 2315 if (isset($result['STATUS']['When'])) 2316 $when = $result['STATUS']['When']; 2317 2318 2319 if ($isbutton) 2320 echo rigbutton($rig, $rig, $when, $row, $rigbuttons); 2321 else 2322 { 2323 list($ignore, $class) = fmt('total', '', '', $when, $row, $cf); 2324 echo "<td align=middle$class>$rig</td>"; 2325 } 2326 2327 foreach ($showfields as $name => $one) 2328 { 2329 if ($name === '#' and $sec != 'total') 2330 { 2331 $rn++; 2332 $value = $rn; 2333 if (isset($total[$name])) 2334 $total[$name]++; 2335 else 2336 $total[$name] = 1; 2337 } 2338 elseif (isset($row[$name])) 2339 { 2340 $value = $row[$name]; 2341 2342 if (isset($sum[$section][$name])) 2343 { 2344 if (isset($total[$name])) 2345 $total[$name] += $value; 2346 else 2347 $total[$name] = $value; 2348 } 2349 } 2350 else 2351 { 2352 if ($sec == 'total' && isset($total[$name])) 2353 $value = $total[$name]; 2354 else 2355 $value = null; 2356 } 2357 2358 if (strpos($secname, '+') === false) 2359 list($showvalue, $class) = fmt($secname, $name, $value, $when, $row, $cf); 2360 else 2361 { 2362 if ($name != '#') 2363 $parts = explode('.', $name, 2); 2364 else 2365 $parts[0] = $parts[1] = '#'; 2366 list($showvalue, $class) = fmt($parts[0], $parts[1], $value, $when, $row, $cf); 2367 } 2368 2369 echo "<td$class align=right>$showvalue</td>"; 2370 } 2371 endrow(); 2372 } 2373 return $total; 2374 } 2375 # 2376 function docalc($func, $data) 2377 { 2378 switch ($func) 2379 { 2380 case 'sum': 2381 $tot = 0; 2382 foreach ($data as $val) 2383 $tot += $val; 2384 return $tot; 2385 case 'avg': 2386 $tot = 0; 2387 foreach ($data as $val) 2388 $tot += $val; 2389 return ($tot / count($data)); 2390 case 'min': 2391 $ans = null; 2392 foreach ($data as $val) 2393 if ($ans === null) 2394 $ans = $val; 2395 else 2396 if ($val < $ans) 2397 $ans = $val; 2398 return $ans; 2399 case 'max': 2400 $ans = null; 2401 foreach ($data as $val) 2402 if ($ans === null) 2403 $ans = $val; 2404 else 2405 if ($val > $ans) 2406 $ans = $val; 2407 return $ans; 2408 case 'lo': 2409 $ans = null; 2410 foreach ($data as $val) 2411 if ($ans === null) 2412 $ans = $val; 2413 else 2414 if (strcasecmp($val, $ans) < 0) 2415 $ans = $val; 2416 return $ans; 2417 case 'hi': 2418 $ans = null; 2419 foreach ($data as $val) 2420 if ($ans === null) 2421 $ans = $val; 2422 else 2423 if (strcasecmp($val, $ans) > 0) 2424 $ans = $val; 2425 return $ans; 2426 case 'count': 2427 return count($data); 2428 case 'any': 2429 default: 2430 return $data[0]; 2431 } 2432 } 2433 # 2434 function docompare($row, $test) 2435 { 2436 // invalid $test data means true 2437 if (count($test) < 2) 2438 return true; 2439 2440 if (isset($row[$test[0]])) 2441 $val = $row[$test[0]]; 2442 else 2443 $val = null; 2444 2445 if ($test[1] == 'set') 2446 return ($val !== null); 2447 2448 if ($val === null || count($test) < 3) 2449 return true; 2450 2451 switch($test[1]) 2452 { 2453 case '=': 2454 return ($val == $test[2]); 2455 case '<': 2456 return ($val < $test[2]); 2457 case '<=': 2458 return ($val <= $test[2]); 2459 case '>': 2460 return ($val > $test[2]); 2461 case '>=': 2462 return ($val >= $test[2]); 2463 case 'eq': 2464 return (strcasecmp($val, $test[2]) == 0); 2465 case 'lt': 2466 return (strcasecmp($val, $test[2]) < 0); 2467 case 'le': 2468 return (strcasecmp($val, $test[2]) <= 0); 2469 case 'gt': 2470 return (strcasecmp($val, $test[2]) > 0); 2471 case 'ge': 2472 return (strcasecmp($val, $test[2]) >= 0); 2473 default: 2474 return true; 2475 } 2476 } 2477 # 2478 function processcompare($which, $ext, $section, $res) 2479 { 2480 if (isset($ext[$section][$which])) 2481 { 2482 $proc = $ext[$section][$which]; 2483 if ($proc !== null) 2484 { 2485 $res2 = array(); 2486 foreach ($res as $rig => $result) 2487 foreach ($result as $sec => $row) 2488 { 2489 $secname = preg_replace('/\d/', '', $sec); 2490 if (!secmatch($section, $secname)) 2491 $res2[$rig][$sec] = $row; 2492 else 2493 { 2494 $keep = true; 2495 foreach ($proc as $test) 2496 if (!docompare($row, $test)) 2497 { 2498 $keep = false; 2499 break; 2500 } 2501 if ($keep) 2502 $res2[$rig][$sec] = $row; 2503 } 2504 } 2505 2506 $res = $res2; 2507 } 2508 } 2509 return $res; 2510 } 2511 # 2512 function ss($a, $b) 2513 { 2514 $la = strlen($a); 2515 $lb = strlen($b); 2516 if ($la != $lb) 2517 return $lb - $la; 2518 return strcmp($a, $b); 2519 } 2520 # 2521 # If you are developing a customsummarypage that uses BGEN or GEN, 2522 # you may want to remove the '@' in front of '@eval()' to help with debugging 2523 # The '@' removes php comments from the web log about missing fields 2524 # Since there are many forks of cgminer that break the API or do not 2525 # keep their fork up to date with current cgminer, the addition of 2526 # '@' solves the problem of generating unnecessary and excessive web logs 2527 # about the eval() 2528 function genfld($row, $calc) 2529 { 2530 uksort($row, "ss"); 2531 2532 foreach ($row as $name => $value) 2533 if (strstr($calc, $name) !== FALSE) 2534 $calc = str_replace($name, $value, $calc); 2535 2536 @eval("\$val = $calc;"); 2537 2538 if (!isset($val)) 2539 return ''; 2540 else 2541 return $val; 2542 } 2543 # 2544 function dogen($ext, $wg, $gname, $section, &$res, &$fields) 2545 { 2546 $gen = $ext[$section][$wg]; 2547 2548 foreach ($gen as $fld => $calc) 2549 $fields[] = "$gname.$fld"; 2550 2551 foreach ($res as $rig => $result) 2552 foreach ($result as $sec => $row) 2553 { 2554 $secname = preg_replace('/\d/', '', $sec); 2555 if (secmatch($section, $secname)) 2556 foreach ($gen as $fld => $calc) 2557 { 2558 $name = "$gname.$fld"; 2559 2560 $val = genfld($row, $calc); 2561 2562 $res[$rig][$sec][$name] = $val; 2563 } 2564 } 2565 } 2566 # 2567 function processext($ext, $section, $res, &$fields) 2568 { 2569 global $allowgen; 2570 2571 $res = processcompare('where', $ext, $section, $res); 2572 2573 // Generated fields (functions of other fields before grouping) 2574 if ($allowgen === true && isset($ext[$section]['bgen'])) 2575 dogen($ext, 'bgen', 'BGEN', $section, $res, $fields); 2576 2577 if (isset($ext[$section]['group'])) 2578 { 2579 $grp = $ext[$section]['group']; 2580 $calc = $ext[$section]['calc']; 2581 if ($grp !== null) 2582 { 2583 $interim = array(); 2584 $res2 = array(); 2585 $cou = 0; 2586 foreach ($res as $rig => $result) 2587 foreach ($result as $sec => $row) 2588 { 2589 $secname = preg_replace('/\d/', '', $sec); 2590 if (!secmatch($section, $secname)) 2591 { 2592 // STATUS may be problematic ... 2593 if (!isset($res2[$sec])) 2594 $res2[$sec] = $row; 2595 } 2596 else 2597 { 2598 $grpkey = ''; 2599 $newrow = array(); 2600 foreach ($grp as $field) 2601 { 2602 if (isset($row[$field])) 2603 { 2604 $grpkey .= $row[$field].'.'; 2605 $newrow[$field] = $row[$field]; 2606 } 2607 else 2608 $grpkey .= '.'; 2609 } 2610 2611 if (!isset($interim[$grpkey])) 2612 { 2613 $interim[$grpkey]['grp'] = $newrow; 2614 $interim[$grpkey]['sec'] = $secname.$cou; 2615 $cou++; 2616 } 2617 2618 if ($calc !== null) 2619 foreach ($calc as $field => $func) 2620 { 2621 if (isset($row[$field])) 2622 { 2623 if (!isset($interim[$grpkey]['cal'][$field])) 2624 $interim[$grpkey]['cal'][$field] = array(); 2625 $interim[$grpkey]['cal'][$field][] = $row[$field]; 2626 } 2627 } 2628 } 2629 } 2630 2631 // Build the rest of $res2 from $interim 2632 foreach ($interim as $rowkey => $row) 2633 { 2634 $key = $row['sec']; 2635 foreach ($row['grp'] as $field => $value) 2636 $res2[$key][$field] = $value; 2637 foreach ($row['cal'] as $field => $data) 2638 $res2[$key][$field] = docalc($calc[$field], $data); 2639 } 2640 2641 $res = array('' => $res2); 2642 } 2643 } 2644 2645 // Generated fields (functions of other fields after grouping) 2646 if ($allowgen === true && isset($ext[$section]['gen'])) 2647 dogen($ext, 'gen', 'GEN', $section, $res, $fields); 2648 2649 return processcompare('having', $ext, $section, $res); 2650 } 2651 # 2652 function processcustompage($pagename, $sections, $sum, $ext, $namemap) 2653 { 2654 global $sectionmap; 2655 global $miner, $port; 2656 global $rigs, $error; 2657 global $warnfont, $warnoff; 2658 global $dfmt; 2659 global $readonly, $showndate; 2660 2661 $cmds = array(); 2662 $errors = array(); 2663 foreach ($sections as $section => $fields) 2664 { 2665 $all = explode('+', $section); 2666 foreach ($all as $section) 2667 { 2668 if (isset($sectionmap[$section])) 2669 { 2670 $cmd = $sectionmap[$section]; 2671 if (!isset($cmds[$cmd])) 2672 $cmds[$cmd] = 1; 2673 } 2674 else 2675 if ($section != 'DATE') 2676 $errors[] = "Error: unknown section '$section' in custom summary page '$pagename'"; 2677 } 2678 } 2679 2680 $results = array(); 2681 foreach ($rigs as $num => $rig) 2682 { 2683 $parts = explode(':', $rig, 3); 2684 if (count($parts) >= 1) 2685 { 2686 $miner = $parts[0]; 2687 if (count($parts) >= 2) 2688 $port = $parts[1]; 2689 else 2690 $port = ''; 2691 2692 if (count($parts) > 2) 2693 $name = $parts[2]; 2694 else 2695 $name = $rig; 2696 2697 foreach ($cmds as $cmd => $one) 2698 { 2699 $process = api($name, $cmd); 2700 2701 if ($error != null) 2702 { 2703 $errors[] = "Error getting $cmd for $name $warnfont$error$warnoff"; 2704 break; 2705 } 2706 else 2707 $results[$cmd][$num] = $process; 2708 } 2709 } 2710 else 2711 otherrow('<td class=bad>Bad "$rigs" array</td>'); 2712 } 2713 2714 // Show API errors at the top 2715 if (count($errors) > 0) 2716 { 2717 foreach ($errors as $err) 2718 otherrow("<td colspan=100>$err</td>"); 2719 $errors = array(); 2720 } 2721 2722 $shownsomething = false; 2723 if (count($results) > 0) 2724 { 2725 list($results, $errors) = joinsections($sections, $results, $errors); 2726 $first = true; 2727 foreach ($sections as $section => $fields) 2728 { 2729 if ($section === 'DATE') 2730 { 2731 if ($shownsomething) 2732 otherrow('<td> </td>'); 2733 2734 newtable(); 2735 showdatetime(); 2736 endtable(); 2737 // On top of the next table 2738 $shownsomething = false; 2739 continue; 2740 } 2741 2742 if ($section === 'RIGS') 2743 { 2744 if ($shownsomething) 2745 otherrow('<td> </td>'); 2746 2747 newtable(); 2748 showrigs($results['version'], 'Rig', ''); 2749 endtable(); 2750 $shownsomething = true; 2751 continue; 2752 } 2753 2754 if (isset($results[$sectionmap[$section]])) 2755 { 2756 if (isset($ext[$section]['fmt'])) 2757 $cf = $ext[$section]['fmt']; 2758 else 2759 $cf = NULL; 2760 2761 $rigresults = processext($ext, $section, $results[$sectionmap[$section]], $fields); 2762 2763 $showfields = array(); 2764 $showhead = array(); 2765 foreach ($fields as $field) 2766 foreach ($rigresults as $result) 2767 foreach ($result as $sec => $row) 2768 { 2769 $secname = preg_replace('/\d/', '', $sec); 2770 if (secmatch($section, $secname)) 2771 { 2772 if ($field === '*') 2773 { 2774 foreach ($row as $f => $v) 2775 { 2776 $showfields[$f] = 1; 2777 $map = $section.'.'.$f; 2778 if (isset($namemap[$map])) 2779 $showhead[$namemap[$map]] = 1; 2780 else 2781 $showhead[$f] = 1; 2782 } 2783 } 2784 elseif ($field === '#') 2785 { 2786 $showfields[$field] = 1; 2787 $showhead[$field] = 1; 2788 } 2789 elseif (isset($row[$field])) 2790 { 2791 $showfields[$field] = 1; 2792 $map = $section.'.'.$field; 2793 if (isset($namemap[$map])) 2794 $showhead[$namemap[$map]] = 1; 2795 else 2796 $showhead[$field] = 1; 2797 } 2798 } 2799 } 2800 2801 if (count($showfields) > 0) 2802 { 2803 if ($shownsomething) 2804 otherrow('<td> </td>'); 2805 2806 newtable(); 2807 if (count($rigresults) == 1 && isset($rigresults[''])) 2808 $ri = array('' => 1) + $showhead; 2809 else 2810 $ri = array('Rig' => 1) + $showhead; 2811 showhead('', $ri, true); 2812 2813 $total = array(); 2814 $add = array('total' => array()); 2815 2816 foreach ($rigresults as $num => $result) 2817 $total = customset($showfields, $sum, $section, $num, true, $result, $total, $cf); 2818 2819 if (count($total) > 0) 2820 customset($showfields, $sum, $section, 'Σ', false, $add, $total, $cf); 2821 2822 $first = false; 2823 2824 endtable(); 2825 $shownsomething = true; 2826 } 2827 } 2828 } 2829 } 2830 2831 if (count($errors) > 0) 2832 { 2833 if (count($results) > 0) 2834 otherrow('<td> </td>'); 2835 2836 foreach ($errors as $err) 2837 otherrow("<td colspan=100>$err</td>"); 2838 } 2839 } 2840 # 2841 function showcustompage($pagename, $systempage = false) 2842 { 2843 global $customsummarypages; 2844 global $placebuttons; 2845 2846 if ($placebuttons == 'top' || $placebuttons == 'both') 2847 pagebuttons(null, $pagename); 2848 2849 if ($systempage === false && !isset($customsummarypages[$pagename])) 2850 { 2851 otherrow("<td colspan=100 class=bad>Unknown custom summary page '$pagename'</td>"); 2852 return; 2853 } 2854 2855 $csp = getcsp($pagename, $systempage); 2856 if ($csp === false) 2857 { 2858 otherrow("<td colspan=100 class=bad>Invalid custom summary page '$pagename'</td>"); 2859 return; 2860 } 2861 2862 degen($csp); 2863 2864 $page = $csp[0]; 2865 $namemap = array(); 2866 foreach ($page as $name => $fields) 2867 { 2868 if ($fields === null) 2869 $page[$name] = array(); 2870 else 2871 foreach ($fields as $num => $field) 2872 { 2873 $pos = strpos($field, '='); 2874 if ($pos !== false) 2875 { 2876 $names = explode('=', $field, 2); 2877 if (strlen($names[1]) > 0) 2878 $namemap[$name.'.'.$names[0]] = $names[1]; 2879 $page[$name][$num] = $names[0]; 2880 } 2881 } 2882 } 2883 2884 $ext = null; 2885 if (isset($csp[2])) 2886 $ext = $csp[2]; 2887 2888 $sum = $csp[1]; 2889 if ($sum === null) 2890 $sum = array(); 2891 2892 // convert them to searchable via isset() 2893 foreach ($sum as $section => $fields) 2894 { 2895 $newfields = array(); 2896 foreach ($fields as $field) 2897 $newfields[$field] = 1; 2898 $sum[$section] = $newfields; 2899 } 2900 2901 if (count($page) <= 1) 2902 { 2903 otherrow("<td colspan=100 class=bad>Invalid custom summary page '$pagename' no content </td>"); 2904 return; 2905 } 2906 2907 processcustompage($pagename, $page, $sum, $ext, $namemap); 2908 2909 if ($placebuttons == 'bot' || $placebuttons == 'both') 2910 pagebuttons(null, $pagename); 2911 } 2912 # 2913 function onlylogin() 2914 { 2915 global $here; 2916 2917 htmlhead('', false, null, null, true); 2918 2919 ?> 2920 <tr height=15%><td> </td></tr> 2921 <tr><td> 2922 <center> 2923 <table width=384 height=368 cellpadding=0 cellspacing=0 border=0> 2924 <tr><td> 2925 <table width=100% height=100% border=0 align=center cellpadding=5 cellspacing=0> 2926 <tr><td><form action='<?php echo $here; ?>' method=post> 2927 <table width=200 border=0 align=center cellpadding=5 cellspacing=0> 2928 <tr><td height=120 colspan=2> </td></tr> 2929 <tr><td colspan=2 align=center valign=middle> 2930 <h2>LOGIN</h2></td></tr> 2931 <tr><td align=center valign=middle><div align=right>Username:</div></td> 2932 <td height=33 align=center valign=middle> 2933 <input type=text name=rut size=18></td></tr> 2934 <tr><td align=center valign=middle><div align=right>Password:</div></td> 2935 <td height=33 align=center valign=middle> 2936 <input type=password name=roh size=18></td></tr> 2937 <tr valign=top><td></td><td><input type=submit value=Login> 2938 </td></tr> 2939 </table></form></td></tr> 2940 </table></td></tr> 2941 </table></center> 2942 </td></tr> 2943 <?php 2944 } 2945 # 2946 function checklogin() 2947 { 2948 global $allowcustompages; 2949 global $readonly, $userlist, $ses; 2950 2951 $out = trim(getparam('logout', true)); 2952 if ($out !== null && $out !== '' && isset($_SESSION[$ses])) 2953 unset($_SESSION[$ses]); 2954 2955 $login = trim(getparam('login', true)); 2956 if ($login !== null && $login !== '') 2957 { 2958 if (isset($_SESSION[$ses])) 2959 unset($_SESSION[$ses]); 2960 2961 onlylogin(); 2962 return 'login'; 2963 } 2964 2965 if ($userlist === null) 2966 return false; 2967 2968 $rut = trim(getparam('rut', true)); 2969 $roh = trim(getparam('roh', true)); 2970 2971 if (($rut !== null && $rut !== '') || ($roh !== null && $roh !== '')) 2972 { 2973 if (isset($_SESSION[$ses])) 2974 unset($_SESSION[$ses]); 2975 2976 if ($rut !== null && $rut !== '' && $roh !== null && $roh !== '') 2977 { 2978 if (isset($userlist['sys']) && isset($userlist['sys'][$rut]) 2979 && ($userlist['sys'][$rut] === $roh)) 2980 { 2981 $_SESSION[$ses] = true; 2982 return false; 2983 } 2984 2985 if (isset($userlist['usr']) && isset($userlist['usr'][$rut]) 2986 && ($userlist['usr'][$rut] === $roh)) 2987 { 2988 $_SESSION[$ses] = false; 2989 $readonly = true; 2990 return false; 2991 } 2992 } 2993 } 2994 2995 if (isset($_SESSION[$ses])) 2996 { 2997 if ($_SESSION[$ses] == false) 2998 $readonly = true; 2999 return false; 3000 } 3001 3002 if (isset($userlist['def']) && $allowcustompages === true) 3003 { 3004 // Ensure at least one exists 3005 foreach ($userlist['def'] as $pg) 3006 if (getcsp($pg) !== false) 3007 return true; 3008 } 3009 3010 onlylogin(); 3011 return 'login'; 3012 } 3013 # 3014 function display() 3015 { 3016 global $miner, $port; 3017 global $mcast, $mcastexpect; 3018 global $readonly, $notify, $rigs; 3019 global $ignorerefresh, $autorefresh; 3020 global $allowcustompages; 3021 global $placebuttons; 3022 global $userlist, $ses; 3023 3024 $pagesonly = checklogin(); 3025 3026 if ($pagesonly === 'login') 3027 return; 3028 3029 $mcerr = ''; 3030 3031 if ($rigs == null or count($rigs) == 0) 3032 { 3033 if ($mcast === true) 3034 $action = 'found'; 3035 else 3036 $action = 'defined'; 3037 3038 minhead(); 3039 otherrow("<td class=bad>No rigs $action</td>"); 3040 return; 3041 } 3042 else 3043 { 3044 if ($mcast === true && count($rigs) < $mcastexpect) 3045 $mcerr = othrow('<td class=bad>Found '.count($rigs)." rigs but expected at least $mcastexpect</td>"); 3046 } 3047 3048 if ($ignorerefresh == false) 3049 { 3050 $ref = trim(getparam('ref', true)); 3051 if ($ref != null && $ref != '') 3052 $autorefresh = intval($ref); 3053 } 3054 3055 if ($pagesonly !== true) 3056 { 3057 $rig = trim(getparam('rig', true)); 3058 3059 $arg = trim(getparam('arg', true)); 3060 $preprocess = null; 3061 if ($arg != null and $arg != '') 3062 { 3063 if ($rig != null and $rig != '' and $rig >= 0 and $rig < count($rigs)) 3064 { 3065 $parts = explode(':', $rigs[$rig], 3); 3066 if (count($parts) >= 1) 3067 { 3068 $miner = $parts[0]; 3069 if (count($parts) >= 2) 3070 $port = $parts[1]; 3071 else 3072 $port = ''; 3073 3074 if ($readonly !== true) 3075 $preprocess = $arg; 3076 } 3077 } 3078 } 3079 } 3080 3081 if ($allowcustompages === true) 3082 { 3083 $pg = urlencode(trim(getparam('pg', true))); 3084 if ($pagesonly === true) 3085 { 3086 if ($pg !== null && $pg !== '') 3087 { 3088 if ($userlist !== null && isset($userlist['def']) 3089 && !in_array($pg, $userlist['def'])) 3090 $pg = null; 3091 } 3092 else 3093 { 3094 if ($userlist !== null && isset($userlist['def'])) 3095 foreach ($userlist['def'] as $pglook) 3096 if (getcsp($pglook) !== false) 3097 { 3098 $pg = $pglook; 3099 break; 3100 } 3101 } 3102 } 3103 3104 if ($pg !== null && $pg !== '') 3105 { 3106 htmlhead($mcerr, false, null, $pg); 3107 showcustompage($pg); 3108 return; 3109 } 3110 } 3111 3112 if ($pagesonly === true) 3113 { 3114 onlylogin(); 3115 return; 3116 } 3117 3118 if (count($rigs) == 1) 3119 { 3120 $parts = explode(':', $rigs[0], 3); 3121 if (count($parts) >= 1) 3122 { 3123 $miner = $parts[0]; 3124 if (count($parts) >= 2) 3125 $port = $parts[1]; 3126 else 3127 $port = ''; 3128 3129 htmlhead($mcerr, true, 0); 3130 doOne(0, $preprocess); 3131 } 3132 else 3133 { 3134 minhead($mcerr); 3135 otherrow('<td class=bad>Invalid "$rigs" array</td>'); 3136 } 3137 3138 return; 3139 } 3140 3141 if ($rig != null and $rig != '' and $rig >= 0 and $rig < count($rigs)) 3142 { 3143 $parts = explode(':', $rigs[$rig], 3); 3144 if (count($parts) >= 1) 3145 { 3146 $miner = $parts[0]; 3147 if (count($parts) >= 2) 3148 $port = $parts[1]; 3149 else 3150 $port = ''; 3151 3152 htmlhead($mcerr, true, 0); 3153 doOne($rig, $preprocess); 3154 } 3155 else 3156 { 3157 minhead($mcerr); 3158 otherrow('<td class=bad>Invalid "$rigs" array</td>'); 3159 } 3160 3161 return; 3162 } 3163 3164 htmlhead($mcerr, false, null); 3165 3166 if ($preprocess != null) 3167 process(array($preprocess => $preprocess), $rig); 3168 3169 if (getcsp('Summary', true) !== false) 3170 showcustompage('Summary', true); 3171 } 3172 # 3173 if ($mcast === true) 3174 getrigs(); 3175 display(); 3176 # 3177 ?> 3178 </table></td></tr></table> 3179 </body></html>