#!/bin/sh
# Written by hip0.
# Under GPL ver. 2.0 and above.
# Description: Uses array of servers, specified port number
# and nmap to check the port defined in $port_num for "open" state.
# If the checked port has different state from "open"
# We assume our server is down and send notify sms and mail
# to the administrator. Where the mail header that the mail's been sent
# from will have the problematic server's ip in instead of username.
# N!B! In order this script to work you need to have working mail server at localhost

# array with boxes we check for
#box[0]="192.168..";
box[0]="192.168.0.1";
box[1]="192.168.0.2";
box[2]="192.168.0.3";
box[3]="127.0.0.1";
box[4]="192.168.0.4";
#box[5]="192.168.0.5";
#box[5]="192.168.0.6";
box[5]="192.168.0.7";
box[6]="192.168.0.8";
box[7]="192.168.0.9";

# Count of the machines in the array counted from zero.
machine_cnt="${#box[@]}";
# port number we shall check for
port_num="80";
# nmap scanner location and options
scanner_stuff="/usr/bin/nmap -P0 -p $port_num";
# string for opened port
op="open";
# my gsm number where our mail shall be sent
mynum=359897765958;
# other admin num
##other_admin=0894716012;
# provider to use for sending
myprov="sms.globul.bg";
# mail address for notifaction 
mymail="hipo@pc-freak.net";
# other admin mail
##other_admin_mail="ganchev@design.bg";
# temporary lock file ( should be manually removed )
lock_file=/tmp/server-down;
# qmail-inject binary full path
qmail_inject=/var/qmail/bin/qmail-inject;
curl=/usr/bin/curl;

if [ -f $lock_file ]; then

# get $lock_file creation time (on Fedora and CentOS, probably redhat you need to change this to $8) otherwise $lock_file won't get cleared up
creation_time=$(ls -al $lock_file |awk '{ print $7 }');
# get $lock_file creation hour and minutes
creation_hour=$(echo $creation_time|sed -e "s#:# #g"|awk '{ print $1 }');
creation_minutes=$(echo $creation_time|sed -e "s#:# #g"|awk '{ print $2 }');

# get from date current hour and minutes
cur_minutes=$(date +%R|sed -e "s#:# #g"|awk '{ print $2 }');
cur_hour=$(date +%R|sed -e "s#:# #g"|awk '{ print $1 }');
#echo "creation_time $creation_time, creation_minutes $creation_minutes, cur_minutes $cur_minutes, creation_hour $creation_hour, cur_hour $cur_hour";

down_ip=$(head -1 $lock_file |awk '{ print $5 }');
sedded_box_name=$(echo ${down_ip} | sed -e "s/\./_/g");

export USER="${sedded_box_name}_up_again";

# check if cur_hour, creation_hour match and cur_minutes > creation_minutes
if [ "$creation_hour" == "$cur_hour" ] && [ "$cur_minutes" -gt "$creation_minutes" ]; then
##let "sum = ($cur_minutes - $creation_minutes)"

# if $lock_file older than 30 minutes and down host is now up delete $lock_file
if [ "$sum" -gt "30" ] && [ "`$scanner_stuff $down_ip | grep "$op" | awk '{ print $2 }'`" == "$op" ] || [ "`$curl -I --connect-timeout 40 $down_ip 2>/dev/null |wc -l`" -lt "8" ]; then
rm -f $lock_file
echo "To:${mynum}@${myprov}" | $qmail_inject
echo -e "Our ${down_ip}'s port $port_num is OK now.\n All should be back to normal" | mail ${mymail} -s "Server $down_ip $port_num is up again! Hooray !";

fi

fi

# check if cur_hour > creation_hour and creation_minutes > cur_minutes
if [ "$cur_hour" -gt "$creation_hour" ] && [ "$creation_minutes" -gt "$cur_minutes" ]; then
echo $creation_minutes
let "sum = (60 - $creation_minutes) + $cur_minutes"

# if $lock_file older than 30 minutes and down host is now ip delete $lock_file
if [ "$sum" -gt "30" ] && [ "`$scanner_stuff $down_ip | grep "$op" | awk '{ print $2 }'`" == "$op" ] || [ "`$curl -I --connect-timeout 40 $down_ip 2>/dev/null |wc -l`" -lt "8" ]; then
rm -f $lock_file

echo "To:${mynum}@${myprov}" | $qmail_inject 
echo -e "Our ${down_ip}'s port $port_num is OK now.\n All should be back to normal" | mail ${mymail} -s "Server $down_ip $port_num is up again! Hooray !";


fi

fi

# check if cur_hour > creation_hour and cur_minutes > creation_minutes
if [ "$cur_hour" -gt "$creation_hour" ] && [ "$cur_minutes" -gt "$creation_minutes" ]; then
let "sum = (60 - $creation_minutes) + $cur_minutes"

# if $lock_file older than 30 minutes and down host is now ip delete $lock_file
if [ "$sum" -gt "30" ] && [ "`$scanner_stuff $down_ip | grep "$op" | awk '{ print $2 }'`" == "$op" ] || [ "`$curl -I --connect-timeout 40 $down_ip 2>/dev/null |wc -l`" -lt "8" ]; then
rm -f $lock_file
fi

echo "To:${mynum}@${myprov}" | $qmail_inject
echo -e "Our ${down_ip}'s port $port_num is OK now.\n All should be back to normal" | mail ${mymail} -s "Server $down_ip $port_num is up again! Hooray !";

fi

exit 1;

fi

for((i=0;i<${machine_cnt};i++)); do
sleep 2;
if [ "`$scanner_stuff ${box[$i]} | grep "$op" | awk '{ print $2 }'`" != "$op" ] || [ "`$curl -I --connect-timeout 40 ${box[$i]} 2>/dev/null |wc -l`" -lt "8" ]; then
sleep 20;
if [ "`$scanner_stuff ${box[$i]} | grep "$op" | awk '{ print $2 }'`" != "$op" ] || [ "`$curl -I --connect-timeout 40 ${box[$i]} 2>/dev/null |wc -l`" -lt "8" ]; then
sleep 40;
if [ "`$scanner_stuff ${box[$i]} | grep "$op" | awk '{ print $2 }'`" != "$op" ] || [ "`$curl -I --connect-timeout 40 ${box[$i]} 2>/dev/null |wc -l`" -lt "8" ]; then
sleep 400;
if [ "`$scanner_stuff ${box[$i]} | grep "$op" | awk '{ print $2 }'`" != "$op" ] || [ "`$curl -I --connect-timeout ${box[$i]} 2>/dev/null |wc -l`" -lt "8" ]; then
sleep 800;
if [ "`$scanner_stuff ${box[$i]} | grep "$op" | awk '{ print $2 }'`" != "$op" ] || [ "`$curl -I --connect-timeout ${box[$i]} 2>/dev/null |wc -l`" -lt "8" ]; then

sedded_box_name=$(echo ${box[$i]} | sed -e "s/\./_/g");
if [ -f $lock_file ]; then
exit 1;
fi
export USER=$sedded_box_name;
echo "To:${mynum}@${myprov}" | $qmail_inject 
echo -e "Our ${box[$i]}'s port $port_num is closed or filtered.\n The box is probably down" | mail ${mymail} -s "Problem with server ${box[$i]}";

##echo "To:${other_admin}@${myprov}" | $qmail_inject 
##echo -e "Our ${box[$i]}'s port $port_num is closed or filtered.\n The box is probably down" | mail ${other_admin_mail} -s "Problem with server ${box[$i]}";


touch $lock_file 
echo "Port: $port_num on box: ${box[$i]} closed or filtered" >> $lock_file
echo "Machine is probably down" >> $lock_file
exit 1;
fi
fi
fi
fi
fi
done

