#!/bin/bash

###########################################################################
#
#	Shell program to connect to ISP using wvdial, and  keep  a log
#       of connection details.
#
#	Copyright 2001, USM Bish, <bish@nde.vsnl.net.in>.
#
#	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.
#
#	Description: Dial an isp and log in as user using sudo
#       Configuration details need changing depending upon the
#       installation
#
#	Usage:
#
#		connect [ -h | --help ] [-c] [-d] [-r] [-s] [-v]
#
#	Options:
#
#		-h, --help	Display this help message and exit.
#		-c              Connect to isp
#		-d              Disconnect
#               -r              Records available for previous months              
#               -s              Summary of connections this month
#               -v              View log file 
#
#
#       Note : This script needs root privileges
#
#       Dependencies:
#
#       This script needs the following programs installed:
#       o wvdial   o pppstats   o bc   and other commonly installed
#       utils like awk, sed, less (or any other pager), basename
#       cut, grep
#
#	Revisions:
#
#	May/16/2001	 File created           .......... ver 0.0
#       May/16/2001      Connect Routine        .......... ver 0.1
#       May/17/2001      Disconnect Routine     .......... ver 0.2 
#       Nov/29/2001      Accounting incorporaed .......... ver 0.3
#       Dec/01/2001      View log file          .......... ver 0.4
#       Dec/02/2001      Summary of Connections .......... ver 0.5 
#       Dec/04/2001      IP (RX/TX) accounting  .......... ver 0.6
#       Dec/21/2001      Monthly accounting     .......... ver 0.7
#       Jan/06/2002      Added byte accounting  .......... ver 0.8 
#
###########################################################################

PROGNAME=$(basename $0)
VERSION="0.8"
             
###########################################################################
#	Constants. Do NOT Edit
###########################################################################

TRUE=1
ONLINE=22
USER_INTERRUPT=13

TEMP_FILE1=/tmp/${PROGNAME}.$$.1
TEMP_FILE2=/tmp/${PROGNAME}.$$.2
TEMP_FILE3=/tmp/${PROGNAME}.$$.3
TEMP_FILE4=/tmp/${PROGNAME}.$$.4

###########################################################################
# User defined variables. Edit for your set up. Usually not needed
###########################################################################

# Change if you want log file at another location
MtYr=`date "+%b%y"`
FILE_LOG=/var/log/$PROGNAME/${MtYr}.${PROGNAME}.log
WV_LOG=$HOME/wvdial.log

# Change if you want to use view, more or some other pager
PAGER="less"

# Rate set for Indian telephones, where each Unit consists
# of 3 min and each Unit costs Rs 2/-. A 7 min call costs
# Rs 6/-. Edit if indicated.
      
UNIT=3          # How many mins accounts for an unit ?
RATE=2          # Rate per Unit ?
DENOM="Rs. "    # What is the currency symbol ?

###########################################################################
#	Functions
###########################################################################

function do_rate
{
     ### This function would vary depending  upon the rate of
     ### your telephone company ...  This has been set up for
     ### Indian Telephone dept which charges Rs 2/- for 3 min
     ### or part thereof. Edit as necessary on top. This rou-
     ### teen needs to change of there are differential rates
     ### rather than flat rates for your telephone vendor.
     
     ### TEMP_FILE2 has the min/ sec accounting. Take the min
     ### field for maths purposes from each line with "#".
     
     TOTAL_AMOUNT=0
     
     ### The delineating char is # for line containing min
     for i in `cat $TEMP_FILE2 | grep "#" | awk '{print $4}'`; 
     do
         echo "(($i / $UNIT) + 1) * $RATE" | bc > $TEMP_FILE3
         AMOUNT=`cat $TEMP_FILE3`
         echo "$TOTAL_AMOUNT + $AMOUNT" | bc > $TEMP_FILE3
         TOTAL_AMOUNT=`cat $TEMP_FILE3`
     done    
     
     PAYABLE=$DENOM$TOTAL_AMOUNT
}    
 
function connect_summary
{
     THIS_MONTH=`basename $FILE_LOG | cut -b 1-5`
     cat $FILE_LOG | grep "Duration" | cut -b 12- > $TEMP_FILE1
     cat $TEMP_FILE1 | awk '
	 {cnt++} 
    	 {MIN += $2}
    	 {SEC += $4}
    	 {TOTAL = MIN/60 + SEC/3600}
    	 END {print cnt"\t" $7" [" $9 "] \t" $2 "\t" $4 "\t" TOTAL} 
         ' > $TEMP_FILE2
     echo
     echo "---------------------------------------------------------"
     echo "Connection details:            This connect     Monthly"
     echo "Sl.     mm/dd/yy [hh:mm:ss]     min     sec     Total (hr)"
     cat $TEMP_FILE2
     echo "----------------------------------------------------------"
     echo
}         

function records_available
{
     PD=`pwd`
     cd /var/log/${PROGNAME}
        
     clear
     echo ""
     echo -en "\t"$PROGNAME"                Version : "$VERSION"\n\n"
     echo -en "\tMonthly records available are :\n\n"
     
     ls | cut -b 1-5 > $TEMP_FILE1
        
     CNT=0
     PASS=0

     for i in `cat $TEMP_FILE1`; do
         CNT=$((CNT + 1))

         # Triple column using ANSI sequence
         case "$PASS" in
            
         0) echo
            ALIGN="\033[09G"
            PASS=1
            ;;
            
         1) ALIGN="\033[30G"
            PASS=2
            ;;
               
         2) ALIGN="\033[51G"
            PASS=0

         esac
            
         OUT_STR=$CNT"]  "$i
         echo -en $ALIGN$OUT_STR 
     done

     TOT_CNT=$CNT
     
     echo -en "\n\n\t0] Abort program\n\n"

     echo -en "\tEnter a number [ 0 to "$TOT_CNT" ] : "
     read NUMBER

     if [ "$NUMBER" = "0" ]; then
        echo
        echo -en "\t"
        int_exit
     fi
           
     CNT=0
     for i in `cat $TEMP_FILE1`; do
         CNT=$((CNT+1)) 
         if [ $CNT = $NUMBER ]; then
              FILE_NO=$i
         fi   
     done

     WHICH_LOG=$FILE_NO.$PROGNAME.log
     summary
     
     cd $PD
}     

function ip_rxtx
{
     pppstats -a | grep -v "PACK" > $HOME/10.$$
     BYTES_IN=`cat $HOME/10.$$ | awk '{print $1}'`
     PACKS_IN=`cat $HOME/10.$$ | awk '{print $2}'`
     BYTES_OUT=`cat $HOME/10.$$ | awk '{print $7}'`
     PACKS_OUT=`cat $HOME/10.$$ | awk '{print $8}'`

     # IN : 12345 bytes ( 345  packets ) | OUT : 10134 bytes  ( 298 packets )
     P="IN : "$BYTES_IN" bytes ( "$PACKS_IN" packets ) | OUT : "$BYTES_OUT" bytes ( "$PACKS_OUT" packets )"
     rm -f $HOME/10.$$
     PACKETS=$P

}
         
function chk_root
{
     WHICH_USER=`whoami`

     if ! [ "$WHICH_USER" = "root" ]; then
         echo
         echo $PROGNAME"                  Version : "$VERSION        
         echo
         echo "Access as root only ... su to root and retry."
         echo "You are logged as : "$WHICH_USER" ... Sorry !!!"
         echo
         term_exit
     fi    
}
           
function summary
{
     THIS_MONTH=`basename $WHICH_LOG | cut -b 1-5`
      
     cat $WHICH_LOG | grep "Duration" | cut -b 12- > $TEMP_FILE1
     echo "************************************************************" >  $TEMP_FILE2
     echo "Summary of connections         : for "$THIS_MONTH >> $TEMP_FILE2
     echo "************************************************************" >> $TEMP_FILE2
     echo ""                                                 >> $TEMP_FILE2
     echo "Sl.     mm/dd/yy [hh:mm:ss]     min     sec     Total (hr)" >> $TEMP_FILE2
     echo ""                                                 >> $TEMP_FILE2
                 
#    awk magic begins  : EDIT VALUES BELOW IF NEEDED

#    The isp_rate is the cost of the isp usage per hour. If
#    you have paid Rs 850/- for a 100 hr package, the isp_rate
#    would be 8.5 ( viz 850 / 100).

     cat $TEMP_FILE1 | awk '

         {isp_rate=8.50}            # isp cost per hour
         
	 {cnt++} 
    	 {MIN += $2}
    	 {SEC += $4}
    	 
    	 {TOTAL = MIN/60 + SEC/3600}
    	 {AVERAGE = TOTAL/cnt}
    	 {print "#"cnt"\t" $7" [" $9 "] \t" $2 "\t" $4 "\t" TOTAL} 
    	 
    	 END {print "\n************************************************************\n"}
    	 END {print "\nTotal usage hours \t\t"MIN/60 + SEC/3600 " hr"}
 	 END {print "Total number of connects \t" cnt} 
         END {print "Average connection time \t"AVERAGE*60" min"} 
         END {print "ISP costs \t\t\tRs. " TOTAL * isp_rate}
         ' >> $TEMP_FILE2

         ### Now do the calc for rates and rewrite file
         do_rate
         echo "" >> $TEMP_FILE2
         echo -en "Telephone expense \t\t"$PAYABLE"\n" >> $TEMP_FILE2        
         echo >> $TEMP_FILE2
         
         cat $FILE_LOG | grep "packets" | awk '
             {cnt++}
             {bytes_in += $3}
             {packets_in += $6}
             {bytes_out += $12}
             {packets_out += $15}
             END {print "Total bytes in \t\t\t"bytes_in / 1024 / 1024" mb in "cnt" connects"}
             END {print "Total packets in  \t\t"packets_in" pkts in "cnt " connects"}
             END {print "Total bytes out \t\t"bytes_out / 1024 / 1024 " mb in "cnt" connects"} 
             END {print "Total packets out\t\t"packets_out" pkts in "cnt " connects"}

             ' >> $TEMP_FILE2
             
    #	End of awk magic

    > $TEMP_FILE3
    > $TEMP_FILE4
    cat $TEMP_FILE2 | grep "Total usage hours" | awk '{print $4}' >> $TEMP_FILE3
    cat $TEMP_FILE2 | grep "mb" | awk '{print $4}' >> $TEMP_FILE3
    for i in `cat $TEMP_FILE3`; do
        echo -en $i" " >> $TEMP_FILE4
    done
    AVG_THOROUGHPUT=`cat $TEMP_FILE4 | awk '{print ($2+$3)/$1}'`
    echo "" >> $TEMP_FILE2
    echo -en "Average Thoroughput \t\t"$AVG_THOROUGHPUT" mb per Hr \n" >> $TEMP_FILE2
    
    echo "" >> $TEMP_FILE2
    echo "************************************************************" >> $TEMP_FILE2
    echo ""                                                 >> $TEMP_FILE2
    SIZE=`ls -al $FILE_LOG | awk '{print $5}'`
    echo -en "Log file \t\t\t"$FILE_LOG"\n" >> $TEMP_FILE2
    echo -en "Present log file size \t\t["$SIZE" bytes]\n\n" >> $TEMP_FILE2

    $PAGER $TEMP_FILE2

    echo
    echo -en "Save this summary to file ? [y/n] : "
    read YN
    case $YN in
    
    y|y ) echo
          echo -en "Enter filename : "
          read FNAME
          cp $TEMP_FILE2 $FNAME
          ;;
    *   ) echo
          echo "Bye ..."
    esac
}

function view_log
{
     $PAGER $FILE_LOG
}
     
function time_on_line
{
     NOW=`date +%s`
     OLD=`cat /tmp/connect.now`
     TOTSECS=`echo "($NOW - $OLD)" | bc`

     #Convert back to mm:ss
     MM=`echo "($TOTSECS / 60)" | bc`
     SS=`echo "($TOTSECS % 60)" | bc`
     if [ $SS -lt 10 ]; then
        SS="0"$SS
     fi
     if [ $MM -lt 10 ]; then
        MM="0"$MM
     fi
     DURATION=" "$MM" min "$SS" sec"  
}

function chk_if_online
{
        trap 'rm -f $TEMP_FILE1; exit $USER_INTERRUPT' TERM INT
        # Cleans up the temp file if script interrupted by control-c.

        rm -f /var/run/ppp*.pid
        # Remove old ppp*.pid files if any

        ALIGN="\033[3G"
        MSGALN="\033[14G"
        SEC=0

        clear
        echo
        echo $PROGNAME"                     Version : "$VERSION        
        echo
        echo "Dialing "$TELE_NO" and logging on to your ISP"
        echo "Press [Ctrl-C] to abort (if needed) ...."
        echo ""
        echo -en "o"
        
        while [ $TRUE ]  #Endless loop.
        do
           # Checks for presence of the ppp?.pid,
           # indicating a successful logon.

           if [ -e /var/run/ppp0.pid ]; then
              echo ""
              echo "---------------------------------------------------"
              tail -4 /var/log/messages | grep "pppd"
              echo "---------------------------------------------------"
              echo ""
              echo "Waiting till IP/ DNS addresses are resolved ... "
              rm -f $TEMP_FILE1
               
              ### However, quit if pppd is started by default            
              tail  $WV_LOG | grep "know what to do" > $TEMP_FILE2
              PPP_ERROR=`cat $TEMP_FILE2`
              if ! [ "$PPP_ERROR" = "" ]; then
                  echo
                  echo $PPP_ERROR
                  killall -INT pppd 2>/dev/null
                  killall -INT wvdial 2>/dev/null
                  rm -f /var/run/ppp*.pid
                  rm -f /var/lock/LCK*
                  term_exit
              else
                  echo "Only a few secs more ..."
                  echo    
              fi    
              
              while [ ! -s $TEMP_FILE1 ]; do
              
                 ### Wait till IP addresses are established
                 tail -6 /var/log/messages | grep "IP" > $TEMP_FILE1

              done
              
              echo
              cat $TEMP_FILE1
              tail -6 /var/log/messages | grep "DNS"
              echo
              echo    
              echo "Ok, On-line now ... Enjoy ... "
              echo "Type "$PROGNAME" -d to disconnect"
              echo ""
              echo "------------------------------------------------------" >> $FILE_LOG
              echo -en "User : " >> $FILE_LOG
              echo $USER >> $FILE_LOG
              echo -en "Started at : " >> $FILE_LOG
              date "+%a  %Y %b %d    %T" >> $FILE_LOG
              date +%s > /tmp/connect.now
              clean_up                  # Clean up temp file
              exit $ONLINE
           else
              SEC=$((SEC+1))
              LYNE=`tail -1 $WV_LOG | cut -b 1-55`
              echo -en $ALIGN"                                                                   "
              echo -en $ALIGN$SEC" sec => "$MSGALN$LYNE

              echo $LYNE | grep "not responding" > $TEMP_FILE2
              PPP_ERROR=`cat $TEMP_FILE2`
              if ! [ "$PPP_ERROR" = "" ]; then
                 echo -en "\n\nCheck your modem and retry :-)\n\n"
                 term_exit
              fi   

           fi

           sleep 1  
        done 

}	# end of chk_if_online


function clean_up
{
	rm -f ${TEMP_FILE1}
	rm -f ${TEMP_FILE2}
	rm -f ${TEMP_FILE3}
	rm -f ${TEMP_FILE4}
}


function graceful_exit
{
	clean_up
	exit
}


function error_exit 
{
	echo "${PROGNAME}: ${1:-"Unknown Error"}" >&2
	clean_up
	exit 1
}


function term_exit
{
	echo "${PROGNAME}: Terminated"
	clean_up
	exit
}


function int_exit
{
	echo "${PROGNAME}: Aborted by user"
	clean_up
	exit
}


function usage
{
	echo "Usage: ${PROGNAME} [-h | --help] [-c] [-d] [-r] [-s] [-v]"
}


function helptext
{
	
	local tab=$(echo -en "\t\t")
		
	cat <<- -EOF-

        ${PROGNAME}                       ver. ${VERSION}	

        This is a program to Connect to ISP using wvdial.
	
        $(usage)
	
        Options:
	
        -h, --help	Display this help message and exit.
        -c              Connect to isp
        -d              Disconnect
        -r              Records available for previous months
        -s              Summary of connections this month
        -v              View log file			
	
        Note : This script needs root privileges.
        		
	-EOF-
}	

function connection_off
{

     ##### Stop the pppd processes ######
        
     echo "Stopping PPPD !"
     killall -INT pppd 2>/dev/null
     killall -INT wvdial 2>/dev/null
     rm -f /var/run/ppp*.pid
     rm -f /var/lock/LCK*

     ##### Write to log file ##########

     echo -en "Ended at   : " >> $FILE_LOG 
     date "+%a  %Y %b %d    %T" >> $FILE_LOG     
     time_on_line
     TODAY=`date +%D`
     AT=`date +%T`
     echo "Duration   :"$DURATION" [ $TODAY : $AT ]" >> $FILE_LOG    
        
     ip_rxtx
     echo $PACKETS >> $FILE_LOG
        
     echo "------------------------------------------------------" >> $FILE_LOG
     echo "" >> $FILE_LOG

     connect_summary
             
     echo $PROGNAME" -v .... to view log file "$FILE_LOG
     echo "or do a ["$PROGNAME" -s] for summary of this month"
        
     # Delete old files at /tmp before quitting
     rm -f /tmp/connect.now
}

function dial_on
{
        # Delete any old log file in /tmp
        rm -f /tmp/connect.now
        
        clear
        echo ""
        echo -en "\t"$PROGNAME"                Version : "$VERSION"\n\n"
        echo -en "\tValid dialers on wvdial.conf are :\n\n"
        cat /etc/wvdial.conf | grep "Dialer" | awk '{print $2}' | tr -d "]" > $TEMP_FILE1
        
        CNT=0
        PASS=0

        for i in `cat $TEMP_FILE1`; do
            CNT=$((CNT + 1))

            # Triple column using ANSI sequence
            case "$PASS" in
            
            0) echo
               ALIGN="\033[09G"
               PASS=1
               ;;
            
            1) ALIGN="\033[30G"
               PASS=2
               ;;
               
            2) ALIGN="\033[51G"
               PASS=0

            esac
            
            OUT_STR=$CNT"]  "$i
            echo -en $ALIGN$OUT_STR 
        done

        TOT_CNT=$CNT

        echo -en "\n\n\t0] Abort program\n\n"

        echo -en "\tEnter a number [ 0 to "$TOT_CNT" ] : "
        read NUMBER

        if [ "$NUMBER" = "0" ]; then
           echo
           echo -en "\t"
           int_exit
        fi
           
        CNT=0
        for i in `cat $TEMP_FILE1`; do
            CNT=$((CNT+1)) 
            if [ $CNT = $NUMBER ]; then
                 TELE_NO=$i
            fi   
        done

        wvdial $TELE_NO > $WV_LOG 2>&1 &

}

###########################################################################
#	Program starts here
###########################################################################

# Trap TERM, HUP, and INT signals and properly exit

trap term_exit TERM HUP
trap int_exit INT

# Process command line arguments

if [ "$1" = "" ]; then
	helptext
	graceful_exit
fi

if [ "$1" = "--help" ]; then
	helptext
	graceful_exit
fi

# IF first time run, create necessary log file
if ! [ -e $FILE_LOG ]; then
   chk_root
   mkdir /var/log/${PROGNAME}
   chmod 777 /var/log/${PROGNAME}
   touch $FILE_LOG
   chown root.root $FILE_LOG
   chmod 666 $FILE_LOG
fi
   
# Process arguments - edit to taste

while getopts ":hcdrsv" opt; do

    case $opt in
 
    c )	chk_root
        echo ""
        if [ -e /var/run/ppp* ]; then
           echo $PROGNAME" Error : ppp active"
           echo "[$PROGNAME -h]  ... for help"         
           exit 1
        else
           dial_on
        fi
        chk_if_online
        ;;
    
    d ) chk_root
        echo ""
        if [ -e /var/run/ppp* ]; then
           connection_off
        else
           echo $PROGNAME" Error : ppp NOT active"
           echo "[$PROGNAME -h]  ... for help"         
           term_exit
        fi
        ;;

    r)  records_available
        ;;
        
    s)  WHICH_LOG=$FILE_LOG
        summary 
        ;;
        
    v)  view_log 
        ;;
        
    h )	helptext
        graceful_exit 
        ;;
         
    * )	usage
	exit 1

    esac

done

graceful_exit

###########################################################
# Everything below is ignored
###########################################################
