File: 1.00.6a/server/base/freenats.inc.php (View as Code)

1: 2: /* ------------------------------------------------------------- 3: This file is part of FreeNATS 4: 5: FreeNATS is (C) Copyright 2008 PurplePixie Systems 6: 7: FreeNATS is free software: you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation, either version 3 of the License, or 10: (at your option) any later version. 11: 12: FreeNATS is distributed in the hope that it will be useful, 13: but WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15: GNU General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with FreeNATS. If not, see www.gnu.org/licenses 19: 20: For more information see www.purplepixie.org/freenats 21: -------------------------------------------------------------- */ 22: 23: class TFreeNATS 24: { 25: var $init=false; 26: var $DB; 27: var $Cfg; 28: var $Tests; 29: var $Version="1.00.6"; 30: var $Release="a"; 31: var $EventHandlers=array(); 32: 33: function TFreeNATS() 34: { 35: $this->Tests=new TNATS_Tests(); // need this available during the include phase pre-start 36: } 37: 38: function Start() 39: { 40: global $BaseDir; 41: if ( (!isset($BaseDir)) || ($BaseDir=="") ) $BaseDir="./"; 42: $this->DB=new TNATS_DB(); 43: $this->Cfg=new TNATS_Cfg(); 44: $this->DB->Connect(); 45: $this->Cfg->Load($this->DB); 46: // Site Includes 47: // Tests 48: if ($this->Cfg->Get("site.include.tests",0)==1) 49: { 50: foreach(glob($BaseDir."site/tests/*.php") as $phpfile) 51: { 52: $this->Event("Including ".$phpfile,10,"NATS","Start"); 53: include_once($phpfile); 54: } 55: } 56: // Events 57: if ($this->Cfg->Get("site.include.events",0)==1) 58: { 59: foreach(glob($BaseDir."site/events/*.php") as $phpfile) 60: { 61: $this->Event("Including ".$phpfile,10,"NATS","Start"); 62: include_once($phpfile); 63: } 64: } 65: $this->init=true; 66: } 67: 68: function Stop() 69: { 70: $this->DB->Disconnect(); 71: $this->init=false; 72: } 73: 74: function Event($logevent,$loglevel=1,$modid="NONE",$catid="NONE") 75: { 76: global $NATS_Session; 77: if ((isset($NATS_Session))&&($NATS_Session->auth)) $username=$NATS_Session->username; 78: else $username=""; 79: $l=$this->Cfg->Get("log.level"); 80: //echo "** $l **\n"; 81: if ( $l=="" ) $l=10; // debug logging if no variable 82: if ( $l < $loglevel ) return false; 83: if (strlen($logevent)>249) $logevent=substr($logevent,0,245)."..."; 84: $q="INSERT INTO fnlog(postedx,modid,catid,loglevel,logevent,username) VALUES(".time().","; 85: $q.="\"".ss($modid)."\",\"".ss($catid)."\",".ss($loglevel).",\"".ss($logevent)."\",\"".ss($username)."\")"; 86: //echo $q; 87: $this->DB->Query($q,false); 88: } 89: 90: function AlertAction($nodeid,$alertlevel,$change,$alerttext) 91: { 92: echo "Called for node: ".$nodeid."\n"; 93: if ($change==0) return false; 94: //echo $nodeid.":".$alertlevel.":".$change.":".$alerttext."\n"; 95: // get all the alertactions for this node id 96: $q="SELECT aaid FROM fnnalink WHERE nodeid=\"".ss($nodeid)."\""; 97: $r=$this->DB->Query($q); 98: while ($arow=$this->DB->Fetch_Array($r)) 99: { 100: // get details for this alert action 101: $aq="SELECT * FROM fnalertaction WHERE aaid=".$arow['aaid']." LIMIT 0,1"; 102: //echo $aq."\n"; 103: $ar=$this->DB->Query($aq); 104: $aa=$this->DB->Fetch_Array($ar); 105: $this->DB->Free($ar); 106: //echo $aa['atype']."FISH\n"; 107: 108: // UGGGGGGGG continue!! 109: if ( ($aa['atype']=="") || ($aa['atype']=="Disabled") ) continue; 110: if ( ($aa['awarnings']==0) && ($alertlevel<2) ) continue; 111: if ( ($aa['adecrease']==0) && ($change<1) ) continue; 112: 113: // made it this far 114: if ($aa['mdata']!="") $ndata=$aa['mdata']."\n".$nodeid.": ".$alerttext; 115: else $ndata=$nodeid.": ".$alerttext; 116: $uq="UPDATE fnalertaction SET mdata=\"".ss($ndata)."\" WHERE aaid=".$arow['aaid']; 117: //echo $uq."\n"; 118: $this->DB->Query($uq); 119: } 120: } 121: 122: function ActionFlush() 123: { 124: global $allowed,$BaseDir; // allowed chars from screen in YA BODGE 125: $q="SELECT * FROM fnalertaction WHERE mdata!=\"\""; 126: $r=$this->DB->Query($q); 127: while ($row=$this->DB->Fetch_Array($r)) 128: { 129: 130: $doalert=true; 131: 132: // clear mdata right at the start to get around duplicate emails whilst processing 133: $q="UPDATE fnalertaction SET mdata=\"\" WHERE aaid=".$row['aaid']; 134: $this->DB->Query($q); 135: 136: if ($this->DB->Affected_Rows()<=0) // already flushed or failed to flush 137: { 138: $doalert=false; 139: $this->Event("Alert Action Already Flushed - Skipping",8,"Flush","Action"); 140: } 141: 142: // alert counter 143: $td=date("Ymd"); 144: if ($td!=$row['ctrdate']) // new day or no flush record 145: { 146: $q="UPDATE fnalertaction SET ctrdate=\"".$td."\",ctrtoday=1 WHERE aaid=".$row['aaid']; 147: $this->DB->Query($q); 148: } 149: else 150: { 151: 152: if ( ($row['ctrlimit']==0) || ($row['ctrlimit']>$row['ctrtoday']) ) // no limit or below 153: { 154: $q="UPDATE fnalertaction SET ctrtoday=ctrtoday+1 WHERE aaid=".$row['aaid']; 155: $this->DB->Query($q); 156: } 157: else // at or over limit 158: { 159: $this->Event("Alert Action Limit Reached - Skipping",2,"Flush","Action"); 160: $doalert=false; 161: } 162: 163: } 164: 165: 166: if ($row['atype']=="email") 167: { 168: if ($row['esubject']==0) $sub=""; 169: else if ($row['esubject']==1) $sub="FreeNATS Alert"; 170: else $sub="** FreeNATS Alert **"; 171: $body=""; 172: if ($row['etype']==0) $body=$row['mdata']; 173: else $body="FreeNATS Alert,\r\n".$row['mdata']."\r\n--FreeNATS @ ".nicedt(time()); 174: //$tolist=preg_split("[\n\r]",$row['etolist']); 175: $tolist=array(); 176: $f=0; 177: $tolist[0]=""; 178: for ($a=0; $a179: { 180: $chr=$row['etolist'][$a]; 181: //echo $chr; 182: if (strpos($allowed,$chr)===false) // special char 183: { 184: $f++; 185: $tolist[$f]=""; 186: } 187: else 188: { 189: $tolist[$f].=$chr; 190: } 191: } 192: 193: foreach($tolist as $toaddr) 194: { 195: $toaddr=nices($toaddr); 196: if ($toaddr!="") 197: { 198: $smtpserver=$this->Cfg->Get("mail.smtpserver",""); 199: if ($smtpserver=="") 200: { 201: // mail() method - local delivery 202: $header="From: ".$row['efrom']."\r\n"; 203: if ($doalert) 204: { 205: mail($toaddr,$sub,$body,$header); 206: $this->Event("Sent alert email to ".$toaddr,4,"Flush","Email"); 207: } 208: } 209: else // use phpmailer direct SMTP delivery 210: { 211: include_once($BaseDir."phpmailer/class.phpmailer.php"); 212: $fromname=$this->Cfg->Get("mail.fromname",""); 213: if ($fromname=="") $fromname="FreeNATS"; 214: $smtpusername=$this->Cfg->Get("mail.smtp.username",""); 215: if ($smtpusername!="") $smtpauth=true; 216: else $smtpauth=false; 217: $smtppassword=$this->Cfg->Get("mail.smtp.password",""); 218: $smtphostname=$this->Cfg->Get("mail.smtp.hostname",""); 219: $mail=new PHPMailer(); 220: $mail->IsSMTP(); 221: $mail->Host=$smtpserver; 222: $mail->From=$row['efrom']; 223: $mail->FromName=$fromname; 224: $mail->AddAddress($toaddr); 225: $mail->Subject=$sub; 226: $mail->Body=$body; 227: $mail->WordWrap=50; 228: if ($smtphostname!="") $mail->Hostname=$smtphostname; 229: if ($smtpauth) 230: { 231: $mail->SMTPAuth=true; 232: $mail->Username=$smtpusername; 233: $mail->Password=$smtppassword; 234: } 235: if (!$mail->Send()) 236: { // failed 237: $this->Event("phpMailer to ".$toaddr." failed",1,"Flush","Email"); 238: $this->Event("phpMailer Error: ".$mail->ErrorInfo,1,"Flush","Email"); 239: } 240: else 241: { 242: $this->Event("phpMailer Sent Email To ".$toaddr,4,"Flush","Email"); 243: } 244: } 245: 246: } 247: } 248: 249: 250: 251: } 252: else if ($row['atype']=="url") 253: { 254: // url send 255: if ($row['etype']==0) $body=$row['mdata']; 256: else $body="FreeNATS Alert,\r\n".$row['mdata']."\r\n--FreeNATS @ ".nicedt(time()); 257: 258: $body=urlencode($body); 259: $tolist=array(); 260: $f=0; 261: $tolist[0]=""; 262: for ($a=0; $a263: { 264: $chr=$row['etolist'][$a]; 265: //echo $chr; 266: if (strpos($allowed,$chr)===false) // special char 267: { 268: $f++; 269: $tolist[$f]=""; 270: } 271: else 272: { 273: $tolist[$f].=$chr; 274: } 275: } 276: 277: foreach($tolist as $tourl) 278: { 279: if ($doalert) 280: { 281: $url=$tourl.$body; 282: $fp=@fopen($url,"r"); 283: if ($fp>0) fclose($fp); 284: else $this->Event("URL Alert Failed ".$url,1,"Flush","URL"); 285: $this->Event("URL Alert ".$url,4,"Flush","URL"); 286: } 287: } 288: 289: 290: } 291: else if ($row['atype']=="mqueue") 292: { 293: // message queue 294: $eventdata=array("aaid"=>$row['aaid'],"name"=>$row['aname'],"data"=>$row['mdata']); 295: $result=$this->EventHandler("alert_action",$eventdata); 296: if ($result===false) // put the data back into the queue 297: { 298: $q="UPDATE fnalertaction SET mdata=\"".$row['mdata']."\"+mdata WHERE aaid=".$row['aaid']; 299: $this->DB->Query($q); 300: if ($this->DB->Affected_Rows()<=0) 301: $this->Event("Persist MDATA Failed for AAID ".$row['aaid'],2,"Flush","MQueue"); 302: } 303: else $this->Event("Queue Cleared for AAID ".$row['aaid']." by Handler",4,"Flush","MQueue"); 304: } 305: 306: } 307: } 308: 309: function GetAlerts() 310: { 311: $q="SELECT nodeid,alertlevel FROM fnalert WHERE closedx=0"; 312: $r=$this->DB->Query($q); 313: $c=0; 314: $al=array(); 315: while ($row=$this->DB->Fetch_Array($r)) 316: { 317: $al[$c]['nodeid']=$row['nodeid']; 318: $al[$c]['alertlevel']=$row['alertlevel']; 319: $c++; 320: } 321: if ($c>0) return $al; 322: else return false; 323: } 324: 325: function SetAlerts($nodeid,$alertlevel,$alerts="") 326: { 327: if ($alerts=="") $alerts=array(); 328: // get current alert level 329: $q="SELECT alertlevel,nodealert FROM fnnode WHERE nodeid=\"".ss($nodeid)."\""; 330: $r=$this->DB->Query($q); 331: $row=$this->DB->Fetch_Array($r); 332: $this->DB->Free($r); 333: $cal=$row['alertlevel']; 334: 335: $eventdata=array("nodeid"=>$nodeid,"alertlevel"=>$alertlevel, 336: "oldalertlevel"=>$cal); 337: $this->EventHandler("set_alerts",$eventdata); 338: 339: if ($alertlevel!=$cal) 340: { 341: // update table 342: $q="UPDATE fnnode SET alertlevel=".ss($alertlevel)." WHERE nodeid=\"".ss($nodeid)."\""; 343: $this->DB->Query($q); 344: } 345: 346: // do not continue if node alert isn't set 347: if ($row['nodealert']!=1) return 0; 348: 349: // ALERTS 350: // is there an existing alert for this node 351: $q="SELECT alertid,alertlevel FROM fnalert WHERE nodeid=\"".ss($nodeid)."\" AND closedx=0"; 352: $r=$this->DB->Query($q); 353: if ($row=$this->DB->Fetch_Array($r)) 354: { // yes there is 355: // if new alert level is 0 let's close it 356: if ($alertlevel==0) 357: { 358: $alertid=$row['alertid']; 359: $q="UPDATE fnalert SET closedx=".time()." WHERE alertid=".$row['alertid']; 360: $this->DB->Query($q); 361: if (is_array($alerts)) $alerts[]="Alert Closed"; 362: else 363: { 364: //$alerts=array(); 365: $alerts[]="Alert Closed"; 366: } 367: $eventdata=array("nodeid"=>$nodeid); 368: $this->EventHandler("alert_close",$eventdata); 369: } 370: else 371: { 372: $alertid=$row['alertid']; 373: // otherwise update the alert to the new value (was: regardless, now just if not a 0) 374: $q="UPDATE fnalert SET alertlevel=".ss($alertlevel)." WHERE alertid=".$alertid; 375: $this->DB->Query($q); 376: } 377: } 378: else 379: { // no there's not 380: if ($alertlevel>0) // only if an actual alert 381: { 382: $q="INSERT INTO fnalert(nodeid,alertlevel,openedx) VALUES("; 383: $q.="\"".ss($nodeid)."\",".ss($alertlevel).",".time().")"; 384: $this->DB->Query($q); 385: $alertid=$this->DB->Insert_Id(); 386: $eventdata=array("nodeid"=>$nodeid); 387: $this->EventHandler("alert_open",$eventdata); 388: } 389: } 390: // ALERT LOG with $alertid 391: $t=time(); 392: $at=""; 393: if (is_array($alerts)) 394: { 395: foreach($alerts as $alert) 396: { 397: if (isset($alertid)) // misses on manual runs methinx 398: { 399: if ($at!="") $at.=", "; 400: $at.=$alert; 401: //echo $at."\n"; 402: $iq="INSERT INTO fnalertlog(alertid,postedx,logentry) VALUES("; 403: $iq.=$alertid.",".$t.",\"".ss($alert)."\")"; 404: //echo $iq; 405: $this->DB->Query($iq); 406: } 407: } 408: } 409: 410: $this->AlertAction($nodeid,$alertlevel,$alertlevel-$cal,$at); 411: 412: 413: 414: } 415: 416: function NodeAlertLevel($nodeid) 417: { 418: $q="SELECT alertlevel FROM fnnode WHERE nodeid=\"".ss($nodeid)."\""; 419: $r=$this->DB->Query($q); 420: if ($row=$this->DB->Fetch_Array($r)) return $row['alertlevel']; 421: else return -1; 422: } 423: 424: function GroupAlertLevel($groupid) 425: { 426: $lvl=-1; 427: $q="SELECT nodeid FROM fngrouplink WHERE groupid=\"".ss($groupid)."\""; 428: $r=$this->DB->Query($q); 429: while ($row=$this->DB->Fetch_Array($r)) 430: { 431: $nl=$this->NodeAlertLevel($row['nodeid']); 432: if ($nl>$lvl) $lvl=$nl; 433: } 434: $this->DB->Free($r); 435: return $lvl; 436: } 437: 438: function PhoneHome($mode=0,$type="ping") // 0 - php, 1 - html, 2 - data 439: { 440: if ($mode<2) 441: { 442: $qs="?type=".$type."&data=version=".$this->Version; 443: if (isset($_SERVER['REMOTE_ADDR'])) 444: $qs.=",ip=".$_SERVER['REMOTE_ADDR']; 445: $ploc="http://www.purplepixie.org/freenats/report/"; 446: if ($mode==1) $ploc.="ping.html"; 447: else $ploc.="ping.php"; 448: 449: $ploc.=$qs; 450: 451: $lp=@fopen($ploc,"r"); 452: if ($lp>0) @fclose($lp); 453: } 454: else 455: { 456: // data post -- !! 457: } 458: } 459: 460: function GetNode($nodeid) 461: { 462: $return_row=false; 463: $q="SELECT * FROM fnnode WHERE nodeid=\"".ss($nodeid)."\" LIMIT 0,1"; 464: $r=$this->DB->Query($q); 465: if ($row=$this->DB->Fetch_Array($r)) 466: $return_row=true; 467: 468: $this->DB->Free($r); 469: if ($return_row) // found a valid 470: { 471: if ($row['nodename']!="") $row['name']=$row['nodename']; // make a "nice" name for it 472: else $row['name']=$row['nodeid']; 473: 474: $row['alerttext']=oText($row['alertlevel']); // textual alert status 475: 476: $row['lastrundt']=nicedt($row['lastrunx']); // text date-time last run 477: $row['lastrunago']=dtago($row['lastrunx'],false); // last run ago 478: 479: // protection 480: $row['nskey']=""; 481: 482: return $row; 483: } 484: else 485: return false; // or failed 486: } 487: 488: function SetNode($nodeid,$data) 489: { 490: $q="UPDATE fnnode SET "; 491: $first=true; 492: foreach($data as $key => $val) 493: { 494: if ($first) $first=false; 495: else $q.=","; 496: $q.=ss($key)."=\"".ss($val)."\""; 497: } 498: $q.=" WHERE nodeid=\"".ss($nodeid)."\""; 499: $this->DB->Query($q); 500: if ($this->DB->Affected_Rows()>0) return true; 501: 502: if ($this->DB->Error()) // query failed 503: { 504: $errstr1="Query Failed: ".$q; 505: $errstr2="Query Failed: ".$this->DB->Error_String(); 506: $this->Event($errstr1,2,"Node","Set"); 507: $this->Event($errstr1,2,"Node","Set"); 508: return false; 509: } 510: return true; // query succeeded but nothing was updated 511: } 512: 513: function EnableNode($nodeid,$enabled=true) 514: { 515: if ($enabled) $ne=1; 516: else $ne=0; 517: $data=array("nodeenabled"=>$ne); 518: return $this->SetNode($nodeid,$data); 519: } 520: 521: function DisableNode($nodeid) 522: { 523: return $this->EnableNode($nodeid,false); 524: } 525: 526: function SetNodeSchedule($nodeid,$scheduleid) 527: { 528: $data=array("scheduleid"=>$scheduleid); 529: return $this->SetNode($nodeid,$data); 530: } 531: 532: function GetGroup($groupid) 533: { 534: $q="SELECT * FROM fngroup WHERE groupid=".ss($groupid)." LIMIT 0,1"; 535: $r=$this->DB->Query($q); 536: if (!$row=$this->DB->Fetch_Array($r)) return false; 537: 538: $this->DB->Free($r); 539: $row['alertlevel']=$this->GroupAlertLevel($groupid); 540: $row['alerttext']=oText($row['alertlevel']); 541: return $row; 542: } 543: 544: function GetTest($testid,$protect=false) 545: { 546: if ($testid=="") return false; 547: $class=$testid[0]; 548: if (is_numeric($class)) 549: { 550: // test ID will stay the same 551: $class="L"; 552: $anytestid=$testid; 553: } 554: else 555: { 556: //$testid=substr($testid,1); // as it will here also so direct use to graphs can be made 557: $anytestid=substr($testid,1); // the classless version 558: } 559: 560: $q=""; 561: switch($class) 562: { 563: case "L": // local tests 564: $q="SELECT * FROM fnlocaltest WHERE localtestid=".ss($anytestid)." LIMIT 0,1"; 565: break; 566: case "N": // node-side test 567: $q="SELECT * FROM fnnstest WHERE nstestid=".ss($anytestid)." LIMIT 0,1"; 568: break; 569: default: 570: return false; // can't lookup this class 571: } 572: 573: if ($q=="") return false; 574: 575: $r=$this->DB->Query($q); 576: 577: if (!$row=$this->DB->Fetch_Array($r)) return false; 578: 579: $row['class']=$class; 580: $row['testid']=$testid; 581: $row['anytestid']=$anytestid; 582: $row['alerttext']=oText($row['alertlevel']); 583: $row['lastrundt']=nicedt($row['lastrunx']); 584: $row['lastrunago']=dtago($row['lastrunx'],false); 585: 586: if ($row['testname']!="") $row['name']=$row['testname']; 587: else 588: { 589: if ($class=="L") 590: { 591: $row['name']=lText($row['testtype']); // TODO OTHER TESTS 592: if ($row['testparam']!="") $row['name'].=" (".$row['testparam'].")"; 593: } 594: else if ($class=="N") 595: { 596: if ($row['testdesc']!="") $row['name']=$row['testdesc']; 597: else $row['name']=$row['testtype']; 598: } 599: } 600: 601: if ($protect&&($class=="L")) // module test protection 602: { 603: if ($this->Tests->Exists($row['testtype'])) // in the module register 604: { 605: $this->Tests->Tests[$row['testtype']]->Create(); 606: $this->Tests->Tests[$row['testtype']]->instance->ProtectOutput($row); 607: } 608: } 609: 610: $this->DB->Free($r); 611: 612: return $row; 613: } 614: 615: 616: function DeleteTest($testid) 617: { 618: if ($testid=="") return false; 619: $class=$testid[0]; 620: if (is_numeric($class)) 621: { 622: // test ID will stay the same 623: $class="L"; 624: $anytestid=$testid; 625: } 626: else 627: { 628: $anytestid=substr($testid,1); // the classless version 629: } 630: 631: $q=""; 632: switch($class) 633: { 634: case "L": // local tests 635: $q="DELETE FROM fnlocaltest WHERE localtestid=".ss($anytestid); 636: break; 637: case "N": // node-side test 638: $q="DELETE FROM fnnstest WHERE nstestid=".ss($anytestid); 639: break; 640: default: 641: return false; // can't lookup this class 642: } 643: 644: if ($q=="") return false; 645: 646: $this->DB->Query($q); 647: $tests=$this->DB->Affected_Rows(); 648: 649: $rq="DELETE FROM fnrecord WHERE testid=\"".ss($testid)."\""; 650: $this->DB->Query($rq); 651: $records=$this->DB->Affected_Rows(); 652: 653: $eq="DELETE FROM fneval WHERE testid=\"".ss($testid)."\""; 654: $this->DB->Query($eq); 655: $eval=$this->DB->Affected_Rows(); 656: 657: $s="Deleted test ".$testid." (".$tests." tests, ".$records." records, ".$eval." evaluators)"; 658: $this->Event($s,6,"Test","Delete"); 659: } 660: 661: 662: 663: function InvalidateTest($testid,$rightnow=false) 664: { 665: $class=$testid[0]; 666: if (is_numeric($class)) $class="L"; 667: else $testid=substr($testid,1); 668: if ($rightnow) 669: { 670: $nextx=time(); 671: $q="UPDATE "; 672: if ($class=="L") $q.="fnlocaltest"; 673: // other ones here 674: 675: $q.=" SET nextrunx=".$nextx." WHERE "; 676: 677: if ($class=="L") $q.="localtestid=".$testid; 678: // other ones here 679: 680: $this->DB->Query($q); 681: return true; 682: } 683: // otherwise use it's interval 684: $q="SELECT testinterval FROM "; 685: 686: if ($class=="L") $q.="fnlocaltest WHERE localtestid="; 687: // other ones here 688: 689: $q.=$testid; 690: $r=$this->DB->Query($q); 691: if ($row=$this->DB->Fetch_Array($r)) 692: { 693: $this->DB->Free($r); 694: $nextx=next_run_x($row['testinterval']); 695: $q="UPDATE "; 696: if ($class=="L") $q.="fnlocaltest"; 697: // other ones here 698: 699: $q.=" SET nextrunx=".$nextx." WHERE "; 700: 701: if ($class=="L") $q.="localtestid=".$testid; 702: // other ones here 703: 704: $this->DB->Query($q); 705: return true; 706: } 707: return false; 708: } 709: 710: function InvalidateNode($nodeid,$rightnow=false,$testsaswell=false) 711: { 712: if ($rightnow) 713: { 714: $nextx=time(); 715: $q="UPDATE fnnode SET nextrunx=".$nextx." WHERE nodeid=\"".ss($nodeid)."\""; 716: $this->DB->Query($q); 717: if ($testsaswell) 718: { 719: $q="UPDATE fnlocaltest SET nextrunx=".$nextx." WHERE nodeid=\"".ss($nodeid)."\""; 720: $this->DB->Query($q); 721: } 722: return true; 723: } 724: // otherwise set to it's interval 725: $q="SELECT testinterval FROM fnnode WHERE nodeid=\"".ss($nodeid)."\""; 726: $r=$this->DB->Query($q); 727: if ($row=$this->DB->Fetch_Array($r)) 728: { 729: $nextx=next_run_x($row['testinterval']); 730: $uq="UPDATE fnnode SET nextrunx=".$nextx." WHERE nodeid=\"".ss($nodeid)."\""; 731: $this->DB->Query($uq); 732: $this->DB->Free($r); 733: if ($testsaswell) 734: { 735: $uq="UPDATE fnlocaltest SET nextrunx=".$nextx." WHERE nodeid=\"".ss($nodeid)."\""; 736: $this->DB->Query($uq); 737: } 738: return true; 739: } 740: return false; 741: } 742: 743: 744: function NodeSide_Pull($nodeid) 745: { 746: $eventdata=array("nodeid"=>$nodeid,"success"=>false); 747: $q="SELECT nsenabled,nspullenabled,nsurl,nskey,nsinterval FROM fnnode WHERE nodeid=\"".ss($nodeid)."\" LIMIT 0,1"; 748: $r=$this->DB->Query($q); 749: if (!$row=$this->DB->Fetch_Array($r)) return false; 750: 751: $this->DB->Free($r); 752: 753: $url=$row['nsurl']; 754: if ($row['nskey']!="") $url.="?nodekey=".$row['nskey']; 755: $this->Event("NodeSide_Pull Started for ".$nodeid,10,"Node","Pull"); 756: 757: $xmlobj=new TNodeXML(); 758: 759: $fp=@fopen($url,"r"); 760: if ($fp<=0) 761: { 762: $this->Event("Pull Failed URL ".$url,1,"Node","Pull"); 763: $this->EventHandler("nodeside_pull",$eventdata); 764: return false; 765: } 766: $xml=""; 767: while (!feof($fp)) 768: { 769: $xml.=fgets($fp,4096); 770: } 771: if ($xml=="") 772: { 773: $this->EventHandler("nodeside_pull",$eventdata); 774: return false; 775: } 776: 777: //echo $xml; 778: 779: $result=$xmlobj->Parse($xml); 780: 781: if ($xmlobj->Error()!="") 782: { 783: $this->Event("NodeXML Error: ".$xmlobj->Error(),1,"Node","Pull"); 784: $this->EventHandler("nodeside_pull",$eventdata); 785: return false; 786: } 787: $this->Event("NodeSide_Pull Fetched ".$xmlobj->Tests." tests for ".$nodeid,10,"Node","Pull"); 788: // Now just to actually process it... 789: $eventdata['success']=true; 790: $this->EventHandler("nodeside_pull",$eventdata); 791: $this->NodeSide_Process($nodeid,$xmlobj); 792: return true; 793: } 794: 795: function NodeSide_Process($nodeid,&$xmlobj) 796: { // nodeid + takes a TNodeXML Object 797: $alvl=0; 798: $this->Event("NodeSide_Process for ".$nodeid,10,"Node","Pull"); 799: $q="SELECT * FROM fnnstest WHERE nodeid=\"".ss($nodeid)."\""; 800: $r=$this->DB->Query($q); 801: $tests=array(); 802: while ($row=$this->DB->Fetch_Array($r)) 803: { 804: $tests[$row['testtype']]=$row; 805: if (isset($xmlobj->Catalogue[$row['testtype']])) 806: { // this test is in the DB and catalogue 807: $tests[$row['testtype']]['incat']=true; 808: if ($row['testenabled']==1) // it is enabled - so we test it 809: { 810: if ($row['simpleeval']==1) $level=$xmlobj->Catalogue[$row['testtype']]['ALERTLEVEL']; // use provided level 811: else $level=nats_eval("N".$row['nstestid'],$xmlobj->Catalogue[$row['testtype']]['VALUE']); 812: $dbs="Nodeside ".$row['testtype']." on ".$row['nodeid']." = ".$level; 813: if ($level==0) $debuglev=8; 814: else if ($level>0) $debuglev=5; 815: else $debuglev=2; 816: $this->Event($dbs,$debuglev,"Node","Process"); 817: 818: if ($level>$alvl) $alvl=$level; 819: 820: if ($row['testrecord']==1) // record it 821: { 822: $testvalue=$xmlobj->Catalogue[$row['testtype']]['VALUE']; 823: $testvalue=str_replace(",",".",$testvalue); 824: if (!is_numeric($testvalue)) $testvalue=0; 825: $iq="INSERT INTO fnrecord(testid,alertlevel,recordx,nodeid,testvalue) VALUES("; 826: $iq.="\"N".$row['nstestid']."\",".$level.",".time().",\"".$row['nodeid']."\",".$testvalue.")"; 827: $this->DB->Query($iq); 828: if ($this->DB->Affected_Rows()<=0) 829: $this->Event("Nodeside ".$row['testtype']." Failed to Record",1,"Node","Process"); 830: } 831: 832: // We don't do any alerting here - the tester will do that for us! 833: $uq="UPDATE fnnstest SET lastrunx=".time().",lastvalue=\"".ss($xmlobj->Catalogue[$row['testtype']]['VALUE'])."\",alertlevel=".$level." "; 834: $uq.="WHERE nstestid=".$row['nstestid']; 835: $this->DB->Query($uq); 836: if ($this->DB->Affected_Rows()<=0) 837: $this->Event("Nodeside ".$row['testtype']." Failed to Update or Same Values",5,"Node","Process"); 838: 839: } 840: 841: // check to see if the desc has changed 842: if ($row['testdesc']!=$xmlobj->Catalogue[$row['testtype']]['DESC']) 843: { 844: $duq="UPDATE fnnstest SET testdesc=\"".ss($xmlobj->Catalogue[$row['testtype']]['DESC'])."\" WHERE nstestid=".$row['nstestid']; 845: $this->DB->Query($duq); 846: } 847: 848: } 849: else 850: { 851: // test in the DB but NOT in the catalogue 852: //$xmlobj->Catalogue[$row['testtype']]['incat']=false; 853: if ($row['testenabled']==1) 854: { // enabled so shown in lists etc 855: // Update it to show failed status 856: $this->Event("No nodeside data for test N".$row['nstestid'],3,"Node","Process"); 857: $uq="UPDATE fnnstest SET alertlevel=2,lastvalue=-1 WHERE nstestid=".$row['nstestid']; 858: $this->DB->Query($uq); 859: $alvl=2; 860: if ($row['testrecord']==1) // record it 861: { 862: $testvalue=-1; 863: $iq="INSERT INTO fnrecord(testid,alertlevel,recordx,nodeid,testvalue) VALUES("; 864: $iq.="\"N".$row['nstestid']."\",2,".time().",\"".$row['nodeid']."\",".$testvalue.")"; 865: $this->DB->Query($iq); 866: if ($this->DB->Affected_Rows()<=0) 867: $this->Event("Nodeside ".$row['testtype']." Failed to Record",1,"Node","Process"); 868: } 869: } 870: else // not enabled so simply delete 871: { 872: $this->DeleteTest("N".$row['nstestid']); 873: } 874: } 875: } 876: $this->DB->Free($r); 877: 878: 879: // and finally we look for new tests i.e. in the cat but not in the DB 880: foreach($xmlobj->Catalogue as $val) 881: { 882: $key=$val['NAME']; 883: if (!isset($tests[$key])) // not in the DB 884: { 885: $q="INSERT INTO fnnstest(nodeid,testtype,testdesc,lastvalue,lastrunx,alertlevel) "; 886: $q.="VALUES(\"".ss($nodeid)."\",\"".$key."\",\"".ss($val['DESC'])."\",\"".ss($val['VALUE'])."\",".time().",".ss($val['ALERTLEVEL']).")"; 887: //echo $q."
";
888: $this->DB->Query($q); 889: } 890: } 891: 892: $eventdata=array("nodeid"=>$nodeid,"alertlevel"=>$alvl); 893: $this->EventHandler("nodeside_process",$eventdata); 894: 895: 896: } 897: 898: 899: function AddEventHandler($event,$function) 900: { 901: if (!isset($this->EventHandlers[$event])) $this->EventHandlers[$event]=array(); 902: $this->EventHandlers[$event][]=$function; 903: } 904: 905: function EventHandler($event,$data) 906: { 907: if ( isset($data) && is_array($data) ) $data['event']=$event; 908: 909: if (isset($this->EventHandlers[$event])) // handler(s) exist 910: { 911: for($a=0; $aEventHandlers[$event]); $a++) 912: { 913: if (function_exists($this->EventHandlers[$event][$a])) 914: { 915: $this->Event("Event ".$event." -> ".$this->EventHandlers[$event][$a],6,"Event","Handler"); 916: return $this->EventHandlers[$event][$a]($data); 917: } 918: else 919: { 920: $t="Illegal Handler ".$this->EventHandlers[$event][$a]." for ".$event; 921: $this->Event($t,2,"Event","Handler"); 922: return false; 923: } 924: } 925: } 926: else return false; 927: } 928: 929: } 930: ?>