#!/usr/bin/perl
#< Interactive shell demonstration script
# This script can be used to create console interfaces to your scripts and applications
# Current functionality has been incorporated for a RHEL4 AS box, and will grab system
# information, as well as send mail. Possibilities for this kind of script are
# limitless.
use strict;
use warnings;
use Net::SMTP;
our $DEBUG = 0;
our %keywords = ( "help", "",
"sysinfo", "",
"mail", "",
"test", "",
"quit", "" );
our $prompt = '$> ';
sub print_err {
# print_err expects two arguments
if ( scalar(@_) != 2 ) {
printf( "Incorrect usage of print_err()\n" );
} else {
my $error_type = $_[0];
my $error_data = $_[1];
SWITCH: for ( $error_type ) {
/NOT_IMPL/ && do {
printf( STDERR "Error (%s) - Command not implemented: %s\n", $error_type, $error_data );
last;
};
/ARG_ERR/ && do {
printf( STDERR "Error (%s) - Incorrect number of arguments for command: %s\n", $error_type,
$error_data );
last;
};
/NON_NUM/ && do {
printf( STDERR "Error (%s) - Numeric argument expected: %s\n", $error_type,
$error_data );
last;
};
/UNK_OPT/ && do {
printf( STDERR "Error (%s) - Unknown option: %s\n", $error_type,
$error_data );
last;
};
/NOT_EXEC/ && do {
printf( STDERR "Error (%s) - %s: Cannot execute\n", $error_type,
$error_data );
last;
};
/NOT_FOUND/ && do {
printf( STDERR "Error (%s) - %s: File not found\n", $error_type,
$error_data );
last;
};
printf( STDERR "Error: Unknown error type (%s)\nError text: %s\n", $error_type, $error_data );
}
}
}
sub display_help {
# the test command will remain undocumented here
print <<END
---------------
Command Summary
---------------
help - Display this help message
mail - Interactive mailer (single recipient only)
sysinfo - System Information (sysinfo -h for usage information)
quit - Exit the shell
END
}
sub sysinfo_help {
print <<END_OF_SYSINFO_HELP
-----------------------
sysinfo Command Summary
-----------------------
If the output scrolls off your terminal, try
<sysinfo command here> | pager
sysinfo cpu - Display CPU information
sysinfo disk - Display disk utilisation information
sysinfo mem - Display memory infromation
sysinfo interfaces - Show network interface confuration
sysinfo hostname - Display system hostname
sysinfo routing - Display kernel routing table
sysinfo uptime - Display system load and uptime
sysinfo [help|-h|--help] - Display this help message
END_OF_SYSINFO_HELP
}
sub display_sysinfo {
my ( @cmd_array ) = @_;
if ( !defined( $cmd_array[1] ) ||
( defined( $cmd_array[1] ) && ( $cmd_array[1] eq "help" || $cmd_array[1] eq "-h" || $cmd_array[1] eq "--help" ) ) ) {
&sysinfo_help();
} else {
if ( !defined ( $cmd_array[1] ) ) {
# sysinfo with no arguments
} elsif ( $cmd_array[1] eq "hostname" ) {
my $hostname_cmd = "/bin/hostname";
if ( ! -e "$hostname_cmd" ) {
print_err( "NOT_FOUND", "$hostname_cmd" );
} elsif ( ! -x "$hostname_cmd" ) {
print_err( "NOT_EXEC", "$hostname_cmd" );
} else {
system( "$hostname_cmd" );
}
} elsif ( $cmd_array[1] eq "cpu" ) {
my $cpu_cmd = "/usr/sbin/x86info";
if ( ! -e "$cpu_cmd" ) {
print_err( "NOT_FOUND", "$cpu_cmd" );
} elsif ( ! -x "$cpu_cmd" ) {
print_err( "NOT_EXEC", "$cpu_cmd" );
} else {
if ( defined($cmd_array[2]) && defined($cmd_array [3]) &&
$cmd_array[2] eq "|" && $cmd_array[3] eq "pager" ) {
my $pager = "/bin/more";
if ( ! -e "$pager" ) {
print_err( "NOT_FOUND", "$pager" );
} elsif ( ! -x "$pager" ) {
print_err( "NOT_EXEC", "$pager" );
} else {
system( "$cpu_cmd | $pager" );
}
} else {
system( "$cpu_cmd" );
}
}
} elsif ( $cmd_array[1] eq "mem" ) {
my $mem_cmd = "/usr/bin/free";
if ( ! -e "$mem_cmd" ) {
print_err( "NOT_FOUND", "$mem_cmd" );
} elsif ( ! -x "$mem_cmd" ) {
print_err( "NOT_EXEC", "$mem_cmd" );
} else {
$mem_cmd .= " -m";
if ( defined($cmd_array[2]) && defined($cmd_array [3]) &&
$cmd_array[2] eq "|" && $cmd_array[3] eq "pager" ) {
my $pager = "/bin/more";
if ( ! -e "$pager" ) {
print_err( "NOT_FOUND", "$pager" );
} elsif ( ! -x "$pager" ) {
print_err( "NOT_EXEC", "$pager" );
} else {
system( "$mem_cmd | $pager" );
}
} else {
system( "$mem_cmd" );
}
}
} elsif ( $cmd_array[1] eq "disk" ) {
my $disk_cmd = "/bin/df";
if ( ! -e "$disk_cmd" ) {
print_err( "NOT_FOUND", "$disk_cmd" );
} elsif ( ! -x "$disk_cmd" ) {
print_err( "NOT_EXEC", "$disk_cmd" );
} else {
$disk_cmd .= " -h";
if ( defined($cmd_array[2]) && defined($cmd_array [3]) &&
$cmd_array[2] eq "|" && $cmd_array[3] eq "pager" ) {
my $pager = "/bin/more";
if ( ! -e "$pager" ) {
print_err( "NOT_FOUND", "$pager" );
} elsif ( ! -x "$pager" ) {
print_err( "NOT_EXEC", "$pager" );
} else {
system( "$disk_cmd | $pager" );
}
} else {
system( "$disk_cmd" );
}
}
} elsif ( $cmd_array[1] eq "uptime" ) {
my $up_cmd = "/usr/bin/uptime";
if ( ! -e "$up_cmd" ) {
print_err( "NOT_FOUND", "$up_cmd" );
} elsif ( ! -x "$up_cmd" ) {
print_err( "NOT_EXEC", "$up_cmd" );
} else {
if ( defined($cmd_array[2]) && defined($cmd_array [3]) &&
$cmd_array[2] eq "|" && $cmd_array[3] eq "pager" ) {
my $pager = "/bin/more";
if ( ! -e "$pager" ) {
print_err( "NOT_FOUND", "$pager" );
} elsif ( ! -x "$pager" ) {
print_err( "NOT_EXEC", "$pager" );
} else {
system( "$up_cmd | $pager" );
}
} else {
system( "$up_cmd" );
}
}
} elsif ( $cmd_array[1] eq "interfaces" ) {
my $net_cmd = "/sbin/ifconfig";
if ( ! -e "$net_cmd" ) {
print_err( "NOT_FOUND", "$net_cmd" );
} elsif ( ! -x "$net_cmd" ) {
print_err( "NOT_EXEC", "$net_cmd" );
} else {
$net_cmd .= " -a";
if ( defined($cmd_array[2]) && defined($cmd_array [3]) &&
$cmd_array[2] eq "|" && $cmd_array[3] eq "pager" ) {
my $pager = "/bin/more";
if ( ! -e "$pager" ) {
print_err( "NOT_FOUND", "$pager" );
} elsif ( ! -x "$pager" ) {
print_err( "NOT_EXEC", "$pager" );
} else {
system( "$net_cmd | $pager" );
}
} else {
system( "$net_cmd" );
}
}
} elsif ( $cmd_array[1] eq "routing" ) {
my $route_cmd = "/bin/netstat";
if ( ! -e "$route_cmd" ) {
print_err( "NOT_FOUND", "$route_cmd" );
} elsif ( ! -x "$route_cmd" ) {
print_err( "NOT_EXEC", "$route_cmd" );
} else {
$route_cmd .= " -rn";
if ( defined($cmd_array[2]) && defined($cmd_array [3]) &&
$cmd_array[2] eq "|" && $cmd_array[3] eq "pager" ) {
my $pager = "/bin/more";
if ( ! -e "$pager" ) {
print_err( "NOT_FOUND", "$pager" );
} elsif ( ! -x "$pager" ) {
print_err( "NOT_EXEC", "$pager" );
} else {
system( "$route_cmd | $pager" );
}
} else {
system( "$route_cmd" );
}
}
} else {
&sysinfo_help();
}
}
}
# test_command() - this is a simple demonstration of how a command could be handled....
# "two" arguments may be passed - -t and a numeric argument, e.g.
# test -t 30
sub test_command {
# Single argument, an erray, will be passed
my ( @cmd_array ) = @_;
if ( $DEBUG ) {
printf( "--(DEBUG)--> \@cmd_array contains %d elements\n", scalar(@cmd_array) );
}
if ( scalar(@cmd_array) != 3 ) {
print_err( "ARG_ERR", "test" );
} else {
if ( $cmd_array[1] eq "-t" ) {
my $testarg = $cmd_array[2];
if ( $testarg !~ /^[0-9]+/ ) {
print_err( "NON_NUM", "test -t $testarg" );
} else {
printf( "test command called with -t and a timeout of %d\n", $testarg );
}
} else {
print_err( "UNK_OPT", "Unknown option $cmd_array[1]" );
}
}
}
sub send_mail {
if ( scalar(@_) != 1 ) {
print_err( "ARG_ERR", "mail" );
} else {
printf( "-- Enter SMTP Gateway: " );
chomp( my $smtp_gateway = <STDIN> );
if ( "$smtp_gateway" =~ /^[\s]*$/ ) {
printf( STDERR "--> No SMTP Gateway specified. Aborting...\n" ) && return;
}
printf( "-- Enter HELO String: " );
chomp( my $hello = <STDIN> );
if ( "$hello" =~ /^[\s]*$/ ) {
printf( STDERR "--> No HELO String specified. Aborting...\n" ) && return;
}
printf( "-- Enter Sender Address: " );
chomp( my $mail_from = <STDIN> );
if ( "$mail_from" =~ /^[\s]*$/ ) {
printf( STDERR "--> No Sender Address specified. Aborting...\n" ) && return;
}
printf( "-- Enter Recipient Address: " );
chomp( my $mail_to = <STDIN> );
if ( "$mail_to" =~ /^[\s]*$/ ) {
printf( STDERR "--> No Recipient Address specified. Aborting...\n" ) && return;
}
my $smtp = Net::SMTP->new( "$smtp_gateway",
Hello => "$hello",
Timeout => 30,
Debug => "$DEBUG",
) or die "Error: Cannot create mail object: $!";
$smtp->mail("$mail_from");
$smtp->to("$mail_to");
$smtp->data();
printf( "-- Enter Subject: " );
chomp( my $subject = <STDIN> );
# We allow empty subject lines
$smtp->datasend("Subject: $subject\n");
# No need CC nor BCC
printf( "-- Enter your message. After last line of input, enter a period \".\"\n" );
printf( "-- by itself on the final line, and hit enter\n" );
my $input_string = "";
while ( 1 ) {
chomp( $input_string = <STDIN> );
if ( $input_string =~ /^\.$/ ) {
$smtp->dataend();
$smtp->quit;
printf( "-- Your message has been sent to the SMTP server.\n" );
return;
}
$smtp->datasend("$input_string\n");
}
}
}
sub main_routine {
printf( "%s", $prompt );
while ( <> ) {
chomp( my $input = $_ );
# translate tab to space
$input =~ s/\t/ /g;
# squash duplicate spaces
$input =~ tr/ //s;
# remove leading spaces
$input =~ s/^[ ]*//;
# and traling spaces
$input =~ s/[ ]*$//;
if ( $DEBUG ) {
printf( STDERR "--(DEBUG)--> %s\n", $input );
}
my @input_array = split( /[ ]/, $input );
my $input_command = $input_array[0];
printf( "%s", $prompt) and next if ( !defined($input_command) );
if ( !defined($keywords{$input_command}) ) {
my $error_data="$input_command";
print_err( "NOT_IMPL", $error_data );
}
SWITCH: for ( $input_command ) {
/test/ && do {
&test_command( @input_array );
last;
};
/sysinfo/ && do {
&display_sysinfo( @input_array );
last;
};
/mail/ && do {
&send_mail( @input_array );
last;
};
/help/ && do {
&display_help();
last;
};
/quit/ && do {
return;
last;
};
}
printf( "%s", $prompt );
}
}
&main_routine();
exit 0