#!/usr/local/bin/perl -w # mvs-web-db.pl use DBI; use strict; use vars qw(%ENV $VERSION); my $VERSION = "0.06"; my $DEBUG = 0; my $mvs_dir = "$ENV{HOME}/mvs_reports"; my $db_dir = "${mvs_dir}/mvs_db"; my $table = "mvslog"; my $db_file = "${db_dir}/${table}.dbf"; my $repdate = localtime; my ($host, $ip, $number, $type, $date); # data point fields my @dpfields = qw( LOGDATE HOST IP NUMBER TYPE ); my @hostfields = qw( HOST IP ); # filter data my %generic_hosts = ('anonymous' => 1, 'mozilla' => 1, 'user@hostname' => 1); # array of data points from the database my $dbdata = []; if (not -d $mvs_dir) { die "Missing base directory ${mvs_dir}, exiting."; } if (not -d $db_dir) { die "Missing database directory ${db_dir}, exiting."; } if (not -f $db_file) { die "Missing database file ${db_file}, exiting."; } my $dbh = DBI->connect("dbi:XBase:${db_dir}"); my $rv; $rv = load_dbdata($dbh, $table, $dbdata); dprint("rv=", $rv); my $filtered = filter($dbdata); dprint("filtered=", scalar @{$filtered}); my $current_number = get_current_number($filtered); dprint("current_number=", $current_number); $rv = make_web($filtered); dprint("rv=", $rv); # end sub load_dbdata { my $dbh = shift; my $table = shift; my $dbdata = shift; my $sql = "select logdate, host, ip, number, type " . "from ${table}"; dprint("load_dbdata sql=", $sql); my $sth = $dbh->prepare($sql); my $rv = $sth->execute; dprint("load_dbdata rv=", $rv); my $row_ref; while ($row_ref = $sth->fetchrow_hashref) { dprint("keys row_ref=", keys %{$row_ref}); dprint("values row_ref=", values %{$row_ref}); push @{$dbdata}, $row_ref; } return scalar @{$dbdata}; } # check for duplicates sub filter { my $dbdata = shift; my %unique; my $tdp; my $duplicate = 0; # find unique hosts, but allow generic hosts to use unique ips for $tdp (@{$dbdata}) { my $key = $tdp->{HOST}; if (exists $generic_hosts{$key}) { $key = $tdp->{IP}; } if (not exists $unique{$key}) { $unique{$key} = $tdp; } elsif ($unique{$key}->{NUMBER} < $tdp->{NUMBER}) { $unique{$key} = $tdp; } } # create list of filtered values my @filtered = reverse sort { $a->{NUMBER} <=> $b->{NUMBER} } values %unique; return \@filtered; } sub get_current_number { my $dbdata = shift; my $current_number = 0; my $tdp; for $tdp (@{$dbdata}) { if ($current_number < $tdp->{NUMBER}) { $current_number = $tdp->{NUMBER}; } } return $current_number; } # make web page from database sub make_web { my $dbdata = shift; my $tdp; my $web_header = ' McAfee VirusScan Update Report

McAfee VirusScan Update Report

Report Date: ' . $repdate . '
Current Definition Number: ' . $current_number . '
'; my $web_footer = '
Hostname IP Address VDN Type Last Update
Update Color Key: Current, Last 7 Days, Last 30 Days, Older Than 30 Days, Anonymous Report.
Type Key: upd Update File(s), dat DAT File, sdat SDAT File.
VDN: Virus Definition Number.
'; # header print $web_header; # body dprint("dbdata=", $dbdata); for $tdp (@{$dbdata}) { dprint("keys tdp=", keys %{$tdp}); dprint("values tdp=", values %{$tdp}); $host = $tdp->{HOST}; $ip = $tdp->{IP}; $number = $tdp->{NUMBER}; $type = $tdp->{TYPE}; $date = $tdp->{LOGDATE}; my $class = "old"; if (exists $generic_hosts{$host}) { $class = "anonymous"; } elsif ($number == $current_number) { $class = "current"; } elsif (($number + 7) > $current_number) { $class = "recent"; } elsif (($number + 30) > $current_number) { $class = "aged"; } print " ${host} ${ip} ${number} ${type} ${date} "; } # footer print $web_footer; print "\n"; } # print debug info if $DEBUG is on sub dprint { if (not $DEBUG) { return; } my ($pkg, $file, $line, $sub, @others) = caller(1); print "${sub} ${line} : "; print join(' ', map { $_ || 'undef' } @_), "\n"; }