File: 1.00.2a/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.2"; 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","FreeNATS"); 213: $smtpusername=$this->Cfg->Get("mail.smtp.username",""); 214: if ($smtpusername!="") $smtpauth=true; 215: else $smtpauth=false; 216: $smtppassword=$this->Cfg->Get("mail.smtp.password",""); 217: $smtphostname=$this->Cfg->Get("mail.smtp.hostname",""); 218: $mail=new PHPMailer(); 219: $mail->IsSMTP(); 220: $mail->Host=$smtpserver; 221: $mail->From=$row['efrom']; 222: $mail->FromName=$fromname; 223: $mail->AddAddress($toaddr); 224: $mail->Subject=$sub; 225: $mail->Body=$body; 226: $mail->WordWrap=50; 227: if ($smtphostname!="") $mail->Hostname=$smtphostname; 228: if ($smtpauth) 229: { 230: $mail->SMTPAuth=true; 231: $mail->Username=$smtpusername; 232: $mail->Password=$smtppassword; 233: } 234: if (!$mail->Send()) 235: { // failed 236: $this->Event("phpMailer to ".$toaddr." failed",1,"Flush","Email"); 237: $this->Event("phpMailer Error: ".$mail->ErrorInfo,1,"Flush","Email"); 238: } 239: else 240: { 241: $this->Event("phpMailer Sent Email To ".$toaddr,4,"Flush","Email"); 242: } 243: } 244: 245: } 246: } 247: 248: 249: 250: } 251: else if ($row['atype']=="url") 252: { 253: // url send 254: if ($row['etype']==0) $body=$row['mdata']; 255: else $body="FreeNATS Alert,\r\n".$row['mdata']."\r\n--FreeNATS @ ".nicedt(time()); 256: 257: $body=urlencode($body); 258: $tolist=array(); 259: $f=0; 260: $tolist[0]=""; 261: for ($a=0; $a262: { 263: $chr=$row['etolist'][$a]; 264: //echo $chr; 265: if (strpos($allowed,$chr)===false) // special char 266: { 267: $f++; 268: $tolist[$f]=""; 269: } 270: else 271: { 272: $tolist[$f].=$chr; 273: } 274: } 275: 276: foreach($tolist as $tourl) 277: { 278: if ($doalert) 279: { 280: $url=$tourl.$body; 281: $fp=@fopen($url,"r"); 282: if ($fp>0) fclose($fp); 283: else $this->Event("URL Alert Failed ".$url,1,"Flush","URL"); 284: $this->Event("URL Alert ".$url,4,"Flush","URL"); 285: } 286: } 287: 288: 289: } 290: else if ($row['atype']=="mqueue") 291: { 292: // message queue 293: $eventdata=array("aaid"=>$row['aaid'],"name"=>$row['aname'],"data"=>$row['mdata']); 294: $result=$this->EventHandler("alert_action",$eventdata); 295: if ($result===false) // put the data back into the queue 296: { 297: $q="UPDATE fnalertaction SET mdata=\"".$row['mdata']."\"+mdata WHERE aaid=".$row['aaid']; 298: $this->DB->Query($q); 299: if ($this->DB->Affected_Rows()<=0) 300: $this->Event("Persist MDATA Failed for AAID ".$row['aaid'],2,"Flush","MQueue"); 301: } 302: else $this->Event("Queue Cleared for AAID ".$row['aaid']." by Handler",4,"Flush","MQueue"); 303: } 304: 305: } 306: } 307: 308: function GetAlerts() 309: { 310: $q="SELECT nodeid,alertlevel FROM fnalert WHERE closedx=0"; 311: $r=$this->DB->Query($q); 312: $c=0; 313: $al=array(); 314: while ($row=$this->DB->Fetch_Array($r)) 315: { 316: $al[$c]['nodeid']=$row['nodeid']; 317: $al[$c]['alertlevel']=$row['alertlevel']; 318: $c++; 319: } 320: if ($c>0) return $al; 321: else return false; 322: } 323: 324: function SetAlerts($nodeid,$alertlevel,$alerts="") 325: { 326: if ($alerts=="") $alerts=array(); 327: // get current alert level 328: $q="SELECT alertlevel,nodealert FROM fnnode WHERE nodeid=\"".ss($nodeid)."\""; 329: $r=$this->DB->Query($q); 330: $row=$this->DB->Fetch_Array($r); 331: $this->DB->Free($r); 332: $cal=$row['alertlevel']; 333: 334: $eventdata=array("nodeid"=>$nodeid,"alertlevel"=>$alertlevel, 335: "oldalertlevel"=>$cal); 336: $this->EventHandler("set_alerts",$eventdata); 337: 338: if ($alertlevel!=$cal) 339: { 340: // update table 341: $q="UPDATE fnnode SET alertlevel=".ss($alertlevel)." WHERE nodeid=\"".ss($nodeid)."\""; 342: $this->DB->Query($q); 343: } 344: 345: // do not continue if node alert isn't set 346: if ($row['nodealert']!=1) return 0; 347: 348: // ALERTS 349: // is there an existing alert for this node 350: $q="SELECT alertid,alertlevel FROM fnalert WHERE nodeid=\"".ss($nodeid)."\" AND closedx=0"; 351: $r=$this->DB->Query($q); 352: if ($row=$this->DB->Fetch_Array($r)) 353: { // yes there is 354: // if new alert level is 0 let's close it 355: if ($alertlevel==0) 356: { 357: $alertid=$row['alertid']; 358: $q="UPDATE fnalert SET closedx=".time()." WHERE alertid=".$row['alertid']; 359: $this->DB->Query($q); 360: if (is_array($alerts)) $alerts[]="Alert Closed"; 361: else 362: { 363: //$alerts=array(); 364: $alerts[]="Alert Closed"; 365: } 366: $eventdata=array("nodeid"=>$nodeid); 367: $this->EventHandler("alert_close",$eventdata); 368: } 369: else 370: { 371: $alertid=$row['alertid']; 372: // otherwise update the alert to the new value (was: regardless, now just if not a 0) 373: $q="UPDATE fnalert SET alertlevel=".ss($alertlevel)." WHERE alertid=".$alertid; 374: $this->DB->Query($q); 375: } 376: } 377: else 378: { // no there's not 379: if ($alertlevel>0) // only if an actual alert 380: { 381: $q="INSERT INTO fnalert(nodeid,alertlevel,openedx) VALUES("; 382: $q.="\"".ss($nodeid)."\",".ss($alertlevel).",".time().")"; 383: $this->DB->Query($q); 384: $alertid=$this->DB->Insert_Id(); 385: $eventdata=array("nodeid"=>$nodeid); 386: $this->EventHandler("alert_open",$eventdata); 387: } 388: } 389: // ALERT LOG with $alertid 390: $t=time(); 391: $at=""; 392: if (is_array($alerts)) 393: { 394: foreach($alerts as $alert) 395: { 396: if (isset($alertid)) // misses on manual runs methinx 397: { 398: if ($at!="") $at.=", "; 399: $at.=$alert; 400: //echo $at."\n"; 401: $iq="INSERT INTO fnalertlog(alertid,postedx,logentry) VALUES("; 402: $iq.=$alertid.",".$t.",\"".ss($alert)."\")"; 403: //echo $iq; 404: $this->DB->Query($iq); 405: } 406: } 407: } 408: 409: $this->AlertAction($nodeid,$alertlevel,$alertlevel-$cal,$at); 410: 411: 412: 413: } 414: 415: function NodeAlertLevel($nodeid) 416: { 417: $q="SELECT alertlevel FROM fnnode WHERE nodeid=\"".ss($nodeid)."\""; 418: $r=$this->DB->Query($q); 419: if ($row=$this->DB->Fetch_Array($r)) return $row['alertlevel']; 420: else return -1; 421: } 422: 423: function GroupAlertLevel($groupid) 424: { 425: $lvl=-1; 426: $q="SELECT nodeid FROM fngrouplink WHERE groupid=\"".ss($groupid)."\""; 427: $r=$this->DB->Query($q); 428: while ($row=$this->DB->Fetch_Array($r)) 429: { 430: $nl=$this->NodeAlertLevel($row['nodeid']); 431: if ($nl>$lvl) $lvl=$nl; 432: } 433: $this->DB->Free($r); 434: return $lvl; 435: } 436: 437: function PhoneHome($mode=0,$type="ping") // 0 - php, 1 - html, 2 - data 438: { 439: if ($mode<2) 440: { 441: $qs="?type=".$type."&data=version=".$this->Version; 442: if (isset($_SERVER['REMOTE_ADDR'])) 443: $qs.=",ip=".$_SERVER['REMOTE_ADDR']; 444: $ploc="http://www.purplepixie.org/freenats/report/"; 445: if ($mode==1) $ploc.="ping.html"; 446: else $ploc.="ping.php"; 447: 448: $ploc.=$qs; 449: 450: $lp=@fopen($ploc,"r"); 451: if ($lp>0) @fclose($lp); 452: } 453: else 454: { 455: // data post -- !! 456: } 457: } 458: 459: function GetNode($nodeid) 460: { 461: $return_row=false; 462: $q="SELECT * FROM fnnode WHERE nodeid=\"".ss($nodeid)."\" LIMIT 0,1"; 463: $r=$this->DB->Query($q); 464: if ($row=$this->DB->Fetch_Array($r)) 465: $return_row=true; 466: 467: $this->DB->Free($r); 468: if ($return_row) // found a valid 469: { 470: if ($row['nodename']!="") $row['name']=$row['nodename']; // make a "nice" name for it 471: else $row['name']=$row['nodeid']; 472: 473: $row['alerttext']=oText($row['alertlevel']); // textual alert status 474: 475: $row['lastrundt']=nicedt($row['lastrunx']); // text date-time last run 476: $row['lastrunago']=dtago($row['lastrunx'],false); // last run ago 477: 478: // protection 479: $row['nskey']=""; 480: 481: return $row; 482: } 483: else 484: return false; // or failed 485: } 486: 487: function SetNode($nodeid,$data) 488: { 489: $q="UPDATE fnnode SET "; 490: $first=true; 491: foreach($data as $key => $val) 492: { 493: if ($first) $first=false; 494: else $q.=","; 495: $q.=ss($key)."=\"".ss($val)."\""; 496: } 497: $q.=" WHERE nodeid=\"".ss($nodeid)."\""; 498: $this->DB->Query($q); 499: if ($this->DB->Affected_Rows()>0) return true; 500: 501: if ($this->DB->Error()) // query failed 502: { 503: $errstr1="Query Failed: ".$q; 504: $errstr2="Query Failed: ".$this->DB->Error_String(); 505: $this->Event($errstr1,2,"Node","Set"); 506: $this->Event($errstr1,2,"Node","Set"); 507: return false; 508: } 509: return true; // query succeeded but nothing was updated 510: } 511: 512: function EnableNode($nodeid,$enabled=true) 513: { 514: if ($enabled) $ne=1; 515: else $ne=0; 516: $data=array("nodeenabled"=>$ne); 517: return $this->SetNode($nodeid,$data); 518: } 519: 520: function DisableNode($nodeid) 521: { 522: return $this->EnableNode($nodeid,false); 523: } 524: 525: function SetNodeSchedule($nodeid,$scheduleid) 526: { 527: $data=array("scheduleid"=>$scheduleid); 528: return $this->SetNode($nodeid,$data); 529: } 530: 531: function GetGroup($groupid) 532: { 533: $q="SELECT * FROM fngroup WHERE groupid=".ss($groupid)." LIMIT 0,1"; 534: $r=$this->DB->Query($q); 535: if (!$row=$this->DB->Fetch_Array($r)) return false; 536: 537: $this->DB->Free($r); 538: $row['alertlevel']=$this->GroupAlertLevel($groupid); 539: $row['alerttext']=oText($row['alertlevel']); 540: return $row; 541: } 542: 543: function GetTest($testid,$protect=false) 544: { 545: if ($testid=="") return false; 546: $class=$testid[0]; 547: if (is_numeric($class)) 548: { 549: // test ID will stay the same 550: $class="L"; 551: $anytestid=$testid; 552: } 553: else 554: { 555: //$testid=substr($testid,1); // as it will here also so direct use to graphs can be made 556: $anytestid=substr($testid,1); // the classless version 557: } 558: 559: $q=""; 560: switch($class) 561: { 562: case "L": // local tests 563: $q="SELECT * FROM fnlocaltest WHERE localtestid=".ss($anytestid)." LIMIT 0,1"; 564: break; 565: case "N": // node-side test 566: $q="SELECT * FROM fnnstest WHERE nstestid=".ss($anytestid)." LIMIT 0,1"; 567: break; 568: default: 569: return false; // can't lookup this class 570: } 571: 572: if ($q=="") return false; 573: 574: $r=$this->DB->Query($q); 575: 576: if (!$row=$this->DB->Fetch_Array($r)) return false; 577: 578: $row['class']=$class; 579: $row['testid']=$testid; 580: $row['anytestid']=$anytestid; 581: $row['alerttext']=oText($row['alertlevel']); 582: $row['lastrundt']=nicedt($row['lastrunx']); 583: $row['lastrunago']=dtago($row['lastrunx'],false); 584: 585: if ($row['testname']!="") $row['name']=$row['testname']; 586: else 587: { 588: if ($class=="L") 589: { 590: $row['name']=lText($row['testtype']); // TODO OTHER TESTS 591: if ($row['testparam']!="") $row['name'].=" (".$row['testparam'].")"; 592: } 593: else if ($class=="N") 594: { 595: if ($row['testdesc']!="") $row['name']=$row['testdesc']; 596: else $row['name']=$row['testtype']; 597: } 598: } 599: 600: if ($protect&&($class=="L")) // module test protection 601: { 602: if ($this->Tests->Exists($row['testtype'])) // in the module register 603: { 604: $this->Tests->Tests[$row['testtype']]->Create(); 605: $this->Tests->Tests[$row['testtype']]->instance->ProtectOutput($row); 606: } 607: } 608: 609: $this->DB->Free($r); 610: 611: return $row; 612: } 613: 614: 615: function DeleteTest($testid) 616: { 617: if ($testid=="") return false; 618: $class=$testid[0]; 619: if (is_numeric($class)) 620: { 621: // test ID will stay the same 622: $class="L"; 623: $anytestid=$testid; 624: } 625: else 626: { 627: $anytestid=substr($testid,1); // the classless version 628: } 629: 630: $q=""; 631: switch($class) 632: { 633: case "L": // local tests 634: $q="DELETE FROM fnlocaltest WHERE localtestid=".ss($anytestid); 635: break; 636: case "N": // node-side test 637: $q="DELETE FROM fnnstest WHERE nstestid=".ss($anytestid); 638: break; 639: default: 640: return false; // can't lookup this class 641: } 642: 643: if ($q=="") return false; 644: 645: $this->DB->Query($q); 646: $tests=$this->DB->Affected_Rows(); 647: 648: $rq="DELETE FROM fnrecord WHERE testid=\"".ss($testid)."\""; 649: $this->DB->Query($rq); 650: $records=$this->DB->Affected_Rows(); 651: 652: $eq="DELETE FROM fneval WHERE testid=\"".ss($testid)."\""; 653: $this->DB->Query($eq); 654: $eval=$this->DB->Affected_Rows(); 655: 656: $s="Deleted test ".$testid." (".$tests." tests, ".$records." records, ".$eval." evaluators)"; 657: $this->Event($s,6,"Test","Delete"); 658: } 659: 660: 661: 662: function InvalidateTest($testid,$rightnow=false) 663: { 664: $class=$testid[0]; 665: if (is_numeric($class)) $class="L"; 666: else $testid=substr($testid,1); 667: if ($rightnow) 668: { 669: $nextx=time(); 670: $q="UPDATE "; 671: if ($class=="L") $q.="fnlocaltest"; 672: // other ones here 673: 674: $q.=" SET nextrunx=".$nextx." WHERE "; 675: 676: if ($class=="L") $q.="localtestid=".$testid; 677: // other ones here 678: 679: $this->DB->Query($q); 680: return true; 681: } 682: // otherwise use it's interval 683: $q="SELECT testinterval FROM "; 684: 685: if ($class=="L") $q.="fnlocaltest WHERE localtestid="; 686: // other ones here 687: 688: $q.=$testid; 689: $r=$this->DB->Query($q); 690: if ($row=$this->DB->Fetch_Array($r)) 691: { 692: $this->DB->Free($r); 693: $nextx=next_run_x($row['testinterval']); 694: $q="UPDATE "; 695: if ($class=="L") $q.="fnlocaltest"; 696: // other ones here 697: 698: $q.=" SET nextrunx=".$nextx." WHERE "; 699: 700: if ($class=="L") $q.="localtestid=".$testid; 701: // other ones here 702: 703: $this->DB->Query($q); 704: return true; 705: } 706: return false; 707: } 708: 709: function InvalidateNode($nodeid,$rightnow=false,$testsaswell=false) 710: { 711: if ($rightnow) 712: { 713: $nextx=time(); 714: $q="UPDATE fnnode SET nextrunx=".$nextx." WHERE nodeid=\"".ss($nodeid)."\""; 715: $this->DB->Query($q); 716: if ($testsaswell) 717: { 718: $q="UPDATE fnlocaltest SET nextrunx=".$nextx." WHERE nodeid=\"".ss($nodeid)."\""; 719: $this->DB->Query($q); 720: } 721: return true; 722: } 723: // otherwise set to it's interval 724: $q="SELECT testinterval FROM fnnode WHERE nodeid=\"".ss($nodeid)."\""; 725: $r=$this->DB->Query($q); 726: if ($row=$this->DB->Fetch_Array($r)) 727: { 728: $nextx=next_run_x($row['testinterval']); 729: $uq="UPDATE fnnode SET nextrunx=".$nextx." WHERE nodeid=\"".ss($nodeid)."\""; 730: $this->DB->Query($uq); 731: $this->DB->Free($r); 732: if ($testsaswell) 733: { 734: $uq="UPDATE fnlocaltest SET nextrunx=".$nextx." WHERE nodeid=\"".ss($nodeid)."\""; 735: $this->DB->Query($uq); 736: } 737: return true; 738: } 739: return false; 740: } 741: 742: 743: function NodeSide_Pull($nodeid) 744: { 745: $eventdata=array("nodeid"=>$nodeid,"success"=>false); 746: $q="SELECT nsenabled,nspullenabled,nsurl,nskey,nsinterval FROM fnnode WHERE nodeid=\"".ss($nodeid)."\" LIMIT 0,1"; 747: $r=$this->DB->Query($q); 748: if (!$row=$this->DB->Fetch_Array($r)) return false; 749: 750: $this->DB->Free($r); 751: 752: $url=$row['nsurl']; 753: if ($row['nskey']!="") $url.="?nodekey=".$row['nskey']; 754: $this->Event("NodeSide_Pull Started for ".$nodeid,10,"Node","Pull"); 755: 756: $xmlobj=new TNodeXML(); 757: 758: $fp=@fopen($url,"r"); 759: if ($fp<=0) 760: { 761: $this->Event("Pull Failed URL ".$url,1,"Node","Pull"); 762: $this->EventHandler("nodeside_pull",$eventdata); 763: return false; 764: } 765: $xml=""; 766: while (!feof($fp)) 767: { 768: $xml.=fgets($fp,4096); 769: } 770: if ($xml=="") 771: { 772: $this->EventHandler("nodeside_pull",$eventdata); 773: return false; 774: } 775: 776: //echo $xml; 777: 778: $result=$xmlobj->Parse($xml); 779: 780: if ($xmlobj->Error()!="") 781: { 782: $this->Event("NodeXML Error: ".$xmlobj->Error(),1,"Node","Pull"); 783: $this->EventHandler("nodeside_pull",$eventdata); 784: return false; 785: } 786: $this->Event("NodeSide_Pull Fetched ".$xmlobj->Tests." tests for ".$nodeid,10,"Node","Pull"); 787: // Now just to actually process it... 788: $eventdata['success']=true; 789: $this->EventHandler("nodeside_pull",$eventdata); 790: $this->NodeSide_Process($nodeid,$xmlobj); 791: return true; 792: } 793: 794: function NodeSide_Process($nodeid,&$xmlobj) 795: { // nodeid + takes a TNodeXML Object 796: $alvl=0; 797: $this->Event("NodeSide_Process for ".$nodeid,10,"Node","Pull"); 798: $q="SELECT * FROM fnnstest WHERE nodeid=\"".ss($nodeid)."\""; 799: $r=$this->DB->Query($q); 800: $tests=array(); 801: while ($row=$this->DB->Fetch_Array($r)) 802: { 803: $tests[$row['testtype']]=$row; 804: if (isset($xmlobj->Catalogue[$row['testtype']])) 805: { // this test is in the DB and catalogue 806: $tests[$row['testtype']]['incat']=true; 807: if ($row['testenabled']==1) // it is enabled - so we test it 808: { 809: if ($row['simpleeval']==1) $level=$xmlobj->Catalogue[$row['testtype']]['ALERTLEVEL']; // use provided level 810: else $level=nats_eval("N".$row['nstestid'],$xmlobj->Catalogue[$row['testtype']]['VALUE']); 811: $dbs="Nodeside ".$row['testtype']." on ".$row['nodeid']." = ".$level; 812: if ($level==0) $debuglev=8; 813: else if ($level>0) $debuglev=5; 814: else $debuglev=2; 815: $this->Event($dbs,$debuglev,"Node","Process"); 816: 817: if ($level>$alvl) $alvl=$level; 818: 819: if ($row['testrecord']==1) // record it 820: { 821: $testvalue=$xmlobj->Catalogue[$row['testtype']]['VALUE']; 822: if (!is_numeric($testvalue)) $testvalue=0; 823: $iq="INSERT INTO fnrecord(testid,alertlevel,recordx,nodeid,testvalue) VALUES("; 824: $iq.="\"N".$row['nstestid']."\",".$level.",".time().",\"".$row['nodeid']."\",".$testvalue.")"; 825: $this->DB->Query($iq); 826: if ($this->DB->Affected_Rows()<=0) 827: $this->Event("Nodeside ".$row['testtype']." Failed to Record",1,"Node","Process"); 828: } 829: 830: // We don't do any alerting here - the tester will do that for us! 831: $uq="UPDATE fnnstest SET lastrunx=".time().",lastvalue=\"".ss($xmlobj->Catalogue[$row['testtype']]['VALUE'])."\",alertlevel=".$level." "; 832: $uq.="WHERE nstestid=".$row['nstestid']; 833: $this->DB->Query($uq); 834: if ($this->DB->Affected_Rows()<=0) 835: $this->Event("Nodeside ".$row['testtype']." Failed to Update or Same Values",5,"Node","Process"); 836: 837: } 838: 839: // check to see if the desc has changed 840: if ($row['testdesc']!=$xmlobj->Catalogue[$row['testtype']]['DESC']) 841: { 842: $duq="UPDATE fnnstest SET testdesc=\"".ss($xmlobj->Catalogue[$row['testtype']]['DESC'])."\" WHERE nstestid=".$row['nstestid']; 843: $this->DB->Query($duq); 844: } 845: 846: } 847: else 848: { 849: // test in the DB but NOT in the catalogue 850: //$xmlobj->Catalogue[$row['testtype']]['incat']=false; 851: if ($row['testenabled']==1) 852: { // enabled so shown in lists etc 853: // Update it to show failed status 854: $this->Event("No nodeside data for test N".$row['nstestid'],3,"Node","Process"); 855: $uq="UPDATE fnnstest SET alertlevel=2,lastvalue=-1 WHERE nstestid=".$row['nstestid']; 856: $this->DB->Query($uq); 857: $alvl=2; 858: } 859: else // not enabled so simply delete 860: { 861: $this->DeleteTest("N".$row['nstestid']); 862: } 863: } 864: } 865: $this->DB->Free($r); 866: 867: 868: // and finally we look for new tests i.e. in the cat but not in the DB 869: foreach($xmlobj->Catalogue as $val) 870: { 871: $key=$val['NAME']; 872: if (!isset($tests[$key])) // not in the DB 873: { 874: $q="INSERT INTO fnnstest(nodeid,testtype,testdesc,lastvalue,lastrunx,alertlevel) "; 875: $q.="VALUES(\"".ss($nodeid)."\",\"".$key."\",\"".ss($val['DESC'])."\",\"".ss($val['VALUE'])."\",".time().",".ss($val['ALERTLEVEL']).")"; 876: //echo $q."
";
877: $this->DB->Query($q); 878: } 879: } 880: 881: $eventdata=array("nodeid"=>$nodeid,"alertlevel"=>$alvl); 882: $this->EventHandler("nodeside_process",$eventdata); 883: 884: 885: } 886: 887: 888: function AddEventHandler($event,$function) 889: { 890: if (!isset($this->EventHandlers[$event])) $this->EventHandlers[$event]=array(); 891: $this->EventHandlers[$event][]=$function; 892: } 893: 894: function EventHandler($event,$data) 895: { 896: if ( isset($data) && is_array($data) ) $data['event']=$event; 897: 898: if (isset($this->EventHandlers[$event])) // handler(s) exist 899: { 900: for($a=0; $aEventHandlers[$event]); $a++) 901: { 902: if (function_exists($this->EventHandlers[$event][$a])) 903: { 904: $this->Event("Event ".$event." -> ".$this->EventHandlers[$event][$a],6,"Event","Handler"); 905: return $this->EventHandlers[$event][$a]($data); 906: } 907: else 908: { 909: $t="Illegal Handler ".$this->EventHandlers[$event][$a]." for ".$event; 910: $this->Event($t,2,"Event","Handler"); 911: return false; 912: } 913: } 914: } 915: else return false; 916: } 917: 918: } 919: ?>