#!/usr/bin/perl
#############################################################################
# Copyright 2001 Sun Microsystems, Inc. 
# All rights reserved.
# This software is the proprietary information of Sun Microsystems, Inc.
# Use is subject to license terms.
#
# Copyright 2001 Sun Microsystems, Inc. Pour certaines parties
# 
# Tous droits r\351serv\351s.
# Ce logiciel est propriet\351 de Sun Microsystems, Inc.
# Distribu\351 par des licences qui en restreignent l'utilisation.
#
#
# SunOne Access Log Analyzer 5.2  
#
#
# Written by: Mark Reynolds  mark.reynolds@sun.com
#
# last modified:  2/9/2004 
#############################################################################


#
# Check for usage
#

if ($#ARGV < 0){;
&displayUsage;
}

#######################################
#                                     #
# parse commandline switches          #
#                                     #
#######################################

$x = "0";
$fc = 0;
$sn = 0;
$manager = "cn=directory manager";
$logversion = "5.2";
$sizeCount = "20";
$myInterval = "NONE";

while ($sn <= $#ARGV)
{
  	if ("$ARGV[$sn]" eq "-d") {
    		$manager = $ARGV[++$sn];
  	} elsif ("$ARGV[$sn]" eq "-v") {
    		print "SunOne Access Log Analyzer v$logversion\n";;
    		exit (0);
	} elsif ("$ARGV[$sn]" eq "-E") {
		$errorCode = $ARGV[++$sn];
		$plugin++;
  	} elsif ("$ARGV[$sn]" eq "-V") {
    		$verb = "yes";
	} elsif ("$ARGV[$sn]" eq "-N") {
		$resolveIP = "yes";
  	} elsif ("$ARGV[$sn]" eq "-X") {
		$exclude[$x] = $ARGV[++$sn];
		$x++;
  	} elsif ("$ARGV[$sn]" eq "-s") {
		$sizeCount = $ARGV[++$sn];
	} elsif ("$ARGV[$sn]" eq "-I") {
		$myInterval = $ARGV[++$sn];
	} elsif ("$ARGV[$sn]" eq "-DELIM") {
                $DELIM = "true";
	} elsif ("$ARGV[$sn]" eq "-R") {
		$reportFile = $ARGV[++$sn];
		$plugin++;
	} elsif ("$ARGV[$sn]" eq "-C") {
		$connFile = $ARGV[++$sn];
		$plugin++;
	} elsif ("$ARGV[$sn]" eq "-B") {
		$bindFile = $ARGV[++$sn];
		$plugin++;
	} elsif ("$ARGV[$sn]" eq "-A0"){
		$clientFile =  $ARGV[++$sn];
                $plugin++;
		$clientOpt = "ops";
	} elsif ("$ARGV[$sn]" eq "-P"){
		$pending = "yes";
	} elsif ("$ARGV[$sn]" eq "-A1"){
		$clientFile =  $ARGV[++$sn];
                $plugin++;
                $clientOpt = "conn";
  	} elsif ("$ARGV[$sn]" eq "-h") {
    		&displayUsage;
  	} elsif ("$ARGV[$sn]" =~ m/^-/) {
		$usage = $ARGV[$sn];
  	} else {
    		$files[$fc] = $ARGV[$sn];
    		$fc++;
  	}
  	$sn++;
}

if ($sizeCount eq "all"){$sizeCount = "10000000";}

if ($plugin > 1){
        print "You can only use one plugin component at a time!!\n";
        exit 1;
}

#######################################
#                                     #
# Initialize Arrays and variables     #
#                                     #
#######################################

print "\nSunOne Access Log Analyzer $logversion";
print "\n\nInitializing Variables...";

# check for plugins

if ($errorCode ne "") { &parseError; }
if ($reportFile ne ""){ &report; }
if ($connFile ne ""){ &connCheck; }
if ($bindFile ne ""){ &checkBind; }
if ($clientFile ne ""){ &checkClient; }
if ($pending eq "yes") { &checkPending; }

# end of plugins

$pcount = "0";
$preport = "0";
$dirmgr = "0";
$notes = "0";
$vlvnotes= "0";
$search = "0";
$fdtake = "0";
$fdreturn = "0";
$highfd = "0";
$bind = "0";
$unbind = "0";
$anony = "0";
$mod = "0";
$delete = "0";
$add = "0";
$modrdn = "0";
$restarts = "0";
$resource = "0";
$broken = "0";
$vlv = "0";
$version2 = "0";
$version3 = "0";
$sortvlv = "0";
$reset = "0";
$vet = "0";
$v = "0";
$errorck = "0";
$errorsucc = "0";
$sslconn = "0";
$sslClientBind = "0";
$sslClientFailed = "0";
$objectclass= "0";
$nc = "0";
$no = "0";
$nt = "0";
$bc = "0";
$fcc = "0";
$nent = "0";
$allOps = "0";
$allResults = "0";
$bpc = "0";
$bpo = "0";
$abandon = "0";
$mmasterop = "0";
$extendedop = "0";
$sasl = "0";
$internal = "0";
$entryOp = "0";
$referral = "0";
$anyAttrs = "0";
$persistent = "0";
$sconn = "0";
$dconn = "0";
$aconn = "0";
$mconn = "0";
$mdconn = "0";
$bconn = "0";
$ubconn = "0";
$econn = "0";
$connectionCount = "0";
$expired = "0";
$myHigh = "0";
$cc = "0";
$xc = "0";
$compare = "0";
$searchTune = "0";
$unsupAdd = "0";
$unsupMod = "0";
$unsupDel = "0";
$unsupCmp = "0";
$unsupMrdn = "0";
$proxiedAuth = "0";
$unsupportedext = "0";
$berdecode = "0";

$err[0] = "Successful Operations\n";
$err[1] = "Operations Error(s)\n";
$err[2] = "Protocal Errors\n";
$err[3] = "Time Limit Exceeded\n";
$err[4] = "Size Limit Exceeded\n";
$err[5] = "Compare False\n";
$err[6] = "Compare True\n";
$err[7] = "Strong Authentication Not Supported\n";
$err[8] = "Strong Authentication Required\n";
$err[9] = "Partial Results\n";
$err[10] = "Referral Received\n";
$err[11] = "Administrative Limit Exceeded (Look Through Limit)\n";
$err[12] = "Unavailable Critical Extension\n";
$err[13] = "Confidentiality Required\n";
$err[14] = "SASL Bind in Progress\n";
$err[16] = "No Such Attribute\n";
$err[17] = "Undefined Type\n";
$err[18] = "Inappropriate Matching\n";
$err[19] = "Constraint Violation\n";
$err[20] = "Type or Value Exists\n";
$err[21] = "Invalid Syntax\n";
$err[32] = "No Such Object\n";
$err[33] = "Alias Problem\n";
$err[34] = "Invalid DN Syntax\n";
$err[35] = "Is Leaf\n";
$err[36] = "Alias Deref Problem\n";
$err[48] = "Inappropriate Authentication (No password presented, etc)\n";
$err[49] = "Invalid Credentials (Bad Password)\n";
$err[50] = "Insufficent (write) Privledges\n";
$err[51] = "Busy\n";
$err[52] = "Unavailable\n";
$err[53] = "Unwilling To Perform\n";
$err[54] = "Loop Detected\n";
$err[60] = "Sort Control Missing\n";
$err[61] = "Index Range Error\n";
$err[64] = "Naming Violation\n";
$err[65] = "Objectclass Violation\n";
$err[66] = "Not Allowed on Non Leaf\n";
$err[67] = "Not Allowed on RDN\n";
$err[68] = "Already Exists\n";
$err[69] = "No Objectclass Mods\n";
$err[70] = "Results Too Large\n";
$err[71] = "Effect Multiple DSA's\n";
$err[80] = "Other :-)\n";
$err[81] = "Server Down\n";
$err[82] = "Local Error\n";
$err[83] = "Encoding Error\n";
$err[84] = "Decoding Error\n";
$err[85] = "Timeout\n";
$err[86] = "Authentication Unknown\n";
$err[87] = "Filter Error\n";
$err[88] = "User Canceled\n";
$err[89] = "Parameter Error\n";
$err[90] = "No Memory\n";
$err[91] = "Connect Error\n";
$err[92] = "Not Supported\n";
$err[93] = "Control Not Found\n";
$err[94] = "No Results Returned\n";
$err[95] = "More Results To Return\n";
$err[96] = "Client Loop\n";
$err[97] = "Referral Limit Exceeded\n";

$conn{"A1"} = "A1";
$conn{"B1"} = "B1";
$conn{"B4"} = "B4";
$conn{"T1"} = "T1";
$conn{"T2"} = "T2";
$conn{"B2"} = "B2";
$conn{"B3"} = "B3";
$conn{"R1"} = "R1";
$conn{"P1"} = "P1";
$conn{"P2"} = "P2";
$conn{"U1"} = "U1";

$connmsg{"A1"} = "Client Aborted Connections";
$connmsg{"B1"} = "Bad Ber Tag Encountered";
$connmsg{"B4"} = "Server failed to flush data (response) back to Client";
$connmsg{"T1"} = "Idle Timeout Exceeded";
$connmsg{"T2"} = "IO Block Timeout Exceeded or NTSSL Timeout";
$connmsg{"B2"} = "Ber Too Big";
$connmsg{"B3"} = "Ber Peek";
$connmsg{"R1"} = "Revents";
$connmsg{"P1"} = "Plugin";
$connmsg{"P2"} = "Poll";
$connmsg{"U1"} = "Cleanly Closed Connections";

$month{"Jan"} = 1;
$month{"Feb"} = 2;
$month{"Mar"} = 3;
$month{"Apr"} = 4;
$month{"May"} = 5;
$month{"Jun"} = 6;
$month{"Jul"} = 7;
$month{"Aug"} = 8;
$month{"Sep"} = 9;
$month{"Oct"} = 10;
$month{"Nov"} = 11;
$month{"Dec"} = 12;



##########################################
#                                        #
#         Parse Access Logs              #
#                                        # 
##########################################

if ($files[$#files] =~ m/access.rotationinfo/) {  $fc--; }

print "\nProcessing $fc Access Log(s)...\n";
if ($#exclude >= 0){
	print "Excluding connections from: ";
	for ($xx1 =0; $xx1 < $#exclude; $xx1++){
		print " " . $exclude[$xx1] . ",";
	}
	print " $exclude[$xx1++]\n";
}

for ($count=0; $count < $fc; $count++){
        chomp($logsize = `wc -l $files[$count]`);
        $logsize =~ /([0-9]+)/;
        $ff="";$iff="";
        print sprintf "\n  %-10s %20s \n",$files[$count],"(Total Lines: $1)";
	open(LOG,"$files[$count]") || die "Error: Can't open file $infile: $!";

	if ($count eq "0"){$start =`head -1 $files[$count]`;}
	if ($start =~ / *([0-9a-z:\/]+)/i){$start=$1;}
	$firstline = "yes";
	$end = `tail -1 $files[$fc-1]`;
	if ($end =~ / *([0-9a-z:\/]+)/i){$end =$1;}
	if ($end =~ / *(^[a-zA-Z])/i) {$end = "Invalid time";}
	while (<LOG>) {
		if (/^\[/ && $firstline eq "yes"){
                        $tline = $_;
                        $firstline = "no";
                } elsif (/^\[/ && $firstline eq "no"){
                         &parseLine($tline);
                         $tline = $_;
                } else {
                        $tline = $tline . $_;
                        $tline =~ s/\n//;
                }
	}
	&parseLine($tline);
	close (LOG);
	$totalLineCount = $totalLineCount + $ff;
	print sprintf "*%10s Lines Processed			Total Lines Processed: %12s\n",$ff,$totalLineCount;
}

print "\n* Total Lines Analyzed:  $totalLineCount\n";

$notes = $notes - $vlvnotes;
if ($notes < 0){ $notes = "0";}

$allOps = $search + $compare + $mod + $add + $delete + $modrdn + $bind + $extendedop;

#
#  Calculate the total number of seconds for all the logs
#

# Start Time

$timeStart = $start;
if ($timeStart =~ / *([0-9a-z:\/]+)/i){$timeStart=$1;}

if ($timeStart =~ / *([0-9A-Z\/]+)/i ){ 
	$timeDate = $1;
	@dateParts = split /\//, $timeDate;

	$timeMonth = $month{$dateParts[1]};
	$timeMonth = $timeMonth * 3600 *24 * 30;
	$timeDay= $dateParts[0] * 3600 *24;
	$timeYear = $dateParts[2] *365 * 3600 * 24; 
	$startDateTotal = $timeMonth + $timeDay + $timeYear;
}

if ($timeStart =~ / *(:[0-9:]+)/i ){ 
	$timeTime = $1;
	@parts = split /:/, $timeTime;

	$timeHour = $parts[1] * 3600;
	$timeMinute = $parts[2] *60;
	$timeSecond = $parts[3];
	$startTimeTotal = $timeHour + $timeMinute + $timeSecond;
}

$startTimeTotal = $startTimeTotal + $startDateTotal;

# Finish Time

$timeEnd = $end;

if ($timeEnd =~ / *([0-9a-z:\/]+)/i){$timeEnd= $1;}

if ($timeEnd =~ / *([0-9A-Z\/]+)/i ){ 
        $timeDate = $1;
	@dateParts = split /\//, $timeDate;

	$endDay = $dateParts[0] *3600 * 24;
	$endMonth = $month{$dateParts[1]};
	$endMonth = $endMonth * 3600 *24 * 30;
	$endYear = $dateParts[2] *365 * 3600 * 24 ;
	$endDateTotal = $endDay + $endMonth + $endYear;

}

if ($timeEnd =~ / *(:[0-9:]+)/i ){ 
        $timeTime = $1;
        @parts = split /:/, $timeTime;

	$endHour = $parts[1] * 3600;
	$endMinute = $parts[2] *60;
	$endSecond = $parts[3];
	$endTimeTotal = $endHour + $endMinute + $endSecond;
}

$endTimeTotal = $endTimeTotal +  $endDateTotal;

# Calculate the difference

$elapseTime = $endTimeTotal - $startTimeTotal;

#  Check to see if the file is a valid access log or if its emtpy

if ($elapseTime eq "" ||  $elapseTime eq "0"){
        print "Access Log is empty.  Processing Terminated!\n";
        exit;
}

#####################################
#                                   #
#     Display Basic Results         #
#                                   #
#####################################


print "\n\n----------- Access Log Output ------------\n";
print "\nStart of Log:  $start\n";
print "End of Log:    $end\n";
print "\nRestarts:                     $restarts\n";
print "\n";
print "Opened Connections:           $connectionCount\n";
print "Closed Connections:           $fdreturn\n";
print "SSL Connections:              $sslconn\n\n";
print "Total Operations:             $allOps\n";
print "Total Results:                $allResults\n";
if ($allOps ne "0"){
 	print sprintf "Overall Performance:          %.1f%\n" , ($allResults / $allOps)*100 ;
} else {
 	print "Overall Performance:          No Operations to evaluate\n";
}
print "Most Pending Operations:      $myHigh\n\n";

printf "Searches:                     %d (%.3f/sec)\n", $search ,$search / $elapseTime;
printf "Modifications:                %d (%.3f/sec)\n", $mod, $mod / $elapseTime;
printf "Adds:                         %d (%.3f/sec)\n", $add, $add / $elapseTime;
printf "Deletes:                      %d (%.3f/sec)\n", $delete, $delete / $elapseTime;
printf "Mod RDNs:                     %d (%.3f/sec)\n", $modrdn, $modrdn / $elapseTime;
printf "Compares:                     %d (%.3f/sec)\n", $compare ,$compare / $elapseTime;
print "\n";
print "Extended Operations:          $extendedop\n";
print "Proxied Auth Operations:      $proxiedAuth\n";
print "Internal Operations:          $internal\n";
print "Entry Operations:             $entryOp\n";
print "\n";
print "Persistent Searches:          $persistent\n";
print "Abandoned Requests:           $abandon\n";
print "\n";
print "VLV Operations:               $vlv\n";
print "VLV Unindexed Searches:       $vlvnotes\n";
print "SORT Operations:              $sortvlv\n";
print "\n";
print "Entire Search Base Queries:   $objectclass\n";
print "Smart Referrals Received:     $referral\n";
print "Search-Tune Searches:         $searchTune\n";
print "Unindexed Searches:           $notes\n";
if ($verb eq "yes" || $usage =~ /u/){
	if ($notes > 0){
		$ns = "1";
		for ($n = 0; $n <= $#notesEtime; $n++){
			print "\n  Unindexed Search #".$ns."\n";
			$ns++;
			print "  -  Date/Time:             $notesTime[$n]\n";
			print "  -  Connection Number:     $notesConn[$n]\n";
			print "  -  Operation Number:      $notesOp[$n]\n";
			print "  -  Etime:                 $notesEtime[$n]\n";
			print "  -  Nentries:              $notesNentries[$n]\n";
			$tempIP = $conn_hash{$notesConn[$n]};
			if ($resolveIP eq "yes"){
				if ($tempIP ne "" || $tempIP ne "*"){
					$domainName = `nslookup $tempIP | grep \"^Name\"`;
                                	$domainName =~ s/Name://g;
                                	$domainName =~ s/ //g;
                                	$domainName =~ s/\n//g;
                                	$Newip = $domainName;
					print "  -  Host Name:             $Newip ($tempIP)\n";
				} else {
					print "  -  IP Address:            $tempIP\n";
				}
			} else {
				print "  -  IP Address:            $tempIP\n";
			}
			for ($nn = 0; $nn <= $bc; $nn++){
				if ($notesConn[$n] eq $bindInfo[$nn][1] ){
					print "  -  Bind DN:               $bindInfo[$nn][0]\n";
				}
			}
			for ($nnn = 0; $nnn <= $fcc; $nnn++){	
				if ($notesConn[$n] eq $filterInfo[$nnn][1] && $notesOp[$n] eq $filterInfo[$nnn][2]){
					print "  -  Search Filter:         $filterInfo[$nnn][0]\n";
				}	
			}
		}
	}

}

print "\n";
print "FDs Taken:                    $fdtake\n";
print "FDs Returned:                 $fdreturn\n";
print "Highest FD Taken:             $highfd\n\n";
print "Broken Pipes:                 $broken\n";
if ($broken > 0){
	foreach $key (sort { $rc{$b} <=> $rc{$a} } keys %rc) {
          	if ($rc{$key} > 0){
           		if ($conn{$key} eq ""){ $conn{$key} = "** Unknown **";}
           		push @etext, sprintf "     -  %-4s (%2s) %-40s\n",$rc{$key},$conn{$key},$connmsg{$key};
          	}
        }
        print @etext;
        print "\n";
}

print "Connections Reset By Peer:    $reset\n";
if ($reset > 0){
	foreach $key (sort { $src{$b} <=> $src{$a} } keys %src) {
          	if ($src{$key} > 0){
           		if ($conn{$key} eq ""){$conn{$key} = "** Unknown **";}
           		push @retext, sprintf "     -  %-4s (%2s) %-40s\n",$src{$key},$conn{$key},$connmsg{$key};
          	}
        }
        print @retext;
	print "\n";
}

print "Resource Unavailable:         $resource\n";
if ($resource > 0){
	foreach $key (sort { $rsrc{$b} <=> $rsrc{$a} } keys %rsrc) {
          	if ($rsrc{$key} > 0){
           		if ($conn{$key} eq ""){$conn{$key} = "** Resource Issue **";}
           		push @rtext, sprintf "     -  %-4s (%2s) %-40s\n",$rsrc{$key},$conn{$key},$connmsg{$key};
          	}
  	}
  	print @rtext;
}

print "Ber Decoding Errors:          $berdecode\n";

print "Unsupported Critical Exts:    $unsupportedext\n";
if ($unsupAdd ne "0"){
	print "  -  Adds:      $unsupAdd\n";
}
if ($unsupMod ne "0"){
	print "  -  Mods:      $unsupMod\n";
}
if ($unsupDel ne "0"){
	print "  -  Deletes:   $unsupDel\n";
}
if ($unsupCmp ne "0"){
	print "  -  Compares:  $unsupCmp\n";
}
if ($unsupMrdn ne "0"){
	print "  -  Modrdns:   $unsupMrdn\n";
}


print "\n";
print "Binds:                        $bind\n";
print "Unbinds:                      $unbind\n";
print "\n LDAP v2 Binds:               $version2\n";
print " LDAP v3 Binds:               $version3\n";
print " Expired Password Logins:     $expired\n";
print " SSL Client Binds:            $sslClientBind\n";
print " Failed SSL Client Binds:     $sslClientFailed\n";
print " SASL Binds:                  $sasl\n";
if ($sasl > 0){
 	foreach $saslb ( sort {$saslmech{$b} <=> $saslmech{$a} } (keys %saslmech) ){
		printf "  %-4s  %-12s\n",$saslmech{$saslb}, $saslb;   
 	}
}

print "\n Directory Manager Binds:     $dirmgr\n";
print " Anonymous Binds:             $anony\n";
$other = $bind -($dirmgr + $anony);
print " Other Binds:                 $other\n\n";


###################################
#                                 #
#      Display Error Codes        #
#                                 #
###################################

if ($usage =~ /e/i || $verb eq "yes"){
	print "\n\n----- Errors -----\n";

	%er = sort( {$b <=> $a} %er);
	for ($i = 0; $i<98; $i++){
		if ($err[$i] ne "" && $er[$i] >0) {
                	push @errtext, sprintf "%-8s       %12s    %-25s","err=$i",$er[$i],$err[$i];
        	}
	}

	for ($i = 0; $i < $#errtext; $i++){
  		for ($ii = 0; $ii < $#errtext; $ii++){
    			$yy="0";
    			$zz="0";
    			while ($errtext[$ii] =~ /(\w+)\s/g){
        			$errornum[$yy]="$1";
        			$yy++;
    			}
    			while ($errtext[$ii+1] =~ /(\w+)\s/g){
        			$errornum2[$zz]="$1";
        			$zz++;
    			}

        		if ($errornum2[1] > $errornum[1]){
                		$tmp = $errtext[$ii];
                		$errtext[$ii] = $errtext[$ii+1];
                		$errtext[$ii+1] = $tmp;
                	}
        	}
	}

	for ($i = 0; $i <= $#errtext; $i++){
		$errtext[$i] =~ s/\n//g;
		print  "\n" . $errtext[$i];
	} 
}

####################################
#            			   #
#     Print Failed Logins          #
# 				   #
####################################

if ($verb eq "yes" || $usage =~ /f/i ){
	if ($bpc > 0){
		print "\n\n----- Top $sizeCount Failed Logins ------\n\n";
		if ($ds5x eq "true"){
			$eloop = "0";
			foreach $dsbp (sort { $ds5xbadpwd{$b} <=> $ds5xbadpwd{$a} } keys %ds5xbadpwd) {
				if ($eloop > $sizeCount){ last; }
				printf "%-4s        %-40s\n", $ds5xbadpwd{$dsbp}, $dsbp;
			}

		} else { 
			for ($ii =0 ; $ii < $bpc; $ii++){
 				for ($i = 0; $i < $bc; $i++){
					if ($badPasswordConn[$ii] eq $bindInfo[$i][1] && $badPasswordOp[$ii] eq $bindInfo[$i][2] ){
						$badPassword{ "$bindInfo[$i][0]" } = $badPassword{ "$bindInfo[$i][0]" } + 1;
					}
 				}
			}

			# sort the new list of $badPassword{}

			$bpTotal = "0";
			$bpCount = "0";
			foreach $badpw (sort {$badPassword{$b} <=> $badPassword{$a} } keys %badPassword){
				if ($bpCount > $sizeCount){ last;}
				$bpCount++;
				$bpTotal = $bpTotal + $badPassword{"$badpw"};
				printf "%-4s        %-40s\n", $badPassword{"$badpw"}, $badpw;
			}

			if ($bpTotal > $bpc){
				print "\n** Warning ". ($bpTotal - $bpc) . " reported failed login attempt(s) are false\n";
			}
		}  # this ends the if $ds5x = true
	}
}


####################################
#                                  #
#     Print Connection Codes       #
#                                  #
####################################


if ($concount > 0){
	if ($usage =~ /c/i || $verb eq "yes"){
 		print "\n\n----- Total Connection Codes -----\n\n";
  			foreach $key (sort { $conncount{$b} <=> $conncount{$a} } keys %conncount) {
          			if ($conncount{$key} > 0){
                  			push @conntext, sprintf "%-4s                 %6s    %-40s\n",$conn{ $key },$conncount{$key},$connmsg{ $key };
          			}
  			}
		print @conntext;
	}

}

########################################
#                                      #
#  Gather and Process all unique IPs   #
#                                      #
########################################

if ($usage =~ /i/i || $verb eq "yes"){
	@ipkeys = keys %ip_hash;
	@exxCount = keys %exCount;
	$ip_count = ($#ipkeys + 1)-($#exxCount + 1); 
	if ($ip_count > 0){
 		print "\n\n----- Top $sizeCount Clients -----\n\n";
 		print "Number of Clients:  $ip_count\n\n";

        	foreach $key (sort { $ip_hash{$b}{"count"} <=> $ip_hash{$a}{"count"} } keys %ip_hash) {
			$exc = "no";
			if ($ccount > $sizeCount){ last;}
       		        $ccount++;
			for ($xxx =0; $xxx <= $#exclude; $xxx++){
				if ($exclude[$xxx] eq $key){$exc = "yes";}
			}
			if ($exc ne "yes"){
				if ($ip_hash{ $key }{"count"} eq ""){
					$ip_hash{ $key }{"count"} = "*";
                			printf "%-6s %-17s\n", $ip_hash{ $key }{"count"}, $key;
				} elsif ($resolveIP eq "yes") {
					$domainName = `nslookup $key | grep \"^Name\"`;
                                	$domainName =~ s/Name://g;
                                	$domainName =~ s/ //g;
                                	$domainName =~ s/\n//g;
                                	$newip = $domainName;	
					printf "%-6s %s %-17s\n", $ip_hash{ $key }{"count"}, $newip, "(" . $key . ")";
				} else {
					printf "%-6s %-17s\n", $ip_hash{ $key }{"count"}, $key;
				}
			}

     			if ($exc ne "yes"){ 	
				foreach $code (sort { $ip_hash{ $key }{$b} <=> $ip_hash{ $key }{$a} } keys %{$ip_hash{ $key }}) {
		 			if ($code eq 'count' ) { next; }
                        		printf "\t\t %6s - %3s   %s\n", $ip_hash{ $key }{ $code }, $code, $connmsg{ $code };
			        }
     			}
                	
                	if ($exc ne "yes"){ print "\n";}
        	}
	}
}



###################################
#                                 #
#   Gather All unique Bind DN's   #
#                                 #
###################################

if ($usage =~ /b/i || $verb eq "yes"){
	@bindkeys = keys %bindlist;
	$bind_count = $#bindkeys + 1;
	if ($bind_count > 0){
        	print "\n----- Top $sizeCount Bind DN's -----\n\n";
        	print "Number of Unique Bind DN's: $bind_count\n\n"; 
		$bindcount = 0;
        	foreach $dn (sort { $bindlist{$b} <=> $bindlist{$a} } keys %bindlist) {
                	if ($bindcount < $sizeCount){
				printf "%-8s        %-40s\n", $bindlist{ $dn },$dn;
			}
			$bindcount++;
        	}
	}
}


#########################################
#					#
#  Gather and process search bases      #
#					#
#########################################

if ($usage =~ /a/i || $verb eq "yes"){
	@basekeys = keys %base;
	$base_count = $#basekeys + 1;
	if ($base_count > 0){
        	print "\n\n----- Top $sizeCount Search Bases -----\n\n";
        	print "Number of Unique Search Bases: $base_count\n\n";

        	$basecount = 0;

        	foreach $bas (sort { $base{$b} <=> $base{$a} } keys %base) {
                	if ($basecount < $sizeCount){
                        	printf "%-8s        %-40s\n", $base{ $bas },$bas;
                	}
                	$basecount++;
        	}
	}

}
 
#########################################
#                                       #
#   Gather and process search filters   #
#                                       #
#########################################

if ($usage =~ /l/ || $verb eq "yes"){
	@filterkeys = keys %filter;
	$filter_count = $#filterkeys + 1;
	if ($filter_count > 0){
		print "\n\n----- Top $sizeCount Search Filters -----\n";  
		print "\nNumber of Unique Search Filters: $filter_count\n\n";

		$filtercount = 0;

		foreach $filt (sort { $filter{$b} <=> $filter{$a} } keys %filter){
			if ($filtercount < $sizeCount){
				printf "%-8s        %-40s\n", $filter{$filt}, $filt;
			}
			$filtercount++;
		}
	}
}

#########################################
#                                       #
# Gather and Process the unique etimes  #
#                                       # 
#########################################

if ($usage =~ /t/i || $verb eq "yes"){

	#
	# print most often etimes
	#

	print "\n\n----- Top $sizeCount Most Frequent etimes -----\n\n";
	$eloop = 0;
	foreach $et (sort { $etime{$b} <=> $etime{$a} } keys %etime) {
        	if ($eloop == $sizeCount) { last; }
		if ($retime ne "2"){
			$first = $et;
			$retime = "2";
		}
        	printf "%-8s        %-12s\n", $etime{ $et }, "etime=$et";
        	$eloop++;
	}

	#
	# print longest etimes
	#

	print "\n\n----- Top $sizeCount Longest etimes -----\n\n";
	$eloop = 0;
	foreach $et (sort { $b <=> $a } (keys %etime)) {
        	if ($eloop == $sizeCount) { last; }
        	printf "%-12s    %-10s\n","etime=$et",$etime{ $et };
        	$eloop++;
	}
        
}

#######################################
#                                     #
# Gather and Process unique nentries  #
#                                     #
#######################################


if ($usage =~ /n/i || $verb eq "yes"){
	print "\n\n----- Top $sizeCount Largest nentries -----\n\n";
	$eloop = 0;
	foreach $nentry (sort { $b <=> $a } (keys %nentries)){
        	if ($eloop == $sizeCount) { last; }
    		printf "%-18s   %12s\n","nentries=$nentry", $nentries{ $nentry };
        	$eloop++;
	}

	print "\n\n----- Top $sizeCount Most returned nentries -----\n\n";
	$eloop = 0;
	foreach $nentry (sort { $nentries{$b} <=> $nentries{$a} } (keys %nentries)){
        	if ($eloop == $sizeCount) { last; }
        	printf "%-12s    %-14s\n", $nentries{ $nentry }, "nentries=$nentry";
        	$eloop++;
	}
	print "\n";
}


###############################################
#					      #
# Gather and process extended operations 5.x  #
#					      #
###############################################

if ($usage =~ /x/i || $verb eq "yes"){
	if ($extendedop > 0){
		print "\n\n----- 5.x Extended Operations -----\n\n";
		foreach $oids (sort { $oid{$b} <=> $oid{$a} } (keys %oid) ){
			if ($oids eq "2.16.840.1.113730.3.5.1"){ $oidmessage = "Transaction Request"}
			elsif ($oids eq "2.16.840.1.113730.3.5.2"){ $oidmessage = "Transaction Response"}
			elsif ($oids eq "2.16.840.1.113730.3.5.3"){ $oidmessage = "Start Replication Request (incremental update)"}
			elsif ($oids eq "2.16.840.1.113730.3.5.4"){ $oidmessage = "Replication Response"}
			elsif ($oids eq "2.16.840.1.113730.3.5.5"){ $oidmessage = "End Replication Request (incremental update)"}
			elsif ($oids eq "2.16.840.1.113730.3.5.6"){ $oidmessage = "Replication Entry Request"}
			elsif ($oids eq "2.16.840.1.113730.3.5.7"){ $oidmessage = "Start Bulk Import"}
			elsif ($oids eq "2.16.840.1.113730.3.5.8"){ $oidmessage = "Finished Bulk Import"}
			elsif ($oids eq "2.16.840.1.113730.3.6.1"){ $oidmessage = "Incremental Update Replication Protocol"}
			elsif ($oids eq "2.16.840.1.113730.3.4.13"){ $oidmessage = "Incremental Protocol ID"}
			elsif ($oids eq "2.16.840.1.113730.3.6.2"){ $oidmessage = "Total Update Replication Protocol (Initialization)"}
			elsif ($oids eq "2.16.840.1.113730.3.5.9"){ $oidmessage = "Digest Authentication (iWS 5.x)"}
			else {$oidmessage = "Other"}

			printf "%-6s      %-23s     %-60s\n", $oid{ $oids }, $oids, $oidmessage;
		}
	}
}

############################################
#					   #	
# Print most commonly requested attributes #
#					   #
############################################

if ($usage =~ /r/i || $verb eq "yes"){
	if ($anyAttrs > 0){
		print "\n\n----- Top $sizeCount Most Requested Attributes -----\n\n";
		$eloop = "0";
		foreach $mostAttr (sort { $attr{$b} <=> $attr{$a} } (keys %attr) ){
			if ($eloop eq $sizeCount){ last; }
			printf "%-10s  %-19s\n", $attr{$mostAttr}, $mostAttr;
			$eloop++;
		}
	}
}

#################################
#			        # 
# abandoned operation stats 5.1 #
#				#
#################################

if ($usage =~ /g/i || $verb eq "yes"){
	$acTotal = $sconn + $dconn + $mconn + $aconn + $mdconn + $bconn + $ubconn + $econn;
	if ($verb eq "yes" && $ac > 0 && $acTotal > 0){
		print "\n\n----- Abandon Request Stats -----\n\n";

 		for ($g = 0; $g < $ac; $g++){
  			for ($sc = 0; $sc < $sconn; $sc++){
				if ($srchConn[$sc] eq $targetConn[$g] && $srchOp[$sc] eq $targetOp[$g] ){
					if ($resolveIP eq "yes" && $conn_hash{$targetConn[$g]} ne ""){
						$iip = $conn_hash{$targetConn[$g]};
						$domainName = `nslookup $iip | grep \"^Name\"`;
                                		$domainName =~ s/Name://g;
                                		$domainName =~ s/ //g;
                                		$domainName =~ s/\n//g;
						print " - SRCH conn=$targetConn[$g] op=$targetOp[$g] msgid=$msgid[$g] client=$domainName\n";
					} else {	
						if ($conn_hash{$targetConn[$g]} eq ""){
							print " - SRCH conn=$targetConn[$g] op=$targetOp[$g] msgid=$msgid[$g] client= Unknown Client\n";
						} else {
							print " - SRCH conn=$targetConn[$g] op=$targetOp[$g] msgid=$msgid[$g] client=$conn_hash{$targetConn[$g]}\n";	
						}
					}
				}
  			}

  			for ($dc = 0; $dc < $dconn; $dc++){
				if ($delConn[$dc] eq $targetConn[$g] && $delOp[$dc] eq $targetOp[$g]){
					if ($resolveIP eq "yes"){
						$iip = $conn_hash{$targetConn[$g]};
                                                $domainName = `nslookup $iip | grep \"^Name\"`;
                                                $domainName =~ s/Name://g;
                                                $domainName =~ s/ //g;
                                                $domainName =~ s/\n//g;
						print " - DEL conn=$targetConn[$g] op=$targetOp[$g] msgid=$msgid[$g] client=$domainName\n";
					} else {
						print " - DEL conn=$targetConn[$g] op=$targetOp[$g] msgid=$msgid[$g] client=$conn_hash{$targetConn[$g]}\n";
					}
				}
  			}

  			for ($adc = 0; $adc < $aconn; $adc++){
				if ($addConn[$adc] eq $targetConn[$g] && $addOp[$adc] eq $targetOp[$g]){
					if ($resolveIP eq "yes"){
                                                $iip = $conn_hash{$targetConn[$g]};
                                                $domainName = `nslookup $iip | grep \"^Name\"`;
                                                $domainName =~ s/Name://g;
                                                $domainName =~ s/ //g;
                                                $domainName =~ s/\n//g;
						print " - ADD conn=$targetConn[$g] op=$targetOp[$g] msgid=$msgid[$g] client=$domainName\n";
					} else {
						print " - ADD conn=$targetConn[$g] op=$targetOp[$g] msgid=$msgid[$g] client=$conn_hash{$targetConn[$g]}\n";
					}
				}
  			}

  			for ($mc = 0; $mc < $mconn; $mc++){
				if ($modConn[$mc] eq $targetConn[$g] && $modOp[$mc] eq $targetOp[$g]){
					if ($resolveIP eq "yes"){
                                                $iip = $conn_hash{$targetConn[$g]};    
                                                $domainName = `nslookup $iip | grep \"^Name\"`;
                                                $domainName =~ s/Name://g;
                                                $domainName =~ s/ //g;
                                                $domainName =~ s/\n//g;
						print " - MOD conn=$targetConn[$g] op=$targetOp[$g] msgid=$msgid[$g] client=$domainName\n";
					} else {
						print " - MOD conn=$targetConn[$g] op=$targetOp[$g] msgid=$msgid[$g] client=$conn_hash{$targetConn[$g]}\n";
					}
				}
  			}

  			for ($mdc = 0; $mdc < $mdconn; $mdc++){
				if ($modrdnConn[$mdc] eq $targetConn[$g] && $modrdnOp[$mdc] eq $targetOp[$g]){
					if ($resolveIP eq "yes"){
                                                $iip = $conn_hash{$targetConn[$g]};    
                                                $domainName = `nslookup $iip | grep \"^Name\"`;
                                                $domainName =~ s/Name://g;
                                                $domainName =~ s/ //g;
                                                $domainName =~ s/\n//g;
						print " - MODRDN conn=$targetConn[$g] op=$targetOp[$g] msgid=$msgid[$g] client=$domainName\n";
					} else {
						print " - MODRDN conn=$targetConn[$g] op=$targetOp[$g] msgid=$msgid[$g] client=$conn_hash{$targetConn[$g]}\n";
					}
				}
  			}

  			for ($bcb = 0; $bcb < $bconn; $bcb++){
				if ($bindConn[$bcb] eq $targetConn[$g] && $bindOp[$bcb] eq $targetOp[$g]){
					if ($resolveIP eq "yes"){
                                                $iip = $conn_hash{$targetConn[$g]};    
                                                $domainName = `nslookup $iip | grep \"^Name\"`;
                                                $domainName =~ s/Name://g;
                                                $domainName =~ s/ //g;
                                                $domainName =~ s/\n//g;
						print " - BIND conn=$targetConn[$g] op=$targetOp[$g] msgid=$msgid[$g] client=$domainName\n";
					} else {
						print " - BIND conn=$targetConn[$g] op=$targetOp[$g] msgid=$msgid[$g] client=$conn_hash{$targetConn[$g]}\n";
					}
				}
  			}

  			for ($ubc = 0; $ubc < $ubconn; $ubc++){
				if ($unbindConn[$ubc] eq $targetConn[$g] && $unbindOp[$ubc] eq $targetOp[$g]){
					if ($resolveIP eq "yes"){
                                                $iip = $conn_hash{$targetConn[$g]};    
                                                $domainName = `nslookup $iip | grep \"^Name\"`;
                                                $domainName =~ s/Name://g;
                                                $domainName =~ s/ //g;
                                                $domainName =~ s/\n//g;
						print " - UNBIND conn=$targetConn[$g] op=$targetOp[$g] msgid=$msgid[$g] client=$domainName\n";
					} else {
						print " - UNBIND conn=$targetConn[$g] op=$targetOp[$g] msgid=$msgid[$g] client=$conn_hash{$targetConn[$g]}\n";
					}
				}
  			}

  			for ($ec = 0; $ec < $econn; $ec++){
				if ($extConn[$ec] eq $targetConn[$g] && $extOp[$ec] eq $targetOp[$g]){
					if ($resolveIP eq "yes"){
                                                $iip = $conn_hash{$targetConn[$g]};    
                                                $domainName = `nslookup $iip | grep \"^Name\"`;
                                                $domainName =~ s/Name://g;
                                                $domainName =~ s/ //g;
                                                $domainName =~ s/\n//g;
						print " - EXT conn=$targetConn[$g] op=$targetOp[$g] msgid=$msgid[$g] client=$domainName\n";
					} else {
						print " - EXT conn=$targetConn[$g] op=$targetOp[$g] msgid=$msgid[$g] client=$conn_hash{$targetConn[$g]}\n";
					}
				}
  			}
 		}
	}
}
print "\n";

#######################################
#                                     #
#       Recommendations               #
#                                     #
#######################################

if ($usage =~ /j/i || $verb eq "yes"){
	print "\n----- Recommendations -----\n";
	$recCount = "1";
	if ($notes > 0){
		print "\n $recCount.  You have unindexed searches, this can be caused from a search on a unindexed attribute, or your returned results exceeded the allidsthreshold.  Unindexed searches are not acceptable, please make any configuration changes necessary to resolve these searches!\n";
		$recCount++;
	}

	if ($conncount{"T1"} > 0){
		print "\n $recCount.  You have some connections that are are being closed by the idletimeout setting.  You may want to increase the idletimeout if it is set low.\n";
		$recCount++;
	}

	if ($conncount{"T2"} > 0){
		print "\n $recCount.  You have some coonections that are being closed by the ioblocktimeout setting.  You may want to increase the ioblocktimeout.\n";
		$recCount++;
	}

	# compare binds to unbinds, if the difference is more than 30% of the binds, then report a issue

	if (($bind - $unbind) > ($bind*.3)){
		print "\n $recCount.  You have a significant difference between binds and unbinds.  You may want to investigate this difference.\n";
		$recCount++;
	}

	# compare fds taken and return, if the difference is more than 30% report a issue

	if (($fdtaken -$fdreturn) > ($fdtaken*.3)){
		print "\n $recCount.  You have a significant difference between file descriptors taken and file descriptors returned.  You may want to investigate this difference.\n";
		$recCount++;
	}

	if ($dirmgr > ($bind *.2)){
		print "\n $recCount.  You have a high number of Directory Manager binds.  The Directory Manager account should only be used under certain circumstances.  Avoid using this account for client applications.\n";
		$recCount++;
	}

	if ($errorck > $errorsucc){
		print "\n $recCount.  You have more unsuccessful operations than successful operations.  You should investigate this difference.\n";
		$recCount++;
	}

	if ($conncount{"U1"} < ($concount - $conncount{"U1"})){
		print "\n $recCount.  You have more abnormal connection codes than cleanly closed connections.  You may want to investigate this difference.\n";
		$recCount++;
	}

	if ($first > 0){
		print "\n $recCount.  You have a majority of etimes that are greater than zero, you may want to investigate this performance problem.\n";
		$recCount++;
	}

	if ($objectclass > ($search *.25)){
		print "\n $recCount.  You have a high number of searches that query the entire search base.  Although this is not necessarily bad, it could be resource intensive if the search base contains many entries.\n"; 
		$recCount++;
	}

	if ($recCount == 1){
		print "\nNone.\n";
	}
}
print "\n";

##################
# 		 #
# display usage  #
#		 #
##################

sub displayUsage {

	print "Usage:\n\n";

	print " ./logconv [-h] [-d <rootDN>] [-s <size limit>] [-X <ip address>] [-E <error code>] [-N] [-v] [-V] [-DELIM] [-C <output file>] [-R <output file>] [-B <output file>] [-P <output file>] [-A0 <output file>] [-A1 <output file>] [-I <MONTH | DAY | HOUR | MINUTE>]\n";
	print " [-efcibaltnxrgju] access logfile...\n\n"; 

	print "- Commandline Switches:\n\n";

        print "         -h help/usage\n";
        print "         -d <Directory Managers DN>  DEFAULT -> cn=directory manager\n";
        print "         -s <Number of results to return per catagory>  DEFAULT -> 20\n";
	print "         -X <IP address to exclude from connection stats>  E.g. Load balancers\n";
        print "         -v show version of tool.\n"; 
        print "         -V enable verbose output - includes all general stats listed below.\n";
	print "         -N resolve IP addresses to hostnames (degrades performance).\n\n";
	print "      *  -E <error code> This reports stats on specific error codes.\n";
	print "      *  -B <output file>  This reports on the busiest binding accounts.\n";
	print "      *  -C <output file> This reports on operations per connection.\n";
	print "      *  -A0 <output file> This reports all client activity based on most operations.\n";
        print "      *  -A1 <output file> This reports all client activity based on most connections.\n";
	print "      *  -R <output file> This option returns a report on operations.\n";
	print "      *  -P <output file> This option reports on pending operations (see README).\n";
	print "         -DELIM Creates the report file in an CSV/spreadsheet format (-R and -B)\n";
	print "        -I <MONTH | DAY | HOUR | MINUTE> Sets the interval for reporting (-R and -B)\n\n";
	print "      The options listed above with a '*' will override the General Stats options listed below\n\n";
	print "     - General Stats:\n\n";
        print "         -[efcibaltnxrgju]\n\n";

        print "                 e       Error Code stats\n";
        print "                 f       Failed Login Stats\n";
        print "                 c       Connection Code Stats\n";
        print "                 i       Client Stats\n";
        print "                 b       Bind Stats\n";
        print "                 a       Search Base Stats\n";
        print "                 l       Search Filter Stats\n";
        print "                 t       Etime Stats\n";
        print "                 n       Nentries Stats\n";
        print "                 x       Extended Operations\n";
        print "                 r       Most Requested Attribute Stats\n";
        print "                 g       Abandoned Operation Stats\n";
        print "                 j       Recommendations\n";
        print "                 u       Unindexed Search Stats\n\n";
	print "  Examples:\n\n";
	print "         ./logconv -s 10 -V access\n";
	print "         ./logconv -d cn=dm /export/server4/slapd-host/logs/access*\n";
	print "         ./logconv -s 50 -ibgju access*\n";
	print "         ./logconv -s 25 -E 49 access\n";
	print "         ./logconv -X 127.0.0.1 -s 5 access\n";
	print "         ./logconv -DELIM -R report.txt -I DAY access\n";

	exit 1;
}

sub parseLine {
	local $_ = $tline;
	$ff++;
	$iff++;
	if ($iff >= 1000){ print STDERR sprintf" %10s Lines Processed\n",$ff; $iff="0";}
	if (m/ RESULT err/){$allResults++;}
	if (/ SRCH base=/ || / DEL dn=/ || / MOD dn=/ || / ADD dn=/ || / MODRDN dn=/ || / EXT oid=/ || / BIND dn=/ || / CMP dn=/){
        	$myOps++;
 	}

	if (m/ ber decoding error/ || m/ ber decoding controls / || m/ ber decoding attributes/){
		$berdecode++;
	}

	if (m/ BIND dn=/ && m/ decoding error/){
		$berdecode++;
        }

 	if (/ ABANDON / || / RESULT err/){
        	$myResults++;
 	}

 	$myDiff = $myOps - $myResults;

 	if ( $myDiff > $myHigh){                
        	$myHigh = $myDiff;
 	}

	if (m/ authzid=\"dn:/){
		$proxiedAuth++;
	}

	if (m/ unsupported critical extentsion/i ){
		$unsupportext++;
		if (m/ ADD dn=/){ $unsupAdd++;}
		if (m/ MOD dn=/){ $unsupMod++;}
		if (m/ DEL dn=/){ $unsupDel++;}
		if (m/ CMP dn=/){ $unsupCmp++;}
		if (m/ MODRDN dn=/){ $unsupMrdn++;}
	}


	if (m/ SRCH base=/){
		$search++;
		if ($_ =~ / attrs=\"(.*)\"/i){
			$anyAttrs++;
			$attrs = $1 . " ";
			while ($attrs =~ /(\S+)\s/g){
				$attr{$1}++;
			}
		} 
		if (/ attrs=ALL/){
			$attr{"All Attributes"}++;
			$anyAttrs++;
		}
		if ($verb eq "yes" || $usage =~ /g/i){ 
			if ($_ =~ /conn= *([0-9]+)/i){ $srchConn[$sconn] = $1;}
			if ($_ =~ /op= *([0-9]+)/i){ $srchOp[$sconn] = $1;}
			$sconn++;
		}
	}

	if (m/ DEL dn=/){
		$delete++;
		if ($verb eq "yes" || $usage =~ /g/i){
			if ($_ =~ /conn= *([0-9]+)/i){ $delConn[$dconn] = $1;}
			if ($_ =~ /op= *([0-9]+)/i){ $delOp[$dconn] = $1;}
			$dconn++;
		}
	}

	if (m/ CMP dn=/){
		$compare++;
		 if ($verb eq "yes"  || $usage =~ /g/i){
                        if ($_ =~ /conn= *([0-9]+)/i){ $compConn[$dconn] = $1;}
                        if ($_ =~ /op= *([0-9]+)/i){ $compOp[$dconn] = $1;}
                        $cconn++;
                }
	}

	if (m/ MOD dn=/){
		$mod++;
		if ($verb eq "yes" || $usage =~ /g/i){
                	if ($_ =~ /conn= *([0-9]+)/i){ $modConn[$mconn] = $1;}
			if ($_ =~ /op= *([0-9]+)/i){ $modOp[$mconn] = $1; }
			$mconn++;
		}
	}

	if (m/ ADD dn=/){
		$add++;
		if ($verb eq "yes" || $usage =~ /g/i){
                	if ($_ =~ /conn= *([0-9]+)/i){ $addConn[$aconn] = $1; }
			if ($_ =~ /op= *([0-9]+)/i){ $addOp[$aconn] = $1; }
			$aconn++;
		}
	}

	if (m/ MODRDN dn=/){
		$modrdn++;
		if ($verb eq "yes"  || $usage =~ /g/i){
                	if ($_ =~ /conn= *([0-9]+)/i){ $modrdnConn[$mdconn] = $1; }
			if ($_ =~ /op= *([0-9]+)/i){ $modrdnOp[$mdconn] = $1; }
			$mdconn++;
		}
	}

	if (m/ ABANDON /){
		$abandon++;
		$allResults++;
		if ($_ =~ /targetop= *([0-9a-zA-Z]+)/i ){
			$targetOp[$ac] = $1;
			if ($_ =~ /conn= *([0-9]+)/i){ $targetConn[$ac] = $1; }
			if ($_ =~ /msgid= *([0-9]+)/i){ $msgid[$ac] = $1;}
			$ac++;
		}
	}

	if (m/ VLV /){
        	if ($_ =~ /conn= *([0-9]+)/i){ $vlvconn[$vlv] = $1;}
        	if ($_ =~ /op= *([0-9]+)/i){ $vlvop[$vlv] = $1;}
        	$vlv++;
	}

	if (m/ SORT /){$sortvlv++}
	if (m/ version=2/){$version2++}
	if (m/ version=3/){$version3++}
	if (m/ conn=0 fd=/){$restarts++}
	if (m/ SSL connection from/ || m/ LDAPS connection from /){$sslconn++;}
	if (m/ connection from/){
     		$exc = "no";
     		if ($_ =~ /connection from *([0-9\.]+)/i ){ 
			for ($xxx =0; $xxx <= $#exclude; $xxx++){
				if ($exclude[$xxx] eq $1){$exc = "yes";}
			}
			if ($exc ne "yes"){ $connectionCount++;}
     		}
	}

	if (m/ SSL client bound as /){$sslClientBind++;}
	if (m/ SSL failed to map client certificate to LDAP DN/){$sslClientFailed++;}
	if (m/ fd=/ && m/slot=/){$fdtake++}
	if (m/ fd=/ && m/ closed /){$fdreturn++};
	if (m/ conn=/ && m/ msgId=/ && m/closed/){$fdreturn++};
	if (m/ BIND dn=/){
		$bind++;
		if ($verb eq "yes" || $usage =~ /g/i){
                	if ($_ =~ /conn= *([0-9]+)/i){ $bindConn[$bconn] = $1; }
			if ($_ =~ /op= *([0-9]+)/i){ $bindOp[$bconn] = $1; }
			$bconn++;
		}
	}
	if (m/ BIND dn=/ && m/$manager/i){$dirmgr++}
	if (m/ BIND dn=""/){$anony++; $bindlist{"Anonymous Binds"}++;}
	if (m/ UNBIND/){
		$unbind++;
	}
	if (m/ notes=U/){
        	if ($_ =~ /conn= *([0-9]+)/i){
                	$con = $1;
                	if ($_ =~ /op= *([0-9]+)/i){ $op = $1;}
        	}
        	for ($i=0; $i <= $vlv;$i++){
                	if ($vlvconn[$i] eq $con && $vlvop[$i] eq $op){ $vlvnotes++; $v="1";}
        	}
        	$notes++;
		if ($usage =~ /u/ || $verb eq "yes"){
        		if ($v eq "0" ){
                		if ($_ =~ /etime= *([0-9]+)/i ) {
                        		$notesEtime[$vet]=$1;
                       		 	$vet++;
                		}
                		if ($_ =~ /conn= *([0-9]+)/i){
                        		$notesConn[$nc]=$1;
                        		$nc++;
                		}
                		if ($_ =~ /op= *([0-9]+)/i){
                        		$notesOp[$no]=$1;
                        		$no++;
                		}
                		if ($_ =~ / *([0-9a-z:\/]+)/i){
                        		$notesTime[$nt] = $1;
                        		$nt++;
                		}
				if ($_ =~ /nentries= *([0-9]+)/i ){
					$notesNentries[$nent] = $1;
					$nent++;
				}
        		}
		}
        	$v = "0";
	}

	if (m/ closed error 32/){
        	$broken++;
        	if (m/- T1/){ $rc{"T1"}++ }
        	elsif (m/- T2/){ $rc{"T2"}++ }
        	elsif (m/- A1/){ $rc{"A1"}++ }
        	elsif (m/- B1/){ $rc{"B1"}++ }
        	elsif (m/- B4/){ $rc{"B4"}++ }
        	elsif (m/- B2/){ $rc{"B2"}++ }
        	elsif (m/- B3/){ $rc{"B3"}++ }
        	elsif (m/- R1/){ $rc{"R1"}++ }
        	elsif (m/- P1/){ $rc{"P1"}++ }
        	elsif (m/- P1/){ $rc{"P2"}++ }
        	elsif (m/- U1/){ $rc{"U1"}++ }
        	else { $rc{"other"}++; }
	}
	if (m/ closed error 131/ || m/ closed error -5961/){
        	$reset++;
        	if (m/- T1/){ $src{"T1"}++ }
        	elsif (m/- T2/){ $src{"T2"}++ }
        	elsif (m/- A1/){ $src{"A1"}++ }
        	elsif (m/- B1/){ $src{"B1"}++ }
        	elsif (m/- B4/){ $src{"B4"}++ }
        	elsif (m/- B2/){ $src{"B2"}++ }
        	elsif (m/- B3/){ $src{"B3"}++ }
        	elsif (m/- R1/){ $src{"R1"}++ }
        	elsif (m/- P1/){ $src{"P1"}++ }
        	elsif (m/- P1/){ $src{"P2"}++ }
        	elsif (m/- U1/){ $src{"U1"}++ }
        	else { $src{"other"}++ }
	}

	if (m/ closed error 11/){
        	$resource++;
        	if (m/- T1/){ $rsrc{"T1"}++ }
        	elsif (m/- T2/){ $rsrc{"T2"}++ }
        	elsif (m/- A1/){ $rsrc{"A1"}++ }
        	elsif (m/- B1/){ $rsrc{"B1"}++ }
        	elsif (m/- B4/){ $rsrc{"B4"}++ }
        	elsif (m/- B2/){ $rsrc{"B2"}++ }
        	elsif (m/- B3/){ $rsrc{"B3"}++ }
        	elsif (m/- R1/){ $rsrc{"R1"}++ }
        	elsif (m/- P1/){ $rsrc{"P1"}++ }
        	elsif (m/- P1/){ $rsrc{"P2"}++ }
        	elsif (m/- U1/){ $rsrc{"U1"}++ }
        	else { $rsrc{"other"}++ }
	}


	if ($usage =~ /g/ || $usage =~ /c/ || $usage =~ /i/ || $verb eq "yes"){
		$exc = "no";
		if ($_ =~ /connection from *([0-9\.]+)/i ) {
			for ($xxx = 0; $xxx <= $#exclude; $xxx++){
                		if ($1 eq $exclude[$xxx]){
                        		$exc = "yes";
                        		$exCount{$1}++;
                		}
        		}
        		$ip = $1;
        		$ip_hash{$ip}{"count"}++;
        		if ($_ =~ /conn= *([0-9]+)/i ){
        			if ($exc ne "yes"){ $ip_hash2{$ip} = sprintf "%-12s               %18s\n",$1,$ip;}
                		$conn_hash{$1} = $ip;
        		}
		}

		if (m/- A1/){
        		if ($_ =~ /conn= *([0-9]+)/i) {
				$exc = "no";
                		$ip = $conn_hash{$1};
				if ($ip eq ""){$ip = "Unknown Host";}
				for ($xxx = 0; $xxx <= $#exclude; $xxx++){
                			if ($ip eq $exclude[$xxx]){$exc = "yes";}
        			}
				if ($exc ne "yes"){
                			$ip_hash{$ip}{"A1"}++;
					$conncount{"A1"}++;
					$concount++;
				}
        		}
		}
		if (m/- B1/){
        		if ($_ =~ /conn= *([0-9]+)/i) {
				$exc = "no";
                		$ip = $conn_hash{$1};
				if ($ip eq ""){$ip = "Unknown Host";}
				for ($xxx = 0; $xxx <= $#exclude; $xxx++){
                        		if ($ip eq $exclude[$xxx]){$exc = "yes";}
                		}
                		if ($exc ne "yes"){
                			$ip_hash{$ip}{"B1"}++;
					$conncount{"B1"}++;
					$concount++;	
				}
        		}
		}
		if (m/- B4/){
        		if ($_ =~ /conn= *([0-9]+)/i) {
				$exc = "no";
                		$ip = $conn_hash{$1};
				if ($ip eq ""){$ip = "Unknown Host";}
				for ($xxx = 0; $xxx <= $#exclude; $xxx++){
                        		if ($ip eq $exclude[$xxx]){$exc = "yes";}
                		}
                		if ($exc ne "yes"){
                			$ip_hash{$ip}{"B4"}++;
					$conncount{"B4"}++;
					$concount++;
				}
    			}
		}

		if (m/- T1/){
        		if ($_ =~ /conn= *([0-9]+)/i) {
				$exc = "no";
               			$ip = $conn_hash{$1};
				if ($ip eq ""){$ip = "Unknown Host";}
				for ($xxx = 0; $xxx <= $#exclude; $xxx++){
                        		if ($ip eq $exclude[$xxx]){$exc = "yes";}
                		}
                		if ($exc ne "yes"){
                			$ip_hash{$ip}{"T1"}++;
					$conncount{"T1"}++;
					$concount++;	
				}
        		}
		}
		if (m/- T2/){
        		if ($_ =~ /conn= *([0-9]+)/i) {
				$exc = "no"; 
                		$ip = $conn_hash{$1};
				if ($ip eq ""){$ip = "Unknown Host";}
				for ($xxx = 0; $xxx <= $#exclude; $xxx++){
                        		if ($ip eq $exclude[$xxx]){$exc = "yes";}
                		}
                		if ($exc ne "yes"){
                			$ip_hash{$ip}{"T2"}++;
					$conncount{"T2"}++;
					$concount++;	
				}
        		}
		}

		if (m/- B2/){
        		if ($_ =~ /conn= *([0-9]+)/i) {
				$exc = "no";
                		$ip = $conn_hash{$1};
				if ($ip eq ""){$ip = "Unknown Host";}
				for ($xxx = 0; $xxx <= $#exclude; $xxx++){
                        		if ($ip eq $exclude[$xxx]){$exc = "yes";}
                		}
                		if ($exc ne "yes"){
                			$ip_hash{$ip}{"B2"}++;
					$conncount{"B2"}++;
					$concount++;	
				}
        		}
		}
		if (m/- B2/){
        		if ($_ =~ /conn= *([0-9]+)/i) {
				$exc = "no";
                		$ip = $conn_hash{$1};
				if ($ip eq ""){$ip = "Unknown Host";}
				for ($xxx = 0; $xxx <= $#exclude; $xxx++){
                        		if ($ip eq $exclude[$xxx]){$exc = "yes";}
                		}
                		if ($exc ne "yes"){
                			$ip_hash{$ip}{"B2"}++;
					$conncount{"B2"}++;
					$concount++;	
				}
        		}
		}
		if (m/- B3/){
        		if ($_ =~ /conn= *([0-9]+)/i) {
				$exc = "no";
                		$ip = $conn_hash{$1};
				if ($ip eq ""){$ip = "Unknown Host";}
				for ($xxx = 0; $xxx <= $#exclude; $xxx++){
                        		if ($ip eq $exclude[$xxx]){$exc = "yes";}
                		}
                		if ($exc ne "yes"){
                			$ip_hash{$ip}{"B3"}++;
					$conncount{"B3"}++;
					$concount++;	
				}
        		}
		}

		if (m/- R1/){
        		if ($_ =~ /conn= *([0-9]+)/i) {
				$exc = "no";
                		$ip = $conn_hash{$1};
				if ($ip eq ""){$ip = "Unknown Host";}
				for ($xxx = 0; $xxx <= $#exclude; $xxx++){
                        		if ($ip eq $exclude[$xxx]){$exc = "yes";}
                		}
				if ($exc ne "yes"){
                			$ip_hash{$ip}{"R1"}++;
					$conncount{"R1"}++;
					$concount++;
				}
        		}
		}
		if (m/- P1/){
        		if ($_ =~ /conn= *([0-9]+)/i) {
				$exc = "no";
                		$ip = $conn_hash{$1};
				if ($ip eq ""){$ip = "Unknown Host";}
				for ($xxx = 0; $xxx <= $#exclude; $xxx++){
                        		if ($ip eq $exclude[$xxx]){$exc = "yes";}
                		}
                		if ($exc ne "yes"){
                			$ip_hash{$ip}{"P1"}++;
					$conncount{"P1"}++;
					$concount++;	
				}
        		}
		}
		if (m/- P2/){
        		if ($_ =~ /conn= *([0-9]+)/i) {
				$exc = "no";
                		$ip = $conn_hash{$1};
				if ($ip eq ""){$ip = "Unknown Host";}
				for ($xxx = 0; $xxx <= $#exclude; $xxx++){
                        		if ($ip eq $exclude[$xxx]){$exc = "yes";}
                		}
                		if ($exc ne "yes"){
                			$ip_hash{$ip}{"P2"}++;
					$conncount{"P2"}++;
					$concount++;
				}
        		}
		}

		if (m/- U1/){
        		if ($_ =~ /conn= *([0-9]+)/i) {
				$exc = "no";
                		$ip = $conn_hash{$1};
				if ($ip eq ""){$ip = "Unknown Host";}
				for ($xxx = 0; $xxx <= $#exclude; $xxx++){
                        		if ($ip eq $exclude[$xxx]){$exc = "yes";}
                		}
                		if ($exc ne "yes"){
                			$ip_hash{$ip}{"U1"}++;
					$conncount{"U1"}++;
					$concount++;
				}
        		}
		}
	}

	if ($_ =~ /err= *([0-9]+)/i){
        	$er[$1]++;
        	if ($1 ne "0"){ $errorck++;}
        	else { $errorsucc++;}
	}

	if ($_ =~ /etime= *([0-9]+)/i ) { $etime{$1}++;}
	if ($_ =~ / tag=101 nentries= *([0-9]+)/i ) {$nentries{$1}++}
	if ($_ =~ / tag=111 nentries= *([0-9]+)/i ) {$nentries{$1}++}
	if ($_ =~ / tag=100 nentries= *([0-9]+)/i ) {$nentries{$1}++}
	if ($_ =~ / tag=115 nentries= *([0-9]+)/i ) {$nentries{$1}++}
	if (m/objectclass=\*/i || m/objectclass=top/i ){
		if (m/ scope=2 /){ $objectclass++;}
	}

	if (m/ EXT oid=/){
        	$extendedop++;
        	if ($_ =~ /oid=\" *([0-9\.]+)/i ){ $oid{$1}++; }
		if ($verb eq "yes" || $usage =~ /g/i){
                	if ($_ =~ /conn= *([0-9]+)/i){ $extConn[$econn] = $1; }
			if ($_ =~ /op= *([0-9]+)/i){ $extOp[$econn] = $1; }
			$econn++;
		}
	}

	if (m/ BIND dn=/ && $_ =~ /dn=\"(.*)\" method/i ){
		if ($1 ne ""){ 
			$tmpp = $1;
			$tmpp =~ tr/A-Z/a-z/;
			$bindlist{$tmpp} = $bindlist{$tmpp} + 1; 
			$bindInfo[$bc][0] = $tmpp;
			if ($_ =~ /conn= *([0-9]+)/i) { $bindInfo[$bc][1] = $1; }
			if ($_ =~ /op= *([0-9]+)/i) { $bindInfo[$bc][2] = $1; }
			$bc++;
		}
	}

	if ($usage =~ /l/ || $verb eq "yes"){
		if (/ SRCH / && / attrs=/ && $_ =~ /filter=\"(.*)\" /i ){
			$tmpp = $1;
			$tmpp =~ tr/A-Z/a-z/;
			$tmpp =~ s/\\22/\"/g;
			$filter{$tmpp} = $filter{$tmpp} + 1; 
			$filterInfo[$fcc][0] = $tmpp;
			if ($_ =~ /conn= *([0-9]+)/i) { $filterInfo[$fcc][1] = $1; }
			if ($_ =~ /op= *([0-9]+)/i) { $filterInfo[$fcc][2] = $1; }
			$fcc++;
		} elsif (/ SRCH / && $_ =~ /filter=\"(.*)\"/i){
        		$tmpp = $1;
        		$tmpp =~ tr/A-Z/a-z/;
        		$tmpp =~ s/\\22/\"/g;
        		$filter{$tmpp} = $filter{$tmpp} + 1;
        		$filterInfo[$fcc][0] = $tmpp;
        		if ($_ =~ /conn= *([0-9]+)/i) { $filterInfo[$fcc][1] = $1; }
        		if ($_ =~ /op= *([0-9]+)/i) { $filterInfo[$fcc][2] = $1; }
        		$fcc++;
		}
	}

	if ($usage =~ /a/ || $verb eq "yes"){
		if (/ SRCH /   && $_ =~ /base=\"(.*)\" scope/i ){
			if ($1 eq ""){
				$tmpp = "Root DSE";
			} else {
				$tmpp = $1;
			}
        		$tmpp =~ tr/A-Z/a-z/;
        		$base{$tmpp} = $base{$tmpp} + 1;
		}
	}

	if ($_ =~ /fd= *([0-9]+)/i ) {
        	$fds[$fdds] = $1;
        	if ($fds[$fdds] > $highfd) {$highfd = $fds[$fdds];}
        	$fdds++;
	}

	if ($usage =~ /f/ || $verb eq "yes"){
		if (/ err=49 tag=/ && / dn=\"/){
			if ($_ =~ /dn=\"(.*)\"/i ){
				$ds5xbadpwd{$1}++;
			}
			$ds5x = "true";
			$bpc++;
		} elsif (/ err=49 tag=/ ){
			if ($_ =~ /conn= *([0-9]+)/i ){
				$badPasswordConn[$bpc] = $1;
				$bpc++;
			}
			if ($_ =~ /op= *([0-9]+)/i ){
				$badPasswordOp[$bpo] = $1;
				$bpo++;
			}
		}
	}

	if (/ BIND / && /method=sasl/i){
		$sasl++;
		if ($_ =~ /mech=(.*)/i ){     
			$saslmech{$1}++;
		}
	}

	if (/ conn=Internal op=-1 / && !/ RESULT err=/){ $internal++; }
	if (/ ENTRY dn=/ ){ $entryOp++; }
	if (/ conn=/ && /op=/ && / REFERRAL/){ $referral++; }
	if (/ options=persistent/){$persistent++;}
	if (/ password expired!/){$expired++;}
}


sub checkPending
{


        print "\nProcessing $fc Access Log(s)...\n";

        for ($count=0; $count < $fc; $count++){
                chomp($logsize = `wc -l $files[$count]`);
                $logsize =~ /([0-9]+)/;
                $ff="";$iff="";
                print sprintf "\n  %-10s %20s \n",$files[$count],"(Total Lines: $1)";
                open(LOG,"$files[$count]") || die "Error: Can't open file $infile: $!";

                while (<LOG>) {
                        $tline = $_;
                        &parsePending($tline);
                }
                &parseLines($tline);
                close (LOG);
		$totalLineCount = $totalLineCount + $ff;
		print sprintf "*%10s Lines Processed			Total Lines Processed: %12s\n",$ff,$totalLineCount;
        }
	print "\n* Total Lines Analyzed:  $totalLineCount\n";

#  DO NOT check the pendings at the end ofthe log only after restarts
#	&doPendingReport();

	exit(0);
}

sub parsePending
{
	local $_ = $tline;
	
	$ff++;
	$iff++;
	if ($iff >= 1000){ print STDERR sprintf" %10s Lines Processed\n",$ff; $iff="0";}

	# check for a restart and do a report

	if (/ conn=0 fd=/){  # restart
		&doPendingReport();
	}

	if (/ SRCH base=/){
		
		# get the base

		if ($_ =~ /base=\"(.*)\" /i ){
			$pending[$pcount][0] = $1;
		}

		# get the filter 

		if ($_ =~ /filter=\"(.*)\"/i ){
			$pending[$pcount][1] = $1;
		}

		# get the conn number

		if ($_ =~ /conn= *([0-9]+)/i ){
			$pending[$pcount][2] = $1;
		}

		# get the op number

		if ($_ =~ /op= *([0-9]+)/i ){
			$pending[$pcount][3] = $1;
                }	

		# get the time

		if ($_ =~ / *([0-9a-z:\/]+)/i){
			$pending[$pcount][4] = $1;
		}
		
		$pcount++;
	}

	if (/ RESULT / && / tag=101 nentries/){
		if ($_ =~ /conn= *([0-9]+)/i ){
                        $pConn = $1;
                }
                if ($_ =~ /op= *([0-9]+)/i ){
                        $pOp = $1;
                }

		for ($i = 0; $i <= $pcount ; $i++){
			if ($pending[$i][2] eq $pConn && $pending[$i][3] eq $pOp){

				# we have a result, remove the op
		
				$pending[$i][0] = -2;
				$pending[$i][1] = -2;
				$pending[$i][2] = -2;
				$pending[$i][3] = -2;
				$pending[$i][4] = -2;
				
				break;
			}
		}
	}

}

sub doPendingReport
{
	$pp = 0;
	$preport++;
	print "Pending Report #" . $preport . "\n\n";
	for ($i = 0; $i <= $pcount; $i++){
		if ($pending[$i][0] ne "-2" && $pending[$i][0] ne ""){
			print $pending[$i][4] . " - Base ($pending[$i][0]) Filter ($pending[$i][1])\n";
			$pp++;
		}
	}
	if ($pp gt "0"){
		print "\n";
	} else {
		print "No pending ops for this session.\n";
	}
	
	$#pending = -1;
	$pcount = 0;

}


sub parseError
{
	# initialize variables

	$fcc = "0";
	$con = "0";
	$bc = "0";
	$mc = "0";
	$dc = "0";
	$mdc = "0";

	$| = 1;  # autoflush print buffers

	# parse the logs

	print "\nProcessing $fc Access Log(s)...\n";

	for ($count=0; $count < $fc; $count++){
        	chomp($logsize = `wc -l $files[$count]`);
        	$logsize =~ /([0-9]+)/;
        	$ff="";$iff="";
        	print sprintf "\n  %-10s %20s \n",$files[$count],"(Total Lines: $1)";
        	open(LOG,"$files[$count]") || die "Error: Can't open file $infile: $!";

        	while (<LOG>) {
              		$tline = $_;
              		&parseLines($tline);
        	}
        	&parseLines($tline);
        	close (LOG);
	}

	print "\nError ($errorCode) Count:  $con\n";
	print "Parsing & Sorting...";

	for ($i = 0; $i < $con; $i++){
		if ($lllll eq 30){
			print ".";
			$lllll = 0;
		} else {
			$lllll++;
		}

        	for ($s = 0; $s < $fcc; $s++){
                	if ($errConn[$i] eq $baseInfo[$s][1] && $errOp[$i] eq $baseInfo[$s][2]){
				if ($resolveIP eq "yes"){
					$iip = $conn_hash{$errConn[$i]};
					$domainName = `nslookup $iip | grep \"^Name\"`;
                                	$domainName =~ s/Name://g;
                                	$domainName =~ s/ //g;
                                	$domainName =~ s/\n//g;
					$text = sprintf "  SRCH      %-30s  %-60s", "(".$domainName.")",$baseInfo[$s][0];
				} else {
					$text = sprintf "  SRCH      %-30s  %-60s", "(".$conn_hash{$errConn[$i]}.")",$baseInfo[$s][0]; 
				}
                        	$found{$text}++;
                	}
        	}

		for ($c = 0; $c < $cc; $c++){
			if ($errConn[$i] eq $cmpInfo[$c][1] && $errOp[$i] eq $cmpInfo[$c][2]){
				if ($resolveIP eq "yes"){
                                        $iip = $conn_hash{$errConn[$i]};
                                        $domainName = `nslookup $iip | grep \"^Name\"`;
                                        $domainName =~ s/Name://g;
                                        $domainName =~ s/ //g;
                                        $domainName =~ s/\n//g;
					$text = sprintf "  CMP       %-30s  %s", "(" .$domainName.")",$cmpInfo[$c][0];
				} else {
                                        $text = sprintf "  CMP       %-30s  %s", "(" .$conn_hash{$errConn[$i]}.")",$cmpInfo[$c][0];
                                }
                                $found{$text}++;
			}
		}

		for ($x = 0; $x < $xc; $x++){
			if ($errConn[$i] eq $extInfo[$c][1] && $errOp[$i] eq $extInfo[$c][2]){
                                if ($resolveIP eq "yes"){
                                        $iip = $conn_hash{$errConn[$i]};
                                        $domainName = `nslookup $iip | grep \"^Name\"`;
                                        $domainName =~ s/Name://g;
                                        $domainName =~ s/ //g;
                                        $domainName =~ s/\n//g;
                                        $text = sprintf "  EXT       %-30s  %s", "(" .$domainName.")",$extInfo[$x][0];     
                                } else {
                                        $text = sprintf "  EXT       %-30s  %s", "(" .$conn_hash{$errConn[$i]}.")",$extInfo[$x][0]; 
                                }
                                $found{$text}++;
                        }
                }
        	for ($b = 0; $b < $bc; $b++){
                	if ($errConn[$i] eq $bindInfo[$b][1] && $errOp[$i] eq $bindInfo[$b][2]){
				if ($resolveIP eq "yes"){
                                        $iip = $conn_hash{$errConn[$i]};
                                        $domainName = `nslookup $iip | grep \"^Name\"`;
                                        $domainName =~ s/Name://g;
                                        $domainName =~ s/ //g;
                                        $domainName =~ s/\n//g;
					$text = sprintf "  BIND      %-30s  %s", "(" .$domainName.")",$bindInfo[$b][0];
				} else {
					$text = sprintf "  BIND      %-30s  %s", "(" .$conn_hash{$errConn[$i]}.")",$bindInfo[$b][0];
				}
                        	$found{$text}++;
                	}
        	}
        	for ($m = 0; $m < $mc; $m++){
                	if ($errConn[$i] eq $modInfo[$m][1] && $errOp[$i] eq $modInfo[$m][2]){
				if ($resolveIP eq "yes"){
                                        $iip = $conn_hash{$errConn[$i]};
                                        $domainName = `nslookup $iip | grep \"^Name\"`;
                                        $domainName =~ s/Name://g;
                                        $domainName =~ s/ //g;
                                        $domainName =~ s/\n//g;
					$text = sprintf "  MOD       %-30s  %s", "(" .$domainName.")",$modInfo[$m][0];
				} else {
					$text = sprintf "  MOD       %-30s  %s", "(" .$conn_hash{$errConn[$i]}.")",$modInfo[$m][0];
				}
                        	$found{$text}++;
                	}
        	}
        	for ($a = 0; $a < $ac; $a++){
                	if ($errConn[$i] eq $addInfo[$a][1] && $errOp[$i] eq $addInfo[$a][2]){
				if ($resolveIP eq "yes"){
                                        $iip = $conn_hash{$errConn[$i]};
                                        $domainName = `nslookup $iip | grep \"^Name\"`;
                                        $domainName =~ s/Name://g;
                                        $domainName =~ s/ //g;
                                        $domainName =~ s/\n//g;
					$text = sprintf "  ADD       %-30s  %s", "(" .$domainName.")",$addInfo[$a][0];
				} else {	
					$text = sprintf "  ADD       %-30s  %s", "(" .$conn_hash{$errConn[$i]}.")",$addInfo[$a][0];
				}
                        	$found{$text}++;
                	}
        	}
        	for ($d = 0; $d < $dc; $d++){
                	if ($errConn[$i] eq $delInfo[$d][1] && $errOp[$i] eq $delInfo[$d][2]){
				if ($resolveIP eq "yes"){
                                        $iip = $conn_hash{$errConn[$i]};
                                        $domainName = `nslookup $iip | grep \"^Name\"`;
                                        $domainName =~ s/Name://g;
                                        $domainName =~ s/ //g;
                                        $domainName =~ s/\n//g;
					$text = sprintf "  DEL       %-30s  %s", "(" .$domainName.")",$delInfo[$d][0];
				} else {
					$text = sprintf "  DEL       %-30s  %s", "(" .$conn_hash{$errConn[$i]}.")",$delInfo[$d][0];
				}
                        	$found{$text}++;
                	}
        	}
		for ($md = 0; $md < $mdc; $md++){
			if ($errConn[$i] eq $modrdnInfo[$md][1] && $errOp[$i] eq $modrdnInfo[$md][2]){
				if ($resolveIP eq "yes"){
                                        $iip = $conn_hash{$errConn[$i]};
                                        $domainName = `nslookup $iip | grep \"^Name\"`;
                                        $domainName =~ s/Name://g;
                                        $domainName =~ s/ //g;
                                        $domainName =~ s/\n//g;
					$text = sprintf "  MODRDN    %-30s  %s", "(" .$domainName.")",$modrdnInfo[$md][0];
				} else {
					$text = sprintf "  MODRDN    %-30s  %s", "(" .$conn_hash{$errConn[$i]}.")",$modrdnInfo[$md][0];
				}
				$found{$text}++;
			}
		}
	}

	print "\n\nNumber   Operation      Client                             Object\n";
	print     "=========================================================================\n";

	foreach $bas (sort { $found{$b} <=> $found{$a} } keys %found) {
        	if ($finalCount > $sizeCount){last;}
                $finalCount++;
                printf "%-8s %-40s\n", $found{ $bas },$bas;
	}
	print "\n";
	exit(0);

} # end of parseError

sub parseLines
{
	local $_ = $tline;
	$ff++;
	$iff++;
	if ($iff >= 1000){ print STDERR sprintf" %10s Lines Processed\n",$ff; $iff="0";}

	if (/ SRCH /   && $_ =~ /base=\"(.*)\" scope/i ){
        	if ($1 eq ""){$tmpp = "Root DSE";}
        	else {$tmpp = $1;}
        	$tmpp =~ tr/A-Z/a-z/;
        	$tmpp =~ s/\\22/\"/g;
        	$baseInfo[$fcc][0] = $tmpp;
        	if ($_ =~ /conn= *([0-9]+)/i) { $baseInfo[$fcc][1] = $1; }
        	if ($_ =~ /op= *([0-9]+)/i) { $baseInfo[$fcc][2] = $1; }
        	$fcc++;
	}

	if (m/ BIND/ && $_ =~ /dn=\"(.*)\" method/i ){
        	if ($1 ne ""){
                	$tmpp = $1;
                	$tmpp =~ tr/A-Z/a-z/;
                	$bindInfo[$bc][0] = $tmpp;
                	if ($_ =~ /conn= *([0-9]+)/i) { $bindInfo[$bc][1] = $1; }
                	if ($_ =~ /op= *([0-9]+)/i) { $bindInfo[$bc][2] = $1; }
                	$bc++;
        	}
	}
	
	if (m/ MODRDN / && $_ =~ /dn=\"(.*)\"/i ){
		if ($1 eq ""){$tmpp = "Root DSE";}
                else {$tmpp = $1;}
                $tmpp =~ tr/A-Z/a-z/;
                $tmpp =~ s/\\22/\"/g;
		$modrdnInfo[$mdc][0] = $tmpp;
		if ($_ =~ /conn= *([0-9]+)/i) { $modrdnInfo[$mdc][1] = $1; }
		if ($_ =~ /op= *([0-9]+)/i) { $modrdnInfo[$mdc][2] = $1; }
		$mdc++;
	}

	if (m/ MOD / && $_ =~ /dn=\"(.*)\"/i ){
        	if ($1 eq ""){$tmpp = "Root DSE";}
        	else {$tmpp = $1;}
        	$tmpp =~ tr/A-Z/a-z/;
        	$tmpp =~ s/\\22/\"/g;
        	$modInfo[$mc][0] = $tmpp;
        	if ($_ =~ /conn= *([0-9]+)/i) { $modInfo[$mc][1] = $1; }
        	if ($_ =~ /op= *([0-9]+)/i) { $modInfo[$mc][2] = $1; }
        	$mc++;
	}

	if (m/ DEL / && $_ =~ /dn=\"(.*)\"/i ){
        	if ($1 eq ""){$tmpp = "Root DSE";}
        	else {$tmpp = $1;}
        	$tmpp =~ tr/A-Z/a-z/;
        	$tmpp =~ s/\\22/\"/g;
        	$delInfo[$dc][0] = $tmpp;
        	if ($_ =~ /conn= *([0-9]+)/i) { $delInfo[$dc][1] = $1; }
        	if ($_ =~ /op= *([0-9]+)/i) { $delInfo[$dc][2] = $1; }
        	$dc++;
	}

	if (m/ EXT / && $_ =~ /oid=\"(.*)\"/i ){
		$tmpp = $1;
		$tmpp =~ s/\\22/\"/g;
		$extInfo[$xc][0] = $tmpp;
		if ($_ =~ /conn= *([0-9]+)/i) { $extInfo[$xc][1] = $1; }
                if ($_ =~ /op= *([0-9]+)/i) { $extInfo[$xc][2] = $1; }
                $xc++;	 
	}

	if (m/ CMP / && $_ =~ /dn=\"(.*)\"/i ){
		if ($1 eq ""){$tmpp = "Root DSE";}
                else {$tmpp = $1;}
                $tmpp =~ tr/A-Z/a-z/;
                $tmpp =~ s/\\22/\"/g;
		$cmpInfo[$cc][0] = $tmpp;
		if ($_ =~ /conn= *([0-9]+)/i) { $cmpInfo[$cc][1] = $1; }           
                if ($_ =~ /op= *([0-9]+)/i) { $cmpInfo[$cc][2] = $1; }     
                $cc++;  
        }

	if (m/ ADD / && $_ =~ /dn=\"(.*)\"/i ){
        	if ($1 eq ""){$tmpp = "Root DSE";}
        	else {$tmpp = $1;}
        	$tmpp =~ tr/A-Z/a-z/;
        	$tmpp =~ s/\\22/\"/g;
        	$addInfo[$ac][0] = $tmpp;
        	if ($_ =~ /conn= *([0-9]+)/i) { $addInfo[$ac][1] = $1; }
        	if ($_ =~ /op= *([0-9]+)/i) { $addInfo[$ac][2] = $1; }
        	$ac++;
	}

	if ($_ =~ /connection from *([0-9\.]+)/i ) {
                $ip = $1;
                if ($_ =~ /conn= *([0-9]+)/i ){
                                $conn_hash{$1} = $ip;
                }
	}

	if (/ err=$errorCode /){
   		if ($_ =~ /conn= *([0-9]+)/i) { $errConn[$con] = $1; }
   		if ($_ =~ /op= *([0-9]+)/i) { $errOp[$con] = $1; }
   		$con++
	}
}  # end of parseLines


sub report
{
$| = 1;
&clearStats();
if ($myInterval eq "NONE"){$myInterval = "HOUR";} 

open(REPORT,">$reportFile") || die "Error Can't create $reportFile: $!";

if ($DELIM eq "true"){
	print REPORT "Year|Month|Day|Time|Operations|Results|Performance|Connections|Searches|Modifications|Adds|Deletes|Modrdns|Binds|Extended Ops|Compares\n";
}

if ($files[$#files] =~ m/access.rotationinfo/) {  $fc--; }
print "\nProcessing $fc Access Log(s)...\n";

for ($count=0; $count < $fc; $count++){
        chomp($logsize = `wc -l $files[$count]`);
        $logsize =~ /([0-9]+)/;
        $ff="";$iff="";
        print sprintf "\n  %-10s %20s \n",$files[$count],"(Total Lines: $1)";
        open(LOG,"$files[$count]") || die "Error: Can't open file $infile: $!";

	$firstline = "yes";
        if ($count eq "0"){
		$start =`head -1 $files[$count]`;
        	if ($start =~ / *([0-9a-z:\/]+)/i){$start=$1;}

		if ($start =~ / *([0-9A-Z\/]+)/i ){ 
			$myDate = $1;
			@dateParts = split /\//, $myDate;
			$myDay = $dateParts[0];
			$myMonth = $dateParts[1];
			$myYear = $dateParts[2];
		}
        	if ($start =~ / *(:[0-9:]+)/i ){ 
			$myTime = $1;
        		@parts = split /:/, $myTime;
        		$myHour = $parts[1];
			$myMinute = $parts[2];
			$mySeconds = $parts[3];
		}
	}

	while (<LOG>) {
                if (/^\[/ && $firstline eq "yes"){
                        $tline = $_;
                        $firstline = "no";
                } elsif (/^\[/ && $firstline eq "no"){
			if ($myDay2 ne ""){
                        	$lastDay = $myDay2;
                        	$lastMonth = $myMonth2;
                        	$lastYear = $myYear2;
                        	$lastHour = $myHour2;
                        	$lastMinute = $myMinute2;
                        	$lastSecond = $mySeconds;
                	} else {
                        	$lastDay = $myDay;
                        	$lastMonth = $myMonth;
                        	$lastYear = $myYear;
                        	$lastHour = $myHour;
                        	$lastMinute = $myMinute;
                        	$lastSecond = $mySeconds;
                	}

                	if ($_ =~ / *([0-9A-Z\/]+)/i ){
                        	$myDate2 = $1;
                        	@dateParts2 = split /\//, $myDate2;
                        	$myDay2 = $dateParts2[0];
                        	$myMonth2 = $dateParts2[1];
                        	$myYear2 = $dateParts2[2];
                	}
                	if ($_ =~ / *(:[0-9:]+)/i ){
                        	$myTime2 = $1;
                        	@parts2 = split /:/, $myTime2;
                        	$myHour2 = $parts2[1];
                        	$myMinute2 = $parts2[2];
                        	$mySeconds = $parts2[3];
                	}

			# check the interval for the next report

                	if ($myInterval =~ /MINUTE/i){
                        	if ($myMinute2 ne $myMinute){
                                	&doReport();
                                	$myMinute =$myMinute2;
                        	}
                	}

                	if ($myInterval =~ /HOUR/i){
                        	if ($myHour2 ne $myHour){
                                	&doReport();
                                	$myHour = $myHour2;
                        	}
                	}

                	if ($myInterval =~ /DAY/i){
                        	if ($myDay2 ne $myDay){
                                	&doReport();
                                	$myDay = $myDay2;
                        	}
                	}
                	if ($myInterval =~ /MONTH/i){
                        	if ($myMonth2 ne $myMonth){
                                	&doReport();
                                	$myMonth = $myMonth2;
                        	}
                	}

			# done checking interval
			
                         &parseReport($tline);
                         $tline = $_;
                } else {
                        $tline = $tline . $_;
                        $tline =~ s/\n//;
                }
        }
        &parseReport($tline);
        close (LOG);
        $totalLineCount = $totalLineCount + $ff;
        print sprintf "*%10s Lines Processed                    Total Lines Processed: %12s\n",$ff,$totalLineCount;
}
$lastReport = "yes";
&doReport();
close (REPORT);
print "\n* Total Lines Analyzed:  $totalLineCount\n";

print "\n$reportFile successfully created.\n"; 

exit 0;

}

sub parseReport
{

        local $_ = $tline;
        $ff++;
        $iff++;
        if ($iff >= 1000){ print STDERR sprintf" %10s Lines Processed\n",$ff; $iff="0";}
        if (m/ RESULT err/){$allResults++;}

        if (m/ SRCH /){
                $search++;
        }

        if (m/ DEL /){
                $delete++;
        }

        if (m/ MOD /){
                $mod++;
        }

        if (m/ ADD/ ){
                $add++;
        }

        if (m/ MODRDN /){
                $modrdn++;
        }

        if (m/ ABANDON /){
                $abandon++;
#                $allResults++;   seems that a result line is logged and 4.x and 5.x report differently
        }

        if (m/ conn=0 fd=/){$restarts++}
        if (m/ SSL connection from/){$sslconn++;}
        if (m/ connection from/){
                $exc = "no";
                if ($_ =~ /connection from *([0-9\.]+)/i ){
                        for ($xxx =0; $xxx <= $#exclude; $xxx++){
                                if ($exclude[$xxx] eq $1){$exc = "yes";}
                        }
                        if ($exc ne "yes"){ $connectionCount++;}
                }
        }

	if (m/ BIND /){
		$bind++;
	}

        if (m/ EXT oid=/){
                $extendedop++;
        }

	if (m/ CMP dn=/){
		$compare++;
	}

}

sub doReport
{

$allOps = $search + $mod + $add + $delete + $modrdn + $bind + $extendedop + $compare;

if ($DELIM eq ""){
	print REPORT "\n";
	if ($lastReport ne "yes"){
		print REPORT "----- Stats for $lastMonth $lastDay $lastYear $lastHour:$lastMinute:$lastSecond -----\n\n";
	} else {
		print REPORT "----- Stats for $myMonth2 $myDay2 $myYear2 $myHour2:$myMinute2:$mySeconds -----\n\n";
	}

	print REPORT "Total Operations:        $allOps\n";
	print REPORT "Total Results:           $allResults\n";
	if ($allOps ne "0"){
       		print REPORT sprintf "Overall Performance:     %.1f%\n" , ($allResults / $allOps)*100 ;
	} else {
        	print REPORT "Overall Performance:     No Operations to evaluate\n";
	}

	print REPORT "Total Connections:       $connectionCount\n";
	if ($sslconn > 0){
		print REPORT "SSL Connections:         $sslconn\n";
	}

	print REPORT "\nSearches:                $search\n";
	print REPORT "Modifications:           $mod\n";
	print REPORT "Adds:                    $add\n";
	print REPORT "Deletes:                 $delete\n";
	print REPORT "Modrdns:                 $modrdn\n";
	print REPORT "Binds:                   $bind\n";
	print REPORT "Extended Ops:            $extendedop\n";
	print REPORT "Compare Ops:             $compare\n";

	print REPORT "\n";
} else {
	if ($allOps ne "0"){
		$myOverall = sprintf "%.1f%" , ($allResults / $allOps)*100 ;
	} else {
		$myOverall = "0";
	}

#
# Format for excel keys:
# 
# YYYY|MMM|DD|HH:MM:SS|OPS|RESULTS|PERF|CONN|SEARCHES|MODS|ADDS|DELS|MODRDN|BINDS|EXTENDED|COMPARE
#

	if ($lastReport ne "yes"){
	
        	print REPORT "$lastYear|$lastMonth|$lastDay|$lastHour:$lastMinute:$lastSecond|$allOps|$allResults|$myOverall|$connectionCount|$search|$mod|$add|$delete|$modrdn|$bind|$extendedop|$compare\n";
	} else {
		print REPORT "$myYear2|$myMonth2|$myDay2|$myHour2:$myMinute2:$mySeconds|$allOps|$allResults|$myOverall|$connectionCount|$search|$mod|$add|$delete|$modrdn|$bind|$extendedop|$compare\n";

	}
}
&clearStats();

} # end of doReport

sub clearStats
{

$allOps = "0"; $allResults = "0";
$search = "0"; $mod = "0"; $add = "0";
$delete = "0"; $modrdn = "0";
$bind = "0"; $extendedop = "0";
$connectionCount = "0";
$sslconn = "0"; $compare = "0";

}


# connection stat plugin 

sub connCheck
{

$| = 1;

open(REPORT,">$connFile") || die "Error Can't create $connFile: $!";
print REPORT "Top $sizeCount Busiest Connections\n";

if ($files[$#files] =~ m/access.rotationinfo/) {  $fc--; }

print "\nProcessing $fc Access Log(s)...\n";

for ($count=0; $count < $fc; $count++){
        chomp($logsize = `wc -l $files[$count]`);
        $logsize =~ /([0-9]+)/;
        $ff="";$iff="";
        print sprintf "\n  %-10s %20s \n",$files[$count],"(Total Lines: $1)";
        open(LOG,"$files[$count]") || die "Error: Can't open file $infile: $!";

        $firstline = "yes";

        while (<LOG>) {
                if (/^\[/ && $firstline eq "yes"){
                        $tline = $_;
                        $firstline = "no";
                } elsif (/^\[/ && $firstline eq "no"){
                         &parseConn($tline);
                         $tline = $_;
                } else {
                        $tline = $tline . $_;
                        $tline =~ s/\n//;
                }
        }
        &parseConn($tline);
        close (LOG);

        $totalLineCount = $totalLineCount + $ff;
        print sprintf "*%10s Lines Processed                    Total Lines Processed: %12s\n",$ff,$totalLineCount;
}

print "\n* Total Lines Analyzed:  $totalLineCount\n";
&doConnReport();
print "Connection stats file $connFile created successfully\n";

exit 0;

}

sub parseConn
{

 local $_ = $tline;
 $backup3 = $_;
 $ff++;
 $iff++;
 if ($iff >= 1000){ print STDERR sprintf" %10s Lines Processed\n",$ff; $iff="0";}

 if (/connection from /){
	$backup = $_;
	$backup2 = $_;
 	if ($_ =~ /connection from *([0-9\.]+)/i ) { $ip = $1; }
 	if ($backup =~ /conn= *([0-9]+)/i) { $conn_hash{$1}{"ip"} = $ip; $connid = $1;}
	if ($backup2 =~ / *([0-9a-z:\/]+)/i){ $conn_hash{$connid}{"start"} = $1;}
	if (/SSL connection from/){ $conn_hash{$connid}{"ssl"} = 1; }
 }

 if (/closed - /){
	$closed = $_;
	if ($_ =~ /conn= *([0-9]+)/i) { $closedid = $1; }
	if ($closed =~ / *([0-9a-z:\/]+)/i){ $conn_hash{$closedid}{"end"} = $1; }
 }

 if (/ SRCH base=/ || / DEL dn=/ || / MOD dn=/ || / ADD dn=/ || / MODRDN dn=/ || / EXT oid=/ || / BIND dn=/ || / CMP dn=/){
        if ($_ =~ /conn= *([0-9]+)/i) {
                $conn_hash{$1}{"op"}++;                         
        }
	$myDiff = $conn_hash{$1}{"op"} - $conn_hash{$1}{"result"};
	if ($myDiff > $conn_hash{$1}{"highop"}) {
		$conn_hash{$1}{"highop"} = $myDiff;
	}
 }

 if (/ BIND dn=/){
	 if ($_ =~ /conn= *([0-9]+)/i) {
                $conn_hash{$1}{"bind"}++;
        }
 }

 if (/ ABANDON / || / RESULT err/){
        if ($_ =~ /conn= *([0-9]+)/i) {                        
                $conn_hash{$1}{"result"}++;                                 
        }                        
 }

 if (m/ SRCH /){
	if ($_ =~ /conn= *([0-9]+)/i) {
                $conn_hash{$1}{"search"}++;
        }
 }

 if (m/ DEL /){
	if ($_ =~ /conn= *([0-9]+)/i) {
                $conn_hash{$1}{"delete"}++;
        }
 }

 if (m/ MOD /){
	if ($_ =~ /conn= *([0-9]+)/i) {
                $conn_hash{$1}{"mod"}++;
        }
 }

 if (m/ ADD/ ){
	if ($_ =~ /conn= *([0-9]+)/i) {
                $conn_hash{$1}{"add"}++;
        }
 }

 if (m/ MODRDN /){
	if ($_ =~ /conn= *([0-9]+)/i) {
                $conn_hash{$1}{"modrdn"}++;
        }
 }

 if (m/ ABANDON /){
	if ($_ =~ /conn= *([0-9]+)/i) {
                $conn_hash{$1}{"abandon"}++;
        }
 }

 if (m/ EXT /){
	if ($_ =~ /conn= *([0-9]+)/i) {
                $conn_hash{$1}{"ext"}++;
        }
 }

 if (m/ CMP /){
	if ($_ =~ /conn= *([0-9]+)/i) {
                $conn_hash{$1}{"compare"}++;
        }
 }

 $_ = $backup3;

 if (m/ conn=0 fd=/){$restarts++}

}

sub doConnReport
{
 $cCount = "0";

 if ($restarts > 0){
	print REPORT "\n\nWARNING: The following results could be inaccurate because the server was restarted $restarts times.\n";
 }

 foreach $key (sort { $conn_hash{$b}{"op"} <=> $conn_hash{$a}{"op"} } keys %conn_hash) {
	$cCount++;
	if ($cCount > $sizeCount){ last; }
        print REPORT "\n\n[$cCount] Connection: $key\n";
	print REPORT "  IP Address:        " . $conn_hash{$key}{"ip"} . "\n";
	print REPORT "  Connection Opened: " . $conn_hash{$key}{"start"} . "\n";
	if ($conn_hash{$key}{"end"} eq ""){
		print REPORT "  Connection Closed: ** Still Open **\n";
	} else {
		print REPORT "  Connection Closed: " . $conn_hash{$key}{"end"} . "\n";
	}
	if ($conn_hash{$key}{"ssl"} eq "1"){ 
		print REPORT "- SSL Connection\n";
	}
        print REPORT "  Operations:        " . $conn_hash{$key}{"op"} . "\n";
        print REPORT "  Results:           " . $conn_hash{$key}{"result"} . "\n";
	print REPORT "  Most Pending Ops:  " . $conn_hash{$key}{"highop"} . "\n\n";

	if ($conn_hash{$key}{"bind"} eq "") {$conn_hash{$key}{"bind"} = "0"; }
	print REPORT "  Binds:             " . $conn_hash{$key}{"bind"} . "\n";
	if ($conn_hash{$key}{"search"} eq "") {$conn_hash{$key}{"search"} = "0";}
	print REPORT "  Searches:          " . $conn_hash{$key}{"search"} . "\n";
	if ($conn_hash{$key}{"add"} eq "") {$conn_hash{$key}{"add"} = "0";}
	print REPORT "  Adds:              " . $conn_hash{$key}{"add"} . "\n";
	if ($conn_hash{$key}{"mod"} eq "") {$conn_hash{$key}{"mod"} = "0";}
	print REPORT "  Modifies:          " . $conn_hash{$key}{"mod"} . "\n";
	if ($conn_hash{$key}{"delete"} eq ""){$conn_hash{$key}{"delete"} = "0";}
	print REPORT "  Deletes:           " . $conn_hash{$key}{"delete"} . "\n";
	if ($conn_hash{$key}{"modrdn"} eq ""){$conn_hash{$key}{"modrdn"} = "0";}
	print REPORT "  Modrdn:            " . $conn_hash{$key}{"modrdn"} . "\n";
	if ($conn_hash{$key}{"ext"} eq "" ){ $conn_hash{$key}{"ext"} = "0";}
	print REPORT "  Extended Op:       " . $conn_hash{$key}{"ext"} . "\n";
	if ($conn_hash{$key}{"compare"} eq ""){ $conn_hash{$key}{"compare"} = "0";}
	print REPORT "  Compares:          " . $conn_hash{$key}{"compare"} . "\n";
	if ($conn_hash{$key}{"abandon"} eq ""){$conn_hash{$key}{"abandon"} = "0";}
	print REPORT "  Abandoned Ops:     " . $conn_hash{$key}{"abandon"} . "\n";
 }
 close(REPORT);
}



sub checkBind
{
$| = 1;

open(REPORT,">$bindFile") || die "Error Can't create $bindFile: $!";
print REPORT "Top $sizeCount Busiest Binds\n\n";

if ($files[$#files] =~ m/access.rotationinfo/) {  $fc--; }

print "\nProcessing $fc Access Log(s)...\n";

for ($count=0; $count < $fc; $count++){
        chomp($logsize = `wc -l $files[$count]`);
        $logsize =~ /([0-9]+)/;
        $ff="";$iff="";
        print sprintf "\n  %-10s %20s \n",$files[$count],"(Total Lines: $1)";
        open(LOG,"$files[$count]") || die "Error: Can't open file $infile: $!";

        $firstline = "yes";

	if ($count eq "0"){
                $start =`head -1 $files[$count]`;
                if ($start =~ / *([0-9a-z:\/]+)/i){$start=$1;}

                if ($start =~ / *([0-9A-Z\/]+)/i ){ 
                        $myDate = $1;
                        @dateParts = split /\//, $myDate;
                        $myDay = $dateParts[0];
                        $myMonth = $dateParts[1];
                        $myYear = $dateParts[2];
                }
                if ($start =~ / *(:[0-9:]+)/i ){ 
                        $myTime = $1;
                        @parts = split /:/, $myTime;
                        $myHour = $parts[1];
                        $myMinute = $parts[2];
                        $mySeconds = $parts[3];
                }
        }

        while (<LOG>) {
                if (/^\[/ && $firstline eq "yes"){
                        $tline = $_;
                        $firstline = "no";
                } elsif (/^\[/ && $firstline eq "no"){
			if ($myDay2 ne ""){
                                $lastDay = $myDay2;
                                $lastMonth = $myMonth2;
                                $lastYear = $myYear2;
                                $lastHour = $myHour2;
                                $lastMinute = $myMinute2;
                                $lastSecond = $mySeconds;
                        } else {
                                $lastDay = $myDay;
                                $lastMonth = $myMonth;
                                $lastYear = $myYear;
                                $lastHour = $myHour;
                                $lastMinute = $myMinute;
                                $lastSecond = $mySeconds;
                        }

                        if ($_ =~ / *([0-9A-Z\/]+)/i ){
                                $myDate2 = $1;
                                @dateParts2 = split /\//, $myDate2;
                                $myDay2 = $dateParts2[0];
                                $myMonth2 = $dateParts2[1];
                                $myYear2 = $dateParts2[2];
                        }
                        if ($_ =~ / *(:[0-9:]+)/i ){
                                $myTime2 = $1;
                                @parts2 = split /:/, $myTime2;
                                $myHour2 = $parts2[1];
                                $myMinute2 = $parts2[2];
                                $mySeconds = $parts2[3];
                        }

                        # check the interval for the next report

                        if ($myInterval =~ /MINUTE/i){
                                if ($myMinute2 ne $myMinute){
                                        &doBindReport();
                                        $myMinute =$myMinute2;
                                }
                        }

                        if ($myInterval =~ /HOUR/i){
                                if ($myHour2 ne $myHour){
                                        &doBindReport();
                                        $myHour = $myHour2;
                                }
                        }

                        if ($myInterval =~ /DAY/i){
                                if ($myDay2 ne $myDay){
                                        &doBindReport();
                                        $myDay = $myDay2;
                                }
                        }
                        if ($myInterval =~ /MONTH/i){
                                if ($myMonth2 ne $myMonth){
                                        &doBindReport();
                                        $myMonth = $myMonth2;
                                }
                        }

                        # done checking interval

                         &parseBind($tline);
                         $tline = $_;
                } else {
                        $tline = $tline . $_;
                        $tline =~ s/\n//;
                }
        }
        &parseBind($tline);
        close (LOG);

        $totalLineCount = $totalLineCount + $ff;
        print sprintf "*%10s Lines Processed                    Total Lines Processed: %12s\n",$ff,$totalLineCount;
}

print "\n* Total Lines Analyzed:  $totalLineCount\n";
$lastReport = "yes";
&doBindReport();
close(REPORT);
print "Bind stats file $bindFile created successfully\n";

exit 0;

}

sub doCheck
{
 $line = $_[0];
 if ($line =~ /conn= *([0-9]+)/i) {
	foreach $keys (keys %bindlist){
		if ($bindlist{$keys}{"conn"} =~ m/ $1 /){
			$bindlist{$keys}{"allops"}++;
			return $keys;
		}
	}
	return "";
 }
}

sub parseBind
{
 local $_ = $tline;
 $ff++;
 $iff++;
 $dn = "";
 if ($iff >= 1000){ print STDERR sprintf" %10s Lines Processed\n",$ff; $iff="0";}

 if (/m conn=0 fd=/){
	# The server has been restarted, clear all previous connection referecnes so we
	# can keep an accurate count

	foreach $key (keys %bindlist){
		$bindlist{$key}{"conn"} = "ZZZ";
	}
 }

 if (m/ BIND/ && $_ =~ /dn=\"(.*)\" method/i ){
	if ($1 ne ""){
		$tmpp = $1;
                $tmpp =~ tr/A-Z/a-z/;
	} else {
		$tmpp = "Anonymous Bind";
	}

	$bindlist{$tmpp}{"count"}++;
	$bindlist{$tmpp}{"allops"}++;

	if ($bindlist{$tmpp}{"count"} eq 1){
		$bindlist{$tmpp}{"search"} = 0;
		$bindlist{$tmpp}{"add"} = 0;
		$bindlist{$tmpp}{"mod"} = 0;
		$bindlist{$tmpp}{"del"} = 0;
		$bindlist{$tmpp}{"cmp"} = 0;
		$bindlist{$tmpp}{"ext"} = 0;
		$bindlist{$tmpp}{"modrdn"} = 0;
	}

	if ($_ =~ /conn= *([0-9]+)/i) {
		$bindlist{$tmpp}{"conn"} = $bindlist{$tmpp}{"conn"} . " " . $1 . " ";
	}
 }

 if (m/ SRCH base=/){
	$dn = &doCheck($_);
	if ($dn ne ""){
		$bindlist{$dn}{"search"}++;
	}
 }	

 if (m/ ADD dn=/){
	$dn = &doCheck($_);
	if ($dn ne ""){
		$bindlist{$dn}{"add"}++;
	}	
 }

 if (m/ MOD dn=/){
	$dn = &doCheck($_);
	if ($dn ne ""){
		$bindlist{$dn}{"mod"}++;
	}
 }

 if (m/ DEL dn=/){
	$dn = &doCheck($_);
	if ($dn ne ""){
		$bindlist{$dn}{"del"}++;
	}
 }

 if (m/ MODRDN dn=/){
	$dn = &doCheck($_);
	if ($dn ne ""){
		$bindlist{$dn}{"modrdn"}++;
	}
 }

 if (m/ CMP dn=/){
	$dn = &doCheck($_);
	if ($dn ne ""){
		$bindlist{$dn}{"cmp"}++;
	}
 }

 if (m/ EXT oid=/){
	$dn = &doCheck($_);
	if ($dn ne ""){
		$bindlist{$dn}{"ext"}++;
	}
 }

 
}

sub clearBinds
{
 foreach $keyzz (keys %bindlist){
	$bindlist{$keyzz}{"allops"} = "0";
	$bindlist{$keyzz}{"count"} = "0";
	$bindlist{$keyzz}{"search"} = "0";
	$bindlist{$keyzz}{"add"} = "0";
	$bindlist{$keyzz}{"mod"} = "0";
	$bindlist{$keyzz}{"del"} = "0";
	$bindlist{$keyzz}{"modrdn"} = "0";
	$bindlist{$keyzz}{"cmp"} = "0";
	$bindlist{$keyzz}{"ext"} = "0";
 }

}

sub doBindReport
{
 $bindCount = "0";

 if ($DELIM ne "true"){
	if ($lastReport ne "yes"){
		print REPORT "                                                       ($lastMonth $lastDay $lastYear $lastHour:$lastMinute:$lastSecond)\n\n";
	} else {
                print REPORT "                                                       ($myMonth2 $myDay2 $myYear2 $myHour2:$myMinute2:$mySeconds)\n\n";
        }
 	print REPORT "            Bind DN                      Total Ops      Binds  Searches      Adds  Modifies   Deletes   Modrdns   Compares  Ext Ops\n";  
 	print REPORT "------------------------------------------------------------------------------------------------------------------------------------\n";
 } else {
	print REPORT "Year|Month|Day|Time|Bind DN|Total Ops|Binds|Searches|Adds|Modifies|Deletes|Modrdns|Compares|Extended Ops\n";
 }

 foreach $keyz (sort { $bindlist{$b}{"allops"} <=> $bindlist{$a}{"allops"} } keys %bindlist) {
	$bindCount++;
	if ($bindCount <= $sizeCount){

		if ($DELIM eq "true"){
		 if ($lastReport ne "yes"){
			print REPORT "$lastYear|$lastMonth|$lastDay|$lastHour:$lastMinute:$lastSecond|$keyz|$bindlist{$keyz}{\"allops\"}|$bindlist{$keyz}{\"count\"}|$bindlist{$keyz}{\"search\"}|$bindlist{$keyz}{\"add\"}|$bindlist{$keyz}{\"mod\"}|$bindlist{$keyz}{\"del\"}|$bindlist{$keyz}{\"modrdn\"}|$bindlist{$keyz}{\"cmp\"}|$bindlist{$keyz}{\"ext\"}\n";
		 } else {
			print REPORT "$myYear2|$myMonth2|$myDay2|$myHour2:$myMinute2:$mySeconds|$keyz|$bindlist{$keyz}{\"allops\"}|$bindlist{$keyz}{\"count\"}|$bindlist{$keyz}{\"search\"}|$bindlist{$keyz}{\"add\"}|$bindlist{$keyz}{\"mod\"}|$bindlist{$keyz}{\"del\"}|$bindlist{$keyz}{\"modrdn\"}|$bindlist{$keyz}{\"cmp\"}|$bindlist{$keyz}{\"ext\"}\n";
		 }
		} else {

format REPORT =
@<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  @>>>>>>>>  @>>>>>>>>  @>>>>>>>  @>>>>>>>  @>>>>>>>  @>>>>>>>  @>>>>>>>  @>>>>>>>>  @>>>>>>
$bindCount $keyz $bindlist{$keyz}{"allops"} $bindlist{$keyz}{"count"} $bindlist{$keyz}{"search"} $bindlist{$keyz}{"add"} $bindlist{$keyz}{"mod"} $bindlist{$keyz}{"del"} $bindlist{$keyz}{"modrdn"} $bindlist{$keyz}{"cmp"} $bindlist{$keyz}{"ext"}
.
write REPORT;
		}

	}
 }
 if ($DELIM ne "true"){
 	print REPORT "------------------------------------------------------------------------------------------------------------------------------------\n";
 }
 print REPORT "\n\n";
 &clearBinds;

}


#
# Client Reporting
#

sub checkClient
{
$| = 1;
$vlv = "0";

open(REPORT,">$clientFile") || die "Error Can't create $clientFile: $!";
print REPORT "Top $sizeCount Busiest Clients\n\n";

if ($files[$#files] =~ m/access.rotationinfo/) {  $fc--; }

print "\nProcessing $fc Access Log(s)...\n";

for ($count=0; $count < $fc; $count++){
        chomp($logsize = `wc -l $files[$count]`);
        $logsize =~ /([0-9]+)/;
        $ff="";$iff="";
        print sprintf "\n  %-10s %20s \n",$files[$count],"(Total Lines: $1)";
        open(LOG,"$files[$count]") || die "Error: Can't open file $infile: $!";

        $firstline = "yes";

        while (<LOG>) {
                if (/^\[/ && $firstline eq "yes"){
                        $tline = $_;
                        $firstline = "no";
                } elsif (/^\[/ && $firstline eq "no"){
                         &parseClient($tline);
                         $tline = $_;
                } else {
                        $tline = $tline . $_;
                        $tline =~ s/\n//;
                }
        }
        &parseClient($tline);
        close (LOG);

        $totalLineCount = $totalLineCount + $ff;
        print sprintf "*%10s Lines Processed                    Total Lines Processed: %12s\n",$ff,$totalLineCount;
}

print "\n* Total Lines Analyzed:  $totalLineCount\n";
&doClientReport();
close (REPORT);
print "Client stats file $clientFile created successfully\n";

exit 0;

}

sub parseClient
{
        local $_ = $tline;
        $ff++;
        $iff++;
	$iip = "";
        if ($iff >= 1000){ print STDERR sprintf" %10s Lines Processed\n",$ff; $iff="0";}

	if (m/ conn=0 fd=/){
		foreach $key (keys %clientHash){
                	$clientHash{$key}{"conn"} = "ZZZ";
		}
		$#vlv = -1;
        }

	if ($_ =~ /connection from *([0-9\.]+)/i ) {
		for ($xxx =0; $xxx <= $#exclude; $xxx++){
                        if ($exclude[$xxx] eq $1){$exc = "yes";}
                }
                if ($exc ne "yes"){ 
			$ip = $1;
			if ($_ =~ /conn= *([0-9]+)/i ){
				$conn = $1;
			}
			$clientHash{$conn} = $ip;
			$clientList{$ip}{"count"}++;
			$clientList{$ip}{"search"} = 0;
			$clientList{$ip}{"add"} = 0;
			$clientList{$ip}{"del"} = 0;
			$clientList{$ip}{"mod"} = 0;
			$clientList{$ip}{"modrdn"} = 0;
			$clientList{$ip}{"cmp"} = 0;
			$clientList{$ip}{"ext"} = 0;
			$clientList{$ip}{"bind"} = 0;
			$clientList{$ip}{"opcount"} = 0;
		}
	}

	if (/ SRCH base=/ || / MOD dn=/ || / ADD dn=/ || / DEL dn=/ || / MODRDN dn=/ || / CMP dn=/ || / EXT oid=/ ){
		if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                        if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientList{$iip}{"opcount"}++;}
        } 

	if (m/ closed / && m/ - A1/){
		if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
			if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"A1"}++;}
	}
 
        if (m/ closing / && m/ - A1/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                        if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"A1"}++;}
        }

	
        if (m/ closed / && m/ - B1/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
			if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"B1"}++;}      
        }

        if (m/ closing / && m/ - B1/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                        if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"B1"}++;}
        }


	
        if (m/ closed / && m/ - B4/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
			if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"B4"}++;}      
        }

        if (m/ closing / && m/ - B4/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                        if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"B4"}++;}
        }


	
        if (m/ closed / && m/ - T1/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
			if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"T1"}++;}      
        }

        if (m/ closing / && m/ - T1/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                        if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"T1"}++;}
        }
	
        if (m/ closed / && m/ - T2/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
			if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"T2"}++;}      
        }

        if (m/ closing / && m/ - T2/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                        if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"T2"}++;}
        }

	
        if (m/ closed / && m/ - B2/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
			if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"B2"}++;}      
        }

        if (m/ closing / && m/ - B2/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                        if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"B2"}++;}
        }

	
        if (m/ closed / && m/ - B3/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
			if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"B3"}++;}      
        }

        if (m/ closing / && m/ - B3/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                        if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"B3"}++;}
        }
	
        if (m/ closed / && m/ - R1/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
			if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"R1"}++;}      
        }

        if (m/ closing / && m/ - R1/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                        if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"R1"}++;}
        }
	
        if (m/ closed / && m/ - P1/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
			if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"P1"}++;}      
        }

        if (m/ closing / && m/ - P1/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                        if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"P1"}++;}
        }

	
        if (m/ closed / && m/ - P2/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
			if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"P2"}++;}      
        }

        if (m/ closing / && m/ - P2/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                        if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"P2"}++;}
        }

	
        if (m/ closed / && m/ - U1/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
			if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"U1"}++;}      
        }

        if (m/ closing / && m/ - U1/){
                if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                        if ($iip eq ""){$iip = "Unknown Client";}
                }
                if ($iip ne ""){ $clientConnList{$iip}{"U1"}++;}
        }

        if (m/ SRCH base=/){
		if ($_ =~ /conn= *([0-9]+)/i ){
			$iip = $clientHash{$1};
		}
		if ($iip ne ""){ $clientList{$iip}{"search"}++;}	
        }

        if (m/ DEL dn=/){
		if ($_ =~ /conn= *([0-9]+)/i ){
		        $iip = $clientHash{$1};
                } 
		if ($iip ne ""){ $clientList{$iip}{"del"}++;}
        }

        if (m/ MOD dn=/){
		if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                } 
		if ($iip ne ""){ $clientList{$iip}{"mod"}++;}
        }

        if (m/ ADD dn=/ ){
		if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                } 
                if ($iip ne ""){ $clientList{$iip}{"add"}++;}
        }

        if (m/ MODRDN dn=/){
		if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                } 
                if ($iip ne ""){ $clientList{$iip}{"modrdn"}++;}
        }

        if (m/ ABANDON /){
		if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                } 
                if ($iip ne ""){ $clientList{$iip}{"abandon"}++;}
        }

        if (m/ SSL connection from/){
		if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                } 
                if ($iip ne ""){ $clientList{$iip}{"ssl"}++;}
	}

        if (m/ BIND dn=/){
		if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                } 
                if ($iip ne ""){ $clientList{$iip}{"bind"}++;}
        }

        if (m/ EXT oid=/){
		if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                } 
                if ($iip ne ""){ $clientList{$iip}{"ext"}++;}
        }

        if (m/ CMP dn=/){
		if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
                } 
                if ($iip ne ""){ $clientList{$iip}{"cmp"}++;}
        }

	if (m/ VLV /){
                if ($_ =~ /conn= *([0-9]+)/i){ $vlvconn[$vlv] = $1;}
                if ($_ =~ /op= *([0-9]+)/i){ $vlvop[$vlv] = $1;}
		$vlv++;
        }

	if (m/ notes=U/){
		if ($_ =~ /conn= *([0-9]+)/i ){
                        $iip = $clientHash{$1};
			$notesConn = $1;
			$v = "0";
                }
                if ($_ =~ /op= *([0-9]+)/i){ $notesOp = $1;}

                for ($i=0; $i <= $vlv;$i++){
                        if ($vlvconn[$i] eq $notesConn && $vlvop[$i] eq $notesOp){ $v="1";}
                }
                if ($v eq "0" ){
			$clientList{$iip}{"notes"}++;
                }
	}

	if (m/ notes=F/){
		$searchTune++;
	}

}

sub doClientReport
{
	$clientCount = "0";

	if ($clientOpt eq "ops"){
		foreach $keyz ( sort {$clientList{$b}{"opcount"} <=> $clientList{$a}{"opcount"} } keys %clientList){
			if ($clientCount < $sizeCount){
				printClientList();
			}
		}
	} else {
		foreach $keyz ( sort {$clientList{$b}{"count"} <=> $clientList{$a}{"count"} } keys %clientList){
		        if ($clientCount < $sizeCount){
                                printClientList();
                        }
		}
	}
}
 
sub printClientList
{
                        $clientCount++;
                        print REPORT "Client[$clientCount]:  $keyz\n";               
			if ($clientOpt eq "ops"){
				print REPORT "Number of Operations:   " . $clientList{$keyz}{"opcount"} . "\n";}
                        print REPORT "Number of Connections:  " . $clientList{$keyz}{"count"} . "\n";
                        if ( $clientList{$keyz}{"ssl"} > 0){
                                print REPORT "SSL Connections:        " . $clientList{$keyz}{"ssl"} . "\n";}
                        foreach $code ( sort { $clientConnList{$keyz}{$b} <=> $clientConnList{$keyz}{$a} } keys %{$clientConnList{ $keyz}}){
                                print REPORT " - $code:  " . $clientConnList{$keyz}{$code} . "\n";
                        }
			if ($clientOpt ne "ops"){
                        	print REPORT "Number of Operations:   " . $clientList{$keyz}{"opcount"} . "\n";}
                        print REPORT "Number of Binds:        " . $clientList{$keyz}{"bind"} . "\n";
                        print REPORT "Number of Searches:     " . $clientList{$keyz}{"search"} . "\n";
                        print REPORT "Number of Modifies:     " . $clientList{$keyz}{"mod"} . "\n";
                        print REPORT "Number of Adds:         " . $clientList{$keyz}{"add"} . "\n";
                        print REPORT "Number of Deletes:      " . $clientList{$keyz}{"del"} . "\n";
                        print REPORT "Number of Modrdns:      " . $clientList{$keyz}{"modrdn"} . "\n";
                        print REPORT "Number of Compares:     " . $clientList{$keyz}{"cmp"} ."\n";
                        print REPORT "Number of Extended Ops: " . $clientList{$keyz}{"ext"} . "\n";
                        if ($clientList{$keyz}{"abandon"} > 0){
                                print REPORT "Abandoned Operations:   " . $clientList{$keyz}{"abandon"} . "\n";}
                        if ($clientList{$keyz}{"notes"} > 0){
                                print REPORT "** Unindexed Searches:  " . $clientList{$keyz}{"notes"} . "\n";}
			print REPORT "\n\n";
}

	
#######################################
#                                     #
#             The  End                #
#                                     #
#######################################
