#!/usr/bin/perl -w
# INCLUDES
use strict;
use Net::Telnet;
use Mail::Sendmail;
use Getopt::Std;

# CONSTANTS
my $timeout = 5;
my $monikeraddr = 'support@wwind.com';
my $smtpserver = 'core.iconnet.net';

my $services = {
    ftp    => { port => 21,   print => "", waitfor => '/220/' },
    ssh    => { port => 22,   print => "", waitfor => '/SSH/' },
    telnet => { port => 23,   print => "", waitfor => '/(login|username)/' },
    www    => { port => 80,   print => "HEAD / HTTP/1.0\n\n", waitfor => '/200/' },
    pop    => { port => 110,  print => "", waitfor => '/\+OK/' },
    nntp   => { port => 119,  print => "", waitfor => '/200/' },
    imap   => { port => 143,  print => "", waitfor => '/OK/' },
    smtp   => { port => 25,   print => "", waitfor => '/SMTP/' }
};

# MAIN
my %opts = ();
getopt('hse', \%opts);
die "Usage: moniker -h host -s service [-e email]"
    unless exists($opts{h}) && exists($opts{s});
die "Service $opts{s} does not compute.\n" 
    unless defined $services->{$opts{s}};

my $service = $opts{s};
my $host    = $opts{h};
my $email   = $opts{e} if exists $opts{e};
my $port    = $services->{$service}->{port};
my $sock    = new Net::Telnet (Telnetmode => 0);
my $waitfor = $services->{$service}->{waitfor};

# Create a connection to the remote host
eval {
    $sock->open(Host    => $host,
		Port    => $port,
		Timeout => $timeout
		);
};

# Catch any errors
&alert("Cannot establish a connection to specified host") if $@;

# send data to remote host
$sock->print($services->{$service}->{print}) if $services->{$service}->{print};

# wait for regex match
&alert("Timed out waiting for $waitfor") unless $sock->waitfor($waitfor);
    
print "Service is operational.\n" unless exists($opts{e});

# SUBROUTINES
sub alert {
    my $error = shift;
    my $message = <<MESSAGE;
Moniker Alert
-------------
Host: $host
Port: $port
-------------
$error
MESSAGE
    
    print "$message";
    if (exists($opts{e})) {
	sendmail(To      => $email,
		 Subject => 'Moniker Alert',
		 From    => $monikeraddr,
		 Message => $message,
		 Server  => $smtpserver,
		 delay   => 1,
		 retries => 5) 
	    || die "Cannot send mail: $Mail::Sendmail::error\n";
    } 
    exit;
}
