#!/var/opt/STORtools/bin/perl 

use Date::Parse;
use Date::Format;
#use File::stat;  # for some reason this causes stat not to work
          # It's in the standard library anyway.  M.Shapiro-12/15/98

# $DEBUG = "TRUE";
require  "subroutines.pm";
&st_globals();

$DIR_MESS   = "/var/adm";

$PROGNAME = "mess_sum";
$SOLARIS57 = "5.7";
####################################################################
#
# summary of /var/adm/messages*
#
# 08/21/98 aku add -dir option to look at any messages file
# 01/26/99 wbd prepare for PCI hooks
# 03/02/99 wbd add DMA error checking
# 03/12/99 wbd First cut of PCI message parsing
#              Test for Solaris 5.7 and parse socal messages accordingly.
#              Reduced header line that was wrapping
#              Added counters to -l option
#              Removed printing of linefeed when no data is output.
#              Retooled the looping option and reinitialize counters.
#              Enhanced reporting of "skipped" files.
#              Added reporting of files "scanned"
#              Added intelligence for find invalid snapshot
# Copyright (c) 1998  Sun Microsystems Computer Corporation, Inc.
####################################################################

    $dateStart = undef;
    $dateEnd = undef;
    $oneDayOfSecs = (24 * 60 * 60);
    $NO_GOLD = undef;
    $LOOP = "FALSE";
    $ERROR_FLAG = undef;

    &check_root_access( $PROGNAME );

    &proc_cli;

    if (!defined($dateEnd)) {
       $dateEnd = time; 
    }

    if (!defined($dateStart)) {
       $dateStart = $dateEnd - $oneDayOfSecs; 
    }

    chomp( $os_version = `/usr/bin/uname -r` );
    if ( ! $QUIET ) {
        &pr_header();
    }
    &get_rawdump();
    &make_name_list();

    $y2kyear = (localtime)[5];
    $year = $y2kyear + 1900;

    $sleep_time = 0;
    $iterations = 0;
    if ( $LOOP eq "TRUE" ) {
       $iterations = $ITERATIONS;
       $sleep_time = $SLEEP_TIME;
    } else {
       $iterations = 1;
    }

    $open_error = 0;
    do {
        if ( $LOOP eq "TRUE" ) {
           $dateEnd = time; 
        }
        # if zero loop forever
        if ( $ITERATIONS == 0 ) {
            $iterations = 1;
        } else {
            $iterations--;
        }

        if ($FIL_MESS eq "") {
            @files = `/usr/bin/ksh -c 'ls -1r $DIR_MESS/messages* 2>/dev/null'`;
            if ($#files < 0) { 
               die "No message files found in $DIR_MESS" 
            }
         } else {
            unshift @files, $FIL_MESS;
         }
    

        print "start of mess_sum:",`/usr/bin/date`,"\n" if ($DEBUG);



	$first = 1;

    
        foreach $file (@files) {

            chomp($file);
            if (! (-r $file) ) {
                printf("Skipping $file  reason: invalid read priviledge\n");
                $open_error = 1;
                next;
            }
            ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat($file);
            if ($mtime < $dateStart) {
                printf("Skipping $file  reason: file is older than start date.\n");
                $open_error = 1;
                next;
            }
            if($size == 0 ) {
                printf("Skipping $file  reason: empty file\n");
                $open_error = 1;
                next;
            }
            open(FILE, "<$file" );
            if ( $open_error == 1 ) {
                $open_error = 0;
                print "\n";
            }
            if ( ( $file eq $T300_MESSAGES ) && ( $STORAGE eq "A5" ) ) {
                printf("Skipping $file  reason: $STORAGE Series Storage Selected\n");
                $open_error = 1;
                next;
            }
            if ( $file eq $T300_MESSAGES ) {
                printf("Scanning $file for T300 related messages.\n");
                while (<FILE>) {
                        $line = $_;
                        # stuff date into $1
			$temp = $line;
			$temp =~ tr/ //s;
			@z = split(/ /, $temp);
			$temp = sprintf("$z[0] $z[1] $z[2]");

    
                        # This is the time stamp found in the file.
                        $ttime = &futurecheck($temp);     
                        if (!$dateStart) {
                                $dateStart = $ttime;
                        }
              
                        # if equal; make it span one day
                        if(($dateStart == $dateEnd) && ($dateStart != 0)) {  
                                $dateEnd = $dateStart + $oneDayOfSecs;
                        }
    
                        # The message time stamp is older than the requested start date
                        # get the next date
                        next if ($ttime < $dateStart); 
                        # The message time stamp is newer than the requested end date


			if ( $first ) {
               	     		if($ttime > $dateStart) {
					$timeDiffers = $ttime;
		     		}
		     		$first = 0;
			}

                        # so we are done
                        last if ($ttime > $dateEnd);   

                        if ($line =~ /W:/) {
                                $hostname = &match_hostname( $line );
                                if ($line =~ /u\d+ctr Hardware Reset \(\w+\) occurred/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+ctr Hardware Reset \(\w+\))/;
                                    $P01WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+ctr Assertion Reset \(\w+\)/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+ctr Assertion Reset \(\w+\))/;
                                    $P02WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+ctr disk error during recon, terminating recon/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+ctr)/;
                                    $P03WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+ctr initialization failed in vol \(\w+\)/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+ctr initialization failed in vol \(\w+\))/;
                                    $P04WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+ctr recon failed in vol \(\w+\)/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+ctr recon failed in vol \(\w+\))/;
                                    $P05WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+d\d+ hard err in vol \(\w+\) starting auto disable/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+d\d+ hard err in vol \(\w+\))/;
                                    $P06WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+d\d+ write disk failed, err=\<\w+\>/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+d\d+ write disk failed, err=\<\w+\>)/;
                                    $P07WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+d\d+ could not open plugged disk/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+d\d+)/;
                                    $P08WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+d\d+ could not create system area/) { 
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+d\d+)/;
                                    $P09WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+d\d+ system area is bad/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+d\d+)/;
                                    $P10WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+d\d+ could not open disk, try unplug then plug/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+d\d+)/;
                                    $P11WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+d\d+ system area verify failed/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+d\d+)/;
                                    $P13WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+d\d+ SCSI Disk Error Occurred \(\w+\)/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+d\d+ SCSI Disk Error Occurred \(\w+\))/;
                                    $P14WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+ctr: Master controller failed; takeover process starts/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+ctr)/;
                                    $P15WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+d\d+: Bypassed on loop A/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+d\d+)/;
                                    $P16WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+d\d+: Bypassed on loop B/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+d\d+)/;
                                    $P17WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+pcu\d+: Fan 1 failed/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+pcu\d+)/;
                                    $P18WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+pcu\d+: Fan 2 failed/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+pcu\d+)/;
                                    $P19WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+pcu\d+: DC not OK/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+pcu\d+)/;
                                    $P20WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+pcu\d+: Disabled/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+pcu\d+)/;
                                    $P21WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+pcu\d+: Off/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+pcu\d+)/;
                                    $P22WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+pcu\d+: On battery/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+pcu\d+)/;
                                    $P23WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+pcu\d+: Switch off/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+pcu\d+)/;
                                    $P25WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+l\d+: Offline/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+l\d+)/;
                                    $P26WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+l\d+: Disabled/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+l\d+)/;
                                    $P27WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+ctr: Disabled/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+ctr)/;
                                    $P28WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+pcu\d+: Battery took too long to recharge/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+pcu\d+)/;
                                    $P29WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+d\d+ Recon attempt failed/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+d\d+)/;
                                    $P30WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+d\d+ Disable attempt failed/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+d\d+)/;
                                    $P31WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+d\d+ Installing u\d+d\d+ failed, Try unplugging and then plugging/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+d\d+ Installing u\d+d\d+)/;
                                    $P32WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+ctr RAM ECC Multi-Bit Error/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+ctr)/;
                                    $P33WARN{$t300_warn}++;
                                } elsif ($line =~ /multi-disk failure, access disallowed/) {
                                    ($t300_warn) = $line;
                                    $P34WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+d\d+ is in wrong disk position, previously in u\d+d\d+/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+d\d+ is in wrong disk position, previously in u\d+d\d+)/; 
                                    $P35WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+ctr read failed during recon stripe \(\w+\)/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+ctr recon failed in vol scb=\<\w+\>)/;
                                    $P36WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+pcu\d+: Replace battery, hold time low./) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+pcu\d+)/;
                                    $P37WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+pcu\d+ 0 day battery life left/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+pcu\d+ 0 day batter life left)/;
                                    $P38WARN{$t300_warn}++;
                                } elsif ($line =~ /u\d+pcu\d+ \d+ days battery life left/) {
                                    ($t300_warn) = $line =~ /( \w+\[\d+\]: W: u\d+pcu\d+ \d+ days batter life left)/;
                                    $P39WARN{$t300_warn}++;
				}
                        } elsif ($line =~ /E:/) {
                                $hostname = &match_hostname( $line );
                                if ($line =~ /u\d+ctr: Not present/) {
                                    ($t300_err) = $line =~ /( \w+\[\d+\]: E: u\d+ctr)/;
                                    $P01ERR{$t300_err}++;
                                } elsif ($line =~ /u\d+d\d+: Not present/) {
                                    ($t300_err) = $line =~ /( \w+\[\d+\]: E: u\d+d\d+)/;
                                    $P02ERR{$t300_err}++;
                                } elsif ($line =~ /u\d+ctr\d+: Missing;/) {
                                    ($t300_err) = $line =~ /( \w+\[\d+\]: E: u\d+ctr\d+)/;
                                    $P03ERR{$t300_err}++;
                                } elsif ($line =~ /u\d+fru\d+: Multiple Fan
Faults;/) {
                                    ($t300_err) = $line =~ /( \w+\[\d+\]: E: u\d+fru\d+)/;
                                    $P04ERR{$t300_err}++;
                                } elsif ($line =~ /u\d+pcu\d+: Not present/) {
                                    ($t300_err) = $line =~ /( \w+\[\d+\]: E: u\d+pcu\d+)/;
                                    $P05ERR{$t300_err}++;
                                } elsif ($line =~ /u\d+pcu\d+: Over temperature/) {
                                    ($t300_err) = $line =~ /( \w+\[\d+\]: E: u\d+pcu\d+)/;
                                    $P06ERR{$t300_err}++;
                                } elsif ($line =~ /u\d+l\d+: Not present/) {
                                    ($t300_err) = $line =~ /( \w+\[\d+\]: E: u\d+l\d+)/;
                                    $P07ERR{$t300_err}++;
                                } elsif ($line =~ /u\d+l\d+: UP cable not present/)
{
                                    ($t300_err) = $line =~ /( \w+\[\d+\]: E: u\d+l\d+)/;
                                    $P08ERR{$t300_err}++;
                                } elsif ($line =~ /u\d+l\d+: DOWN cable not present/) {
                                    ($t300_err) = $line =~ /( \w+\[\d+\]: E: u\d+l\d+)/;
                                    $P09ERR{$t300_err}++;
                                } elsif ($line =~ /u\d+pcu\d+: Battery not present/) {
                                    ($t300_err) = $line =~ /( \w+\[\d+\]: E: u\d+pcu\d+)/;
                                    $P10ERR{$t300_err}++;
                                } elsif ($line =~ /u\d+pcu\d+: Missing;/) {
                                    ($t300_err) = $line =~ /( \w+\[\d+\]: E: u\d+pcu\d+)/;
                                    $P11ERR{$t300_err}++;
                                } elsif ($line =~ /u\d+d\d+: Missing;/) {
                                    ($t300_err) = $line =~ /( \w+\[\d+\]: E: u\d+d\d+)/;
                                    $P12ERR{$t300_err}++;
                                } elsif ($line =~ /u\d+l\d+: Missing;/) {
                                    ($t300_err) = $line =~ /( \w+\[\d+\]: E: u\d+l\d+)/;
                                    $P13ERR{$t300_err}++;
                                }
                        }
                }
                close(FILE);
                next;
            }

      	    printf("Scanning $file for FC-AL related messages.\n");

	    while (<FILE>) {
                   push (@filestuff, $_);
       	    }

        
            while ( $line = shift @filestuff  ) {

                $_ = $line;
                # stuff date into $1

		$temp = $line;
		$temp =~ tr/ //s;
		@z = split(/ /, $temp);
		$temp = sprintf("$z[0] $z[1] $z[2]");
    

                $ttime = &futurecheck($temp);     

                # if equal; make it span one day

                if(($dateStart == $dateEnd) && ($dateStart != 0)) {  
                   $dateEnd = $dateStart + $oneDayOfSecs;
                }
    
                # The message time stamp is older than the requested start date
                # get the next date
                if ($ttime < $dateStart) { 
			next;
		}

		if ( $first ) {
            if($ttime > $dateStart) {
			   $timeDiffers = $ttime;
		    }
		    $first = 0;
		}
        # The message time stamp is newer than the requested end date
        # so we are done
        if ($ttime > $dateEnd)  {  
			#printf("last\n");
			last;
		}
 
                if ( $HBA eq "S" ) {
                        
                    if ( $os_version eq $SOLARIS57 ) {
    
                        # look for offline messages
                        if ($line =~ /OFFLINE/) {
                            # are they socal?
                            ($myoff) = $line =~ /(socal\d+:\s+port\s+\d+)/;
                            if ( $myoff ) {
                                $SFOFFL{$myoff}++;
                            }
                        # look for WARNINGS
                        } elsif ($line =~ /WARNING/) {
                            # is it a FCAL disk? (ssd)
                            if ($line =~ /\((ssd\d+)\)/) {
                                ($mywarn) = $1;
                                $WARNSSD{$mywarn}++;
                                $line = shift @filestuff;
                                if ( $line =~ /Error for Command: write/i ) {
                                    if(checkParity(\@filestuff)) {
                                        $PARITYSSD{$mywarn}++;
                                        $PARITYSF{$ssdContList{$mywarn}}++;
                                    }
                                } else {
                                    unshift (@filestuff, $line);
                                }

                            # is it a Serial Fiber Port? (sf)
                            } elsif ($line =~ /\((sf\d+)\)/) {
                                ($mysfwarn) = $1;
                                ($mysf) = $line =~ /\((sf\d+)\):/;
                                $line = shift @filestuff ;
                                # look for CRC warnings
                                if ($line =~ /CRC/) {       
                                    # count it against the sf
                                    $SFCRCWARN{$mysfwarn}++;    
                                    # get an index for sf target
                                    my ($tmpt) = $line =~ /target=(0x[0-9a-f]+):/;
                                    my $mytarg = "${mysfwarn} target ${tmpt}";
                                    # count it against the sf target
                                    $DDCRCWARN{$mytarg}++;      
                                } elsif ($line =~ /Offline Timeout/) {
                                    $SFOFFTOWARN{$mysfwarn}++;
                                } elsif ($line =~ /INCOMPLETE DMA XFER/) {
                                    $SFDMAWARN{$mysfwarn}++;
                                # look for reset messages
                                } elsif ($line =~ /sf_reset/) {
                                    $SFRESET{$mysf}++;
                                # look for Extened Link Status messages
                                } elsif ($line =~ /ELS/) {
                                    ($mytarg) = $line =~ /(target\s+0x[0-9a-f]+)/;
                                    ($myidx) = "$mysf $mytarg";
                                    if ($line =~ /retrying/) {
                                        $RETRYELS{$myidx}++;
                                        $RETRYSF{$mysf}++;
                                    } elsif ($line =~ /timed out/) {
                                        $TOELS{$myidx}++;
                                        $SFTOELS{$mysf}++;
                                    }
                                }
                            }
                        # look for disk offline messages
                        } elsif ( ( $line =~ /offline/ ) && ( $line =~ /ssd/ ) ) {
                            ($ssd_wwn) = $line =~ /ssd\@w([a-f_0-9]+)/;
                            $DDOFFL{$ssd_wwn}++;
                        }
    
                    } else {
    
                        # look for offline messages
                        if ($line =~ /OFFLINE/) {
                            # are they socal?
                            ($myoff) = $line =~ /(socal\d+:\s+port\s+\d+)/;
                            if ( $myoff ) {
                                $SFOFFL{$myoff}++;
                            }
                        # look for WARNINGS
                        } elsif ($line =~ /WARNING/) {
                            # is it a FCAL disk? (ssd)
                            if ($line =~ /\((ssd\d+)\)/) {
                                ($mywarn) = $1;
                                $WARNSSD{$mywarn}++;
                                $line = shift @filestuff;
                                if ( $line =~ /Error for Command: write/i ) {
                                    if(checkParity(\@filestuff)) {
                                        $PARITYSSD{$mywarn}++;
                                        $PARITYSF{$ssdContList{$mywarn}}++;
                                    } 
                                } else {
                                    unshift (@filestuff, $line);
                                }

                            # is it a Serial Fiber Port? (sf)
                            } elsif ($line =~ /\((sf\d+)\)/) {
                                ($mysfwarn) = $1;
                                $line = shift @filestuff ;
                                # look for CRC warnings
                                if ($line =~ /CRC/) {       
                                    # count it against the sf
                                    $SFCRCWARN{$mysfwarn}++;    
                                    # get an index for sf target
                                    my ($tmpt) = $line =~ /target=(0x[0-9a-f]+):/;
                                    my $mytarg = "${mysfwarn} target ${tmpt}";
                                    # count it against the sf target
                                    $DDCRCWARN{$mytarg}++;      
                                } elsif ($line =~ /Offline Timeout/) {
                                    $SFOFFTOWARN{$mysfwarn}++;
                                } elsif ($line =~ /INCOMPLETE DMA XFER/) {
                                    $SFDMAWARN{$mysfwarn}++;
                                }
                            }
                        # look for reset messages
                        } elsif ($line =~ /sf_reset/) {
                            ($mysf) = $line =~ /(sf\d+)/;
                            $SFRESET{$mysf}++;
                        # look for Extened Link Status messages
                        } elsif ($line =~ /ELS/) {
                            ($mysf) = $line =~ /(sf\d+)/;
                            ($mytarg) = $line =~ /(target\s+0x[0-9a-f]+)/;
                            ($myidx) = "$mysf $mytarg";
                            if ($line =~ /retrying/) {
                                $RETRYELS{$myidx}++;
                                $RETRYSF{$mysf}++;
                            } elsif ($line =~ /timed out/) {
                                $TOELS{$myidx}++;
                                $SFTOELS{$mysf}++;
                            }
                        # look for disk offline messages
                        } elsif ($line =~ /offline/) {
                            ($mysf) = $line =~ /(sf\d+)/;
                            ($mytarg) = $line =~ /(target 0x[0-9a-f]+)/;
                            ($myidx) = "$mysf $mytarg";
                            $DDOFFL{$myidx}++;
                        }
    
                    }
    
                } elsif ( $HBA eq "P" ) {


                    # require 2 versions  



                    if ( $os_version eq "NOT_READY" ) {

			undef $lookahead;
                        $lookahead = shift @filestuff;
                        unshift (@filestuff, $lookahead);
			
                        if (   $line =~ /WARNING/ || $line =~ /LIP reset occured/ || $lookahead =~ /LIP reset occured/ ) {
    
                            if ( $line =~ /\((ssd\d+)\)/ ) {
                                ($mywarn) = $1;
                                $WARNSSD{$mywarn}++;
                                $line = shift @filestuff;

                                if ( $line =~ /Error for Command: write/i ) {
                                    if(checkParity(\@filestuff)) {
                                        $PARITYSSD{$mywarn}++;
                                        $PARITYSF{$ssdContList{$mywarn}}++;
                                    } 
                                } else {
                                    unshift (@filestuff, $line);
                                }

                            } elsif ( $line =~ /ifp/ ) {
                                $nextline = shift @filestuff;
                                if ( $line =~ /LIP reset occured/  ) {
                                    ($myoff) = $line =~ /(ifp\d+)/;
                                    $SFOFFL{$myoff}++;
				    printf("mark unshift\n");
                                    unshift (@filestuff, $nextline);
                                } elsif ( $nextline =~ /LIP reset occured/ ) {
                                    ($myoff) = $line =~ /(ifp\d+)/;
                                    $SFOFFL{$myoff}++;
				    printf("mark no unshift\n");
                                } elsif ($nextline =~ /CRC/) {       
                                    # count it against the ifp
                                    $SFCRCWARN{$mysfwarn}++;    
                                    my ($tmpt) = $line =~ /target=(0x[0-9a-f]+):/;
                                    my $mytarg = "${mysfwarn} target ${tmpt}";
                                    # count it against the ifp targ
                                    $DDCRCWARN{$mytarg}++;      
                                } elsif ($nextline =~ /DMA Failure/) {
                                    $SFDMAWARN{$mysfwarn}++;
                                } else { 
                                    unshift (@filestuff, $nextline);
				}
					
				undef $nextline;
                            } elsif ($line =~ /offline/) {
                                ($mysf) = $line =~ /(ifp\d+)/;
                                ($mytarg) = $line =~ /(target 0x[0-9a-f]+)/;
                                ($myidx) = "$mysf $mytarg";
                                $DDOFFL{$myidx}++;
                            }
                        }
    
                    } else {
    
			undef $nextline;
			undef $lookahead;

                        $lookahead = shift @filestuff;
                        unshift (@filestuff, $lookahead);
			
                        if (   $line =~ /WARNING/ || $line =~ /LIP reset occured/ || $lookahead =~ /LIP reset occured/ ) {


                            if ( $line =~ /\((ssd\d+)\)/ ) {
                                ($mywarn) = $1;
                                $WARNSSD{$mywarn}++;
                                $line = shift @filestuff;

                                if ( $line =~ /Error for Command: write/i ) {
                                    if(checkParity(\@filestuff)) {
                                        $PARITYSSD{$mywarn}++;
                                        $PARITYSF{$ssdContList{$mywarn}}++;
                                    } 
                                } else {
                                    unshift (@filestuff, $line);
                                }

                            } elsif ( $line =~ /ifp/ ) {
                                $nextline = shift @filestuff;
                                if ( $line =~ /LIP reset occured/  ) {
                                    ($myoff) = $line =~ /(ifp\d+)/;
                                    $SFOFFL{$myoff}++;
                                    unshift (@filestuff, $nextline);
                                } elsif ( $nextline =~ /LIP reset occured/ ) {
                                    ($myoff) = $line =~ /(ifp\d+)/;
                                    $SFOFFL{$myoff}++;
                                } elsif ($nextline =~ /CRC/) {       
                                    # count it against the ifp
                                    $SFCRCWARN{$mysfwarn}++;    
                                    my ($tmpt) = $line =~ /target=(0x[0-9a-f]+):/;
                                    my $mytarg = "${mysfwarn} target ${tmpt}";
                                    # count it against the ifp targ
                                    $DDCRCWARN{$mytarg}++;      
                                } elsif ($nextline =~ /DMA Failure/) {
                                    $SFDMAWARN{$mysfwarn}++;
                                } else {
                                    unshift (@filestuff, $nextline);
				}
	
                            } elsif ($line =~ /offline/) {
                                ($mysf) = $line =~ /(ifp\d+)/;
                                ($mytarg) = $line =~ /(target 0x[0-9a-f]+)/;
                                ($myidx) = "$mysf $mytarg";
                                $DDOFFL{$myidx}++;
                            }
                        }
    
                    }
                }
            }
            close (FILE);
        }
        print "end:",`/usr/bin/date`,"\n" if ($DEBUG);
        $startDateString = localtime($dateStart);
        $endDateString     = localtime($dateEnd);
        print "\nSummary report start time = $startDateString\n";
	if ( defined($timeDiffers)) {
		$diffString = localtime($timeDiffers);
        	print "First message entry date  = $diffString\n";
	}
        print "Summary report end time   = $endDateString\n";
    
       
        # display formatted FC-AL messages summary
        if ( ( $NO_GOLD ne "TRUE" ) && ( !$QUIET ) ) {
            &pr_ha_summary;
            &pr_disk_summary;
            if ( $DD_CNT == 0 ) {
                print "Disk(s) log NOT generated!\n";
                print "Probable cause(s):\n";
                print "  invalid or missing Golden Snapshot\n";
                print "  no -ssd- entries in the Golden Snapshot - RAWDUMP section\n";
                print "  Golden Snapshot:  ${GOLD_PATH}/$golden_log\n";
                print "Long listing enabled.\n";
                $LONG_OUT = "TRUE";
                $NO_GOLD = "TRUE";
            }
        }
    
    
        # display raw FC-AL messages summary
        $LF = 0;
        $LINES = 0;
        if ( ( $LONG_OUT ) && ( ! $QUIET ) ) {
            print "\nLong Listing:\n\n";
            foreach $key (sort keys %SFCRCWARN) {
                $ERROR_FLAG = "TRUE";
                print "SF WARNING: (CRC)  $key = $SFCRCWARN{$key}\n";
                $SFCRCWARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %SFOFFTOWARN) {
                $ERROR_FLAG = "TRUE";
                print "SF OFFLINE TIMEOUT: $key = $SFOFFTOWARN{$key}\n";
                $SFOFFTOWARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %SFDMAWARN) {
                $ERROR_FLAG = "TRUE";
                print "SF DMA XFER ERROR: $key = $SFDMAWARN{$key}\n";
                $SFDMAWARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $count (sort keys %SFOFFL) {
                $ERROR_FLAG = "TRUE";
                print "OFFLINE: $count = $SFOFFL{$count}\n";
                $SFOFFL{$count} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $elssf (sort keys %TOELS) {
                $ERROR_FLAG = "TRUE";
                print "ELS TIME OUT: $elssf = $TOELS{$elssf}\n";
                $TOELS{$elssf} = 0;
                $LINES++;
            } 
            pr_lf();
            foreach $elssf (sort keys %RETRYELS) {
                $ERROR_FLAG = "TRUE";
                print "ELS RETRY: $elssf = $RETRYELS{$elssf}\n";
                $RETRYELS{$elssf} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $sf (sort keys %SFTOELS) {
                $ERROR_FLAG = "TRUE";
                print "sf ELS TIME OUT: $sf = $SFTOELS{$sf}\n";
                $SFTOELS{$sf} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $sf (sort keys %RETRYSF) {
                $ERROR_FLAG = "TRUE";
                print "sf ELS RETRY: $sf = $RETRYSF{$sf}\n";
                $RETRYSF{$sf} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %SFRESET) {
                $ERROR_FLAG = "TRUE";
                print "sf reset $key = $SFRESET{$key}\n";
                $SFRESET{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %DDOFFL) {
                $ERROR_FLAG = "TRUE";
                print "ssd offline: $key = $DDOFFL{$key}\n";
                $DDOFFL{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $ssdinst (sort keys %WARNSSD) {
                $ERROR_FLAG = "TRUE";
                print "ssd WARNING: $ssdinst = $WARNSSD{$ssdinst}\n";
                $WARNSSD{$ssdinst} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $ssdinst (sort keys %DDCRCWARN) {
                $ERROR_FLAG = "TRUE";
                print "ssd CRC WARNING: $ssdinst = $DDCRCWARN{$ssdinst}\n";
                $DDCRCWARN{$ssdinst} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $ssdinst (sort keys %PARITYSSD) {
                $ERROR_FLAG = "TRUE";
                print "ssd PARITY WARNING: $ssdinst = $PARITYSSD{$ssdinst}\n";
                $PARITYSSD{$ssdinst} = 0;
                $LINES++;
            }
            pr_lf();
            #
            # T300 ERROR MESSAGE HANDLING
            #
            if  ($T300_WARNINGS && ( $STORAGE eq "T3" ) ) {

            foreach $key (sort keys %P01WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING Reset Occurred: $key = $P01WARN{$key}\n";
                $P01WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P02WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING Assertion Reset Occurred: $key = $P02WARN{$key}\n";
                $P02WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P03WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING Disk Error occurred during reconstruction: $key = $P03WARN{$key}\n";
                $P03WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P04WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING Initialization of RAID parity failed: $key = $P04WARN{$key}\n";
                $P04WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P05WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING Reconstruct operation failed: $key = $P05WARN{$key}\n";
                $P05WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P06WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING hard error on disk occurred: $key = $P06WARN{$key}\n";
                $P06WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P07WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING write disk failed: $key = $P07WARN{$key}\n";
                $P07WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P08WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING could not open plugged disk: $key = $P08WARN{$key}\n";
                $P08WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P09WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING could not create system area: $key = $P09WARN{$key}\n";
                $P09WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P10WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING system area is bad: $key = $P10WARN{$key}\n";
                $P10WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P11WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING attempt to bring newly plugged disk online failed: $key = $P11WARN{$key}\n";
                $P11WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P13WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING attempt to verify the data in the system area failed: $key = $P13WARN{$key}\n";
                $P13WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P14WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING SCSI disk driver error: $key = $P14WARN{$key}\n";
                $P14WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P15WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING Master controller failed to send out heartbeats: $key = $P15WARN{$key}\n";
                $P15WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P16WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING Bypassed a disk drive on loop A: $key = $P16WARN{$key}\n";
                $P16WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P17WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING Bypassed a disk drive on loop B: $key = $P17WARN{$key}\n";
                $P17WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P18WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING System detects fan fault on pcu: $key = $P18WARN{$key}\n";
                $P18WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P19WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING System detects fan fault on pcu: $key = $P19WARN{$key}\n";
                $P19WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P20WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING DC on pcu not ok: $key = $P20WARN{$key}\n";
                $P20WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P21WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING pcu is disabled: $key = $P21WARN{$key}\n";
                $P21WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P22WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING pcu is off: $key = $P22WARN{$key}\n";
                $P22WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P23WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING pcu switched to battery: $key = $P23WARN{$key}\n";
                $P23WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P24WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING battery not present: $key = $P24WARN{$key}\n";
                $P24WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P25WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING pcu switched off: $key = $P25WARN{$key}\n";
                $P25WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P26WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING loop card offline: $key = $P26WARN{$key}\n";
                $P26WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P27WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING loop card disabled: $key = $P27WARN{$key}\n";
                $P27WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P28WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING system disabled a controller: $key = $P28WARN{$key}\n";
                $P28WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P29WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING battery took too long to recharge: $key = $P29WARN{$key}\n";
                $P29WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P30WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING Disk Reconstruct failed: $key = $P30WARN{$key}\n";
                $P30WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P31WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING Disk Disable failed for disk: $key = $P31WARN{$key}\n";
                $P31WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P32WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING Disk hot plug in installation failed: $key = $P32WARN{$key}\n";
                $P32WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P33WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING System detects multiple bit error in controller's memory: $key = $P33WARN{$key}\n";
                $P33WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P34WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING System detects multiple disk failure in a lun: $key = $P34WARN{$key}\n";
                $P34WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P35WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING Previously inserted disk in wrong position: $key = $P35WARN{$key}\n";
                $P35WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P36WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING Read Failed: $key = $P36WARN{$key}\n";
                $P36WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P37WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING Replace Battery, hold time low: $key = $P37WARN{$key}\n";
                $P37WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P38WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING Replace Batery: $key = $P38WARN{$key}\n";
                $P38WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P39WARN) {
                $ERROR_FLAG = "TRUE";
                print "T300 WARNING Replace Batery: $key = $P39WARN{$key}\n";
                $P39WARN{$key} = 0;
                $LINES++;
            }
            pr_lf();

            }

            #
            # T300 ERROR MESSAGE HANDLING
            #
            if ($T300_ERRORS && ( $STORAGE eq "T3" ) ) {

            foreach $key (sort keys %P01ERR) {
                $ERROR_FLAG = "TRUE";
                print "T300 ERROR Controller Not Present: $key = $P01ERR{$key}\n";
                $P01ERR{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P02ERR) {
                $ERROR_FLAG = "TRUE";
                print "T300 ERROR Missing Disk Drive: $key = $P02ERR{$key}\n";
                $P02ERR{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P03ERR) {
                $ERROR_FLAG = "TRUE";
                print "T300 ERROR Missing Controller: $key = $P03ERR{$key}\n";
                $P03ERR{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P04ERR) {
                $ERROR_FLAG = "TRUE";
                print "T300 ERROR Multiple Fan Faults: $key = $P04ERR{$key}\n";
                $P04ERR{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P05ERR) {
                $ERROR_FLAG = "TRUE";
                print "T300 ERROR Missing Power Supply Unit: $key = $P05ERR{$key}\n";
                $P05ERR{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P06ERR) {
                $ERROR_FLAG = "TRUE";
                print "T300 ERROR Power Supply Unit Over Temperature: $key = $P06ERR{$key}\n";
                $P06ERR{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P07ERR) {
                $ERROR_FLAG = "TRUE";
                print "T300 ERROR Missing Loop Card: $key = $P07ERR{$key}\n";
                $P07ERR{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P08ERR) {
                $ERROR_FLAG = "TRUE";
                print "T300 ERROR Missing (UP) Cable for Loop Card: $key = $P08ERR{$key}\n";
                $P08ERR{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P09ERR) {
                $ERROR_FLAG = "TRUE";
                print "T300 ERROR Missing (DOWN) Cable for Loop Card: $key = $P09ERR{$key}\n";
                $P09ERR{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P10ERR) {
                $ERROR_FLAG = "TRUE";
                print "T300 ERROR Battery not present: $key = $P10ERR{$key}\n";
                $P10ERR{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P11ERR) {
                $ERROR_FLAG = "TRUE";
                print "T300 ERROR Missing Power Unit: $key = $P11ERR{$key}\n";
                $P11ERR{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P12ERR) {
                $ERROR_FLAG = "TRUE";
                print "T300 ERROR Missing Disk: $key = $P12ERR{$key}\n";
                $P12ERR{$key} = 0;
                $LINES++;
            }
            pr_lf();
            foreach $key (sort keys %P13ERR) {
                $ERROR_FLAG = "TRUE";
                print "T300 ERROR Missing Loop Card: $key = $P13ERR{$key}\n";
                $P13ERR{$key} = 0;
                $LINES++;
            }
            pr_lf();
            }
        }
        if ( ( $sleep_time > 0 ) && ( $iterations != 0 ) ) {
            sleep( $sleep_time );
        }
    } until ( $iterations == 0 );

if ( defined $QUIET ) {
    if ( defined $ERROR_FLAG ) {
        print "$PROGNAME detected errors!\n";
    } else {
        print "$PROGNAME completed!\n";
    }
}
####################################################################
#           SUBROUTINES
####################################################################

####################################################################
# print header message if long output
####################################################################
sub pr_header {
    &st_header();
    print "FCAL Messages Summary\n";
    print "---------------------\n";
    print "The following counters represent events recorded in the specified\n";
    print "message file(s). A non-zero value does not necessarily\n";
    print "indicate a problem. Some non-zero values indicate normal\n";
    print "operation. The values are presented to facilitate diagnosis\n";
    print "of a FCAL disk sub-system.\n";
    print "\n";
    print "Note: A current Golden Snapshot is required for a meaningful\n";
    print "      message analysis. Use the cli $PROGNAME -l if the\n";
    print "      snapshot is invalid.\n";
    print "\n";
}
################################################################
# print the summary information
#  [phys path]  [socal+ port] [sf] [offline] [warn] [timeout]
################################################################
sub pr_ha_summary {

    print "\n";
    @cfs = (54, 12 );
    
    if ( $HBA eq "P" ) {
    	printf("%-$cfs[0]s%-$cfs[1]s\n",
       	    "Controller(s)", "FC100");
    	printf("%-$cfs[0]s%-$cfs[1]s\n",
       	    "-------------", "------");
    	foreach $path (@ALL_FCAL_PORTS) {
       	  printf("%-$cfs[0]s%-$cfs[1]s\n",
       	        "$path ($CNUM{$path})", "$SOCNUM{$path}" );
	}
    } else {
    	printf("%-$cfs[0]s%-$cfs[1]s\n",
       	    "Controller(s)", "FC100:port");
    	printf("%-$cfs[0]s%-$cfs[1]s\n",
       	    "-------------", "----------");
    	foreach $path (@ALL_FCAL_PORTS) {
       	 printf("%-$cfs[0]s%-$cfs[1]s\n",
       	        "$path ($CNUM{$path})", "$SOCNUM{$path}:$PORTNUM{$path}" );
	}
    }

    print "\n";

    if ( $HBA eq "S" ) {
        @pfs = (12, 5, 9, 6, 8, 5);
        printf("%-$pfs[0]s%-$pfs[1]s%-$pfs[2]s%-$pfs[3]s%-$pfs[4]s%-$pfs[5]s\n",
           "FC100:Port", "sf", "OFF/LIP", "CRC", "PARITY", "DMA");
        printf("%-$pfs[0]s%-$pfs[1]s%-$pfs[2]s%-$pfs[3]s%-$pfs[4]s%-$pfs[5]s\n",
           "----------", "--", "-------", "---", "------", "---");
        foreach $path (@ALL_FCAL_PORTS) {
            $socal_port = "$SOCNUM{$path}: port $PORTNUM{$path}";
            $sfnum = $SFNUM{$path};
            if (!defined $SFOFFL{$socal_port}) {
                $SFOFFL{$socal_port} = 0;
            } else {
                $ERROR_FLAG = "TRUE";
            }
            if (!defined $SFCRCWARN{$sfnum}) {
                $SFCRCWARN{$sfnum} = 0;
            } else {
                $ERROR_FLAG = "TRUE";
            }
            if (!defined $SFDMAWARN{$sfnum}) {
                $SFDMAWARN{$sfnum} = 0;
            } else {
                $ERROR_FLAG = "TRUE";
            }
            if (!defined $PARITYSF{$path}) {
                $PARITYSF{$path} = 0;
            } else {
                $ERROR_FLAG = "TRUE";
            }

            printf("%-$pfs[0]s%-$pfs[1]s%-$pfs[2]s%-$pfs[3]s%-$pfs[4]s%-$pfs[5]s\n",
                   "$SOCNUM{$path}:$PORTNUM{$path}", 
                   $SFNUM{$path}, $SFOFFL{$socal_port}, 
                   $SFCRCWARN{$sfnum}, $PARITYSF{$path}, $SFDMAWARN{$sfnum});
           # if -l do NOT clear until the long output is done
           if ( $LONG_OUT ne "TRUE" ) {
               $SFOFFL{$socal_port} = 0;
               $SFCRCWARN{$sfnum} = 0;
               $SFDMAWARN{$sfnum} = 0;
               $PATIYSF{$path} = 0;
           }
        }
    } elsif ( $HBA eq "P" ) {

        @pfs = (12, 9, 9, 9, 6);
        printf("%-$pfs[0]s%-$pfs[1]s%-$pfs[2]s%-$pfs[3]s%-$pfs[4]s\n",
           "FC100", "OFF/LIP", "CRC", "PARITY", "DMA");
        printf("%-$pfs[0]s%-$pfs[1]s%-$pfs[2]s%-$pfs[3]s%-$pfs[4]s\n",
           "------", "-------", "---", "-------", "----");
        foreach $path (@ALL_FCAL_PORTS) {
            $socal_port = "$SOCNUM{$path}: port $PORTNUM{$path}";
            $sfnum = $SFNUM{$path};
            if (!defined $SFOFFL{$SOCNUM{$path}}) {
                $SFOFFL{$SOCNUM{$path}} = 0;
            } else {
                $ERROR_FLAG = "TRUE";
            }
            if (!defined $SFCRCWARN{$sfnum}) {
                $SFCRCWARN{$sfnum} = 0;
            } else {
                $ERROR_FLAG = "TRUE";
            }
            if (!defined $SFDMAWARN{$sfnum}) {
                $SFDMAWARN{$sfnum} = 0;
            } else {
                $ERROR_FLAG = "TRUE";
            }
            if (!defined $PARITYSF{$path}) {
                $PARITYSF{$path} = 0;
            } else {
                $ERROR_FLAG = "TRUE";
            }
            printf("%-$pfs[0]s%-$pfs[1]s%-$pfs[2]s%-$pfs[3]s%-$pfs[4]s\n",
                   "$SOCNUM{$path}", 
                   $SFOFFL{$SOCNUM{$path}}, $SFCRCWARN{$sfnum}, $PARITYSF{$path}, $SFDMAWARN{$sfnum});
           # if -l do NOT clear until the long output is done
           if ( $LONG_OUT ne "TRUE" ) {
               $SFOFFL{$socal_port} = 0;
               $SFCRCWARN{$sfnum} = 0;
               $SFDMAWARN{$sfnum} = 0;
           }
        }
    }
    print "\n";
}

################################################################
#
################################################################
sub pr_disk_summary {

    $cnum_idx = 3;
    $wwn_idx = 2;
    $ssd_idx = 8;
    print "\n";

    @pfd = (15, 20, 10, 10, 10, 5, 9);

    $DD_CNT = 0;

    
    foreach $diskdr (sort keys %DDID) {
        $DD_CNT++;
        if ( $DD_CNT == 1 ) {
            if ( $STORAGE eq "A5" ) {
                printf("%-$pfd[0]s%-$pfd[1]s%-$pfd[2]s%-$pfd[3]s%-$pfd[4]s%-$pfd[5]s%-$pfd[6]s\n", "Disk(s)", "Enclosure,Location", "ssd", "offline", "WARNING", "CRC", "PARITY");
                printf("%-$pfd[0]s%-$pfd[1]s%-$pfd[2]s%-$pfd[3]s%-$pfd[4]s%-$pfd[5]s%-$pfd[6]s\n", "-------", "------------------", "---", "-------", "-------", "---", "------");
            } elsif ( $STORAGE eq "T3" ) {
                printf("%-$pfd[0]s%-$pfd[1]s%-$pfd[2]s%-$pfd[3]s%-$pfd[4]s%-$pfd[5]s\n", "Disk(s)", "ssd", "offline", "WARNING", "CRC", "PARITY");
                printf("%-$pfd[0]s%-$pfd[1]s%-$pfd[2]s%-$pfd[3]s%-$pfd[4]s%-$pfd[5]s\n", "-------", "---", "-------", "-------", "---", "------");
            }
        }
        (@mydd) = split(' ', $DDID{$diskdr});
        ($mycnum) = $mydd[$cnum_idx] =~ /^(c\d+)t\d+/;
        ($myddsf) = $CN2SF{$mycnum};
        ($mytarg) = "target 0x${mydd[6]}";
        ($mysftg) = "$myddsf $mytarg";
        ($ssd_wwn) = $mydd[$wwn_idx];
        if ( $os_version ne $SOLARIS57 ) {
            $ssd_wwn = $mysftg;
        }

        if (!defined $WARNSSD{$mydd[$ssd_idx]}) {
            $WARNSSD{$mydd[$ssd_idx]} = 0;
        } else {
            $ERROR_FLAG = "TRUE";
        }
        if (!defined $PARITYSSD{$mydd[$ssd_idx]}) {
            $PARITYSSD{$mydd[$ssd_idx]} = 0;
        } else {
            $ERROR_FLAG = "TRUE";
        }
        if (!defined $TOELS{$mysftg}) {
            $TOELS{$mysftg} = 0;
        } else {
            $ERROR_FLAG = "TRUE";
        }
        if (!defined $DDOFFL{$ssd_wwn}) {
            $DDOFFL{$ssd_wwn} = 0;
        } else {
            $ERROR_FLAG = "TRUE";
        }
        if (!defined $DDCRCWARN{$mysftg}) {
            $DDCRCWARN{$mysftg} = 0;
        } else {
            $ERROR_FLAG = "TRUE";
        }


        if ( $STORAGE eq "A5" ) {
            printf("%-$pfd[0]s%-$pfd[1]s%-$pfd[2]s%-$pfd[3]s%-$pfd[4]s%-$pfd[5]s%-$pfd[6]s\n", $mydd[$cnum_idx], $mydd[0], $mydd[$ssd_idx], $DDOFFL{$ssd_wwn}, $WARNSSD{$mydd[$ssd_idx]}, $DDCRCWARN{$mysftg}, $PARITYSSD{$mydd[$ssd_idx]});
        } elsif ( $STORAGE eq "T3" ) {
            printf("%-$pfd[0]s%-$pfd[1]s%-$pfd[2]s%-$pfd[3]s%-$pfd[4]s%-$pfd[5]s\n", $mydd[$cnum_idx], $mydd[$ssd_idx], $DDOFFL{$ssd_wwn}, $WARNSSD{$mydd[$ssd_idx]}, $DDCRCWARN{$mysftg}, $PARITYSSD{$mydd[$ssd_idx]});
        }
        # if -l do NOT clear until the long output is done
        if ( $LONG_OUT ne "TRUE" ) {
            $DDCRCWARN{$mysftg} = 0;
            $DDOFFL{$ssd_wwn} = 0;
            $TOELS{$mysftg} = 0;
            $WARNSSD{$mydd[8]} = 0;
            $PARITYSSD{$mydd[8]} = 0;
        }
    }

    print "\n";
}


################################################################
# make a list of names
# if name is an input, then single item in list
# else (all), then go discover all of the box names
# connected to this system via the rawdump
################################################################
sub make_name_list {

    &make_port_list( $HBA );

    push @ALL_FCAL_PORTS, @LD_A5_PORTS;
    push @ALL_FCAL_PORTS, @LD_T3_PORTS;
    push @ALL_FCAL_PORTS, @LD_MB_PORTS;

    @storage_list = @GOLDRAW;
    $ssd_idx = 8;
    $cnum_idx = 3;

    foreach $line (@storage_list) {
        (@rawline) = split(' ', $line);
        if ($rawline[$ssd_idx] =~ /^ssd/) {
            # save the entire Disk Drive line indexed by the c#t#d#
            ($cnum) = $rawline[$cnum_idx] =~ /^c(\d+)t\d+/;
            ($tnum) = $rawline[$cnum_idx] =~ /^c\d+t(\d+)/;
            if ( $STORAGE eq "A5" ) {
                $ddid_key = sprintf( "%03d%03d", $cnum, $tnum ); 
            } elsif ( $STORAGE eq "T3" ) {
                ($dnum) = $rawline[$cnum_idx] =~ /^c\d+t\d+d(\d+)/;
                $ddid_key = sprintf( "%03d%03d%03d", $cnum, $tnum, $dnum ); 
            }
            $DDID{$ddid_key} = $line;
        }
    }

    foreach $path (@ALL_FCAL_PORTS) {
        $CN2SF{ $CNUM{ $path } } = $SFNUM{ $path };
        print "DEBUG:  This is the cnum:  $CNUM{$path} \t phys = $path \t sf = $CN2SF{$path} \n" if ( $DEBUG );
    }

    if ( ($NO_GOLD ne "TRUE") && ( ! @ALL_FCAL_PORTS ) ) {
        print "No Fibre Channel Components Online\n\n";
        exit();
    }

}
####################################################################
# get the rawdump information from the snapshot
#
####################################################################
sub get_rawdump {
    if ( $HBA eq "S" ) {
        $golden_log = &get_golden_snapshot( $GOLD_PATH );
        if (($golden_log ne "") & (-e "${GOLD_PATH}/${golden_log}")) {
            unless (open(GOLDFILE, "${GOLD_PATH}/${golden_log}")) { 
                print "\nUnable to open golden logfile: ${GOLD_PATH}/$golden_log\n";
                print "FC-AL formatted summary NOT generated.\n";
                print "Long listing enabled.\n\n";
                $LONG_OUT = "TRUE";
                $NO_GOLD = "TRUE";
                return;
            }      
        } else {
            print "\nUnable to find Golden Snapshot:  ${GOLD_PATH}/$golden_log\n";
            print "FC-AL formatted summary NOT generated.\n";
            print "Long listing enabled.\n\n";
            $LONG_OUT = "TRUE";
            $NO_GOLD = "TRUE";
            return;
        }

        $found_section = "FALSE";

        while ($line=<GOLDFILE>) {
            if ($line =~ /^RAWDUMP:/) {
                $found_section = "TRUE";
                next;
            }
            next if ($found_section eq "FALSE");
            last if ($line =~ /^============/);
            my $temp = $line;   
            $temp =~ tr/ //s;
            @a= split(/ /, $temp);
                                        # keep track of SSD's and associate with
                                        # controllers for future use.
            if ( $line =~ /^\*HA\*/ ) { # look for host adapter  
                $cont = $a[10];
                chomp $cont;
            }
            my $ssd = $a[8];
            $ssdContList{$ssd} = $cont;
            push @GOLDRAW, $line;
        }
        close GOLDFILE;
    } elsif ( $HBA eq "P" ) {
        @GOLDRAW = `/usr/bin/ksh -c '${BINDIR}/rawdump -$HBA -$STORAGE 2>&1'`;
        if ($GOLDRAW[0] =~ /not\s+found/i) {
            print "ERROR : ${BINDIR}/rawdump not found!\n";
            print "FC-AL formatted summary NOT generated.\n";
            print "Long listing enabled.\n\n";
            $LONG_OUT = "TRUE";
            $NO_GOLD = "TRUE";
         }
    }

}

###############################################################
# Process the command line inputs
###############################################################

sub proc_cli {
    @usage = 
    (
     "USAGE:  $PROGNAME [-S] [-P] [-A5] [-T3] [-l] [-iw] [-ie] [-dir <dir>] [-dg] [-f <file>] [-s <date>] [-e <date>] [-i # #] [-q]\n",
     "\t-S      = SBUS HBA\n",
     "\t-P      = PCI HBA\n",
	 "\t-A5     = Select A5K Series Storage (default)\n",
     "\t-T3     = Select T300 Series Storage\n",
     "\t-l      = long output (default for T300)\n",
     "\t-dir    = select a directory for messages\n",
     "\t-f file = select a message file\n",
     "\t-dg     = disable use of Golden Snapshot\n",
     "\t-s date = start date format mm/dd:hh:mm:ss - default first log entry\n",
     "\t-e date = end date format mm/dd:hh:mm:ss - default current\n",
     "\t-i # #  = iterate $PROGNAME # of times with # seconds delay, 0=infinite\n",
     "\t-iw     = Ignore T300 Warning Messages (default on)\n",
     "\t-ie     = Ignore T300 Error Messages (default on)\n",
     "\t-q      = Quiet - Only display the detection of errors (internal use)\n"
     );
    $LONG_OUT = undef;
    $DEBUG = undef;
    $FIL_MESS = "";
    $ITERATIONS = -1;
    $STORAGE = "A5";
    $T300_ERRORS = "TRUE";
    $T300_WARNINGS = "TRUE";  
    $T300_MESSAGES = "${DIR_MESS}/messages.t300";
    undef $QUIET;

    while($arg = shift @ARGV) {
        if ($arg =~ /^-S/) {
            $HBA = "S";
            check_bus_option( $HBA );
        } elsif ($arg =~ /^-P/) {
            $HBA = "P";
            check_bus_option( $HBA );
        } elsif ($arg =~ /^-l/) {
            $LONG_OUT = "TRUE";
        } elsif ($arg =~ /^-debug/i) {
            # Intended to be an undocumented option.
            $DEBUG = "TRUE";
            print "******* DEBUG MODE ********* \n\n"
        } elsif ($arg =~ /^-dg/i) {
            $NO_GOLD = "TRUE";
            $LONG_OUT = "TRUE";
        } elsif ($arg =~ /^-dir/i) {
            $DIR_MESS = shift @ARGV;
            print "Checking $DIR_MESS ... \n";
            if (! -e $DIR_MESS) {
                print STDERR "$DIR_MESS does not exist\n";
                exit 1;
            }
        } elsif ($arg =~ /^-f/i) {
            $infile = shift @ARGV;
            ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($infile);
            if (-e $infile && ($size > 0)) {
                $FIL_MESS = $infile;
            } else {
                print "$infile does not exist or has zero length\n";
                exit 1;
            }
        } elsif ($arg =~ /^-s/) {
            $datestr = shift @ARGV;
            &checkdate($datestr);
            $dateStart = str2time($datestr);
            undef $datestr;
        } elsif ($arg =~ /^-e/) {
            $datestr = shift @ARGV;
            &checkdate($datestr);
            $dateEnd = str2time($datestr);
        
            if(! ($datestr =~ /\:/)) {
                $dateEnd += $oneDayOfSecs-1;    
            }
            if($dateStart > $dateEnd) {
                printf("invalid date: Start date is later than End date!\n");
                exit 1;
            }
        
            undef $datestr;
        } elsif ($arg =~ /^-i/) {
            $ITERATIONS = shift @ARGV;
            if ($ITERATIONS !~ /\d+/) {
                die "\ninvalid -i iterations argument $ITERATIONS!\n\n @usage";
            }
            $SLEEP_TIME = shift @ARGV;
            if ($SLEEP_TIME !~ /\d+/) {
                die "\ninvalid -i delay argument $SLEEP_TIME!\n\n @usage";
            }
            $LOOP = "TRUE";
        } elsif ($arg =~ /-A5/i) {
            $STORAGE      = "A5";
        } elsif ($arg =~ /-T3/i) {
            $LONG_OUT = "TRUE";
            $STORAGE      = "T3";
        } elsif ($arg =~ /^-iw/) {
            $T300_WARNINGS = "FALSE";
        } elsif ($arg =~ /^-ie/) {
            $T300_ERRORS = "FALSE";
        } elsif ($arg =~ /^-q/) {
            $QUIET = "TRUE";
        } elsif ($arg =~ /[\?|h]/i) {
            die @usage;
        } else {
            die "\n$arg is an invlaid option!\n\n @usage";
        }
    }
    $GOLD_PATH  = "${LOGDIR}/${STORAGE}";
    if ( $HBA ne "P" && $HBA ne "S" ) {
       &get_fcal_hbas();
       &select_fcal_hbas();
    }

}
#############################################################
# checkdate - parse the date string for validity
#############################################################
sub checkdate {

    my $datestring = shift @_;
    my $now = time;
    my $limit = $now - (35*24*60*60);
    my $t;

    @a = split(/\:/, $datestring);
    ($m, $d, $y) = split(/\//, $a[0]);


    if(! ($y =~ /\d{4}/) ) { 
        print STDERR "$y is not a legitimate year.  Please use 4 digits.\n";

	exit 1;
    }

    if($m > 12 && $m < 1) { 
        print STDERR "$m is not a legitimate month\n";
        exit 1;
    }

    if ( $d < 1 ) {
        print STDERR "$d is not a legitimate day\n";
        exit 1;
    }

    $t = str2time($datestring);

    if (!defined($t)) {
        print STDERR "$datestring is not a legitimate date\n";
        exit 1;
    } elsif ($t > $now) {
        print STDERR "$datestring is in the future\nPlease select another date\n";
        exit 1;
    }
}
#############################################################
# futurecheck - be sure the date we have is real
#############################################################
sub futurecheck {
    my ($dstr) = @_;
    my $t = str2time("$dstr $year");
    if ($t > time) {
        my $lastyear = $year - 1;
        $t = str2time("$dstr $lastyear");
    }
    return $t;
}
#############################################################
# print lf only if needed
#############################################################
sub pr_lf {
    print "\n" if ( $LF < $LINES );
    $LF = $LINES;
}


#############################################################
# check for parity errors in the input array 
# arg0 = Warning line
# arg1 = Array of lines from the current messages file
#############################################################




sub checkParity {

        my $temp = $_[0];


        my @filestuff = @$temp;



        my @save = ();  

        my $parity = 0;
        
        #look ahead about 5 lines
        $lookahead = 5;

        for ( $i = 0; $i < $lookahead; $i++ ) {

                my $temp = shift @filestuff;  # get next line
                
                push (@save, $temp);
                if ( $temp =~ /parity/i ) {
                        chomp $temp;
                        return(1);
                }
        }

        # no parity so put look ahead lines back into array
        while ( $z = pop @save ) {
                unshift (@filestuff, $z);
        }


        return(0);

                        


                


}
        


