Mrtg_nsi
上传用户:shbosideng
上传日期:2013-05-04
资源大小:1555k
文件大小:43k
源码类别:

SNMP编程

开发平台:

C/C++

  1. #! /usr/bin/perl
  2. # -*- mode: Perl -*-
  3. BEGIN{
  4. #$main::OS = 'UNIX';
  5. $main::OS = 'NT';
  6. #$main::OS = 'VMS';
  7. ##################################################################
  8. # MRTG-NSI 1.0 Network Status Imager for MRTG
  9. ##################################################################
  10. # Created by:  Mac Kloberg <mac@nacs.net><mac.kloberg@lam.liebherr.com>
  11. #
  12. # WARNING:  This thing was developed 'quick and dirty' on WinNT...
  13. # I've never actually tried this on Unix or VMS, so I 
  14. # don't know if it will work. Guess you'll find out... 
  15. # Send me mail...
  16. #
  17. # Built and based on: MRTG by Tobias Oetiker <oetiker@ee.ethz.ch>
  18. #             and Dave Rand <dlr@bungi.com>
  19. #
  20. # Credits: THANKS, TOBI AND DAVE!!!   K.U.T.G.W.
  21. #
  22. #################################################################
  23. #
  24. # Distributed under the GNU copyleft
  25. #
  26. ###################################################################
  27.  # The path separator is a slash, backslash or semicolon, depending
  28.  # on the platform.
  29.  $main::SL = {
  30.    UNIX=>'/',
  31.    WINDOWS=>'\',
  32.    NT=>'\',
  33.    VMS=>''
  34.    }->{$main::OS};
  35.  # The search path separator is a colon or semicolon depending on the
  36.  # operating system.
  37.  $main::PS = {
  38.    UNIX=>':',
  39.    WINDOWS=>';',
  40.    NT=>';',
  41.    VMS=>':'
  42.    }->{$main::OS};
  43. # We need to find the place where mrtg is installed, and
  44. # then take it from there...
  45. $main::binpath ="";
  46. if ($0 =~ /^(.+Q${main::SL}E)/) {
  47.   $main::binpath="$1";
  48. } else {
  49.   foreach $pathname ( split ${main::PS}, $ENV{'PATH'}) {
  50.     if ((($main::OS eq 'NT') &&
  51.          (-e "$pathname${main::SL}$0")) ||
  52.          (-x "$pathname${main::SL}$0")) {
  53. $main::binpath=$pathname;
  54. last;
  55.     }
  56.   }
  57. }
  58. die "ERROR: Can't find location of mrtg executablen" 
  59.   unless $main::binpath; 
  60. unshift (@INC,$main::binpath);
  61. }
  62. # There older perls tend to behave peculiar with
  63. # large integers ... 
  64. require 5.003;
  65. if ($main::OS eq 'UNIX' || $main::OS eq 'NT') {
  66.   use GD;
  67.   use Net::SMTP; #requires libnet package to be installed
  68.      #use SNMP_Session "0.71";
  69.      #use BER "0.66";
  70.      #use SNMP_util "0.71";
  71.   use locales_mrtg "0.01";
  72.   use Config;
  73.   #$main::SNMPDEBUG =0;
  74. }
  75. #Doesn't seem to work very well with the win32 port of GD
  76. #use strict; 
  77. if($main::OS eq 'UNIX')
  78. {
  79.   my($i) = 0;
  80.   my($name);
  81.   foreach $name (split(/ /, $Config{sig_name}))
  82.   {
  83. $main::signo{$name} = $i;
  84. $main::signame[$i++] = $name;
  85.   }
  86. }
  87. $main::DEBUG=1;
  88. sub END {
  89. local($?, $!);
  90. unlink ${main::Cleanfile} if($main::Cleanfile);
  91. }
  92. sub main {
  93. my ($router, $target ,$gdstyles, $neweventcounter, $eventcounter, $newevents, $neweventstype);
  94. # unbuffer stdout to see everything immediately
  95. $|=1 if $main::DEBUG;   
  96. print "nMRTG - Network Status Imager loading & initializing...nn" if $main::DEBUG;
  97. my ($routers, $cfg, $rcfg, $cfgfile) = readcfg();
  98. $target = cfgcheck($routers, $cfg, $rcfg);
  99. print "Locking Config Files...n";
  100. # Check the config and create the target object
  101. # lets make sure that there are not two mrtg-nsi's running in parallel.
  102. # so we lock on the cfg file. Nothing fancy, just a lockfile
  103. #
  104. my $lockfile = $cfgfile."_l";
  105. my $templock = $cfgfile."_l_" . $$ ;
  106. if ($main::OS eq 'VMS' || $main::OS eq 'NT') {
  107. # too sad NT and VMS can't do links we'll do the diletants lock
  108.   if (-e $lockfile && not unlink $lockfile){
  109.     my($lockage) = time()-(stat($lockfile))[9];
  110.     die ("ERROR: I guess another mrtg-nsi is running. A lockfile ($lockfile)
  111.      aged $lockage seconds is hanging around and I can't remove 
  112.      it because another process is still using it.");
  113.   }
  114.   
  115.   open (LOCK, ">$lockfile") or die "ERROR: Can't create lockfile $lockfilen";
  116.   print LOCK "$$n";
  117.   close LOCK;
  118.   open (LOCK, "<$lockfile") or die "ERROR: Can't open lockfile $lockfile for owner checkn";
  119.   my($read)=<LOCK>;
  120.   chomp($read);
  121.   die "ERROR: Someone else just got the lockfile $lockfilen" 
  122. unless  $$ == $read;
  123. } else {
  124.   # now, lets do it the UNIX way ... Daves work ...
  125.   open(LOCK,">$templock") || die "Can't create templock $templock";
  126.   $main::Cleanfile = $templock;
  127.   if (!link($templock,$lockfile)) {  # Lock file exists - deal with it.
  128.     my($nlink,$lockage) = (stat($lockfile))[3,9]; 
  129.     $lockage = time() - $lockage;
  130.     if ($nlink < 2 || $lockage > 30*60) { #lockfile is alone and old
  131. unlink($lockfile) 
  132.   || do{ unlink $templock; 
  133.  die "ERROR: Can't unlink stale lockfile ($lockfile). Permissions?n"};
  134. link($templock,$lockfile) 
  135.   || do{ unlink $templock; 
  136.  die "ERROR: Can't create lockfile ($lockfile).n".
  137.    "Permission problem or another mrtg locking succesfully?n"};
  138.     }
  139.     else {
  140. unlink $templock;
  141. die ("ERROR: I guess another mrtg is running. A lockfile ($lockfile) agedn".
  142.      "$lockage seconds is hanging around. If you are sure that no other mrtgn".
  143.      "is running you can remove the lockfilen");
  144.     }
  145.     
  146.   }
  147. }
  148. #Read the messages
  149.   my($msg) = readmsgfile($$cfg{'msgfile'});
  150. open (BACKGROUNDIMG,"<$$cfg{'statusmapbackground'}") || die "ERROR: Can't open StatusMapBackGroundn";
  151.    my($ImageData) = newFromGif GD::Image(BACKGROUNDIMG) || die "ERROR: GD::newFromGifn";
  152.    close BACKGROUNDIMG;
  153. #Allocate colors for this image...
  154. my %defcolors =
  155.    (#Color allocation table
  156.    'black', "0,0,0",
  157.    'red', "255,0,0",
  158.    'green', "0,255,0",
  159.    'blue', "0,0,255",
  160.    'yellow',  "255,250,205",
  161.    'white', "255,0,0"
  162. );   
  163. %colors = ();
  164. while(($color, $cvalue) = each(%defcolors)){
  165. #Try to allocate our color
  166. if($ImageData->colorAllocate(split(/,/,$cvalue)) ne "-1"){
  167. $colors{$color} = $ImageData->colorAllocate(split(/,/,$cvalue));
  168. }else{
  169. #Didn't work, we'll have to match the closest then
  170. $colors{$color} = $ImageData->colorClosest(split(/,/,$cvalue));
  171. }
  172. }
  173. #Define our linestyles
  174. $$gdstyles{'linestylec1'}{'style'} = "$colors{'yellow'},$colors{'yellow'},$colors{'yellow'},$colors{'yellow'},$colors{'blue'},$colors{'blue'},$colors{'blue'},$colors{'blue'},gdTransparent,gdTransparent";
  175. $$gdstyles{'linestylew1'}{'style'} = "$colors{'red'},$colors{'red'},$colors{'red'},$colors{'red'},$colors{'blue'},$colors{'blue'},$colors{'blue'},$colors{'blue'},gdTransparent,gdTransparent";
  176. $$gdstyles{'linestylea1'}{'style'} = "$colors{'red'},$colors{'red'},$colors{'blue'},$colors{'red'},$colors{'red'},$colors{'red'},$colors{'blue'},$colors{'blue'},gdTransparent,gdTransparent,gdTransparent,gdTransparent,gdTransparent,gdTransparent,gdTransparent,gdTransparent,gdTransparent";
  177. drawtext($ImageData, $gdstyles, $cfg, $rcfg, $routers, $router, "cool", "cool", "", "always", "1", "baxter.x", "baxter.y", "baxtersprings", "black",);
  178. $neweventcounter = 0;
  179. foreach $router (@$routers) {
  180.   my($savetz) = $ENV{'TZ'};
  181.   if ($$rcfg{'timezone'}{$router} ne '') {
  182.     $ENV{'TZ'} = $$rcfg{'timezone'}{$router}
  183.   }  
  184.   print "Imaging node: $routern";
  185.   
  186.   # set the locale
  187.   my($LOC);
  188.   if( $$cfg{'language'} && defined($lang2tran::LOCALE{"L$$cfg{'language'}E"}))
  189.   {
  190.     $LOC=$lang2tran::LOCALE{"L$$cfg{'language'}E"};
  191.   }
  192.   else
  193.   {
  194.     $LOC=$lang2tran::LOCALE{'default'};
  195.   };
  196.    #Node test...
  197. if($$cfg{'testnodelocations'} =~ /y/i){
  198. action_draw_crosshair($ImageData, $cfg, $rcfg, $routers, $router, $$rcfg{'nodecenterx'}{$router},$$rcfg{'nodecentery'}{$router},$black);
  199. next;
  200. #Normal node processing
  201. }else{
  202. my ($incurrent, $outcurrent, $inlast, $outlast) = getnodevalues($$rcfg{'node'}{$router}, $router, $rcfg, $cfg);
  203. #DEBUG --- DEBUG --- DEBUG --- DEBUG --- DEBUG --- DEBUG --- DEBUG --- 
  204. #if ($router =~ /NewportNewsEmailX400Kirchdorf/i){
  205. #$inlast = 0;$incurrent = 50;
  206. #$inlast = 5000;$incurrent = 100;
  207. #}
  208. #DEBUG --- DEBUG --- DEBUG --- DEBUG --- DEBUG --- DEBUG --- DEBUG --- 
  209. my ($nodeinstatus,$nodeoutstatus) = getnodestatus($incurrent,$outcurrent,$$rcfg{'node'}{$router}, $router, $rcfg, $cfg); 
  210. my ($nodeinlaststatus,$nodeoutlaststatus) = getnodestatus($inlast,$outlast,$$rcfg{'node'}{$router}, $router, $rcfg, $cfg); 
  211. print "NodeStatus-Old: $nodeinlaststatus($inlast)/$nodeoutlaststatus($outlast)n";
  212. print "NodeStatus-New: $nodeinstatus($incurrent)/$nodeoutstatus($outcurrent)n";
  213. #Generate events for the log and status-email
  214. my $ineventid = "";
  215. my $outeventid = "";
  216. my $ineventtype = "";
  217. my $outeventtype = "";
  218. #Cool event (in)
  219. if($nodeinstatus eq "cool" && $nodeinlaststatus eq "alarm" && defined $$rcfg{'nodeincoolmsgid'}{$router}){$ineventid = lc($$rcfg{'nodeincoolmsgid'}{$router});$ineventtype = "Cool";};
  220. #Cool event (in)
  221. if($nodeinstatus eq "warning" && $nodeinlaststatus eq "alarm" && defined $$rcfg{'nodeincoolmsgid'}{$router}){$ineventid = lc($$rcfg{'nodeincoolmsgid'}{$router});$ineventtype = "Cool";};
  222. #Warning event (in)
  223. if($nodeinstatus eq "warning" && $nodeinlaststatus eq "cool" && defined $$rcfg{'nodeinwarningmsgid'}{$router}){$ineventid = lc($$rcfg{'nodeinwarningmsgid'}{$router});$ineventtype = "Warn";};
  224. #Alarm event (in)
  225. if($nodeinstatus eq "alarm" && ($nodeinlaststatus eq "cool" || $nodeinlaststatus eq "warning") && defined $$rcfg{'nodeinalarmmsgid'}{$router}){$ineventid = lc($$rcfg{'nodeinalarmmsgid'}{$router});$ineventtype = "Alarm";};
  226. #Cool event (out)
  227. if($nodeoutstatus eq "cool" && $nodeoutlaststatus eq "alarm" && defined $$rcfg{'nodeoutcoolmsgid'}{$router}){$outeventid = lc($$rcfg{'nodeoutcoolmsgid'}{$router});$outeventtype = "Cool";};
  228. #Cool event (out)
  229. if($nodeoutstatus eq "warning" && $nodeoutlaststatus eq "alarm" && defined $$rcfg{'nodeoutcoolmsgid'}{$router}){$outeventid = lc($$rcfg{'nodeoutcoolmsgid'}{$router});$outeventtype = "Cool";};
  230. #Warning event (out)
  231. if($nodeoutstatus eq "warning" && $nodeoutlaststatus eq "cool" && defined $$rcfg{'nodeoutwarningmsgid'}{$router}){$outeventid = lc($$rcfg{'nodeoutwarningmsgid'}{$router});$outeventtype = "Warn";};
  232. #Alarm event (out)
  233. if($nodeoutstatus eq "alarm" && ($nodeoutlaststatus eq "cool" || $nodeoutlaststatus eq "warning") && defined $$rcfg{'nodeoutalarmmsgid'}{$router}){$outeventid = lc($$rcfg{'nodeoutalarmmsgid'}{$router});$outeventtype = "Cool";};
  234. #Log events (in)
  235. if($ineventid ne ""){
  236. $newevents[$neweventcounter] = $$msg{$ineventid};
  237. #Translate variables in the event message
  238. $newevents[$neweventcounter] = transeventvar($cfg, $rcfg, $routers, $router, $incurrent, $outcurrent, $newevents[$neweventcounter]);
  239. #Anybody needs to know about this?
  240. if($$rcfg{'email'}{lc($ineventtype)}{$router}){
  241. $neweventstype[$neweventcounter] = "$ineventtype/e";
  242. sendmail($cfg, $rcfg, $routers, $router, $incurrent, $outcurrent, $newevents[$neweventcounter],$neweventstype[$neweventcounter],$$rcfg{'nodestatusemailtarget'}{$router});
  243. }else{
  244. $neweventstype[$neweventcounter] = $ineventtype;
  245. }
  246. $neweventcounter++;
  247. }
  248. #Log events (out)
  249. if($outeventid ne ""){
  250. $newevents[$neweventcounter] = $$msg{$outeventid};
  251. $neweventstype[$neweventcounter] = $outeventtype;
  252. #Translate variables in the event message
  253. $newevents[$neweventcounter] = transeventvar($cfg, $rcfg, $routers, $router, $incurrent, $outcurrent, $newevents[$neweventcounter]);
  254. #Anybody needs to know about this?
  255. if($$rcfg{'email'}{lc($outeventtype)}{$router}){
  256. $neweventstype[$neweventcounter] = "$outeventtype/e";
  257. sendmail($cfg, $rcfg, $routers, $router, $incurrent, $outcurrent, $newevents[$neweventcounter],$neweventstype[$neweventcounter],$$rcfg{'nodestatusemailtarget'}{$router});
  258. }else{
  259. $neweventstype[$neweventcounter] = $outeventtype;
  260. }
  261. $neweventcounter++;
  262. }
  263. #Main action loop, the right sequencing is important because of overlappling graphics in the status map
  264. for ($actioncounter = 0; $actioncounter <= $$rcfg{maxaction}{$router}; $actioncounter++){
  265. if (exists $$rcfg{"action.$actioncounter"}{$router}) {
  266. my $action = $$rcfg{"action.$actioncounter"}{$router};
  267. my @acfunctelements = split(/(/,$action);
  268. my $acfunc = $acfunctelements[0];
  269. #Cleanup the function name
  270. $acfunc=~s/s/ /g;  
  271. $acfunc=~s/^ *//g;  
  272. $acfunc=~s/ *$//g;  
  273. $acfunc=lc($acfunc);
  274. my @acfunctelements = split(/[()]/,$action);
  275. my @acargs = split(/,/,$acfunctelements[1]);
  276. #Cleanup the functions arguments and put them in parethesis...
  277. foreach $acarg (@acargs){
  278. $acarg=~s/s/ /g;  
  279. $acarg=~s/^ *//g;  
  280. $acarg=~s/ *$//g;  
  281. $acarg=lc($acarg);
  282. $acarg=""$acarg",";
  283. }
  284. #Execute Action
  285. eval("$acfunc($ImageData, $gdstyles, $cfg, $rcfg, $routers, $router, $msg, "$nodeinstatus", "$nodeoutstatus", "$incurrent" , "$outcurrent", @acargs);");
  286. die "* Problem with action statement: $acfunc($ImageData, $gdstyles, $cfg, $rcfg, $routers, $router, $msg, "$nodeinstatus", "$nodeoutstatus", "$incurrent" , "$outcurrent", @acargs);n" if $@;
  287. }
  288. }
  289. }
  290.   #put TZ things back in shape ... 
  291.   if ($savetz) {$ENV{'TZ'} =  $savetz;} else
  292.   {delete $ENV{'TZ'}};
  293. }
  294. #If there are no events, don't do anything
  295. if ($neweventcounter > 0){
  296. #Open current log file and get the old log entries
  297. open (LOGFILE,"<$$cfg{'workdir'}\mrtg-nsi.log") || print "WARNING: Couldn't open eventlog file for reading: $$cfg{'workdir'}//mrtg-nsi.logn";
  298. my @oldeventloglines = <LOGFILE>;
  299. close LOGFILE;
  300. #Open eventlog again and add new events
  301. open (LOGFILE,">$$cfg{'workdir'}\mrtg-nsi.log") || die "ERROR: Couldn't open eventlog file for writing: $$cfg{'workdir'}//mrtg-nsi.logn";
  302. open (HTMLLOG,">$$cfg{'eventlog'}") || die "ERROR: Couldn't open eventlog file for writing: $$cfg{'eventlog'}n";
  303. #Add header to the html-log
  304. print HTMLLOG "<html>n";
  305. print HTMLLOG "n";
  306. print HTMLLOG "<head>n";
  307. print HTMLLOG "<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">n";
  308. print HTMLLOG "<meta http-equiv="Refresh" CONTENT="60">n";
  309. print HTMLLOG "<title>Home Page</title>n";
  310. print HTMLLOG "</head>n";
  311. print HTMLLOG "n";
  312. print HTMLLOG "<body topmargin="1" leftmargin="1" bordercolor="#FFFFFF" bgcolor="#FFFFFF">n";
  313. print HTMLLOG "n";
  314. print HTMLLOG "<p><strong><font face="Arial" size="5">Network Status Imager: Event Log</font><fontn";
  315. print HTMLLOG "face="Arial"><br>n";
  316. print HTMLLOG "</font></strong><font face="Arial" size="1">NSI v1.0 for MRTG, Created by Macn";
  317. print HTMLLOG "Kloberg <a href="mailto:mac.kloberg@lam.liebherr.com">&lt;mac.kloberg@lam.liebherr.com&gt;</a> <an";
  318. print HTMLLOG "href="mailto:mac@nacs.net">&lt;mac@nacs.net&gt;</a>)<br>n";
  319. print HTMLLOG "Credits to Tobias Oetiker <a href="mailto:oetiker@ee.ethz.ch">&lt;oetiker@ee.ethz.ch&gt;</a> and Dave Rand <an";
  320. print HTMLLOG "href="mailto:dlr@bungi.com">&lt;dlr@bungi.com&gt;</a>.<br>n";
  321. print HTMLLOG "Sofware distributed under the GNU copyleft.";
  322. print HTMLLOG "<br>n";
  323. print HTMLLOG "</font></p>n";
  324. print HTMLLOG "n";
  325. print HTMLLOG "<table border="1" cellpadding="0" cellspacing="0" width="575" bgcolor="#C0C0C0">n";
  326. print HTMLLOG "  <tr>n";
  327. print HTMLLOG "    <td valign="top" nowrap width="65"><strong><font size="2">Date</font></strong></td>n";
  328. print HTMLLOG "    <td valign="top" nowrap width="44"><strong><font size="2">Time</font></strong></td>n";
  329. print HTMLLOG "    <td valign="top" nowrap width="46" bgcolor="#C0C0C0" align="left"><strong><font size="2">Type</font></strong></td>n";
  330. print HTMLLOG "    <td valign="top" nowrap width="420" <font size="2"><strong> <font size="2">Event</font></strong></td>n";
  331. print HTMLLOG "  </tr>n";
  332. print HTMLLOG "</table>n";
  333. print HTMLLOG "n";
  334. print HTMLLOG "<table border="0" cellpadding="0" cellspacing="0" width="1575"> n";
  335. for ($logfileeventcounter = 0; $logfileeventcounter <= $$cfg{'eventlogmax'}; $logfileeventcounter++){
  336. #Add new events
  337. if($logfileeventcounter eq 0){
  338. for ($neweventlogcounter = 0; $neweventlogcounter < $neweventcounter; $neweventlogcounter++){
  339. my $shortdatestr = &shortdatestr(time);
  340. print LOGFILE "$shortdatestr - $neweventstype[$neweventlogcounter] - $newevents[$neweventlogcounter]n";
  341. my($htmldate,,$htmltime) = split(/ - /,$shortdatestr);
  342. print HTMLLOG "  <tr>n";
  343. print HTMLLOG "    <td valign="top" nowrap width="56"><font size="2">$htmldate</font></td>n";
  344. print HTMLLOG "    <td valign="top" nowrap width="9"><font size="2">-</font></td>n";
  345. print HTMLLOG "    <td valign="top" nowrap width="44"><font size="2">$htmltime</font></td>n";
  346. print HTMLLOG "    <td valign="top" nowrap width="46" bgcolor="#C0C0C0" align="left"><font size="2">$neweventstype[$neweventlogcounter]</font></td>n";
  347. if($neweventstype[$neweventlogcounter] =~ /cool.*/i){
  348. print HTMLLOG "    <td valign="top" nowrap width="5" bgcolor="#00FF00"><strong><font size="2"></font></strong></td>n";
  349. print HTMLLOG "    <td valign="top" nowrap width="1415" bgcolor="#00FF00"><strong><font size="2">$newevents[$neweventlogcounter]n";
  350. }
  351. if($neweventstype[$neweventlogcounter] =~ /warn.*/i){
  352. print HTMLLOG "    <td valign="top" nowrap width="5" bgcolor="#C0C0C0"><strong><font size="2"></font></strong></td>n";
  353. print HTMLLOG "    <td valign="top" nowrap width="1415" bgcolor="#C0C0C0"><strong><font size="2">$newevents[$neweventlogcounter]n";
  354. }
  355. if($neweventstype[$neweventlogcounter] =~ /alarm.*/i){
  356. print HTMLLOG "    <td valign="top" nowrap width="5" bgcolor="#FF0000"><strong><font size="2"></font></strong></td>n";
  357. print HTMLLOG "    <td valign="top" nowrap width="1415" bgcolor="#FF0000"><strong><font size="2">$newevents[$neweventlogcounter]n";
  358. }
  359. print HTMLLOG "    </font></strong></td>n";
  360. print HTMLLOG "  </tr>n";
  361. }
  362. }
  363. #Add old events
  364. if($logfileeventcounter > 0 && $oldeventloglines[$logfileeventcounter-1] ne ""){
  365. print LOGFILE "$oldeventloglines[$logfileeventcounter-1]";
  366. #print "Writing oldevent ($logfileeventcounter): $oldeventloglines[$logfileeventcounter-1]<br>";
  367. my($htmldate,$htmltime,$htmleventtype,$htmlevent) = split(/ - /,$oldeventloglines[$logfileeventcounter-1]);
  368. print HTMLLOG "  <tr>n";
  369. print HTMLLOG "    <td valign="top" nowrap width="56"><font size="2">$htmldate</font></td>n";
  370. print HTMLLOG "    <td valign="top" nowrap width="9"><font size="2">-</font></td>n";
  371. print HTMLLOG "    <td valign="top" nowrap width="44"><font size="2">$htmltime</font></td>n";
  372. print HTMLLOG "    <td valign="top" nowrap width="46" bgcolor="#C0C0C0" align="left"><font size="2">$htmleventtype</font></td>n";
  373. if($htmleventtype =~ /cool.*/i){
  374. print HTMLLOG "    <td valign="top" nowrap width="5" bgcolor="#00FF00"><strong><font size="2"></font></strong></td>n";
  375. print HTMLLOG "    <td valign="top" nowrap width="1415" bgcolor="#00FF00"><strong><font size="2">$htmleventn";
  376. }
  377. if($htmleventtype =~ /warn.*/i){
  378. print HTMLLOG "    <td valign="top" nowrap width="5" bgcolor="#C0C0C0"><strong><font size="2"></font></strong></td>n";
  379. print HTMLLOG "    <td valign="top" nowrap width="1415" bgcolor="#C0C0C0"><strong><font size="2">$htmleventn";
  380. }
  381. if($htmleventtype =~ /alarm.*/i){
  382. print HTMLLOG "    <td valign="top" nowrap width="5" bgcolor="#FF0000"><strong><font size="2"></font></strong></td>n";
  383. print HTMLLOG "    <td valign="top" nowrap width="1415" bgcolor="#FF0000"><strong><font size="2">$htmleventn";
  384. }
  385. print HTMLLOG "    </font></strong></td>n";
  386. print HTMLLOG "  </tr>n";
  387. }
  388. }
  389. print HTMLLOG "</table>n";
  390. print HTMLLOG "</body>n";
  391. print HTMLLOG "</html>n";
  392. close HTMLLOG;
  393. close LOGFILE;
  394. }
  395. #Finally, timestamp the image
  396.    my($ImgSizeX,$ImgSizeY) = $ImageData->getBounds;
  397. $Today=&datestr(time);
  398. my $stampstring = "Network Status Imager for MRTG - $Today";
  399. my $stringwidth = GD::Font::width(gdSmallFont) * length($stampstring);
  400. $ImageData->string(gdSmallFont,$ImgSizeX - $stringwidth - 3,$ImgSizeY - 13,"$stampstring",$colors{'black'});
  401. #Write the whole thing to the status map
  402. open (STATUSMAP,">$$cfg{'workdir'}\\$$cfg{statusmapimagename}") || die "ERROR: Couldn't write to status map image $$cfg{'workdir'}\\$$cfg{statusmapimagename}";
  403. binmode STATUSMAP;
  404. print STATUSMAP $ImageData->gif;
  405. close STATUSMAP;
  406. # OK we are done, remove the lock files ... 
  407. print "Removing Lockfilesn";
  408. close LOCK; unlink ($templock, $lockfile);
  409. print "nMRTG - Network Status Imager unloading, gone and done...nn" if $main::DEBUG;
  410. }
  411. main;
  412. exit(0);
  413. sub readcfg {
  414. my ($first,$second,$key);
  415. my (%seen);
  416. my (@routers);
  417. my (%rcfg,%cfg,%pre,%post,%deflt,%defaulted);
  418. my ($cfgfile) = pop(@ARGV);
  419. open (CFG, $cfgfile) || do { print "ERROR: unable to open config file: $cfgfilenn"; &printusage };
  420. while (<CFG>) {
  421.   s/s+$//g; #remove whitespace at the end of the line
  422.   s/s/ /g;  #replace whitespace by space
  423.   next if /^s*#/; #ignore comment lines
  424.   next if /^s*$/;  #ignore empty lines
  425.   # oops spelling error
  426.   s/^supress/suppress/gi;
  427.   #Trashcan leading zeros in action statements
  428.   s/^action.0+/action./gi;
  429.   
  430.      #Also lets record the number of the highest action given for later
  431.   if ($first =~ /^action.+/){
  432. $actionnumber = $first;
  433. $actionnumber =~ s/action.//gi;
  434. if($actionnumber > $rcfg{'maxaction'}{$second}){
  435. $rcfg{'maxaction'}{$second} = $actionnumber;
  436. }
  437.   }
  438.   # append mode
  439.   if ($first && /^s+(.*S)s*$/) {
  440.     if ($second eq '^') {
  441. $pre{$first} .= " $1";
  442. next;
  443.     }
  444.     if ($second eq '$' ) {
  445. $post{$first} .= " $1";
  446. next;
  447.     }
  448.     if ($second eq '_') {
  449. $deflt{$first} .= " $1";
  450. next;
  451.     }
  452.     if ($second) {
  453. $rcfg{$first}{$second} .= " $1";
  454.     } else {
  455. $cfg{$first} .= " $1";
  456.     }
  457.     next;
  458.   }
  459.   
  460.   if ($first && $second && $post{$first} && ($second !~ /^[$^_]$/)) {
  461.     if ($defaulted{$first}{$second}) {
  462.       $rcfg{$first}{$second} = $post{$first};
  463.       delete $defaulted{$first}{$second};
  464.     } else {
  465.       $rcfg{$first}{$second} .= " $post{$first}"
  466.     }
  467.   }
  468.   if ($first && exists $deflt{$first} && ($second eq '_')) {
  469.     &quickcheck($first,$second,$deflt{$first},$.)
  470.   } elsif ($first && $second && ($second !~ /^[$^_]$/)) {
  471.     &quickcheck($first,$second,$rcfg{$first}{$second},$.)
  472.   } elsif ($first && ($second !~ /^[$^_]$/)) {
  473.     &quickcheck($first,0,$cfg{$first},$.)
  474.   }
  475.   if (/^([A-Za-z0-9.]+)[(S+)]s*:s*(.*S?)s*$/) {
  476.     print "readcfg: rcfg $1 $2  = $3n" if $main::DEBUG > 1; 
  477.     
  478.     $first = lc($1);
  479.     $second = lc($2);
  480.     if ($second eq '^')
  481.       { if ($3 ne '') {$pre{$first}=$3} else {delete $pre{$first}}; next; }
  482.     if ($second eq '$')
  483.       { if ($3 ne '') {$post{$first}=$3} else {delete $post{$first}}; next; }
  484.     if ($second eq '_')
  485.       { if ($3 ne '') {$deflt{$first}=$3} else {delete $deflt{$first}}; next; }
  486.     push (@routers, $second) unless grep (/^$second$/, @routers); 
  487.     
  488.     # make sure that default tags spring into existance upon first 
  489.     # call of a router
  490.     foreach $key (keys %deflt) {
  491. if (! exists $rcfg{$key}{$second}) {
  492.   $rcfg{$key}{$second} = $deflt{$key};
  493.   $defaulted{$key}{$second} = 1;
  494. }
  495.     }
  496.     # make sure that prefix-only tags spring into existance upon first 
  497.     # call of a router
  498.     foreach $key (keys %pre) {
  499. if (! exists $rcfg{$key}{$second}) {
  500.         delete $defaulted{$key}{$second} if $defaulted{$key}{$second};
  501.   $rcfg{$key}{$second} = "$pre{$key} ";
  502. }
  503.     }
  504.     if ($seen{$first}{$second}) {
  505. die ("nLine $. in CFG file contains a duplicate definition forn".
  506.      "$first[$second]. First definition is on line $seen{$first}{$second}n")
  507.     } else {
  508. $seen{$first}{$second} = $.;
  509.     }
  510.     if ($defaulted{$first}{$second}) {
  511.       $rcfg{$first}{$second} = '';
  512.       delete $defaulted{$first}{$second};
  513.     }
  514.     $rcfg{$first}{$second} .= $3;
  515.     next;
  516.   }
  517.   if (/^(S+):s*(.*S)s*$/) {
  518.     $first = lc($1);
  519.     $cfg{$first} = $2;
  520.     $second = '';
  521.     next;
  522.   }
  523.   die ( "nLine $. in CFG file does not make sensen" );
  524. }
  525. # append $ stuff to the very last tag in cfg file if necessary 
  526. if ($first && $second && $post{$first} && ($second !~ /^[$^_]$/)) {
  527.   if ($defaulted{$first}{$second}) {
  528.     $rcfg{$first}{$second} = $post{$first};
  529.     delete $defaulted{$first}{$second};
  530.   } else {
  531.     $rcfg{$first}{$second} .= " $post{$first}"
  532.   }
  533. }
  534. #Tobi, I don't know how you did this, but this is something else:
  535.    #Get highest action number for the last line in the config file...
  536.    if ($first =~ /^action.+/){
  537. $actionnumber = $first;
  538. $actionnumber =~ s/action.//gi;
  539. if($actionnumber > $rcfg{'maxaction'}{$second}){
  540. $rcfg{'maxaction'}{$second} = $actionnumber;
  541. }
  542.    }
  543. #check the last input line
  544.   if ($first && exists $deflt{$first} && ($second eq '_')) {
  545.   &quickcheck($first,$second,$deflt{$first},$.)
  546. } elsif ($first && $second) {
  547.   &quickcheck($first,$second,$rcfg{$first}{$second},$.)
  548. } elsif ($first) {
  549.   &quickcheck($first,0,$cfg{$first},$.)
  550. }
  551. close (CFG);
  552. (@routers, %cfg, %rcfg, $cfgfile);
  553. }
  554. sub cfgcheck {
  555. my ($routers, $cfg, $rcfg) = @_;
  556. my ($rou, $confname, $one_option);
  557. my %node;
  558. my $error="no";
  559. my(@known_options) = qw(alarmifnull);
  560. if (! $$cfg{workdir}) {
  561.     warn ("nERROR: "WorkDir" not specifiedn");
  562.     $error = "yes";
  563. }
  564. foreach $rou (@$routers) {
  565. if ($$rcfg{'directory'}{$rou})
  566. {
  567. # They specified a directory for this router.  Append the
  568. # pathname seperator to it (so that it can either be present or
  569. # absent, and the rules for including it are the same).
  570. $$rcfg{'directory'}{$rou} .= ${main::SL};
  571. # remove any stray spaces ...
  572. $$rcfg{'directory'}{$rou} =~ s/s//g;
  573. }
  574. # Configure e-mail notification for this node
  575. if (defined($$rcfg{'nodestatusemail'}{$rou})){
  576. if($$rcfg{'nodestatusemailtarget'}{$rou} ne ""){
  577. if($$rcfg{'nodestatusemail'}{$rou} =~ /[^cwa *]/i ){
  578. warn ("nERROR: NodeStatusEmail[$rou]: "$$rcfg{'nodestatusemail'}{$rou}" contains invalid options [cwa].n");
  579.       $error="yes";
  580. }else{
  581. if($$rcfg{'nodestatusemail'}{$rou} =~ /c/i ){
  582. $$rcfg{'email'}{'cool'}{$rou} = 1;
  583. }
  584. if($$rcfg{'nodestatusemail'}{$rou} =~ /w/i ){
  585. $$rcfg{'email'}{'warn'}{$rou} = 1;
  586. }
  587. if($$rcfg{'nodestatusemail'}{$rou} =~ /a/i ){
  588. $$rcfg{'email'}{'alarm'}{$rou} = 1;
  589. }
  590. }
  591. }else{
  592.   warn ("nERROR: NodeStatusEmail[$rou]: "$$rcfg{'nodestatusemail'}{$rou}" is given but no NodeStatusEmailTarget[$rou] was found.n");
  593.      $error="yes";
  594. }
  595. }
  596.    if (exists $$rcfg{"options"}{$rou}) {
  597.     foreach $one_option (split /[,s]+/, lc($$rcfg{"options"}{$rou})) {
  598. if (grep {$one_option eq $_} @known_options) {
  599.   $$rcfg{'options'}{$one_option}{$rou} = 1;
  600. } else {
  601.   warn ("nERROR: Option[$rou]: "$one_option" is unknownn");
  602.   $error="yes";
  603. }
  604.     }
  605.   }
  606.   if ($error eq "yes") {
  607.     die ("nnABORT: Please fix the error(s) in your config filenn");
  608.   }
  609. }
  610. %node;
  611. }
  612. sub quickcheck {
  613. my ($first,$second,$arg,$line) = @_;
  614. my %rules =
  615.   (# General CFG
  616.    'workdir' => 
  617.    ['$arg && (-d $arg)','"Directory $arg does not exist"'],
  618.    'eventlog' => 
  619.    ['$arg','"Eventlog path is missing"'],
  620.    'eventlogmax' => 
  621.    ['$arg =~ /d+/','"You must specify a value"'],
  622.    'icondir' => 
  623.    ['$arg && (-d $arg)','"Directory $arg does not exist"'],
  624.    'statusmapbackground' => 
  625.    ['$arg && (-f $arg)','"Image file $arg does not exist"'],
  626.    
  627.    'statusmapimagename' => 
  628.    ['$arg','"Target image name is missing"'],
  629.    'imgsourcedir' => 
  630.    ['$arg && (-d $arg)','"Directory $arg does not exist"'],
  631.    'msgfile' => 
  632.    ['$arg && (-f $arg)','"Message file $arg does not exist"'],
  633.    'statusemailorigin' => 
  634.    ['$arg =~ /w+/','"You must specify something for this option"'],
  635.    'refresh' => 
  636.    ['int($arg) >= 300', '"$arg should be 300 seconds or more"'],
  637.    
  638.    'interval' => 
  639.    ['int($arg) >= 5','"$arg should be more than 5 Minutes"'], 
  640.    'testnodelocations' => 
  641.    ['$arg =~ /[ynYN]/','"This option is either y or n"'],
  642.   #Nodes CFG
  643.    'node[]' => 
  644.    ['$arg =~ /w+/','"You must specify something for this option"'],
  645.    'nodecenterx[]' => 
  646.    ['int($arg) >= 0', '"$arg <-- Value cannot be negative"'],
  647.    'nodecentery[]' => 
  648.    ['int($arg) >= 0', '"$arg <-- Value cannot be negative"'],
  649.    'nodealarmthreshhold[]' => 
  650.    ['$arg =~ /d+/','"You must specify a value"'],
  651.    'nodewarningthreshhold[]' => 
  652.    ['$arg =~ /d+/','"You must specify a value"'],
  653.    'nodeincoolmsgid[]' => 
  654.    ['$arg =~ /w+/','"You must specify something for this option"'],
  655.    'nodeinwarningmsgid[]' => 
  656.    ['$arg =~ /w+/','"You must specify something for this option"'],
  657.    'nodeinalarmmsgid[]' => 
  658.    ['$arg =~ /w+/','"You must specify something for this option"'],
  659.    'nodeoutcoolmsgid[]' => 
  660.    ['$arg =~ /w+/','"You must specify something for this option"'],
  661.    'nodeoutwarningmsgid[]' => 
  662.    ['$arg =~ /w+/','"You must specify something for this option"'],
  663.    'nodeoutalarmmsgid[]' => 
  664.    ['$arg =~ /w+/','"You must specify something for this option"'],
  665.    'nodestatusemail[]' => 
  666.    ['$arg =~ /w+/','"You must specify something for this option"'],
  667.    'nodestatusemailtarget[]' => 
  668.    ['$arg =~ /w+/','"You must specify something for this option"'],
  669.       'options[]' =>
  670.       ['1','"Internal Error"'],
  671.    'action[]' => 
  672.    ['$arg =~ /w+/','"You must specify something for this option"'],
  673.   );
  674.  
  675. my $braces = $second ? '[]':'';
  676. #The actions are different from the other options
  677. if ($first =~ /^action.+/){
  678. if ($first =~ /action.d*/) {
  679.   return 1;
  680. }
  681. }elsif (exists $rules{$first.$braces}) {
  682.   if (eval($rules{$first.$braces}[0])) {
  683.     return 1;
  684.   } else {
  685.     if ($second) {
  686. die "nCFG Error in "$first[$second]", line $line: ".
  687.   eval($rules{$first.$braces}[1])."nn"; 
  688.     } else {
  689. die "nCFG Error in "$first", line $line: ".
  690.   eval($rules{$first.$braces}[1])."nn"; 
  691.     } 
  692.   }
  693. }
  694. die "nCFG Error: Unknown Option "$first" on line $line or above.n".
  695.   "           Check readme.html for Helpnn";
  696. }
  697. sub readmsgfile {
  698. my ($msgfile) = @_;
  699. my ($first,$second,$key);
  700. my (%seen);
  701. my (%rmsg,%msg,%pre,%post);
  702. open (MSGFILE, $msgfile) || do { print "ERROR: unable to open message file: $msgfilenn"};
  703. while (<MSGFILE>) {
  704.   s/s+$//g; #remove whitespace at the end of the line
  705.   s/s/ /g;  #replace whitespace by space
  706.   next if /^s*#/; #ignore comment lines
  707.   next if /^s*$/;  #ignore empty lines
  708.   # append mode
  709.   if ($first && /^s+(.*S)s*$/) {
  710.     if ($second eq '^') {
  711. $pre{$first} .= " $1";
  712. next;
  713.     }
  714.     if ($second eq '$' ) {
  715. $post{$first} .= " $1";
  716. next;
  717.     }
  718.     if ($second) {
  719. $rmsg{$first}{$second} .= " $1";
  720.     } else {
  721. $msg{$first} .= " $1";
  722.     }
  723.     next;
  724.   }
  725.   if (/^(S+):s*(.*S)s*$/) {
  726.     $first = lc($1);
  727.     $msg{$first} = $2;
  728.     $second = '';
  729.     next;
  730.   }
  731.   die ( "nLine $. in MSGFILE file does not make sensen" );
  732. }
  733. close (MSGFILE);
  734. (%msg);
  735. }
  736. sub action_draw_crosshair {
  737. #This one draws a crosshair symbol
  738. my($ImageData, $cfg, $rcfg, $routers, $router, $cox, $coy,$color) = @_;
  739. $cox = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, $cox);
  740. $cox = $cox + nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, $$rcfg{'nodelabeloffsetx'}{$router});
  741. $coy = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, $coy);
  742. $coy = $coy + nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, $$rcfg{'nodelabeloffsety'}{$router});
  743. #Draw the crosshair...
  744.    $ImageData->arc($cox,$coy,30,30,0,360,$color);
  745.    $ImageData->arc($cox,$coy,20,20,0,360,$color);
  746. $ImageData->arc($cox,$coy,10,10,0,360,$color);
  747. $ImageData->line($cox-17,$coy,$cox+17,$coy,$color);
  748. $ImageData->line($cox,$coy-17,$cox,$coy+17,$color);
  749. }
  750. sub datestr {
  751.   my ($time) = shift(@_) || return 0;
  752.   my ($wday) = ('Sunday','Monday','Tuesday','Wednesday',
  753. 'Thursday','Friday','Saturday')[(localtime($time))[6]];
  754.   my ($month) = ('January','February' ,'March' ,'April' ,
  755.  'May' , 'June' , 'July' , 'August' , 'September' , 
  756.  'October' ,
  757.  'November' , 'December' )[(localtime($time))[4]];
  758.   my ($mday,$year,$hour,$min,$sec) = (localtime($time))[3,5,2,1,0];
  759.   if ($min<10) {$min = "0$min";}
  760.   if ($sec<10) {$sec = "0$sec";}
  761.   return "$wday, $month $mday, ".($year+1900)." - $hour:$min:$sec";
  762. }
  763. sub shortdatestr {
  764.   my ($time) = shift(@_) || return 0;
  765.   my ($mday,$month,$year,$hour,$min,$sec) = (localtime($time))[3,4,5,2,1,0];
  766.   $month++;
  767.   if ($min<10) {$min = "0$min";}
  768.   if ($sec<10) {$sec = "0$sec";}
  769.   return "$month/$mday/".($year+1900)." - $hour:$min:$sec";
  770. }
  771. sub nsi_eval {
  772. #Replace references to other nodes and evaluate expressions
  773.    my($ImageData, $cfg, $rcfg, $routers, $router, $evali) = @_;
  774. #Replace .xy-references to other nodes
  775. foreach $eval_node (@$routers) {
  776. my $lceval_node = lc($eval_node);
  777. #Replace "node.x"
  778. $evali =~ s/[W]$lceval_node.x/$$rcfg{'nodecenterx'}{$eval_node}/gie;
  779. $evali =~ s/^$lceval_node.x/$$rcfg{'nodecenterx'}{$eval_node}/gie;
  780. #Replace "node.y"
  781. $evali =~ s/[W]$lceval_node.y/$$rcfg{'nodecentery'}{$eval_node}/gie;
  782. $evali =~ s/^$lceval_node.y/$$rcfg{'nodecentery'}{$eval_node}/gie;
  783. }
  784. #If something else expanded from the nodecenter, evaluate that too...
  785. $evali = lc($evali);
  786. foreach $eval_node (@$routers) {
  787. my $lceval_node = lc($eval_node);
  788. #Replace "node.x"
  789. $evali =~ s/[W]$lceval_node.x/$$rcfg{'nodecenterx'}{$eval_node}/gie;
  790. $evali =~ s/^$lceval_node.x/$$rcfg{'nodecenterx'}{$eval_node}/gie;
  791. #Replace "node.y"
  792. $evali =~ s/[W]$lceval_node.y/$$rcfg{'nodecentery'}{$eval_node}/gie;
  793. $evali =~ s/^$lceval_node.y/$$rcfg{'nodecentery'}{$eval_node}/gie;
  794. }
  795. #Evaluate and format the expression
  796. $evali = sprintf("%.0f",eval($evali));
  797. return $evali;
  798. }
  799. sub getnodevalues {
  800. my ($target, $rou, $rcfg, $cfg) = @_;
  801.    my $period = 0;
  802. my $lastperiod = 0;
  803. my $incurrent=0;
  804.    my $outcurrent=0;
  805. my $inlast = 0;
  806. my $outlast = 0;
  807. open (LOG, "<$$cfg{'workdir'}\\$target.log") or die "ERROR: Can't open .log file for this node: $targetn";
  808. my($counterline,$line,$lastline) = <LOG>;
  809. ($period,$incurrent,$outcurrent)=split(/D/,$line);
  810. ($lastperiod,$inlast,$outlast)=split(/D/,$lastline);
  811. close LOG;
  812. #Check the period (if we're too far out, we've probably lost contact with the node)
  813.    $time = time unless defined $time;
  814. my($timediff)=$time - $period;
  815. #Give it 2 more minutes, then report the node as down
  816. if($timediff > $$cfg{'interval'} * 60 + 120){
  817. $incurrent = -1;
  818. $outcurrent = -1;
  819. }
  820.    ($incurrent, $outcurrent, $inlast, $outlast);
  821. }
  822. sub getnodestatus{
  823. my ($incurrent,$outcurrent,$target, $router, $rcfg, $cfg) = @_;
  824. my $nodeinstatus = "cool";
  825. my $nodeoutstatus = "cool";
  826. #Node down?
  827. if($incurrent eq -1){
  828. $nodeinstatus = "alarm";
  829. $nodeoutstatus = "alarm";
  830. }else{
  831. #Which direction are we looking?
  832. if($$rcfg{'nodealarmthreshhold'}{$router} >= $$rcfg{'nodewarningthreshhold'}{$router}){
  833. #Straight forward
  834. if($incurrent > $$rcfg{'nodewarningthreshhold'}{$router}){
  835. $nodeinstatus = "warning";
  836. }
  837. if($outcurrent > $$rcfg{'nodewarningthreshhold'}{$router}){
  838. $nodeoutstatus = "warning";
  839. }
  840. if($incurrent > $$rcfg{'nodealarmthreshhold'}{$router}){
  841. $nodeinstatus = "alarm";
  842. }
  843. if($outcurrent > $$rcfg{'nodealarmthreshhold'}{$router}){
  844. $nodeoutstatus = "alarm";
  845. }
  846. }else{
  847. #Backwards
  848. if($incurrent < $$rcfg{'nodewarningthreshhold'}{$router}){
  849. $nodeinstatus = "warning";
  850. }
  851. if($outcurrent < $$rcfg{'nodewarningthreshhold'}{$router}){
  852. $nodeoutstatus = "warning";
  853. }
  854. if($incurrent < $$rcfg{'nodealarmthreshhold'}{$router}){
  855. $nodeinstatus = "alarm";
  856. }
  857. if($outcurrent < $$rcfg{'nodealarmthreshhold'}{$router}){
  858. $nodeoutstatus = "alarm";
  859. }
  860. }
  861. }
  862. #Check for nulls
  863. if($$rcfg{'options'}{'alarmifnull'}{$router}){
  864. if($incurrent eq "0"){
  865. $nodeinstatus = "alarm";
  866. }
  867. if($outcurrent eq "0"){
  868. $nodeoutstatus = "alarm";
  869. }
  870. }
  871. ($nodeinstatus,$nodeoutstatus);
  872. }
  873. sub drawnodeline{
  874. my ($ImageData, $gdstyles, $cfg, $rcfg, $routers, $router, $msg, $nodeinstatus, $nodeoutstatus, $incurrent, $outcurrent, $direction, $cond, $source, $destination, $style) = @_;
  875. #Expand our numeric arguments
  876. my $sourcex = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$source.x");
  877. my $sourcey = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$source.y");
  878. my $destinationx = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$destination.x");
  879. my $destinationy = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$destination.y");
  880. my $absnodestatus = "$direction$cond";
  881. my $absnodeinstatus = "in$nodeinstatus";
  882. my $absnodeoutstatus = "out$nodeoutstatus";
  883. #Draw something depending on the node's status
  884. if ($absnodestatus eq $absnodeinstatus || $absnodestatus =~ /always/i){
  885. $ImageData->setStyle(split(/,/,$$gdstyles{$style}{'style'}));
  886. #$ImageData->setStyle($$gdstyles{$style}{'style'});
  887. $ImageData->line($sourcex,$sourcey,$destinationx,$destinationy,gdStyled);
  888. }
  889. }
  890. sub copyimage{
  891. my ($ImageData, $gdstyles, $cfg, $rcfg, $routers, $router, $msg, $nodeinstatus, $nodeoutstatus, $incurrent, $outcurrent, $direction, $cond, $image, $coordx, $coordy) = @_;
  892. #Expand our numeric arguments
  893. my $coordx = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$coordx");
  894. my $coordy = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$coordy");
  895. my $absnodestatus = "$direction$cond";
  896. my $absnodeinstatus = "in$nodeinstatus";
  897. my $absnodeoutstatus = "out$nodeoutstatus";
  898. #Draw something depending on the node's status
  899. if ($absnodestatus eq $absnodeinstatus || $absnodestatus =~ /always/i){
  900. open (SRCIMG,"<$$cfg{'icondir'}\\$image") || die "ERROR: Can't open source image for copy: $$cfg{'icondir'}\\$imagen";
  901.     my($srcImageData) = newFromGif GD::Image(SRCIMG) || die "ERROR: GD::newFromGifn";
  902.     close SRCIMG;
  903.     my($srcImgDataSizeX,$srcImgDataSizeY) = $srcImageData->getBounds;
  904. $ImageData->copy($srcImageData,$coordx,$coordy,0,0,$srcImgDataSizeX,$srcImgDataSizeY);
  905. }
  906. }
  907. sub multicopyimage{
  908. my ($ImageData, $gdstyles, $cfg, $rcfg, $routers, $router, $msg, $nodeinstatus, $nodeoutstatus, $incurrent, $outcurrent, $direction, $cond, $image, $coordx, $coordy, $howoften, $minoften, $maxoften, $stepsize, $angle) = @_;
  909. #Expand our numeric arguments
  910. print "Coordinates: $coordx/$coordyn";
  911. my $coordx = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$coordx");
  912. my $coordy = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$coordy");
  913. my $howoften = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$howoften");
  914. print "Coordinates: $coordx/$coordyn";
  915. if ($howoften < $minoften){
  916. $howoften = $minoften;
  917. }
  918. if ($howoften > $maxoften){
  919. $howoften = $maxoften;
  920. }
  921. my $absnodestatus = "$direction$cond";
  922. my $absnodeinstatus = "in$nodeinstatus";
  923. my $absnodeoutstatus = "out$nodeoutstatus";
  924. #Draw something depending on the node's status
  925. if ($absnodestatus eq $absnodeinstatus || $absnodestatus =~ /always/i){
  926. open (SRCIMG,"<$$cfg{'icondir'}\\$image") || die "ERROR: Can't open source image for copy: $$cfg{'icondir'}\\$imagen";
  927.     my($srcImageData) = newFromGif GD::Image(SRCIMG) || die "ERROR: GD::newFromGifn";
  928.     close SRCIMG;
  929. my($srcImgDataSizeX,$srcImgDataSizeY) = $srcImageData->getBounds;
  930. my $rad = ($angle * 3.141592654) / 180;
  931. if ($stepsize >= 0){
  932. for($multicounter = 0; $multicounter < $howoften; $multicounter++){
  933.    my $hyp = $multicounter * $stepsize;
  934. my $a = sprintf("%.0f",sin($rad) * $hyp);
  935. my $b = sprintf("%.0f",cos($rad) * $hyp);
  936. #print "Angle: $angle, Rad: $rad, a: $a, b: $bn";
  937. $ImageData->copy($srcImageData,$coordx + $b,$coordy - $a,0,0,$srcImgDataSizeX,$srcImgDataSizeY);
  938. }
  939. }else{
  940. $stepsize = abs($stepsize);
  941. for($multicounter = $howoften - 1; $multicounter >= 0; $multicounter--){
  942.    my $hyp = $multicounter * $stepsize;
  943. my $a = sprintf("%.0f",sin($rad) * $hyp);
  944. my $b = sprintf("%.0f",cos($rad) * $hyp);
  945. #print "Angle: $angle, Rad: $rad, a: $a, b: $bn";
  946. $ImageData->copy($srcImageData,$coordx + $b,$coordy - $a,0,0,$srcImgDataSizeX,$srcImgDataSizeY);
  947. }
  948. }
  949. }
  950. }
  951. sub drawtext{
  952. my ($ImageData, $gdstyles, $cfg, $rcfg, $routers, $router, $msg, $nodeinstatus, $nodeoutstatus, $incurrent, $outcurrent, $direction, $cond, $font, $coordx, $coordy, $textid, $color) = @_;
  953. #Expand our numeric arguments
  954. my $coordx = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$coordx");
  955. my $coordy = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$coordy");
  956. my $absnodestatus = "$direction$cond";
  957. my $absnodeinstatus = "in$nodeinstatus";
  958. my $absnodeoutstatus = "out$nodeoutstatus";
  959. #Draw something depending on the node's status
  960. if ($absnodestatus eq $absnodeinstatus || $absnodestatus =~ /always/i){
  961. if(!defined($$msg{$textid})){
  962. $$msg{$textid} = "MSG not defined!";
  963. }
  964. if($font eq 1){$ImageData->string(gdTinyFont,$coordx,$coordy,$$msg{$textid},$colors{$color});}
  965. if($font eq 2){$ImageData->string(gdSmallFont,$coordx,$coordy,$$msg{$textid},$colors{$color});}
  966. if($font eq 3){$ImageData->string(gdMediumBoldFont,$coordx,$coordy,$$msg{$textid},$colors{$color});}
  967. if($font eq 4){$ImageData->string(gdLargeFont,$coordx,$coordy,$$msg{$textid},$colors{$color});}
  968. }
  969. }
  970. sub transeventvar{
  971. my ($cfg, $rcfg, $routers, $router, $incurrent, $outcurrent, $transstring) = @_;
  972. my @transsplit = split(/$/,$transstring);
  973. my $maxelements = $transsplit;
  974. print "MAXELEMNTS: $transstringn";
  975. for ($transcounter = 0; $transcounter <= $maxelements; $transcounter++){
  976. $transstring =~ s/$NodeWarningThreshhold/$$rcfg{nodewarningthreshhold}{$router}/i;
  977. $transstring =~ s/$NodeAlarmThreshhold/$$rcfg{nodealarmthreshhold}{$router}/i;
  978. $transstring =~ s/$NodeIn/$incurrent/i;
  979. $transstring =~ s/$NodeOut/$outcurrent/i;
  980. }
  981. return $transstring;
  982. }
  983. sub sendmail{
  984. my ($cfg, $rcfg, $routers, $router, $incurrent, $outcurrent, $event, $eventtype, $address) = @_;
  985. print "Sending e-mail to: $address from $$cfg{'statusemailorigin'}n";
  986. my $smtp = Net::SMTP->new('hampton.lam.liebherr.com'); # connect to an SMTP server
  987. foreach $target (split(/;/,$address)){
  988.    $smtp->mail( $$cfg{'statusemailorigin'} );     # use the sender's address here
  989.    $smtp->to($target);         # recipient's address
  990.    $smtp->data();                      # Start the mail
  991.    # Send the header.
  992.    $smtp->datasend("To: $addressn");
  993.    $smtp->datasend("From: $$cfg{'statusemailorigin'}n");
  994. $smtp->datasend("Subject: $eventtype on Node "$router"n");
  995.    $smtp->datasend("n");
  996.     # Send the body.
  997.    $smtp->datasend("$eventn");
  998. $smtp->datasend("n");
  999. $smtp->datasend("n");
  1000. $smtp->datasend("*******************************************************n");
  1001. $smtp->datasend("***   This was an automated network status update   ***n");
  1002. $smtp->datasend("***             message generated by:               ***n");
  1003. $smtp->datasend("***    NSI v1.0 for MRTG, Created by Mac Kloberg    ***n");
  1004. $smtp->datasend("***  <mac.kloberg@lam.liebherr.com> <mac@nacs.net>  ***n");
  1005. $smtp->datasend("*******************************************************n");
  1006.    $smtp->dataend();                   # Finish sending the mail
  1007. }
  1008. $smtp->quit;                        # Close the SMTP connection
  1009. }