#// TESTNAME="Test For Any Check Conditions" FUNC="chk_cond" OUTPUTFILE="NONE" use Tharn; use Subtest; use English qw($BASETIME); use Cwd 'abs_path'; sub test_check_cond($@); sub parse_rule_files($); sub test_sp_rule($@); sub send_to_console($$$$); sub create_log_files($$); sub calcTimeDiff($); sub filterOutDir($); sub chk_cond($) { my ($line, $matchs, $report, $reportWarn, $wCnt, $cCnt, $curSP, $consolehandleA, $consolehandleB, $scCnt, $maxcCnt, $maxwCnt); my ($cntt) = (0, 0); my @errorstrings = parse_rule_files("Common_rules"); my @spstrings = parse_rule_files(retrieve_var("CurTest")); my $LOGDIR = retrieve_var("LOGDIR"); my $PARSE_ID = filterOutDir(cur_logpos()->{"file"});#retrieve_var("CurTest"); my $logbegin = cur_logpos(); my $icCnt = 0; my $inspection_report; my $san = retrieve_var("SAN"); my $init_time = "0"; my $tmpdir; my @short_smry; my $smry_cnt = 0; my $is_sub_test = "false"; my $subtests = retrieve_var("SUBTESTS"); my $current_test = filterOutDir(cur_logpos()->{"file"}); foreach my $subtst (@$subtests) { if(trim(filterOutDir($subtst)) eq trim(filterOutDir($current_test))) { $is_sub_test = "true"; } } $scCnt = 0; $maxcCnt = 0; $maxwCnt = 0; if($is_sub_test eq "false") { $consoleAname = retrieve_var("LOGDIR") . "/../../../" . $PARSE_ID . "_" . retrieve_var("FILER") . ".console"; } else { $consoleAname = retrieve_var("LOGDIR") . "/../../../" . $PARSE_ID . ".console"; } if($is_sub_test eq "false") { open($consolehandleA, ">$consoleAname") or die "write:FAIED " . $consoleAname . "\n"; } if(retrieve_var("TEST_CONFIG") eq "C" && retrieve_var("CurTest") ne "check_setup" && $is_sub_test eq "false") { open($consolehandleB, ">$LOGDIR/../../../" . $PARSE_ID . "_" . retrieve_var("FILERB") . ".console") or die "write:FAIED\n"; } while(($line = next_logline()) ne "") { if($init_time eq "0") { if(($line =~ m/^(\d+) (\d+) \[.*\] !!/) || ( $line =~ /^(\d+) (\d+) TESTCASE BEGIN/ ) || ($line =~ /^(\d+) (\d+)\s+\S+/ )) { $init_time = calcTimeDiff($1 . " " . $2); } } if($line =~ m/Test fatal failure/ || $line =~ m/Test failure/ || $line =~ m/FAILED&/ || $line =~ m/FAIL&/ || $line =~ m/FAIL:/) { $scCnt++; next; } $line = send_to_console($line, $consolehandleA, $consolehandleB, $is_sub_test); my $cur = test_check_cond($line, @errorstrings); if($cur ne undef) { my ($curOp, $drive, $mesg, $errstr) = ($cur-> { "Opcode"}, $cur-> { "Drive" }, $cur-> { "Message" }, $cur-> {"ErrorString"}); #Check TestSpecific file if error is appropriate #What does the specific test require of the rule? $curSP = test_sp_rule($cur, @spstrings); if($curSP eq undef) { next; } if($cur-> { "Severity" } == 1) { $cntt++; $maxcCnt++; } elsif($cur-> { "Severity" } < 3) { $cntt++; $maxcCnt++; } else { $maxwCnt++; } if(exists $cur-> { "Opcode" }) { if(exists ($matchs-> { $drive }-> { $curOp })) { $matchs-> { $drive }-> { $curOp }-> { "Cnt" }++; $matchs-> { $drive }-> { $curOp }-> { "Last" } = $cur-> { "LineNum" }; } else { $matchs-> { $drive }-> { $curOp }-> { "Severity" } = $cur-> { "Severity" }; $matchs-> { $drive }-> { $curOp }-> { "Cnt" } = 1; $matchs-> { $drive }-> { $curOp }-> { "First" } = $cur-> { "LineNum" }; $matchs-> { $drive }-> { $curOp }-> { "Last" } = $cur-> { "LineNum" }; $matchs-> { $drive }-> { $curOp }-> { "Message" } = $cur-> { "Message" }; if($cur-> { "Severity" } == 1) { logresult("INSPECT", $cur-> {"Message"}); $san->sanlog(-msg => "\nERROR requiring inspection found: " . $cur-> {"Message"} . ""); } } } else { if(exists ($matchs-> { $drive }-> { "Unknown" }-> { $errstr })) { $matchs-> { $drive }-> { "Unknown" }-> { $errstr }-> { "Last" } = $cur-> { "LineNum" }; $matchs-> { $drive }-> { "Unknown" }-> { $errstr }-> { "Cnt" }++; $matchs-> { $drive }-> { "Unknown" }-> { $errstr }-> { "Severity" } = $cur-> { "Severity" }; } else { $matchs-> { $drive }-> { "Unknown" }-> { $errstr }-> { "Message"} = $mesg; $matchs-> { $drive }-> { "Unknown" }-> { $errstr }-> { "Severity" } = $cur-> { "Severity" }; $matchs-> { $drive }-> { "Unknown" }-> { $errstr }-> { "First" } = $cur-> { "LineNum" }; $matchs-> { $drive }-> { "Unknown" }-> { $errstr }-> { "Last" } = $cur-> { "LineNum" }; $matchs-> { $drive }-> { "Unknown" }-> { $errstr }-> { "Cnt" } = 1; $matchs-> { $drive }-> { "Unknown" }-> { $errstr }-> { "" } = 1; if($cur-> { "Severity" } == 1) { logresult("INSPECT", $cur-> {"Message"}); $san->sanlog(-msg => "\nERROR requiring inspection found: " . $cur-> {"Message"} . ""); } } } } } #log_error("COMMENT", "Check Condition rule file Version 1.0"); if($cntt eq 0) { log_pass("Checked " . return_curline_num() . " lines no Check Conditions were found"); } else { log_fail("Checked " . return_curline_num() . " lines " . $cntt . " Check Conditions were found."); } foreach my $DriveErr (keys %$matchs) { $cntt = 0; $cCnt= 0; $wCnt= 0; $icCnt = 0; foreach my $opCode (keys %{$matchs-> { $DriveErr }}) { if($cntt == 0) { $report = "Drive: $DriveErr"; $reportWarn = "Drive: $DriveErr"; } $cntt++; if( $opCode ne "Unknown") { if($matchs-> { $DriveErr }-> { $opCode }-> { "Severity" } < 3) { push (@short_smry, ($matchs-> { $DriveErr }-> { $opCode }-> { "Message" }) . " found " . ($matchs-> { $DriveErr }-> { $opCode }-> { "Cnt" }) . " times"); $report = $report . "\n\tOpcode: " . trim($opCode) . " reported " . $matchs-> { $DriveErr }-> { $opCode }-> { "Cnt" } . " times" . " between lines " . $matchs-> { $DriveErr }->{ $opCode }-> { "First"} . " & " . $matchs-> { $DriveErr }->{ $opCode }-> { "Last" }; $report = $report . "\n\t Msg: " . $matchs-> { $DriveErr }-> { $opCode }-> { "Message" }; $cCnt++; } else #if($matchs-> { $DriveErr }-> { $opCode }-> { "Severity" } eq 2) { $reportWarn = $reportWarn . "\n\tOpcode: " . trim($opCode) . " reported " . $matchs-> { $DriveErr }-> { $opCode }-> { "Cnt" } . " times" . " between lines " . $matchs-> { $DriveErr }->{ $opCode }-> { "First"} . " & " . $matchs-> { $DriveErr }->{ $opCode }-> { "Last" }; $reportWarn = $reportWarn . "\n\t Msg: " . $matchs-> { $DriveErr }-> { $opCode }-> { "Message" }; $wCnt++; } } else { foreach my $msg (keys %{$matchs-> { $DriveErr } -> {$opCode}}) { if($matchs-> { $DriveErr }-> { $opCode }-> {$msg}-> { "Severity" } eq 1) { push (@short_smry, $msg . " found " . $matchs-> {$DriveErr}-> {$opCode}-> {$msg} ->{ "Cnt" } . " times"); $inspection_report = $inspection_report . "\n\tError: " . trim($msg) . " reported " . $matchs-> { $DriveErr }-> { $opCode }-> {$msg} ->{ "Cnt" } . " times" . " between lines " . $matchs-> { $DriveErr }->{ $opCode }-> {$msg} -> { "First"} . " & " . $matchs-> { $DriveErr }->{ $opCode }-> {$msg}-> { "Last" }; $inspection_report = $inspection_report . "\n\t Msg: " . $matchs-> { $DriveErr }-> { $opCode }-> {$msg}->{ "Message" }; $icCnt++; } elsif($matchs-> { $DriveErr }-> { $opCode } -> {$msg}-> { "Severity" } < 3) { push (@short_smry, $msg . " found " . $matchs-> {$DriveErr}-> {$opCode}-> {$msg} ->{ "Cnt" } . " times"); #push (@short_smry, $msg); #push (@short_smry, $matchs-> { $DriveErr }-> { $opCode }-> {$msg} ->{ "Cnt" }); $report = $report . "\n\tError: " . trim($msg) . " reported " . $matchs-> { $DriveErr }-> { $opCode }-> {$msg} ->{ "Cnt" } . " times" . " between lines " . $matchs-> { $DriveErr }->{ $opCode }-> {$msg} -> { "First"} . " & " . $matchs-> { $DriveErr }->{ $opCode }-> {$msg}-> { "Last" }; $report = $report . "\n\t Msg: " . $matchs-> { $DriveErr }-> { $opCode }-> {$msg}->{ "Message" }; $cCnt++; } else #if($matchs-> { $DriveErr }-> { $opCode }-> {$msg}-> { "Severity" } eq 2) { $reportWarn = $reportWarn . "\n\tError: " . trim($msg) . " reported " . $matchs-> { $DriveErr }-> { $opCode }-> {$msg}-> { "Cnt" } . " times" . " between lines " . $matchs-> { $DriveErr }->{ $opCode }-> {$msg}->{ "First"} . " & " . $matchs-> { $DriveErr }->{ $opCode }-> {$msg}->{ "Last" }; $reportWarn = $reportWarn . "\n\t Msg: " . $matchs-> { $DriveErr }-> { $opCode }-> {$msg}->{ "Message" }; $wCnt++; } } } } log_error("DEBUG", $inspection_report . "\n") if($icCnt > 0); log_error("CRITICAL", $report) if($cCnt > 0); log_error("WARNING", $reportWarn) if($wCnt > 0); } close $consolehandleA; close $consolehandleB; open(my $mainResult, ">>$LOGDIR/../../../HDD_SUMMARY_RESULTS") or die "Cant Record results"; if($is_sub_test eq "true") { print($mainResult "\nSubtest:" . $current_test . "\n"); } else { print($mainResult "\nTest:" . $current_test . "\n"); } print($mainResult " Total time taken: " . $init_time . "\n"); if( $is_sub_test eq "false") { $san->sanlog(-msg => "\n----------------------------------- Parser Results: -----------------------------------"); } if($scCnt > 0 or $icCnt > 0) { # if(not $is_sub_test) #{ $san->sanlog(-msg => retrieve_var("FILER") . " - SCRIPT -" . " $PARSE_ID - FAILED after running for " . $init_time); #} print($mainResult " Script Results: FAILED on " . scalar(localtime()) . "\n"); } else { #if(not $is_sub_test) #{ $san->sanlog(-msg => retrieve_var("FILER") . " - SCRIPT -" . " $PARSE_ID - PASSED after running for " . $init_time); #} print($mainResult " Script Results: PASSED on " . scalar(localtime()) . "\n"); } $tmpdir = abs_path("$LOGDIR/../../../"); print($mainResult " Log file: $tmpdir/$PARSE_ID" ."_" . retrieve_var("FILER") . ".log\n"); if((retrieve_var("TEST_CONFIG")) eq "C" && ($PARSE_ID ne "check_setup") && $is_sub_test eq "false") { print($mainResult " Log file: $tmpdir/$PARSE_ID" . "_" . retrieve_var("FILERB") . ".log\n"); } else { print($mainResult "\n"); } if($maxcCnt > 0) { $line = "\n First Three Failures:\n"; #Variable no longer used above so I will recycle foreach my $err (@short_smry) { if($smry_cnt < 3) { $line .= " $err\n"; $smry_cnt++; } } if($maxwCnt > 0) { if($is_sub_test eq "false") { $san->sanlog(-msg => retrieve_var("FILER") . " - PARSER -" . " $PARSE_ID - FAILED with " . $maxcCnt . " Failures & " . $maxwCnt . " Warnings" . $line); } print($mainResult " Parser Results: FAILED with $maxcCnt " . "Failures & $maxwCnt Warnings" . $line); } else { # if(not $is_sub_test) #{ $san->sanlog(-msg => retrieve_var("FILER") . " - PARSER -" . " $PARSE_ID - FAILED with " . $maxcCnt . " Failures" . $line); #} print($mainResult " Parser Results: FAILED with $maxcCnt " . "Failures" . $line); } } else { if($maxwCnt > 0) { #if(not $is_sub_test) #{ $san->sanlog(-msg => retrieve_var("FILER") . " - PARSER -" . " $PARSE_ID - PASSED with " . $maxwCnt . " Warnings\n"); #} print($mainResult " Parser Results: PASSED with $maxcCnt " . "Failures & $maxwCnt Warnings"); } else { #if(not $is_sub_test) #{ $san->sanlog(-msg => retrieve_var("FILER") . " - PARSER -" . " $PARSE_ID - PASSED"); #} print($mainResult " Parser Results: PASSED"); } } if($is_sub_test eq "false") { print($mainResult "\n Parsed File: $tmpdir/$PARSE_ID" . ".parsed\n"); } else { print($mainResult "\n"); } close $mainResult; # if($is_sub_test eq "false") #{ create_log_files($logbegin, $is_sub_test); # } } sub parse_rule_files($) { my @strings, $ruleline; my $rulename = shift; my (@splitrule, $crHandle) = (undef, undef); open($crHandle, "<" . $ENV{HOME} . "/NDATE/SUPPORT_SCRIPTS/rules/" . $rulename) or return undef; foreach $ruleline (<$crHandle>) { if($ruleline =~ m/^\#/) { next; } @splitrule = split(";", $ruleline); push (@strings, $splitrule[0] . ";" . $splitrule[2] . ";" . $splitrule[1] . ";" . $splitrule[3]); } close $crHandle; @strings; } sub test_sp_rule($@) { my ($rule, @strings) = (shift, shift); my (@parsedmtch, $mtch, $tmp); foreach $tmp (@strings) { @parsedmtch = split(";", $tmp); $mtch = $parsedmtch[0]; if($rule-> { "ErrorString" } =~ m/$mtch/i) { if($parsedmtch[3] eq "n") { return undef; } } } return $rule; } sub test_check_cond($@) { my $crHandle = undef; my ($line, %result, @splitrule) = (shift, " ", undef); $result{ "Drive" } = "Unknown"; my @parsedmtch = undef; my $severity = ""; foreach my $tmp (@_) { @parsedmtch = split(";", $tmp); $mtch = $parsedmtch[0]; if($line =~ m/$mtch/i) { $result { "Severity" } = $parsedmtch[1]; $severity = $parsedmtch[1]; if($line =~ m/fci.initialization.failed/) { $severity = 4; #I dont know why I need this but I do } $result { "ErrorString" } = $mtch; if($line =~ m/Check Condition: (\S+) (\d)x(\S+)/ ) { $result { "Opcode" } = $2 . "x" . $3; $result { "Message" } = trim($'); $result { "LineNum" } = return_curline_num(); if($line =~ m/Disk device (\S+):/i) { $result { "Drive" } = $1; } if( $line =~ m/(aborted command|illegal request)/) { $result { "Severity" } = "4"; } } elsif($line =~ m/Test fatal failure/ || $line =~ m/Test failure/) { $result { "ErrorString" } = $mtch; } elsif($line =~ m/Recovered Error Reported/) { my $pos = cur_logpos(); my $newline = next_logline(); my $opsense = next_logline(); if($newline =~ m/\[(\S+)\]: Sense Data: (.+)$/) { $result { "Drive" } = $1; $result { "LineNum" } = $pos-> { "line" }; $result { "Opcode" } = $2; if($opsense =~ m/\[(\S+)\]: OpSense: (.+)$/) { $result { "Message" } = trim($2); } else { $result { "Message" } = $mtch; } } set_logpos($pos); } elsif($line =~ m/check condition!/) { my $pos = cur_logpos(); my $newline = next_logline(); my $opsense = next_logline(); if($newline =~ m/\[(\S+)\]: Sense key: (.+)$/) { $result { "Drive" } = $1; $result { "LineNum" } = $pos-> { "line" }; if($2 =~ m/SCSI:/) { $result { "Message" } = "SCSI:" . $'; if($opsense =~ m/\[(\S+)\]: OpSense: (.+)$/) { $result { "Opcode" } = trim($2); } } else { $result { "Opcode" } = $2; } } set_logpos($pos); } elsif($line =~ m/\[(\S+)\]: (.+)Failed due to SCSI error:/) { my $pos = cur_logpos(); my $newline; $result { "Drive" } = $1; $result { "Message" } = $2 . "Failed due to SCSI error:"; $result { "LineNum" } = return_curline_num(); skip_lines("2"); $newline = next_logline(); if($newline = m/Opcode (.+)$/) { $result { "Opcode" } = $1; } set_logpos($pos); } elsif($line =~ m/raid\.rg\.scrub\.summary\.(cksum|media|pi)/) { if($line =~ m/found (\d+)/) { if($1 == 0) { return undef; } } $result { "Message" } = trim($line); $result { "LineNum" } = return_curline_num(); } elsif($line =~ m/disk\.readReservationFailed:error/) { if($line =~ m/Disk read reservation failed on (\S*)(:| )/) { $result { "Drive" } = $1; } $result { "Message" } = trim($line); $result { "LineNum" } = return_curline_num(); } else { if($line =~ m/Disk( device | )(\S*)(:| )/) { $result { "Drive" } = $2; } if($severity eq 1) { $result { "Message" } = $parsedmtch[2]; } else { $result { "Message" } = trim($line); } $result { "LineNum" } = return_curline_num(); } return \%result; } } return undef; } sub send_to_console($$$$) { my ($line, $ahandle, $bhandle) = (shift @_, shift @_, shift @_); my $filer; my ($PARSE_ID, $FILER, $FILERA, $FILERB) = (retrieve_var("CurTest"), retrieve_var("FILER"), retrieve_var("FILERA"), retrieve_var("FILERB")); my $is_sub_test = shift; if(($line =~ /(.*)$PARSE_ID\] <<(.*)console\|(.*)/ ) || ($line =~ /(.*)\[HDD(.*)\#rsh\|(.*)/ ) || (($line =~ /(.*)\[HDD(.*)\#rsh CMD(.*)/ ))) { $line_console = $3; if ($line_console =~ /(.*)\\r\\r\\n(.*)/) { $line_console = $1 . $2; } if ($line_console =~ /(.*)\\r\\n(.*)/) { $line_console = $1 . $2; } if ($line_console =~ /(.*)\\t\\t(.*)/) { $line_console = $1 . $2; } if ($line_console =~ /(.*)\\t(.*)/) { $line_console = $1 . $2; } if ($line_console =~ /(.*)\\r(.*)/) { $line_console = $1 . $2; } if ($line_console =~ /(.*)\\n(.*)/) { $line_console = $1 . $2; } if($is_sub_test eq "false") { if(retrieve_var("TEST_CONFIG") eq "C" && retrieve_var("CurTest") ne "check_setup") { if ($line =~ /^(.*)\[HDD(.*)$PARSE_ID\](.*)$FILERA(.*)/) { print($ahandle "$line_console\n") if($line ne $ident_line); $ident_line = $line_console; } elsif($line =~ /$FILERB/) { print($bhandle "$line_console\n") if($line ne $ident_line); $ident_line = $line_console; } else { print($ahandle "$line_console\n") if($line ne $ident_line); $ident_line = $line_console; } } else { print($ahandle "$line_console\n") if($line ne $ident_line); $ident_line = $line_console; } } $line = $line_console; } $line; } sub create_log_files($$) { my ($line, $line_new, $logA, $logB, $write_log); my $PARSE_ID = filterOutDir(cur_logpos()->{"file"}); my $TEST_CONFIG = retrieve_var("TEST_CONFIG"); my $LOGDIR = retrieve_var("LOGDIR"); my $identical_line = ""; my $FILER = retrieve_var("FILER"); my $FILERB = retrieve_var("FILERB"); my $filename = cur_logpos()->{"file"}; set_logpos(shift); my $is_sub_test = shift; if($is_sub_test eq "false") { $write_log = "$LOGDIR/../../../$PARSE_ID" . "_$FILER" . ".log"; } else { $write_log = "$LOGDIR/../../../$PARSE_ID" . ".log"; } open ($logA, ">$write_log") or die "write:Failed opening $write_log \n"; if(("$TEST_CONFIG" eq "C") && ($PARSE_ID ne "check_setup") && $is_sub_test eq "false") { $write_log = "$LOGDIR/../../../$PARSE_ID" . "_$FILERB" . ".log"; open ($logB, ">$write_log") or die "write:Failed opening $write_log \n"; } my $eye_c; while(($line = next_logline()) ne "") { if ($line =~ /(.*)\[HDD(.*)$PARSE_ID\](.*)/) { $line_new = $1 . $3 ; } else { $line_new = $line; } if(("$TEST_CONFIG" eq "C") && ($PARSE_ID ne "check_setup") && $is_sub_test eq "false") { if (($line =~ /^(.*)\[HDD(.*)$PARSE_ID\](.*)$FILER(.*)/) && ( $line !~ /=====================|=== Step/ )) { print($logA "$line_new\n") if ($line ne $identical_line); $identical_line = $line; } elsif ( $line =~ /====================/ ) { $eye_c = $line; } elsif(($line =~ /$FILERB/) && ($line !~ /$FILER\,$FILEB/)){ if ( $line =~ /=== Step/ ) { if ( $eye_c =~ /=================/ ){ print($logB "$eye_c\n"); } print($logB "$line_new\n") if ($line ne $identical_line); $identical_line = $line; if ( $eye_c =~ /=================/ ){ print($logB "$eye_c\n"); } } else { print($logB "$line_new\n") if ($line ne $identical_line); $identical_line = $line; } } elsif($line =~ /$FILER/) { if ( $line =~ /=== Step/ ){ if ( $eye_c =~ /=================/ ){ print($logA "$eye_c\n"); } print($logA "$line_new\n") if ($line ne $identical_line); $identical_line = $line; if ( $eye_c =~ /=================/ ){ print($logA "$eye_c\n"); } } else { print($logA "$line_new\n") if ($line ne $identical_line); $identical_line = $line; } } } else { print($logA "$line_new\n") if ($line ne $identical_line); $identical_line = $line; } } close ($logA); close ($logB); return undef; } sub calcTimeDiff($) { my $init = shift; my ($sec, $min, $hour, $day, $mon, $year) = localtime(); my $rtn = ""; $year +=1900; $mon += 1; if($mon < 10) { $mon = 0 . $mon; } if($hour < 10) { $hour = 0 . $hour; } if($init =~ m/(\d\d\d\d)(\d\d)(\d\d) (\d\d)(\d\d)(\d\d)/) #1=year 2=month 3=day 4=hour 5=min 6=sec { my ($in_yr, $in_mon, $in_day, $in_hr, $in_min, $in_sec) = ($1, $2, $3, $4, $5, $6); if($in_min > $min) { $min += 60; $hour -= 1; } if($in_min ne $min) { $rtn .= ($min - $in_min) . " minute(s)"; } if($in_hr > $hour) { $day -=1; $hour += 24; } if($hour ne $in_hr) { $rtn = ($hour - $in_hr) . " hour(s) " . $rtn; } if($day ne $in_day) { if($day < $in_day) { if($mon == 1) { $day += 31; } elsif($mon == 2) { $day += 31; } elsif($mon == 3) { $day += 28; } elsif($mon == 4) { $day += 31; } elsif($mon == 5) { $day += 30; } elsif($mon == 6) { $day += 31; } elsif($mon == 7) { $day += 30; } elsif($mon == 8) { $day += 31; } elsif($mon == 9) { $day += 31; } elsif($mon == 10) { $day += 30; } elsif($mon == 11) { $day += 31; } elsif($mon == 12) { $day += 30; } } $rtn = ($day - $in_day) . " day(s) " . $rtn; } else{$rtn = ($day - $in_day) . " day(s) " . $rtn;} if($rtn eq "") { if($in_sec > $sec) { $sec += 60; } $rtn .= ($sec - $in_sec) . " second(s)"; } } return $rtn; } sub filterOutDir($) { my $tmp = shift; if($tmp =~ m/.*\/(.*)\..*/) { return $1; } if($tmp =~ m/(.*)\..*/) { return $1; } return $tmp; } 1;