#!/usr/bin/perl
#
# jabber_alert.pl
#
# Cobbled by Will Kamishlian (will@jabberdoc.org) from 
# a script written by David Cox.
#
# See http://www.jabberdoc.org/sysadmin.html#jabber_alert
#
# Feel free to use and share.
#
# This script works standalone or as an alert script for 
# Mon (http://www.kernel.org/software/mon/)
# As a standalone, or with other scripts, this script 
# can be used to send a pre-formatted alert message
# via Jabber.
#
# Feel free to use and share.
#
# Last Modified 2 August 2004
#

use strict;
use vars qw ($opt_g $opt_s $opt_t $opt_e $opt_o $opt_w $opt_a $opt_q 
	     $opt_b $opt_u $opt_n $opt_r $opt_m $opt_h $opt_k $recipient_jid
       $sender_jid $sender_pw $sender_port $sender_resource $message_subject 
	     $max_wait $summary $OPSTATUS $ALERT $sender_uid $sender_host 
	     $alert_message $connection @result $message $alert_type 
	     $alert_status $alert_user $utc_offset $time_local $time_gm 
	     $time_secs $date $wday $day $mon $sec $min $hour $mday $mon 
	     $year $wday $yday $isdst $hour_min $alert_user $alert_hostname
	     @passed_args $passed_args_count $header_txt $use_ssl
	    );
	    
use Net::Jabber qw(Client) ;
use Net::Jabber qw(Message) ;
use Net::Jabber qw(Protocol) ;
use Net::Jabber qw(Presence) ;
use Getopt::Std ;
use Time::Local;           	# For UTC differential 

#
# Get args
#
getopts ("s:g:h:t:l:e:n:w:o:a:c:q:b:u:m:r:h:k:");

#
# Check for required args and print usage
#
if ( ! ($opt_e) or ! ($opt_n) or ! ($opt_w) ){
    print <<EOF;
Missing Argument
    
Usage: jabber_alert.pl -e [recipient] -n [sender] -w [password] 
                       [message summary = STDIN]

Optional Jabber Args: -o [port] -k [use SSL] -u [resource] -b [subject]                       
			       
Optional Header Args: -t [time] -a [alert type] -g [alert group]
                      -s [alert service] -q [alert status] 
                      -r [alert user] -m [user host] 
		      
Note that arguments containing spaces must be enclosed in quotation marks.
The -k option takes either 0 or 1 as an argument, and it defaults to 
0 (non-ssl). Time defaults to local time.  If used as an argument, time 
should be formatted as seconds since epoch.  Recipient and sender can be 
the same Jabber user.  Alert user and host default to the calling user and
hostname from ENV.  The message comes from STDIN, and multiple lines are 
acceptable. When using from the command line, use RETURN and CTRL-d to send
the message. 

EOF
    exit 1;
}


# Chomp STDIN
while (<STDIN>) {     
    chomp;            
    $summary="$summary\n$_";
}

print $_;

#
# Set variables
#
# Jabber variables
$opt_o ||= 5222;
$recipient_jid = $opt_e;
$sender_jid = $opt_n;
$sender_pw = $opt_w;
$sender_port = $opt_o;

if ( $opt_u ) {
    $sender_resource = $opt_u;
}
else {
    $sender_resource = "DaemonMonitor";
}
 
if ( $opt_k ) {
  $use_ssl = $opt_k;
}
else {
  $use_ssl = 0;
}
 
 
# max_wait specifies how long the script will keep 
# the jabber connection open. 
#    
$max_wait = 2;

if ( $opt_b ) {
    $message_subject = $opt_b;
}
else {
    $message_subject = "Monitor Alert";
}
    
# Message Header Variables
#
if ( $opt_t ) {
    $time_secs = $opt_t;
}
else {
    $time_secs = time();
}
if ( $opt_h ) {
    $header_txt = $opt_h;
}
else {
    $header_txt = "Summary";
}




# Get ENV variables if exist
#

if ( $opt_r ) {
    $alert_user = $opt_r;
}
elsif ( $ENV{"USER"} ) {
    $alert_user = $ENV{"USER"};
} 

if ( $opt_m ) {
    $alert_hostname = $opt_m;   
}
elsif ( $ENV{"HOSTNAME"} ) {
    $alert_hostname = $ENV{"HOSTNAME"};
} 

if ( $opt_a ) {
    $alert_type = $opt_a;
}
  # MON_ALERTTYPE is ENV variable set by Mon
elsif ( $ENV{"MON_ALERTTYPE"} ) {
    $alert_type = $ENV{"MON_ALERTTYPE"};
}
else {
    $alert_type = "Alert Message";
}    

if ( $opt_q ) {
    $alert_status = $opt_q;
}
  # MON_OPSTSTATUS is ENV variable set by Mon
elsif ( $ENV{"MON_OPSTATUS"} ) {
    $alert_status = $ENV{"MON_OPSTATUS"};
}   

# Strip off leading/trailing quotation marks if they exist.
# All args should be readable if enclosed in quotation marks.
# Stripping the leading/trailing means that a password cannot
# begin or end with a quotation mark unless it is escaped.
#
foreach ( $recipient_jid, $sender_jid, $sender_pw, 
    	    $sender_port, $sender_resource, $sender_uid, 
          $message_subject, $time_secs, $alert_user , 
          $alert_hostname, $alert_type, $alert_status,
          $opt_s, $opt_g
        ) {
	  
    $_ =~ s/^\"//;
    $_ =~ s/\"$//;
}


# Split sender UID from host
#
$sender_uid = (split(/@/, $sender_jid))[0];
$sender_host = (split(/@/, $sender_jid))[1];


# My kludge for figuring UTC offset without adding another package
#
( $sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst ) = gmtime();
$time_gm = timelocal( $sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst );

( $sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst ) = localtime($time_secs);
$time_local = timelocal( $sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst );

$utc_offset = $time_local - $time_gm ;
$utc_offset = $utc_offset / 3600 ;
$utc_offset = sprintf("%.2f", $utc_offset);

# Format time for output
#
$time_local = localtime($time_secs);
( $wday, $mon, $day, $hour_min ) = split (/\s+/, $time_local);


#
# Concatenate Message Header
#
if ( $alert_type ) {
    $alert_message = "Alert: $alert_type\n";
}

$alert_message = "\n" . $alert_message . "Time:  $wday, $day $mon  $hour_min   UTC: $utc_offset\n";

if ( $alert_user ) {
    $alert_message = $alert_message . "User:  $alert_user\n";
}

if ( $alert_hostname ) {
    $alert_message = $alert_message . "Host:  $alert_hostname\n";
}

if ( $opt_g ) {
    $alert_message = $alert_message . "Group:  $opt_g\n";
}

if ( $opt_s) {
    $alert_message = $alert_message . "Service:  $opt_s\n";
}

if ( $alert_status ) {
    $alert_message = $alert_message . "Status:  $alert_status\n";
}  


#
# Add message body from STDIN
#
$alert_message = "$alert_message------------Beg-$header_txt------------\n$summary\n------------End-$header_txt------------";


# Connect and Jab message
#
$connection = Net::Jabber::Client->new();
$connection->Connect( "hostname" => $sender_host,"port" => $sender_port, "ssl" => $use_ssl )  or die
"Cannot connect ($!)\nhostname: $sender_host\nport: $sender_port\nsender JID:$sender_jid\n\n";

@result = $connection->AuthSend( "username" => $sender_uid,"password" =>
$sender_pw,"resource" => $sender_resource, "ssl" => $use_ssl );

if ($result[0] ne "ok") {
 die "Ident/Auth with server failed: $result[0] - $result[1]\n";
}

$message = Net::Jabber::Message->new();
$message->SetMessage( "to"           => $recipient_jid,
                      "subject"      => $message_subject,
                      "type"         => "normal",
                      "body"         => $alert_message,
                       "ssl"         => $use_ssl);

$connection->Send($message);
sleep($max_wait);
$connection->Disconnect();
exit;
