#!/bin/bash
#  A monitor device utility for Linux. 
#  Monitors that a network device is alive and sends SMS alarm if no response.
#  
#  Copyright 2011 Arto Jääskeläinen   
#  temp001(at)pp.inet.fi, ajaaskel(at)forum.ubuntu-fi.org
#
#  This program is free software; you can redistribute it and/or 
#  modify it under the terms of the GNU General Public License as 
#  published by the Free Software Foundation; either version 2 of the
#  License, or (at your option) any later version.
# 
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  Ver 1.00 September 25, 2011 First version
#  Ver 1.01 September 29, 2011 Fixed: Date/time entry, user defined mobile port. New: Error counter.
#  Ver 1.02 October 1, 2011 New: Two phase ping
#  Ver 1.03 May 21, 2012 Changes: Compatibility with new version of sendmob (autodetect dev)
#
THIS_VER=1.03    # <--Remember to update current version number here
#
# Do not add ANY characters in front of the line above --- version control variable.
#

GET_VERSION()
#Entry none, return INSTALLED_VER 
{
if [ -e /usr/local/bin/$installname ]; then  # Some version of chknodes utility exists ?
INSTALLED_VER=`cut -b 1-14 /usr/local/bin/$installname | grep THIS_VER= | sed 's/[a-Z _#<='-']*//g' `
if [ -z $INSTALLED_VER ]; then   #No version number found
INSTALLED_VER=1.00
fi 
else
INSTALLED_VER=0    #No ver file found
fi
}

CONV_IN() #Returns string looking like integer
#Entry ST, return RET
{
DOTPOS=`expr index $ST '.'`       #Position of dot
ST1=`expr match $ST '\([0-9]*\)'` #All before dot
ST2=`echo ${ST:$DOTPOS}`          #All after dot
LEN_ST2=${#ST2}                   #Length after dot
if [ $LEN_ST2 != 2 ]; then        #We force always two digits
ST2=`expr $ST2 \* 10`             #FYI, no parentehsis allowed here
if [ $ST2 = 0 ]; then             #Specific case of zero
ST2=00                            #Two digits for zero, too
fi
fi
RET=$ST1$ST2                      #Concatenated string
}

INSTALL()
{
if [ $THIS_VER_IN -gt $INSTALLED_VER_IN ] ; then  		# Need to update 
	sudo cp $0 /usr/local/bin/$installname
	GET_VERSION
	ST=$INSTALLED_VER
	CONV_IN
	INSTALLED_VER_IN=$RET
	if [ $THIS_VER_IN = $INSTALLED_VER_IN ] ; then
	echo -e 
	fgblue; echo "Installed/updated \"$installname\" utility succesfully."; fgdefault
	else
	fgred; echo "Could not install/update \"$installname\" utility."
	echo "This ver:" $THIS_VER  "installed ver: " $INSTALLED_VER;fgdefault
	fi
fi
}

UNINSTALL()
{
if ! [ -e /usr/local/bin/$installname ] ; then
fgblue; echo "Nothing to uninstall."; fgdefault; return
else
sudo rm /usr/local/bin/$installname 2>/dev/null
fi
if [ ! -e /usr/local/bin/$installname ]; then
fgblue; echo "Uninstall succesful."; fgdefault
else
fgred; echo "Could not uninstall "sendmob" utility."; fgdefault
fi
}

HELP()
{
echo
fgbold 
echo $installname "v"$THIS_VER  "--- A monitor device utility for Linux using a net stick for alarms."
fgdefault
echo "Designed to monitor once a minute a network device which can be pinged."
echo "Sends a text message (SMS) to mobile phone if ping fails i.e. device or link is down."
echo "Failures will be logged to text file \"mondev.log\"for later analysis. "
echo "Depends on \"sendmob\" utility for sending SMS alarms."
echo
fgbold
echo "    $installname name int_tel [dev_name] [message]"
echo 
echo "    $installname [-h | --help, -u | --uninstall]"
fgdefault
echo
echo "name..........Name or ip address of device to monitor."
echo
echo "int_tel ..... Tel. number must start with plus sign and be numbers only after that"
echo
echo "dev_name .... Optional device name of your mobile Internet stick, defaults to /dev/ttyUSB0."
echo
echo "message ..... Optional free alarm text, can be omitted = blank message. PDU mode not supported."
echo 
echo "Examples:"
echo
echo "    $installname example.com +3584012345678 Alarm, connection lost."
echo
echo "    $installname example.com +3584012345678 /dev/ttyUSB2 No response from example.com"
echo
echo "    $installname 192.168.1.5 +3584012345678 My server xyz is down."
echo
}

CHECK_TELNUMBER()
# International telephone number format sanity check.
# Checks that first character is "+" and after that at least 6 numbers.
{
str_to_test="$*"
telnumber_ok="false"
min_number_length=6
if [ ${str_to_test:0:1} = "+" ] ; then
non_numeric=$( echo "${str_to_test:1}" | tr -d '[0-9]' )
if [ ${#non_numeric} = 0 ] && [ ${#str_to_test} -gt $min_number_length ] ; then
telnumber_ok="true"
fi
fi
}

clearline()
{
echo -en '\r'
echo -en "\x1b[2K"
}

fgred()
{
echo -en "\x1b[31;01m"
}

fgblue()
{
echo -en "\x1b[34;01m"
}

fgcyan()
{
echo -en "\x1b[36;01m"
}

fggreen()
{
echo -en "\x1b[32;01m"
}

fgblack()
{
echo -en "\x1b[30;01m"
}

fgbold()
{
echo -en "\x1b[1m"
}

fgblink()
{
echo -en "\x1b[5m"
}

fgunder()
{
echo -en "\x1b[4m"
}

fgrev()
{
echo -en "\x1b[7m"
}

fgover()
{
echo -en "\x1b[9m"
}

fgdefault()
{
tput sgr0
}

runmessage()
{
echo
fgbold; echo "Monitor Device Utility v"$THIS_VER "Running..."; fgdefault
echo "Started.................."$startdatetime
if [ $errors -eq "0" ] ; then
  echo "Errors..................."$errors
else
  echo -n "Errors...................";fgred;echo $errors;fgdefault
fi
echo "Device to monitor"........$devtomon
echo -n "Mobile port"..............$mobiledev
if [ $usinggivendev = "true" ] ; then
  echo "  (User given)"
else
  echo "Default"  
fi
echo "Sending alarms to"........$telnumber
echo "Optional alarm message"...$message
echo
}

getdatetime()
{
datetimenow=$(date "+%F %T %z %u %a")
}

pingnow()
{
pingresp=$(ping -c $1 $devtomon 2>pingtemp2 | grep '100% packet loss')
pingtemp2=$(cat pingtemp2)
}

# Main ------------------------------------------------------
installname="mondev"
allparams=$*
numparms=$#
errors=0
pingresp=''
pingtemp2=''
getdatetime
startdatetime=$datetimenow
#Version/update control ----------------------
GET_VERSION
ST=$INSTALLED_VER
CONV_IN
INSTALLED_VER_IN=$RET
ST=$THIS_VER
CONV_IN
THIS_VER_IN=$RET
if ! [[ $1 = "-u" || $1 = "--unistall" ]] ; then 
INSTALL
fi
#-------------------------------------------------------------
if [ $numparms = 0 ] ; then
HELP; exit 1  #No command line parameters
fi
 
case $1 in
-h | --help )
  HELP;exit 0 ;;
-u | --uninstall )
  UNINSTALL;exit 0 ;;
-v | --version )
  echo $installname v$THIS_VER;exit 0 ;;
* )
#-------------------------------------------------------------
if ! [ -e /usr/local/bin/sendmob ] ; then
	fgred 
	echo "***Error: Dependency sendmob (sms backend) missing, please install it first"
	echo "by running ./sendmob.bash once. "  
	fgdefault; exit 255
	fi
   
devtomon=$(echo $allparams | cut -d " " -f1)
telnumber=$(echo $allparams | cut -d " " -f2) 
mobiledev=""		#Default device =autodetect
message=$(echo $allparams | cut -d " " -f3-999)
usinggivendev=false

CHECK_TELNUMBER $telnumber
if [ "$telnumber_ok" = "false" ] ; then
fgred; echo;echo "***Error: Telephone number."; echo; fgdefault; exit 3  
fi

givendev=$(echo $allparams | cut -d " " -f3)
if [ "${givendev:0:5}" = "/dev/" ] && [ ${#givendev} -gt 5 ] ; then #Device given
if ! [ -e "$givendev" ] ; then
fgred; echo;echo "***Error: Device does not exist."; echo; fgdefault; exit 2  
fi    
mobiledev=$givendev
message=$(echo $allparams | cut -d " " -f4-999)   #Must not include parm3 into message
usinggivendev=true
fi
runmessage
while true
do	
	clearline; fgcyan; echo -en "*** Checking now *** "; fgdefault
	pingnow 3
	if [ ${#pingresp} -ne "0" ] || [ ${#pingtemp2} -ne "0" ] ; then
	clearline; fgcyan; echo -en "*** Quick check failed, running now longer check ***"; fgdefault
	sleep 10		#Traffic congestion ?
	pingnow 15
	fi
	if [ ${#pingresp} -ne "0" ] || [ ${#pingtemp2} -ne "0" ] ; then
		echo $pingresp $pingtemp2 > pingresp		
		echo -e '\a'   #Sound
		fgred; echo "Connection to "$devtomon "lost"; fgdefault
		errors=$[$errors+1]
		getdatetime
		errordatetime=$datetimenow
		echo "Date & time: " $errordatetime
		clearline; echo "Preparing to send a message, 10 seconds..."
		echo $errordatetime $devtomon $mobiledev $telnumber $message >> mondev.log
		sleep 10
		if [ ${#message} -eq "0" ] ; then
		message=$devtomon 
		fi
		sendmob $mobiledev $telnumber $message
		fgblue; echo "Alarm sent to: "$2; fgdefault
		runmessage
		clearline; echo -en "Latest status "; fgred; echo -en "FAILURE, "; fgdefault;
	else
	clearline; echo -en "Latest status "; fgblue; echo -en "OK, "; fgdefault
	fi
 	echo -en "idle until next check..."
	sleep 60
done


#----------------------------------------------------------------
  ;;
esac



