File:
0.04.31b/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 $Version="0.04.31";
29: var $Release="b";
30:
31: function Start()
32: {
33: $this->DB=new TNATS_DB();
34: $this->Cfg=new TNATS_Cfg();
35: $this->DB->Connect();
36: $this->Cfg->Load($this->DB);
37: $this->init=true;
38: }
39:
40: function Stop()
41: {
42: $this->DB->Disconnect();
43: $this->init=false;
44: }
45:
46: function Event($logevent,$loglevel=1,$modid="NONE",$catid="NONE")
47: {
48: global $NATS_Session;
49: if ((isset($NATS_Session))&&($NATS_Session->auth)) $username=$NATS_Session->username;
50: else $username="";
51: $l=$this->Cfg->Get("log.level");
52: //echo "** $l **\n";
53: if ( $l=="" ) $l=10; // debug logging if no variable
54: if ( $l < $loglevel ) return false;
55: if (strlen($logevent)>249) $logevent=substr($logevent,0,245)."...";
56: $q="INSERT INTO fnlog(postedx,modid,catid,loglevel,logevent,username) VALUES(".time().",";
57: $q.="\"".ss($modid)."\",\"".ss($catid)."\",".ss($loglevel).",\"".ss($logevent)."\",\"".ss($username)."\")";
58: //echo $q;
59: $this->DB->Query($q);
60: }
61:
62: function AlertAction($nodeid,$alertlevel,$change,$alerttext)
63: {
64: echo "aaCalled for node: ".$nodeid."\n";
65: if ($change==0) return false;
66: // catch alerttext
67: if (trim($alerttext)=="") return false;
68: echo "aaContinue for node: ".$nodeid."\n";
69:
70: //echo $nodeid.":".$alertlevel.":".$change.":".$alerttext."\n";
71: // get all the alertactions for this node id
72: $q="SELECT aaid FROM fnnalink WHERE nodeid=\"".ss($nodeid)."\"";
73: $r=$this->DB->Query($q);
74: while ($arow=$this->DB->Fetch_Array($r))
75: {
76: // get details for this alert action
77: $aq="SELECT * FROM fnalertaction WHERE aaid=".$arow['aaid']." LIMIT 0,1";
78: //echo $aq."\n";
79: $ar=$this->DB->Query($aq);
80: $aa=$this->DB->Fetch_Array($ar);
81: $this->DB->Free($ar);
82: //echo $aa['atype']."FISH\n";
83:
84: // UGGGGGGGG continue!!
85: if ( ($aa['atype']=="") || ($aa['atype']=="Disabled") ) continue;
86: if ( ($aa['awarnings']==0) && ($alertlevel==1) ) continue;
87: if ( ($aa['adecrease']==0) && ($change<1) ) continue;
88:
89: // made it this far
90: if ($aa['mdata']!="") $ndata=$aa['mdata']."\n".$nodeid.": ".$alerttext;
91: else $ndata=$nodeid.": ".$alerttext;
92: $uq="UPDATE fnalertaction SET mdata=\"".ss($ndata)."\" WHERE aaid=".$arow['aaid'];
93: //echo $uq."\n";
94: $this->DB->Query($uq);
95: }
96: }
97:
98: function ActionFlush()
99: {
100: global $allowed; // allowed chars from screen in YA BODGE
101: $q="SELECT * FROM fnalertaction WHERE mdata!=\"\"";
102: $r=$this->DB->Query($q);
103: while ($row=$this->DB->Fetch_Array($r))
104: {
105:
106: $doalert=true;
107:
108: // clear mdata right at the start to get around duplicate emails whilst processing
109: $q="UPDATE fnalertaction SET mdata=\"\" WHERE aaid=".$row['aaid'];
110: $this->DB->Query($q);
111:
112: if ($this->DB->Affected_Rows()<=0) // already flushed or failed to flush
113: {
114: $doalert=false;
115: $this->Event("Alert Action Already Flushed - Skipping",8,"Flush","Action");
116: }
117:
118: // alert counter
119: $td=date("Ymd");
120: if ($td!=$row['ctrdate']) // new day or no flush record
121: {
122: $q="UPDATE fnalertaction SET ctrdate=\"".$td."\",ctrtoday=1 WHERE aaid=".$row['aaid'];
123: $this->DB->Query($q);
124: }
125: else
126: {
127:
128: if ( ($row['ctrlimit']==0) || ($row['ctrlimit']>$row['ctrtoday']) ) // no limit or below
129: {
130: $q="UPDATE fnalertaction SET ctrtoday=ctrtoday+1 WHERE aaid=".$row['aaid'];
131: $this->DB->Query($q);
132: }
133: else // at or over limit
134: {
135: $this->Event("Alert Action Limit Reached - Skipping",2,"Flush","Action");
136: $doalert=false;
137: }
138:
139: }
140:
141:
142: if ($row['atype']=="email")
143: {
144: if ($row['esubject']==0) $sub="";
145: else if ($row['esubject']==1) $sub="FreeNATS Alert";
146: else $sub="** FreeNATS Alert **";
147: $body="";
148: if ($row['etype']==0) $body=$row['mdata'];
149: else $body="FreeNATS Alert,\r\n".$row['mdata']."\r\n--FreeNATS @ ".nicedt(time());
150: //$tolist=preg_split("[\n\r]",$row['etolist']);
151: $tolist=array();
152: $f=0;
153: $tolist[0]="";
154: for ($a=0; $a155: {
156: $chr=$row['etolist'][$a];
157: //echo $chr;
158: if (strpos($allowed,$chr)===false) // special char
159: {
160: $f++;
161: $tolist[$f]="";
162: }
163: else
164: {
165: $tolist[$f].=$chr;
166: }
167: }
168:
169: foreach($tolist as $toaddr)
170: {
171: $toaddr=nices($toaddr);
172: if ($toaddr!="")
173: {
174: //echo $row['efrom'].":".$toaddr.":".$sub.":".$body."\n\n";
175: //$body="fish";
176: //mail($toaddr,$sub,$body,"From: ".$row['efrom']."\r\n","-f".$row['efrom']);
177: $header="From: ".$row['efrom']."\r\n";
178: //$header="";
179: //$exhead="-f".$row['efrom'];
180: //db("Sending Email: ".$toaddr);
181: if ($doalert)
182: {
183: mail($toaddr,$sub,$body,$header);
184: $this->Event("Sent alert email to ".$toaddr,4,"Flush","Email");
185: }
186: }
187: }
188:
189:
190:
191: }
192: else if ($row['atype']=="url")
193: {
194: // url send
195: if ($row['etype']==0) $body=$row['mdata'];
196: else $body="FreeNATS Alert,\r\n".$row['mdata']."\r\n--FreeNATS @ ".nicedt(time());
197:
198: $body=urlencode($body);
199: $tolist=array();
200: $f=0;
201: $tolist[0]="";
202: for ($a=0; $a203: {
204: $chr=$row['etolist'][$a];
205: //echo $chr;
206: if (strpos($allowed,$chr)===false) // special char
207: {
208: $f++;
209: $tolist[$f]="";
210: }
211: else
212: {
213: $tolist[$f].=$chr;
214: }
215: }
216:
217: foreach($tolist as $tourl)
218: {
219: if ($doalert)
220: {
221: $url=$tourl.$body;
222: $fp=@fopen($url,"r");
223: if ($fp>0) fclose($fp);
224: else $this->Event("URL Alert Failed ".$url,1,"Flush","URL");
225: $this->Event("URL Alert ".$url,4,"Flush","URL");
226: }
227: }
228:
229:
230: }
231:
232: }
233: }
234:
235: function GetAlerts()
236: {
237: $q="SELECT nodeid,alertlevel FROM fnalert WHERE closedx=0";
238: $r=$this->DB->Query($q);
239: $c=0;
240: $al=array();
241: while ($row=$this->DB->Fetch_Array($r))
242: {
243: $al[$c]['nodeid']=$row['nodeid'];
244: $al[$c]['alertlevel']=$row['alertlevel'];
245: $c++;
246: }
247: if ($c>0) return $al;
248: else return false;
249: }
250:
251: function SetAlerts($nodeid,$alertlevel,$alerts="")
252: {
253: if ($alerts=="") $alerts=array();
254: // get current alert level
255: $q="SELECT alertlevel,nodealert FROM fnnode WHERE nodeid=\"".ss($nodeid)."\"";
256: $r=$this->DB->Query($q);
257: $row=$this->DB->Fetch_Array($r);
258: $this->DB->Free($r);
259: $cal=$row['alertlevel'];
260:
261: if ($alertlevel>$cal)
262: {
263: // trigger alert process
264: }
265:
266: if ($alertlevel!=$cal)
267: {
268: // update table
269: $q="UPDATE fnnode SET alertlevel=".ss($alertlevel)." WHERE nodeid=\"".ss($nodeid)."\"";
270: $this->DB->Query($q);
271: }
272:
273: // do not continue if node alert isn't set
274: if ($row['nodealert']!=1) return 0;
275: // or if it's untested
276: if ($alertlevel<0) return 0;
277:
278: // ALERTS
279: // is there an existing alert for this node
280: $q="SELECT alertid,alertlevel FROM fnalert WHERE nodeid=\"".ss($nodeid)."\" AND closedx=0";
281: $r=$this->DB->Query($q);
282: if ($row=$this->DB->Fetch_Array($r))
283: { // yes there is
284: // if new alert level is 0 let's close it
285: if ($alertlevel==0)
286: {
287: $alertid=$row['alertid'];
288: $q="UPDATE fnalert SET closedx=".time()." WHERE alertid=".$row['alertid'];
289: $this->DB->Query($q);
290: if (is_array($alerts)) $alerts[]="Alert Closed";
291: else
292: {
293: //$alerts=array();
294: $alerts[]="Alert Closed";
295: }
296: }
297: else
298: {
299: $alertid=$row['alertid'];
300: // otherwise update the alert to the new value (was: regardless, now just if not a 0)
301: $q="UPDATE fnalert SET alertlevel=".ss($alertlevel)." WHERE alertid=".$alertid;
302: $this->DB->Query($q);
303: }
304: }
305: else
306: { // no there's not
307: if ($alertlevel>0) // only if an actual alert
308: {
309: $q="INSERT INTO fnalert(nodeid,alertlevel,openedx) VALUES(";
310: $q.="\"".ss($nodeid)."\",".ss($alertlevel).",".time().")";
311: $this->DB->Query($q);
312: $alertid=$this->DB->Insert_Id();
313: }
314: }
315: // ALERT LOG with $alertid
316: $t=time();
317: $at="";
318: if (is_array($alerts))
319: {
320: foreach($alerts as $alert)
321: {
322: if (isset($alertid)) // misses on manual runs methinx
323: {
324: if ($at!="") $at.=", ";
325: $at.=$alert;
326: //echo $at."\n";
327: $iq="INSERT INTO fnalertlog(alertid,postedx,logentry) VALUES(";
328: $iq.=$alertid.",".$t.",\"".ss($alert)."\")";
329: //echo $iq;
330: $this->DB->Query($iq);
331: }
332: }
333: }
334:
335: $this->AlertAction($nodeid,$alertlevel,$alertlevel-$cal,$at);
336:
337:
338:
339: }
340:
341: function NodeAlertLevel($nodeid)
342: {
343: $q="SELECT alertlevel FROM fnnode WHERE nodeid=\"".ss($nodeid)."\"";
344: $r=$this->DB->Query($q);
345: if ($row=$this->DB->Fetch_Array($r)) return $row['alertlevel'];
346: else return -1;
347: }
348:
349: function GroupAlertLevel($groupid)
350: {
351: $lvl=-1;
352: $q="SELECT nodeid FROM fngrouplink WHERE groupid=\"".ss($groupid)."\"";
353: $r=$this->DB->Query($q);
354: while ($row=$this->DB->Fetch_Array($r))
355: {
356: $nl=$this->NodeAlertLevel($row['nodeid']);
357: if ($nl>$lvl) $lvl=$nl;
358: }
359: $this->DB->Free($r);
360: return $lvl;
361: }
362:
363: function PhoneHome($mode=0,$type="ping") // 0 - php, 1 - html, 2 - data
364: {
365: if ($mode<2)
366: {
367: $qs="?type=".$type."&data=version=".$this->Version;
368: if (isset($_SERVER['REMOTE_ADDR']))
369: $qs.=",ip=".$_SERVER['REMOTE_ADDR'];
370: $ploc="http://www.purplepixie.org/freenats/report/";
371: if ($mode==1) $ploc.="ping.html";
372: else $ploc.="ping.php";
373:
374: $ploc.=$qs;
375:
376: $lp=@fopen($ploc,"r");
377: if ($lp>0) @fclose($lp);
378: }
379: else
380: {
381: // data post -- !!
382: }
383: }
384:
385: function GetNode($nodeid)
386: {
387: $return_row=false;
388: $q="SELECT * FROM fnnode WHERE nodeid=\"".ss($nodeid)."\" LIMIT 0,1";
389: $r=$this->DB->Query($q);
390: if ($row=$this->DB->Fetch_Array($r))
391: $return_row=true;
392:
393: $this->DB->Free($r);
394: if ($return_row) // found a valid
395: {
396: if ($row['nodename']!="") $row['name']=$row['nodename']; // make a "nice" name for it
397: else $row['name']=$row['nodeid'];
398:
399: $row['alerttext']=oText($row['alertlevel']); // textual alert status
400:
401: $row['lastrundt']=nicedt($row['lastrunx']); // text date-time last run
402: $row['lastrunago']=dtago($row['lastrunx'],false); // last run ago
403:
404: return $row;
405: }
406: else
407: return false; // or failed
408: }
409:
410: function GetGroup($groupid)
411: {
412: $q="SELECT * FROM fngroup WHERE groupid=".ss($groupid)." LIMIT 0,1";
413: $r=$this->DB->Query($q);
414: if (!$row=$this->DB->Fetch_Array($r)) return false;
415:
416: $this->DB->Free($r);
417: $row['alertlevel']=$this->GroupAlertLevel($groupid);
418: $row['alerttext']=oText($row['alertlevel']);
419: return $row;
420: }
421:
422: function GetTest($testid)
423: {
424: if ($testid=="") return false;
425: $class=$testid[0];
426: if (is_numeric($class))
427: {
428: // test ID will stay the same
429: $class="L";
430: $anytestid=$testid;
431: }
432: else
433: {
434: //$testid=substr($testid,1); // as it will here also so direct use to graphs can be made
435: $anytestid=substr($testid,1); // the classless version
436: }
437:
438: $q="";
439: switch($class)
440: {
441: case "L": // local tests only thus-far
442: $q="SELECT * FROM fnlocaltest WHERE localtestid=".ss($anytestid)." LIMIT 0,1";
443: break;
444: default:
445: return false; // can't lookup this class
446: }
447:
448: if ($q=="") return false;
449:
450: $r=$this->DB->Query($q);
451:
452: if (!$row=$this->DB->Fetch_Array($r)) return false;
453:
454: $row['class']=$class;
455: $row['testid']=$testid;
456: $row['anytestid']=$anytestid;
457: $row['alerttext']=oText($row['alertlevel']);
458: $row['lastrundt']=nicedt($row['lastrunx']);
459: $row['lastrunago']=dtago($row['lastrunx'],false);
460:
461: if ($row['testname']!="") $row['name']=$row['testname'];
462: else
463: {
464: $row['name']=lText($row['testtype']); // TODO OTHER TESTS
465: if ($row['testparam']!="") $row['name'].=" (".$row['testparam'].")";
466: }
467:
468: $this->DB->Free($r);
469:
470: return $row;
471: }
472:
473:
474: }
475: ?>