Cover V03, I03
Article
Figure 1
Figure 2
Figure 3
Figure 4
Listing 1
Listing 2
Listing 3
Sidebar 1

may94.tar


Listing 1: dnatRpt Perl script

#!/usr/local/bin/perl
#=====================================================
# AUTHOR: Dave Brillhart
# FILE:   dnatRpt
#-----------------------------------------------------
# This PERL program checks every host listed in a
# selectable configuration file for connectivity.
# If reachable - it determines how long the host has
# been up. The program then generates and optionally
# mails a report based on its findings. UNIX (and
# optionally VMS via DECnet) hosts can be checked.
#
# Usage: dnatRpt [ -rpt -silent hostnameFile ]
#
# Rtn_Value: #_hosts_unavailable
#=====================================================

#-----------------------------------------------------
$rcPath   = "/usr/local/etc/";
$rptFile  = "/tmp/dnatRpt_$$";
$chkFile  = "/tmp/dnat911";
$rID      = "peru";
$rdclCmd  = "/usr/local/bin/rdcl";
$pingCmd  = "/usr/etc/ping";
$rshCmd   = "/usr/ucb/rsh";
$rupCmd   = "/usr/local/bin/rup";
$mailCmd  = "/usr/ucb/mail";
$dow      = (Sunday,Monday,Tuesday,
Wednesday,Thursday,Friday,
Saturday,Sunday)[(localtime)[6]];
$sub      = "Downtime Tracking Status Report - $dow";
#-----------------------------------------------------

$rpt = 0; $silent = 0; $rcFile = "dnatHosts"; $| = 1;
while ($ARGV[0]) {     # digest command line options #
if    ($ARGV[0] eq "-rpt")   { $rpt   = 1; }
elsif ($ARGV[0] eq "-silent") { $silent = 1; }
else  { $rcFile = $ARGV[0]; }
shift;
}

open(HOSTS,"<$rcPath$rcFile") ||
die "Can't open $rcPath$rcFile file.\n";
open(RPT,">$rptFile") ||
die "Can't open $rptFile file.\n";
open(CHK,">$chkFile") ||
die "Can't open $rptFile file.\n";

if ($silent == 0 && $rpt == 0)
{ print "\n[ DNAT: Will NOT mail reports. ]\n"; }
elsif ($silent == 0 && $rpt == 1)
{ print "\n[ DNAT: Will mail reports. ]\n"; }

print RPT "***************************************\n";
print RPT "******   System Status Report    ******\n";
print RPT "***************************************\n";

#----------------------------------------------------#
# Main loop - Check each host and generate report    #
#----------------------------------------------------#
$ucnt = $rcnt = 0;            # host status counters #
while ($host = <HOSTS>)  # process all hosts in file #
{
chop $host;                      # remove new line #
$host =~ y/ / /s;    # squeeze spaces into 1 space #
if (length($host) < 2) { next; }     # skip blanks #
if ($host =~ m/^\#.*$/) { next; }  # skip comments #

#--------------------------------------------------#
# if the line is enclosed in double quotes, it is  #
# interpreted as a section header for the report.  #
#--------------------------------------------------#
if ($host =~ m/^\"(.*)\"$/) {
print RPT "\n$1\n";
print RPT "-----------------------------------\n";
next;             # get next line from host file #
}

$pos = index($host,"#");  # parse in-line comments #
if ($pos > -1) { $host = substr($host,0,$pos); }
if ($silent == 0) { print "\n + processing $host"; }
#--------------------------------------------------#
# if the hostname ends in "::" then use DECnet and #
# derive uptime from the top of "show system" cmd. #
#--------------------------------------------------#
if ($host =~  m/^([^:]+)::.*$/) {
$host = $1;         # strip off the double colon #
$cmd = "$rdclCmd $host show system 2>&1 |";
open(CMD, $cmd) ||
die "ERROR: Couldn't run $cmd: $!\n";
$available = 0; $uplong = 0;
while ($cmdLine = <CMD>) {
chop $cmdLine;
if ($cmdLine =~
m/^.*\s+Uptime\s+(\d+)\s+([\d:]+)/) {
$available = 1; $days = $1;
}
if ($available == 1 && $days > 0)
{ $uplong = 1; }
}
close(CMD);
}
#--------------------------------------------------#
# otherwise it must be UNIX, use TCP/IP, try 'rup' #
# first (faster), then 'rsh' if rup fails.         #
#--------------------------------------------------#
else {
# if string "alive" is missing, host unavailable #
$available = 0;
$ping = `$pingCmd $host 2>&1`;
if ($ping =~ m/^.*alive.*$/) { $available = 1; }

$uptime = $uplong = $rupOK = 0;
if ($available) {    # host alive, go get uptime #
$uptime = `$rupCmd $host 2>&1`;
if ($uptime =~ m/^.* up .*$/) { $rupOK = 1; }
if ($rupOK) {   # rup command appeared to work #
if ($uptime =~ m/^.*up (.*) day.*$/)
{ $uplong = 1; $days = $1; }
}
else {       # rup failed, try rsh'ing to host #
$uptime = `$rshCmd $host -l $rID uptime 2>&1`;
if ($uptime =~ m/^.*up (.*) day.*$/)
{ $uplong = 1; $days = $1; }
}
}
}

#--------------------------------------------------#
# append host status to the end of report file     #
#--------------------------------------------------#
if ($available == 0) {
printf(RPT "%-15s %s\n",$host,
"** HOST UNAVAILABLE **");
printf(CHK "%-15s %s\n",$host,
"** HOST UNAVAILABLE **");
if ($silent == 0) { print "... ** UNAVAILABLE!"; }
$ucnt++;
}
elsif ($uplong == 0) {
printf(RPT "%-15s %s\n",$host,
"** HOST RESTARTED **");
printf(CHK "%-15s %s\n",$host,
"** HOST RESTARTED **");
if ($silent == 0) { print "... ** RESTARTED!"; }
$rcnt++;
}
else {
if ($silent == 0) { print "... OKAY!"; }
printf(RPT "%-15s [up %3s days]\n",$host,$days);
}
}

print RPT "\nTOTAL UNAVAILABLE: $ucnt  ";
print RPT " RESTARTED:    $rcnt\n";
print RPT "***************************************\n";
close(RPT); close(CHK);

if ($silent == 0)       # display report on /dev/tty #
{ print "\n"; system("cat $rptFile"); }

if ($rpt == 0)                 # do not mail reports #
{ unlink $rptFile; exit $ucnt; }

#----------------------------------------------------#
# Mail the DNAT report to all appropriate aliases.   #
# 'dnatSunday', 'dnatAdmin', & 'dnatAlert' are mail  #
# aliases defined in the /etc/aliases file.          #
#----------------------------------------------------#
if ($dow eq "Sunday") {         # Send to dnatSunday #
$mc = "$mailCmd -s '$sub' dnatSunday < $rptFile";
system($mc);
}
if ($rcnt > 0) { # Send to dnatAlert if any rebooted #
($sub1 = $sub) =~ s/Down/*ALERT* : Down/;
$mc = "$mailCmd -s '$sub1' dnatAlert < $rptFile";
system($mc);
}
else {             # Send to dnatAdmin every morning #
($sub1 = $sub) =~ s/Down/Daily Down/;
$mc = "$mailCmd -s '$sub1' dnatAdmin < $rptFile";
system($mc);
}

unlink $rptFile;
exit $ucnt;