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