#!/bin/sh

# drpadmin - adminstrative tool for adding and removing portservers,
#    tty devices, and configuration files.

# $Id: drpadmin,v 1.29 2004/03/29 21:06:15 scottk Exp $

CONFIGDIR="/etc/conf/digi"
CONFIGFILE="/etc/conf/digi/drp.conf"
RPDAEMON="/sbin/drpd"
TTY="drp"

ttyname=tty
prname=pr
cuname=cu

# driver prefix
NAME="drp"

#
# Verify super-user privilege.
#

if [ '!' -w /etc/passwd ]
then
    echo "Must be root to use $0"
    exit 2
fi

#
# Define return values
#
: ${OK=0} ${FAIL=1}

#
# Initialize variables
#
PATH=/bin:/usr/bin:/etc:$PATH
list=
tmp=/tmp/${NAME}.$$

exitval=OK

#
# Clean up and exit after signals
#
trap 'rm -f tmp* ; exit 1' 1 2 3 15

#
# Remove temp files and exit with the status passed as argument
#
# Usage: cleanup status
# References: $tmp indicates prefix of files to remove
# Notes: cleanup exits with whatever value it is passed.
#
cleanup()
{
    trap '' 1 2 3 15
    [ -n "$tmp" ] && rm -f $tmp*
    exit $1
}

#
# yes or no
#
getyn='(while   read yn
	do	case "$yn" in
		[yY])   exit 0
			;;
		[nN])   exit 1
			;;
		*)      echo "  Please answer y or n : \c" >&2
			;;
	esac
	done)'

toupper(){
	<&0 tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ >&1
}

tolower(){
	<&0 tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz >&1
}


spin_count=1
schar1='/'
schar2='\055' 
schar3='\\'      
schar4='|'        

spinner() 
{
	eval blah=\$schar${spin_count}
	printf "\b$blah" >&2
	spin_count=`expr $spin_count + 1`
	if [ $spin_count -eq 5 ]
	then
		spin_count=1
	fi
}       



#
# add a PortServer entry
#
add_ps()
{
# grab the last ps number
i=0
psn=0
while read n rest
do
    if [ $n -gt $i ]
    then
	break
    fi
    i=`expr $i + 1`
    psn=$i
done < $CONFIGFILE

while :
do
    printf "\nEnter the host name or IP address: "
    read node

    while :
    do
	printf "Enter the number of ports: "
	read ndev
	if [ "$ndev" -ge 1 -a "$ndev" -le 64 ] 2>/dev/null
	then break
	fi
	printf "\n**** Please enter a number from 1 to 64\n\n"
    done

    while :
    do
	printf "Enter the tty device ID : "
	read devid

	# This returns the number of chars + 1 for some reason.
	total_chars=`echo "$devid" | wc -c`

	# Remember, wc seems to return chars + 1...
	if [ $total_chars -gt 3 ]
	then
		printf "\nWARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING\n\n"
		printf "The HPUX /etc/inittab file has a limit of 2 characters that can be in a tty name\n"
		printf "and still be able  in /etc/inittab.  You have exceeded this limit.\n"
		printf "If you choose to continue, these new ttys will NOT be put into the /etc/inittab\n"
		printf "file.   Is this okay? (y / n) "
		if eval "$getyn"
		then
			echo ""
		else
			continue;
                fi
	fi

	# Search for the next available chunk of ttys.
	printf "\nSearching for ${ndev} consecutive tty numbers for \"${ttyname}${devid}\" in /dev. Please wait...  "

	i=1
	start=01
	pstart=1
	need=${ndev}
	gotit=0

	char2=`expr "$devid" : '.\(.\)'`
	if [ -z "$char2" ]
	then
		max_allowed=999
	else  
		max_allowed=99
	fi

	while [ $pstart -lt $max_allowed ]
	do
		case $pstart in
			?) p=0$pstart;;
			??) p=$pstart;;
			???) p=$pstart;;
		esac

		spinner

		if [ -f /dev/${ttyname}${devid}${p} -o -c /dev/${ttyname}${devid}${p} ]
		then
			need=${ndev}
			pstart=`expr $pstart + 1`
			case $pstart in
				?) p=0$pstart;;
				??) p=$pstart;;
				???) p=$pstart;;  
			esac
			start=$p   
		else
			need=`expr $need - 1`
			if [ $need -eq 0 ]  
			then
				gotit=1
				break
			fi
			pstart=`expr $pstart + 1`
		fi  
	done

	if [ $gotit -eq 1 ]
	then
		printf "\b\b  \nFound a set of ${ndev} consecutive tty names from tty${devid}${start} to tty${devid}${p}\n"  
		break
	else
		printf "\b\b  \n**** That ID is already fully used, please try another ID\n\n"
	fi
    done

    while :
    do
        printf "\n\nWould you like this RealPort session to be encrypted?\n\n"
        printf "NOTE: Not all RealPort products support encrypted RealPort sessions.\n"
        printf "Please check your RealPort product's firmware release notes\n"
        printf "or product literature before selecting \"always\".\n"
        printf "If in doubt, select \"never\".\n\n"
        printf "(always/never) : (never): "

        read secure
        if [ -z "$secure" ]
        then
                secure="never"
        fi    

        case $secure in
        [aA])
                secure="always"
                secureopt="always"
                ;;
        always)
                secureopt="always"
                ;;
        [nN])
                secure="never"
                secureopt="never"
                ;;
        never)  
                secureopt="never"
                ;;
        *)   
                printf "\nPlease answer (a)lways or (n)ever.\n" >&2
                ;;
        esac

        if [ ! -z "$secureopt" ]  
        then
                break
        fi
                
    done


    while :
    do
	printf "\nIf the network connection between your HP-UX system\n"
	printf "and the remote unit includes a WAN link slower than 1 MBit,\n"
	printf "see the drpd.1m manual page and enter the WAN speed here : "
	read wan
	if [ -z "$wan" ] || s=`$RPDAEMON -s "$wan" 2>&1` 
	then 
	    break
	fi
	printf "\n**** "
	expr "$s" : '.*:\(.*\)'
    done

    printf "\nThe following unit will be configured,\n"
    printf "$psn\t$node\t$ndev\t$ttyname$devid$start-$ttyname$devid$p\t\tsecure ($secureopt)\t$wan\n"
    printf "\nIs this correct (y to add or x to abort) ? "
    read ans
    if [ -z "$ans" ]
    then
        printf "\nEmpty response, not configuring this unit.\n"
        return
    fi
    if [ $ans = 'x' ]
    then
	printf "\nx pressed, not configuring this unit.\n"
	return
    fi
    if [ $ans = 'y' ]
    then
	printf "$psn\t%-8s\t$ndev\t$devid\t$start\t771\t$secureopt\t1027\t$wan\n" $node >> $CONFIGFILE
	sort +n $CONFIGFILE > $tmp
	mv $tmp $CONFIGFILE
	mkdevices $psn $ndev $devid $start
	$RPDAEMON -p 771 -e $secureopt -q 1027 ${psn} $node $wan > /dev/null 2>&1 &
	return
    fi
done
}

#
# mkdevices - make the realport devices
#
# $1 == portserver number
# $2 == number tty ports
# $3 == device id
# $4 == start number. ie, 01 or 17, 33, etc.
#
mkdevices()
{
printf "Creating Digi RealPort Devices, Please wait...  "
# make the daemon device
psn=$1
nports=$2
devid=$3
start=$4

major=`/etc/lsdev -d drp | tail -1 | awk '{ print $1 }'`
if [ $? != 0 ]
then
    printf "RealPort Driver is not installed "
    return
fi

mknod /dev/drp${psn} c $major ${psn}
mknod /dev/drpmon${psn} c $major `expr ${psn} + 2048`

chmod 0600 /dev/drp${psn} /dev/drpmon${psn}
chgrp root /dev/drp${psn} /dev/drpmon${psn}

>/tmp/mktty.${TTY}
>/tmp/init.${TTY}
>/tmp/ttytype.${TTY}

i=0
#pstart=1
pstart=$start

base=`expr ${psn} \* 4096 + 4096`

char1=`expr "$devid" : '\(.\)'`
char2=`expr "$devid" : '.\(.\)'`

char3=`expr "$devid" : '..\(.\)'`

upperchar1=`echo $char1 | toupper`
lowerchar1=`echo $char1 | tolower`
upperchar2=`echo $char2 | toupper`
lowerchar2=`echo $char2 | tolower`


while [ $i -lt $nports ]
do

    spinner

    case $pstart in
    ?) p=0$pstart;;
    ??) p=$pstart;;
    esac

    ttyminor=`expr $base + $i`
    prminor=`expr $base + $i + 512`
    cuminor=`expr $base + $i + 1024`

    (
    echo "mknod /dev/${ttyname}${devid}${p} c $major $ttyminor"
    echo "mknod /dev/${prname}${devid}${p} c $major $prminor"
    echo "mknod /dev/${cuname}${devid}${p} c $major $cuminor"
    ) >>/tmp/mktty.${TTY}

    char3=`expr "$devid" : '..\(.\)'`

    if [ -z "$char3" ]
    then
        if [ -z "$char2" ]
        then
            if [ $p -gt "99" ]
            then
                echo "${devid}${p}:234:off:/etc/getty -h ${ttyname}${devid}${p} H" >> /tmp/init.${TTY}
            else
                echo "D${devid}${p}:234:off:/etc/getty -h ${ttyname}${devid}${p} H" >> /tmp/init.${TTY}
            fi
        else
            echo "${devid}${p}:234:off:/etc/getty -h ${ttyname}${devid}${p} H" >> /tmp/init.${TTY}
        fi
    fi

#    echo "${devid}${p}:234:off:/etc/getty -h" \
#	 "${ttyname}${devid}${p} H" >>/tmp/init.${TTY}

    
    echo "vt100 ${ttyname}${devid}${p}" >>/tmp/ttytype.${TTY}

    ttyminor=`expr $ttyminor + 1`
    i=`expr $i + 1`
    pstart=`expr $pstart + 1`
done

(
echo "chmod 0666 /dev/${ttyname}${devid}[0-9][0-9]"
echo "chmod 0666 /dev/${prname}${devid}[0-9][0-9]"
echo "chmod 0666 /dev/${cuname}${devid}[0-9][0-9]"
echo "chgrp tty /dev/${ttyname}${devid}[0-9][0-9]"
echo "chgrp tty /dev/${prname}${devid}[0-9][0-9]"
echo "chgrp tty /dev/${cuname}${devid}[0-9][0-9]"
) >>/tmp/mktty.${TTY}

sh -x /tmp/mktty.${TTY} > /dev/null 2>&1
cat /tmp/init.${TTY} >> /etc/inittab
cat /tmp/ttytype.${TTY} >> /etc/ttytype

rm -f /tmp/mktty.${TTY} /tmp/init.${TTY} /tmp/ttytype.${TTY}

printf "\b\b  Done\n"
}

#
# delete a PortServer entry
#
delete_ps()
{
while :
do
    printf "\nEnter the number of the unit to delete: "
    read del_psn
    grep "^$del_psn[^0-9]" $CONFIGFILE
    if [ $? = 1 ]
    then
	printf "Unit not found\n"
	return
    fi
    printf "\nIs this correct (y to delete or x to abort) ? "
    read ans
    if [ $ans = 'x' ]
    then
	return
    fi
    if [ $ans = 'y' ]
    then
	printf "Deleting Digi RealPort Devices, Please wait...  "
	del_ps_entry $del_psn
	printf "\b\b  Done.\n"
	break
    fi
done
}

#
# del_ps_entry - delete entry from configs file.
#
# $1 == portserver number to delete
#
del_ps_entry()
{
del_psn=$1

# try to kill the daemon if it is running
fuser -k /dev/drp${del_psn} >/dev/null 2>&1

#if [ $? != 0 ]
#then
#    printf "warning: device /dev/drp${del_psn} does not exist\n"
#fi

del_times=`grep "^${del_psn}[^0-9]" $CONFIGFILE | awk '{ print $3 }'`
del_devid=`grep "^${del_psn}[^0-9]" $CONFIGFILE | awk '{ print $4 }'`
del_devstart=`grep "^${del_psn}[^0-9]" $CONFIGFILE | awk '{ print $5 }'`
del_socket=`grep "^${del_psn}[^0-9]" $CONFIGFILE | awk '{ print $6 }'`
upper=`echo $del_devid | toupper`
lower=`echo $del_devid | tolower`

# remove line from config file
grep -v "^$1[^0-9]" $CONFIGFILE > $tmp
mv $tmp $CONFIGFILE

# remove the drp devices
rm -f /dev/drp${del_psn}
rm -f /dev/drpmon${del_psn}


char1=`expr "$del_devstart" : '\(.\)'`
char2=`expr "$del_devstart" : '.\(.\)'`
char3=`expr "$del_devstart" : '..\(.\)'`

if [ $char1 -eq 0 ]
then
     pstart=$char2
else
     pstart=$del_devstart
fi

# Loop thru each port, deleting it from /dev and from the inittab
while [ $del_times -ne 0 ]
do
        case $pstart in
                ?) p=0$pstart;;
                ??) p=$pstart;;   
                ???) p=$pstart;;
        esac

        spinner

        rm -f /dev/${ttyname}${del_devid}${p}
        rm -f /dev/${cuname}${del_devid}${p}
        rm -f /dev/${prname}${del_devid}${p}

        # remove the tty entries from the ttytype file
        grep -v "${ttyname}${del_devid}${p}" /etc/ttytype >/tmp/new_ttytype
        mv /etc/ttytype /etc/ttytype.prev
        mv /tmp/new_ttytype /etc/ttytype   

        # remove the tty entries from the inittab file
        grep -v "${ttyname}${del_devid}${p}" /etc/inittab >/tmp/new_init
        mv /etc/inittab /etc/inittab.prev
        mv /tmp/new_init /etc/inittab

        
        del_times=`expr $del_times - 1`
        pstart=`expr $pstart + 1`
        
done

}


#
# reset_ps
#
reset_ps()
{
while :
do
    printf "\nEnter the unit to reset: "
    read reset_psn
    grep "^$reset_psn[^0-9]" $CONFIGFILE
    if [ $? = 1 ]
    then
        printf "Unit not found\n"
        return
    fi
    printf "\nIs this correct (y to reset or x to abort) ? "
    read ans
    if [ $ans = 'x' ]
    then
        return
    fi
    if [ $ans = 'y' ]
    then
        # get info
        while read psn node ports name start socket encrypt encrypt_socket wan rest
        do
            if [ $psn = "#" ]
            then
                continue
            fi

            if [ $psn -eq $reset_psn ]
            then

		# try to kill the daemon if it is running
		fuser -k /dev/drp${reset_psn} >/dev/null 2>&1

		# just in case, try another method of killing it
                ps -ef | grep "${RPDAEMON} -p ${socket} -e $encrypt -q $encrypt_socket ${psn}" > /dev/null
                [ $? = 0 ] && {
		    pid=`ps -ef | grep "${RPDAEMON} -p ${socket} -e $encrypt -q $encrypt_socket ${psn}" | grep -v "grep" | awk '{print $2}'`
                    [ ! -z "$pid" ] && kill ${pid} 2>/dev/null
                }
                
                sleep 1

                # start daemon
		${RPDAEMON} -p ${socket} -e $encrypt -q $encrypt_socket ${psn} $node $wan > /dev/null 2>&1 &
                break
            fi
                            
        done < $CONFIGFILE
                            
        break
    fi
done
                                
}




#
# main body
#

if [ ! -f $CONFIGFILE ]
then
    > $CONFIGFILE
fi

while :
do
    printf "\nPlease select an option (a)dd (d)elete (s)how (r)eset (q)uit : "
    read opt

    case $opt in
    's')
	more $CONFIGFILE
	;;
    'a')
	add_ps
	;;
    'd')
	delete_ps
	;;
    'r')
	reset_ps
	;;
    'q')
	exit 0
	;;
    esac
done
