#!/usr/bin/perl
use strict;
use warnings;
=head1 NAME

sqlplus_wrapper.pl is wrapper around sqlplus. 

=head1 DESCRIPTION

The script's purpose is to check connectivity to an Oracle DB. 

The one feature of this script is to terminate the sqlplus process in the event a timeout is reached.

=head1 SYNOPSIS

./sqlplus_wrapper.pl <user> <passwd> <hostname> <sid> [timeout]

=head1 COREQUISITES

Pretty much any Perl version.

=head1 COPYRIGHT

This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.

=head1 SCRIPT CATEGORIES

UNIX/System_administration

=head1 AUTHOR

Jess Portnoy <kernel01@gmail.com>

=cut

if (scalar @ARGV < 4){
	print "\n\nUsage: $0 <user> <passwd> <hostname> <sid> [timeout]\n\n";
	exit 1;
}
my ($user,$passwd,$hostname,$sid,$l_timeout)=@ARGV;
if (!defined ($l_timeout)){
	$l_timeout = 10; 
}
my $line;
my $tns='(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = '.$hostname.')(PORT = 1521))) (CONNECT_DATA = (SID = '. $sid.')))';
my $l_cmd = 'echo "select sysdate from dual;"|sqlplus64 -L '. $user.'/'.$passwd.'@"'.$tns.'"';
my $pid = 0;
my @output;
eval
{
	local $SIG{ALRM} = sub 
	{
		printf "\n%%'sqlplus' Action took more than '$l_timeout' seconds !\n";
		printf "($l_cmd); pid=$pid\n\n";
		kill( 15, $pid )  if $pid > 1;
		exit 2;
	};
	alarm( $l_timeout );
	$pid = open( PH, "$l_cmd |" ) || printf( "Could not execute '$l_cmd': $!\n" );
	while ( my $line = <PH> ){
		push @output, $line;
	}
	alarm(0);
};
if (grep(/SYSDATE/, @output)){
	print "Connected :)\n";
	exit 0;
}else{
	print "@output\n";
	exit 1;
}
#print "pid = $pid\n\n";
eval { alarm(0) };  # The alarm reset must be outside the eval{}.
