#!/usr/bin/perl
#
# IOG v1.03 - Input/Output Grapher
# Copyright (c) 2000-2003 James Dogopoulos <jd@dynw.com>
#
# Please read the "Artistic" license included.
#
# E-mail iog@dynw.com with any bug reports,
# fixes or comments.
#

BEGIN{
if ($ARGV[0] eq "NT") { $main::OS = 'NT'; } else { $main::OS = 'UNIX'; }

$main::SL = { UNIX=>'/', NT=>'\\' }->{$main::OS};
$main::PS = { UNIX=>':', NT=>';' }->{$main::OS};

$main::binpath ="";                                          
  if ($0 =~ /^(.+\Q${main::SL}\E)/) { $main::binpath="$1";
  }
  else {
    foreach $pathname ( split ${main::PS}, $ENV{'PATH'}) {
      if ((($main::OS eq 'NT') && (-e "$pathname${main::SL}$0")) ||
           (-x "$pathname${main::SL}$0")) {
        $main::binpath=$pathname;
        last;
      }
    }
  }
unshift (@INC,$main::binpath);
}

use SDBM_File;                
use BER;
use SNMP_Session;
use Fcntl;
                              
my($inoid,$outoid,$host,$community,$snmpget,$datafile,$cfgfile,%inf);
my($inoctets,$outoctets,$path,$iogver,$hostreset,$kbsize,$mbsize,$gbsize);

$BER::pretty_print_timeticks="0";
$cfgfile="$main::binpath"."iog.cfg";
$iogver="v1.03";

# Default Byte Sizes

$kbsize="1024";
$mbsize="1048576";
$gbsize="1024";

# Date/Time stuff
#

my @weekdays = qw(Sunday Monday Tuesday Wednesday Thursday Friday Saturday);

my @months = qw(January February March April May June July August September
October November December);

my %days = (1 => "1st", 2 => "2nd", 3 => "3rd", 21 => "21st", 22 => "22nd",
23 => "23rd", 31 => "31st");

my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$lday = $mday - 1;

sub last_mday {
my ($month, $year) = @_;
( qw(31 0 31 30 31 30 31 31 30 31 30 31) )[$month] ||
28 + (($year % 100 && !($year % 4))|| !($year % 400));
}

if ($days{$mday}) { $pday = $days{$mday}; $nday = $days{$lday}; }
else { $pday = $mday."th"; $nday = $lday."th"; }

# Read config file.
#

open(CONFIG,$cfgfile) || die("Cannot open $cfgfile!");

   while (<CONFIG>) {
   s/\s+$//g; # remove whitespace at the end of the line
   s/\s/ /g;  # replace whitespace by space                    
   next if /^\s*\#/; # ignore comment lines
   next if /^\s*$/;  # ignore empty lines
   if ($_ =~ /\[.*.\]/) { chkuptime($_); next; }
   my($name,$host,$community,$inoid,$outoid,$path) = split(/:/, $_);
   $path =~ s/\n//;
   $datafile = "$name".".dat";
   my @results = snmpget($host,$community,$inoid,$outoid);
   next if ($results[0] eq "error");
   $inoctets = $results[0];
   $outoctets = $results[1];
   main($name,$host,$community,$inoid,$outoid,$path,$datafile);
   }

close(CONFIG);


# SNMP Get routine. Thanks to Simon Leinen for the SNMP module.
# http://www.switch.ch/misc/leinen/snmp/perl/
#

sub snmpget {
   my($host, $community, $inoid, $outoid) = @_;
   my($response, $bindings, $binding, $value, $oid, $session, @results);

   my %oidnames = qw(ifInOctets      1.3.6.1.2.1.2.2.1.10
		     ifOutOctets     1.3.6.1.2.1.2.2.1.16
                     ifHCInOctets    1.3.6.1.2.1.31.1.1.1.6
                     ifHCOutOctets   1.3.6.1.2.1.31.1.1.1.10);

   my ($inoidname,$inoidport) = split(/\./, $inoid);
   my ($outoidname,$outoidport) = split(/\./, $outoid);

   $inoid = encode_oid(split(/\./, ($oidnames{$inoidname} . ".$inoidport")));
   $outoid = encode_oid(split(/\./, ($oidnames{$outoidname} . ".$outoidport")));

   my @oids = ($inoid,$outoid);

   if ($inoidname =~ /HC/i or $outoidname =~ /HC/i) {
   $session = SNMPv2c_Session->open($host, $community, 161) or return "error";
   } else {
   $session = SNMP_Session->open($host, $community, 161) or return "error";
   };

   if ($session->get_request_response (@oids)) {
       $response = $session->pdu_buffer;
       ($bindings) = $session->decode_get_response ($response);

        while ($bindings ne '') {
            ($binding,$bindings) = decode_sequence ($bindings);
            ($oid,$value) = decode_by_template ($binding, "%O%@");
           push (@results, pretty_print($value));
        }
   return @results;
   } else { warn "SNMP Error: $SNMP_Session::errmsg\n";
	    return "error"; }
}

sub snmpgetup {
   my($host, $community, $inoid) = @_;
   my($response, $bindings, $binding, $value, $oid, $result);

   my %oidnames = qw(sysUpTime	1.3.6.1.2.1.1.3
		     sysUpTime.0  1.3.6.1.2.1.1.3.0);

   $inoid = encode_oid(split(/\./, $oidnames{$inoid}));

   my $session = SNMP_Session->open($host, $community, 161) or return "0";

   if ($session->get_request_response ($inoid)) {
       $response = $session->pdu_buffer;
       ($bindings) = $session->decode_get_response ($response);
  	while ($bindings ne '') {
            ($binding,$bindings) = decode_sequence ($bindings);
            ($oid,$value) = decode_by_template ($binding, "%O%@");
        $result = pretty_print($value);
        }
   return $result;
   } else { warn "SNMP Error: $SNMP_Session::errmsg\n";
            return 0; }

}

sub chkuptime {

 $_ =~ s/\[|\]//g;
 my($uphost,$upip,$upcommunity,$upoid,$upfile) = split (/:/, $_);
 my $upresult = snmpgetup($upip,$upcommunity,$upoid);

 tie(%inf, 'SDBM_File', ($upfile."$main::SL"."uptimes"), O_RDWR|O_CREAT, 0640)
 or print "WARNING: Error opening uptime database file!\n";

   if ($upresult < $inf{$uphost} && $upresult > "1") { $hostreset = "1"; }
   else { $hostreset = "0"; }

 if ($upresult > "1") { $inf{$uphost} = $upresult; }

 untie(%inf);

}

sub main {
my($name,$host,$community,$inoid,$outoid,$path,$datafile) = @_;

tie(%inf, 'SDBM_File', ($path."$main::SL".$datafile), O_RDWR|O_CREAT, 0640) or
print "Error opening database file for $name at $host\n";

  if (-s (($path."$main::SL".$datafile) . ".pag")) {

    if ($inf{day} != $mday && $hour > "0") { newday();
      dailyhtml($name,$host,$path); }

    if ($inf{month} != $mon) {
				$newmon = "1";
				newday();
				dailyhtml($name,$host,$path);
				newmonth($name,$path);
                             	monthlyhtml($name,$host,$path);
				}

    if ($inf{year} != ($year + "1900")) { newyear($name,$path); }

    if (!$newmon) { updatedata(); }

    if ($inf{day} != $mday) { $newday = "1"; } else { $newday = "0"; }

  hourlyhtml($name,$host,$path,$newday);

  } else { createdata(); hourlyhtml($name,$host,$path); }      

untie(%inf);
}       
                              
# create data file if ! exist 
#

sub createdata {
%inf = (lastin => $inoctets, lastout => $outoctets,
	month => $mon, day => $mday, year => ($year + "1900"));
}

#
#

sub newyear {

my($name,$path) = @_;
my($count);

$count = 0;

 while ($count <= "11") {
 delete $inf{"m" . $count};
 $count++;
 }

 # move yearly html file.

 $oldfile="$path"."$main::SL"."$name"."-months".".html";
 $newfile="$path"."$main::SL"."$name"."-year".($year).".html";

 if ($main::OS eq "NT") { system("move /Y $oldfile $newfile"); }
 else { system("mv $oldfile $newfile"); }

$inf{year} = ($year + "1900");
}

#
#

sub newmonth {

my($name,$path) = @_;
my($count,$intotal,$outtotal,$inoct,$outoct);

 # get MB total for the month and store it.

 $count = 1;
 while ($count <= "31") {
   if ($inf{"d" . $count}) {
   ($inoct,$outoct) = split(/:/, $inf{"d" . $count});
   $intotal += $inoct;
   $outtotal += $outoct;
   }
 $count++;
 }

$intotal = ($intotal / $mbsize);
$outtotal = ($outtotal / $mbsize);

$inf{"m" . $inf{month}} = "$intotal:$outtotal";

 # clear days

 $count = 1;
 while ($count <= "31") {
 delete $inf{"d" . $count};
 $count++;
 }

 # move monthly html file.

 $oldfile="$path"."$main::SL"."$name"."-days".".html";
 $newfile="$path"."$main::SL"."$name"."-month".($mon).".html";

 if ($main::OS eq "NT") { system("move /Y $oldfile $newfile"); }
 else { system("mv $oldfile $newfile"); }

# set $inf{month} to the new month.
$inf{month} = $mon;
}


# newday:
# run every time the day of the month changes on the system.
#

sub newday {

my($count,$nmday,$intotal,$outtotal,$inoct,$outoct);

 # get megabyte total for the day and store it.
 #

 $count = 0;
 while ($count <= "23") {
   if ($inf{$count}) {
   ($inoct,$outoct) = split(/:/, $inf{$count});
   $intotal += $inoct;
   $outtotal += $outoct;
   }
 $count++;
 }

if ($newmon) { $nmday = last_mday($inf{month}, $inf{year}); }
else { $nmday = ($mday - 1); }

$inf{"d" . $nmday} = "$intotal:$outtotal:" . ($intotal + $outtotal);

 # clear hours
 #

 $count = 0;
 while ($count <= "23") {
 delete $inf{$count};
 $count++;
 }

$inf{day} = $mday;
}


# update DBM file.
#

sub updatedata {             
my ($lasthour,$wrapin,$wrapout);
my $intwrap="4294967296";

  if ($hour eq "0") { $lasthour = "23"; } else { $lasthour = ($hour - "1"); }

  if ($hostreset == "1") { $inf{lastin} = $inf{lastout} = "0"; }

    # detect if a counter has wrapped and adjust.
    #        
    if ($inoctets < $inf{lastin}) {
    $wrapin = $inoctets;
    $inoctets = ($intwrap - $inf{lastin}) + $inoctets;
    $inf{lastin} = "0";
    }

    if ($outoctets < $inf{lastout}) {
    $wrapout = $outoctets;
    $outoctets = ($intwrap - $inf{lastout}) + $outoctets;
    $inf{lastout} = "0";
    }

$inf{$lasthour} = (($inoctets - $inf{lastin}).":".($outoctets - $inf{lastout}));
if ($wrapin) { $inf{lastin} = $wrapin } else { $inf{lastin} = $inoctets }
if ($wrapout) { $inf{lastout} = $wrapout } else { $inf{lastout} = $outoctets }
}

sub footer {        
print DHTML "<br><br><br></td></tr></table><table cellpadding=3 align=left>        
<tr><td><a href=http://www.dynw.com/iog/><img src=ioglogo.gif border=0></a></td>    
<td>IOG $iogver - <a href=http://www.dynw.com/iog/>Input Output Grapher</a><br>
-<br>James Dogopoulos &lt;<a href=mailto:jd\@dynw.com>jd\@dynw.com</a>&gt;<br>
Questions or comments to <a href=mailto:iog\@dynw.com>iog\@dynw.com</a>
</td></tr></table><br>";
}

# make the hourly html
#

sub hourlyhtml {

my($name,$host,$path,$newday) = @_;

# make todays graph
#

my $enddays = last_mday($mon, ($year + "1900"));

my $count = "0";
my ($besthour,$bestday,$inoct,$outoct) = "0";

  # find busiest hour
  #
  while ($count <= "23") {
  if ($inf{$count}) { ($inoct,$outoct) = split(/:/, $inf{$count}); }
  else { $inoct = $outoct = "0"; }
    if ($inoct > $besthour) { $besthour = $inoct; }
    if ($outoct > $besthour) { $besthour = $outoct; }
  $count++;
  }

my $hscalemax = ($besthour / "1000000");
my ($hscaleunit,$intotal,$outtotal) = 0;

if ($hscalemax > "0") { $hscaleunit = ("450" / $hscalemax); }

 open(DHTML, ">>$path".$main::SL."$name".".html") or print "can't open in $name $host $!";
 flock(DHTML, 2) or print "can't flock $name $host: $!";
 truncate(DHTML, 0);

 print DHTML "<html><title>IOG $iogver - $host</title>
<META HTTP-EQUIV=Refresh CONTENT=3600><body bgcolor=#FFFFFF>
<table border=0><tr><td>";

 my $dexist = (-f "$path".$main::SL."$name"."-days.html");
 my $mexist = (-f "$path".$main::SL."$name"."-months.html");

  if ($newday != "1") {
   if ($dexist && $mexist) {
   print DHTML "<font size=3> [ Today | <a href="."$name"."-days.html>This Month</a>
   | <a href="."$name"."-months.html>Previous Months</a> ]</font><br><br>";
   } else {
     if ($dexist && !$mexist) {
     print DHTML "<font size=3> [ Today | <a href="."$name"."-days.html>This
     Month</a> | Previous Months ]</font><br><br>";
     } else { 
        if (!$dexist && $mexist) {
        print DHTML "<font size=3> [ Today | This Month 
        | <a href="."$name"."-months.html>Previous Months</a> ]</font><br><br>";
        } else { print DHTML "[ Today | This Month | Previous Months ]"; }
     }
   }
  } 
  else { 
   if ($dexist && $mexist) {
   print DHTML "<font size=3> [ <a href="."$name"."-days.html>This Month</a>
   | <a href="."$name"."-months.html>Previous Months</a> ]</font><br><br>";
   } else {
     if ($dexist && !$mexist) {
     print DHTML "<font size=3> [ <a href="."$name"."-days.html>This
     Month</a> | Previous Months ]</font><br><br>";
     } else { 
        if (!$dexist && $mexist) {
        print DHTML "<font size=3> [ This Month 
        | <a href="."$name"."-months.html>Previous Months</a> ]</font><br><br>";
        }
     }
   }

  }

 if ($newday eq "1") { $tday = "$nday"; } else { $tday = "$pday"; }

 print DHTML "<h3>$months[$mon] $tday - Network I/O for $name ($host)</h3>";
 print DHTML "<table cellpadding=5 border=1>";

 $count = "0";

 while ($count <= "23") {
 my($inwidth,$outwidth);

   if ($inf{$count}) {
   ($inoct,$outoct) = split(/:/, $inf{$count});
   $intotal += $inoct;
   $outtotal += $outoct;
   $inwidth = ($inoct / "1000000" * $hscaleunit);
   $outwidth = ($outoct / "1000000" * $hscaleunit);
   } else { $count++; next; }

   # if day is over 1gb, switch to GB/MB display.
   #
   my($gstring,$gbin,$gbout,$mbin,$mbout);

   $mbin = sprintf("%.1f", $inoct / $mbsize);
   $mbout = sprintf("%.1f", $outoct / $mbsize);

   if ($mbin > $gbsize or $mbout > $gbsize) {
   $gbin = sprintf("%.1f", $mbin / $gbsize);
   $gbout = sprintf("%.1f", $mbout / $gbsize);

   $gstring = "<td><font size=2><font color=#00CC00>In:</font> $gbin GB 
   ($mbin MB)<br><font color=#0000FF>Out:</font> $gbout GB ($mbout MB)
   </font></td></tr>";
   } 
   else {
   $gstring = "<td><font size=2><font color=#00CC00>In:</font> $mbin MB (".
   sprintf("%.f", $inoct / $kbsize)." KB)<br><font color=#0000FF>Out:</font> $mbout 
   MB (".sprintf("%.f", $outoct / $kbsize)." KB)";
   }

 $inwidth = (sprintf("%.f", $inwidth) + 1);
 $outwidth = (sprintf("%.f", $outwidth) + 1);

 print DHTML "<tr><td><b>"."$count".":00</b></td><td width=455><img src=in.gif height=12 width=$inwidth><br>\n";
 print DHTML "<img src=out.gif height=12 width=$outwidth><br></td>\n";

 print DHTML $gstring;

 $count++;
 }

$intotal = sprintf("%.f", ($intotal / $mbsize));
$outtotal = sprintf("%.f", ($outtotal / $mbsize));

print DHTML "</table><br></td></tr><tr><td align=right>";

  if ($intotal > $gbsize or $outtotal > $gbsize) {
  my $gbtotal = sprintf("%.1f", ($intotal + $outtotal) / $gbsize);
  print DHTML "Today's Total: <b>$gbtotal GB</b><br><font color=#00CC00>
In:</font> $intotal MB - <font color=#0000FF>Out:</font>
 $outtotal MB<br>";
  }
  else {
   print DHTML "Today's Total: <b>".($intotal + $outtotal)." MB</b><br>
<font color=#00CC00>In:</font> $intotal MB - <font color=#0000FF>Out:</font> 
 $outtotal MB<br>";
  }

footer();

flock(DHTML, 8);
close(DHTML);
}

sub monthlyhtml {

my ($name,$host,$path) = @_;
my ($bestmonth,$m_intotal,$m_outtotal,$m_total); 
my $count = 0;

  # find busiest month

  while ($count <= "11") {
    if ($inf{"m" . $count}) {
    ($m_intotal,$m_outtotal) = split(/:/, $inf{"m" . $count});
    if ($m_intotal > $bestmonth) { $bestmonth = $m_intotal; }
    if ($m_outtotal > $bestmonth) { $bestmonth = $m_outtotal; }
    }
  $count++;
  }

my $mscalemax = $bestmonth;
my ($mscaleunit,$intotal,$outtotal) = 0;

if ($mscalemax > "0") { $mscaleunit = ("450" / $mscalemax); }

open(DHTML, ">>$path".$main::SL."$name"."-months.html") or print "can't open $name $host $!";
flock(DHTML, 2)	or print "can't flock $name $host : $!";
truncate(DHTML, 0);

print DHTML "<html><title>IOG $iogver - $host</title><body bgcolor=#FFFFFF>
<table border=0><tr><td>";

my $dexist = (-f "$path".$main::SL."$name"."-days.html");

if ($dexist) {
print DHTML "<font size=3>[ <a href="."$name".".html>Today</a> |
<a href="."$name"."-days.html>This Month</a> | Previous Months ]</font><br><br>";
} else {
print DHTML "<font size=3>[ <a href="."$name".".html>Today</a> | 
This Month | Previous Months ]</font><br><br>";
}

print DHTML "<h3>Monthly Network I/O for $name ($host)</h3>";
print DHTML "<table cellpadding=5 border=1>";

 $count = "0";

 while ($count <= "11") {
 my($inwidth,$outwidth,$intotal,$outtotal,$inoct,$outoct,$mtotal);

   if ($inf{"m" . $count}) {
   ($inoct,$outoct,$mtotal) = split(/:/, $inf{"m" . $count});
   $intotal += $inoct;
   $outtotal += $outoct;
   $inwidth = ($inoct * $mscaleunit);
   $outwidth = ($outoct * $mscaleunit);
   } else { $count++; next; }

   # if day is over 1gb, switch to GB/MB display.
   #
   my($gstring,$gbin,$gbout,$gbtotal,$mbin,$mbout);

   $mbin = sprintf("%.f", $inoct);
   $mbout = sprintf("%.f", $outoct);

   $gbin = sprintf("%.1f", $mbin / $gbsize);
   $gbout = sprintf("%.1f", $mbout / $gbsize);
   $gbtotal = sprintf("%.1f", ($gbin + $gbout));

   $gstring = "<td><font size=2><font color=#00CC00>In:</font> $gbin GB
   ($mbin MB)<br><font color=#0000FF>Out:</font> $gbout GB ($mbout MB)
   </font></td></tr>";

 $inwidth = (sprintf("%.f", $inwidth) + 1);
 $outwidth = (sprintf("%.f", $outwidth) + 1);

 if (-f "$path".$main::SL."$name"."-month".($count + "1").".html") { 
 $mlink = "<a href=$name"."-month".($count + "1").".html>$months[$count]</a>";
 } else { $mlink = "$months[$count]"; }

 print DHTML "<tr><td><b>$mlink<br>$gbtotal GB</b></td><td width=455>
<img src=in.gif height=12 width=$inwidth><br>\n";
 print DHTML "<img src=out.gif height=12 width=$outwidth><br></td>\n";

 print DHTML $gstring;

 $count++
 }

print DHTML "</tr></td></table><br>";

footer();

flock(DHTML, 8);                                  
close(DHTML);
}

sub dailyhtml {

my ($bestday,$d_intotal,$d_outtotal) = 0;
my ($name,$host,$path) = @_;
my $count = 1;
my $endday = last_mday($inf{month}, $inf{year});

 if ($endday eq $mday) { $lastday="1"; } else { $lastday="0"; }

 # fix math errors from previous sub
 if ($newmon) { $mon--; }

 # move Today's html file unless it's a new month.

 if (!$newmon) {
 $oldfile="$path"."$main::SL"."$name".".html";
 $newfile="$path"."$main::SL"."$name"."-day".($mday - "1").".html";
 if ($main::OS eq "NT") { system("move /Y $oldfile $newfile"); }
 else { system("mv $oldfile $newfile"); }
 }

  # find busiest day (should be merged with totals)

  while ($count <= $endday) {
    if ($inf{"d" . $count}) {
    ($d_intotal,$d_outtotal) = split(/:/, $inf{"d" . $count});
    if ($d_intotal > $bestday) { $bestday = $d_intotal; }
    if ($d_outtotal > $bestday) { $bestday = $d_outtotal; }
    }
  $count++;
  }

my $dscalemax = ($bestday / "1000000");
my ($dscaleunit,$intotal,$outtotal) = 0;

if ($dscalemax > "0") { $dscaleunit = ("450" / $dscalemax); }

open(DHTML, ">>$path".$main::SL."$name"."-days.html") or print "can't open $name $host  $!";        
flock(DHTML, 2) or print "can't flock $name $host : $!";
truncate(DHTML, 0);

print DHTML "<html><title>IOG $iogver - $host</title><body bgcolor=#FFFFFF>
<table border=0><tr><td>";

  if (-f "$path".$main::SL."$name"."-months.html") {     
  print DHTML "<font size=3>[ <a href="."$name".".html>Today</a> |
  This Month | <a href="."$name"."-months.html>Previous Months</a> ]</font><br><br>";
  } else {
  print DHTML "<font size=3>[ <a href="."$name".".html>Today</a> | This Month
  | Previous Months ]</font><br><br>";
  }

print DHTML "<h3>$months[$mon] - Network I/O for $name ($host)</h3>";
print DHTML "<table cellpadding=5 border=1>";

 $count = "1";

 while ($count <= $endday) {
 my($inwidth,$outwidth,$inoct,$outoct,$pday);

   if ($inf{"d" . $count}) {
   ($inoct,$outoct) = split(/:/, $inf{"d" . $count});
   $intotal += $inoct;
   $outtotal += $outoct;
   $inwidth = ($inoct / "1000000" * $dscaleunit);
   $outwidth = ($outoct / "1000000" * $dscaleunit);
   } else { $count++; next; }

   # if day is over 1gb, switch to GB/MB display.
   #
   my($gstring,$gbin,$gbout,$mbin,$mbout);

   $mbin = sprintf("%.f", $inoct / $mbsize);
   $mbout = sprintf("%.f", $outoct / $mbsize);

   if ($mbin > $gbsize or $mbout > $gbsize) {
   $gbin = sprintf("%.1f", $mbin / $gbsize);
   $gbout = sprintf("%.1f", $mbout / $gbsize);

   $gstring = "<td><font size=2><font color=#00CC00>In:</font> $gbin GB
   ($mbin MB)<br><font color=#0000FF>Out:</font> $gbout GB ($mbout MB)
   </font></td></tr>";
   }
   else {
   $gstring = "<td><font size=2><font color=#00CC00>In:</font> $mbin MB (".
   sprintf("%.f", $inoct / $kbsize)." KB)<br><font color=#0000FF>Out:</font> $mbout
   MB (".sprintf("%.f", $outoct / $kbsize)." KB)";
   }

 $inwidth = (sprintf("%.f", $inwidth) + 1);
 $outwidth = (sprintf("%.f", $outwidth) + 1);

   if ($days{$count}) { $pday = $days{$count}; } else { $pday = $count."th"; }

   if (-f "$path".$main::SL."$name"."-day".$count.".html" && $lastday eq "0"
	&& ($newmon ne "1")) { 
     $pday = "<a href=$name"."-day".$count.".html>$pday</a>";
   }

 print DHTML "<tr><td><b>$pday</b></td><td width=455>
 <img src=in.gif height=12 width=$inwidth><br>\n";
 print DHTML "<img src=out.gif height=12 width=$outwidth><br></td>\n";
 print DHTML $gstring;

 $count++;
 }

$intotal = sprintf("%.f", ($intotal / $mbsize));
$outtotal = sprintf("%.f", ($outtotal / $mbsize));

my $gbtotal = sprintf("%.1f", (($intotal + $outtotal) / $gbsize));

print DHTML "</table><br></td></tr><tr><td align=right>";
print DHTML "Monthly Total: <b>$gbtotal GB</b><br><font color=#00CC00>
In:</font> $intotal MB - <font color=#0000FF>Out:</font> $outtotal MB<br>";

footer();

flock(DHTML, 8);
close(DHTML);

 # reverse math errors
 if ($newmon) { $mon++; }

}


# END















#
# IOG v1.03 - Input/Output Grapher
# Copyright 2000-2003 (c) James Dogopoulos
#


