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: ?>