Cover V11, I05
may2002.tar

Listing 2

#!/usr/bin/perl

# /usr/local/bin/makelist.pl
# Create the data file for GetHost.cgi and send to STDOUT
#
# by John D. Shearer

# Version 0.9a

# *** SECTION 1 ***
use Text::ParseWords;
use Text::DHCPparse;

# *** SECTION 2 ***
# Fixed Length Field Definitions:
# Position       Field
# --------  --------------------
#   1-17    IP Address
#  18-38    Last Lease Timestamp
#  39-52    Hardware Address
#  53-69    Client Hostname
#  70-95    Inventory Assignment
#  96-      WINS and { e-mail }

# *** SECTION 3 ***
$statfile = "home/jsmith/logs/stat.comp";
$winsfile = "home/jsmith/wins.txt";  
$logfile = "home/jsmith/dhcpd.leases.comp"; 
$invfile = "home/jsmith/HW.TXT"; 

# *** SECTION 4 ***
# Process combined DHCP lease files and create %$lease
# (we use the leaseparsenc() function instead of the
# leaseparse() function to remove the colons from 
# the MAC addresses) 
$list = leaseparsenc($logfile);

# Process WINS database and create %wins
&winssub;

# Process email Stats file and create %email
&emailsub;

# Process Inventory File and create %inv
# If this is not working, check the field numbers
&invsub;

# Step through %$lease and append %inv entry as necessary
# -also make sure %inv entries are minimum length
&invproc;

# Step through %email and append to %$lease as necessary
&emailproc;

# Step through %wins and append to %$lease as necessary
&winsproc;

# Print the newly created database to STDOUT
foreach (sort(keys %$lease)) {
   print "$list->{$_}\n";
}

# *** SECTION 5 ***
# *** 
# *** SUBROUTINES FOR FILE PROCESSING
# ***
sub emailsub {
   open STAT, "$statfile";
   while (<STAT>) {
      chomp;
      next if ( /MDM|HTTP/ );
      @current = split /,/;
      if ( shift(@current) eq "Login" ) {
         @addr = split(/:/, $current[10]);
         $email{$addr[0]} .= "$current[0] " 
                        if ($email{$addr[0]} !~ /$current[0]/i);
      }
   }
   close STAT; 
}

sub winssub {
   open WINS, $winsfile or die;
   while (<WINS>) {
      @new = quotewords(",", 0, $_);
      next if ($new[11] !~ /\d+\.\d+\.\d+\.\d+/);
      chop $new[1] if (length $new[1] >= 16);
      chomp @new;
      $new[1] =~ s/\s*$//;
      $wins{$new[11]} .= "$new[1] " if ($wins{$new[11]} !~ /\Q$new[1]/i);
   }
   close WINS;
}

sub invsub {
   # $pos is the field position in HW.TXT of the MAC Address
   $pos = '1';
   open INV, $invfile
      or die "Could not open INV file\n";
   while (<INV>) {
# Kind of weird - the chomp and chop are both needed because of the database
# export - maybe there is a '\n' and a <cr>? (or however that works...)
      chomp;
      chop;
      @var = split /\t/;
      next unless ($var[$pos]);
      next if ($var[$pos] =~ /none/i);
      $var[$pos] =~ s/ |-|://g;
      $var[$pos] =~ s/o|O/0/g;
      $var[$pos] = sprintf("%12.12s", lc($var[$pos]));
      $var[$pos] =~ s/ /0/g;
      $inv{$var[$pos]} = $var[2];
   }
   close INV;
}

# *** SECTION 6 ***
# ***
# *** Subroutines for HASH Processing
# ***
sub invproc {
   for $ip (keys %$lease) {
      $mac = substr $list->{$ip}, 38, 12;
#      $mac =~ s/://g;
      if (exists $inv{$mac}) {
         $list->{$ip} .= sprintf("%-26s", $inv{$mac});
      }
      else {
         $list->{$ip} .= (" "x26);
      }
   }
}

sub emailproc {
   for $ip (keys %email) {
      if (exists $list->{$ip}) {
         $list->{$ip} .= sprintf("%-17s", " ")
                            if (length($list->{$ip}) <= 36);
         $list->{$ip} .= "{ ". $email{$ip} ."} ";
      }
      else {
         $list->{$ip} = sprintf("%-17s%-78s{ %s} \t", $ip, "NO DHCP", 
                                $email{$ip});
      }   
   } 
}

sub winsproc {
   for $ip (keys %wins) {
      if (exists $list->{$ip}) {
         ($list->{$ip} .= sprintf("%-17s", " ")) 
                           if (length($list->{$ip}) <= 85);
         $list->{$ip} .= "[ " . $wins{$ip} ."] ";
      }
      else {
         $list->{$ip} = sprintf("%-17s%-78s[ %s]", $ip, "NO DHCP", 
                                 $wins{$ip});
      }
   }
}