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

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