#!/usr/local/bin/perl # # $Header: ftp_response.pl 01-jul-2005.15:43:59 afontana Exp $ # # ftp_response.pl # # Copyright (c) 2004, 2005, Oracle. All rights reserved. # # NAME # ftp_response.pl - # # DESCRIPTION # # # NOTES # # # MODIFIED (MM/DD/YY) # afontana 07/01/05 - fix retries for read timeout # afontana 06/29/05 - catch timeouts better # afontana 04/08/05 - fix parse error # afontana 04/06/05 - don't delete file in read-only mode # afontana 01/03/05 - fix symbol ref while strict refs # afontana 12/27/04 - change tries to retries # afontana 11/12/04 - fix retries # afontana 11/08/04 - use strict # afontana 11/02/04 - afontana_service_beacon_ftp # afontana 11/02/04 - add sleep # afontana 11/01/04 - Creation # ## ## Note that this requires a special modified version of Net::DNS ## in order to get timing data accurately. ## use Net::FTP; use Net::FTP::dataconn; use Time::HiRes qw(gettimeofday tv_interval); use ParseStdin; use strict; ParseStdin::initStdin(); my $txnname = ParseStdin::getParameter("TxnName"); my $beaconname = ParseStdin::getParameter("BeaconName"); my $host = ParseStdin::getParameter("host", "127.0.0.1"); my $port = ParseStdin::getParameter("port", 21); my $filename = ParseStdin::getParameter("filename", ""); my $readwrite = ParseStdin::getParameter("readwrite", "readwrite"); my $username = ParseStdin::getParameter("username", "anonymous"); my $password = ParseStdin::getParameter("password", $txnname ."@" . $beaconname); my $timeout = ParseStdin::getParameter("timeout", 120); my $numretries = ParseStdin::getParameter("numretries", 2); my $retryInterval = ParseStdin::getParameter("retryInterval", 120); my $numbytes = ParseStdin::getParameter("numbytes", 1000); my $actualtries = 0; my $success = 0; my $connect_time = ""; my $login_time = ""; my $noop_time = ""; my $write_time = ""; my $write_rate = ""; my $read_time = ""; my $read_rate = ""; my $total_time = ""; my $error = ""; my $numbytes_read = 0; my $ftp = 0; my $t0; my $t1; while ($actualtries < ($numretries + 1) && $success == 0) { sleep($retryInterval) unless $actualtries == 0; $actualtries += 1; $success = 0; $connect_time = ""; $login_time = ""; $noop_time = ""; $write_time = ""; $read_time = ""; $total_time = ""; $error = ""; #Connect $error = "Connect Error"; $t0 = [gettimeofday]; $ftp = Net::FTP->new($host, Port => $port, Timeout => $timeout, Debug => 1); next unless ($ftp); $t1 = [gettimeofday]; $connect_time = tv_interval($t0, $t1); if ($connect_time > $timeout){ $error = "Connect Timeout"; next; } #Login $error = "Login Error"; $t0 = [gettimeofday]; eval{next unless $ftp->login($username, $password);}; $t1 = [gettimeofday]; $login_time = tv_interval($t0, $t1); if ($login_time > $timeout){ $error = "Login Timeout"; next; } next if ($@); #NOOP $error = "NOOP Error"; $t0 = [gettimeofday]; eval{next unless ($ftp->command("NOOP")->response == $ftp->CMD_OK);}; $t1 = [gettimeofday]; $noop_time = tv_interval($t0, $t1); if ($noop_time > $timeout){ $error = "NOOP Timeout"; next; } next if ($@); #Write my $buffer0_len = $numbytes % 1000; my $buffer0; my $checksum = 0; my $buffer1; if (lc($readwrite) =~ /write/) { if ($buffer0_len > 0) { $buffer0 = genString($buffer0_len); $checksum = genSum($buffer0, 0); } if ($numbytes >= 1000) { $buffer1 = genString(1000); for (my $i = $buffer0_len; $i<$numbytes; $i +=1000) { $checksum = genSum($buffer1, $checksum); } } #Delete previous, don't care if it gets an error or not eval{$ftp->delete($filename);}; $error = "Write Error"; $t0 = [gettimeofday]; my $response; eval{$response = $ftp->stor($filename);}; next unless ($response); if ($@) { $t1 = [gettimeofday]; $write_time = tv_interval($t0, $t1); $error = "Write Timeout" if ($write_time > $timeout); next; } if ($buffer0_len > 0) { eval{$response->write($buffer0, $buffer0_len, $timeout);}; if ($@) { $t1 = [gettimeofday]; $write_time = tv_interval($t0, $t1); $error = "Write Timeout" if ($write_time > $timeout); next; } } if ($numbytes >= 1000) { for (my $i = $buffer0_len; $i<$numbytes; $i +=1000) { eval{$response->write($buffer1, 1000, $timeout);}; if ($@) { $t1 = [gettimeofday]; $write_time = tv_interval($t0, $t1); $error = "Write Timeout" if ($write_time > $timeout); next; } } } eval{next unless ($response->close());}; next if ($@); $t1 = [gettimeofday]; $write_time = tv_interval($t0, $t1); if ($write_time > $timeout) { $error = "Write Timeout"; next; } } #Read $error = "Read Error"; if (lc($readwrite) =~ /read/) { my $read_checksum = 0; $t0 = [gettimeofday]; my $response; eval{$response = $ftp->retr($filename);}; next unless ($response); if ($@) { $t1 = [gettimeofday]; $read_time = tv_interval($t0, $t1); $error = "Read Timeout" if ($read_time > $timeout); next; } my $numbytes_buffer = 0; eval{do { $numbytes_buffer = $response->read($buffer0, 1000, $timeout); $read_checksum = genSum($buffer0, $read_checksum); $numbytes_read += $numbytes_buffer; } while ($numbytes_buffer);}; if ($@) { $t1 = [gettimeofday]; $read_time = tv_interval($t0, $t1); $error = "Read Timeout" if ($read_time > $timeout); next; } eval{next unless ($response->close());}; next if ($@); $t1 = [gettimeofday]; $read_time = tv_interval($t0, $t1); if (lc($readwrite) =~ /write/) { if ($numbytes_read != $numbytes) { $error = ("Wrote " . $numbytes . " bytes. Read " . $numbytes_read . "bytes."); next; } if ($read_checksum != $checksum) { $error = ("Checksum Mismatch " . $read_checksum . " vs. " . $checksum); next; } } if ($read_time > $timeout) { $error = "Read Timeout"; next; } } if (lc($readwrite) =~ /write/) { $error = "Delete Error"; eval{$ftp->delete($filename);}; next if ($@); } $total_time = $connect_time + $login_time + $noop_time + $write_time + $read_time; if ($total_time > $timeout) { $error = "Transaction Timeout"; next; } $error = ""; $success = 1; } #Cleanup if ($ftp) { eval{$ftp->quit();}; if ($success && $@){ $error = "Close Error"; $success = 0; } } # Convert seconds to millis $connect_time *= 1000; $login_time *= 1000; $noop_time *= 1000; $write_time *= 1000; $read_time *= 1000; $total_time *= 1000; if ($write_time && $numbytes) { $write_rate = ($numbytes / $write_time); } if ($read_time && $numbytes_read) { $read_rate = ($numbytes_read / $read_time); } if ($success) { print "em_result="; print ($txnname ."|"); print ($beaconname . "|"); print ($success . "|"); print ($total_time . "|"); print ($connect_time . "|"); print ($login_time . "|"); print ($noop_time . "|"); print ($write_time . "|"); printf "%.2f|", $write_rate; print ($read_time . "|"); printf "%.2f|", $read_rate; print (($actualtries - 1) ."|"); print $error; } else { print "em_result="; print ($txnname ."|"); print ($beaconname . "|"); print ("0|"); print "|"; print "|"; print "|"; print "|"; print "|"; print "|"; print "|"; print "|"; print (($actualtries - 1) ."|"); print $error; } sub genString { my $genString_size = shift; my @genString_string = qw(a b c d e f g h i j k l m n o p q r s t u v w x y z); my $genString_result = ""; while ($genString_size--) { $genString_result .= @genString_string[$genString_size % 26]; } return $genString_result; } sub genSum { my @genSum_string = unpack("C*", shift); my $genSum_sum = shift; foreach my $genSum_var (@genSum_string) { $genSum_sum += $genSum_var; } return $genSum_sum % 4096; } 1; #print $ftp;