#!/bin/sh
# mugetty: rustic getty/agetty/mgetty replacemnt
# (C) M. Andreoli 2000, for muLinux

export PATH=/bin:/usr/bin:/usr/sbin:/usr/local/bin
VERSION=0.3
TIMEOUT=3600
SANE="CS8 CSTOPB -PARENB IGNPAR OPOST ECHOK IEXTEN"

FLOW_DIRECT="-CRTSCTS -IXON -IXOFF -IXANY" # simple null-modem
FLOW_MODEM="CRTSCTS -IXON -IXOFF IXANY"

CHAT_SCRIPT=/etc/ppp/chat 
CHAT_LOG=/tmp/chat.log ; > $CHAT_LOG
PPP_OPTIONS=/etc/ppp/dialin.opt

#set -x

usage()
{
cat <<END
mugetty v$VERSION, rustic getty replacement (C)2000 M. Andreoli
Usage: mugetty [options] tty
Options are:
	-v			verbose mode 
	-a			auto-answer (no RING-RING required)
	-x program		program to execute (def: /bin/login)
	-s speed		baud speed 19200,38400,57600,115200,...
        -ppp                    Auto-PPP mode; starts pppd using
                                the $PPP_OPTIONS file
        -ip [local]:remote      Auto-PPP mode: using internal sane
                                defaults, and these ip-addresses
        +pap                  	request peer to authenticate itself 
				with PAP (default: no auth) 

Log file is /var/log/mugetty.log
 
END
exit 0
}

parse_command_line()
{
set -- $@
[ $# = 0 ] && usage


while [ $# != 0 ]; do
case $1 in
-a)     modem_model=ata;
        shift
        ;;
-s)    	# baud
	shift; SPEED=$1
        shift
        ;;
-x)    	# command to execute, ex /bin/login 
	shift; EXE=$1
        shift
	mode=program
        ;;
-ip)   # Auto-PPP mode (using internal defaults) and this IP 
	mode=pppd	
	shift; IP=$1
        shift
        ;;
+pap) 	# PAP authentication 
	auth="+pap";
        shift
        ;;
-ppp)   # Auto-PPP mode (using /etc/opt.tty)
        mode=pppd; IP=
        shift
        ;;

-v)    	# verbose mode 
	VERBOSE=yes ; shift
        ;;
-h)     usage
        ;;
-*)	
	echo "Unsupported option. Please, do not combine options"
	usage
	;;
*)      TTY=$1 ; shift
        ;;
esac
done

# fix is user specify /dev/

case $TTY in
/dev/*)		TTY=`basename $TTY`;;
esac

DEVICE=/dev/$TTY

}

debug()
{
[ "$VERBOSE" ] && echo -e "mugetty: $@"
echo -e "mugetty: $@" >> /var/log/mugetty.log
}

quit()
{
debug "quitting ..."
case $HAVE_MODEM in
yes)
	hangup;;
*)
esac
exit 0
}

hangup()
{
sleep 1
for a in 1 2 3 4 5 6 7 8 9
do
chat -t 2 '' AT OK '+++ATH0' OK < $DEVICE > $DEVICE &&\
 debug "modem hungup" && return 
done
return
}

STTY()
{
debug "stty $@ ..."
stty $@ < $DEVICE > $DEVICE
debug "stty done"
}

init_serial()
{
debug "Initializing $DEVICE ..."
STTY $SANE $SPEED
}

probe_modem()
{
HAVE_MODEM=no
debug "Probe modem"
chat -t 1 '' AT OK < $DEVICE > $DEVICE
rc=$?
[ $rc -eq 0 ] && HAVE_MODEM=yes

if [ $HAVE_MODEM = yes ] ; then
	debug "found."
	STTY $FLOW_MODEM $SPEED
else
	debug "not found. Assume direct line."
	STTY $FLOW_DIRECT $SPEED
fi

return $rc 
}

trap quit 2 


load_drivers()
{
if [ -z "`cat /proc/devices|rgrep ttyS`" ] ; then
	insmod serial
	setserial -b $DEVICE auto_irq autoconfig session_lockout
fi

if [ -z "`lsmod|rgrep ppp`" ] ; then
	insmod slhc; insmod ppp
fi
}

# start pppd

start_pppd()
{

# pppd options

OPT="local -detach -chap $auth"

if [ $HAVE_MODEM = yes ] ; then
	OPT="$OPT crtscts"
else
	OPT="$OPT -crtscts"
fi

case $IP in
noipdefault)
	OPT="$OPT defaultroute passive noipdefault"
	;;
*:*)
	OPT="$OPT -defaultroute $IP"
	;;
*)	# overwrite using a user-supplied file
	OPT="$OPT file $PPP_OPTIONS" 
	;;
esac

OPT="$OPT connect $CHAT_SCRIPT" 

load_drivers
debug "Starting pppd (auth $auth) ..."
debug pppd $DEVICE $SPEED $OPT $CONNECT 
pppd $DEVICE $SPEED $OPT $CONNECT 
debug "pppd, closing connection: return code $?"
speed=`get_speed`
debug "Speed was: $speed"
sleep 2
}

start_program()
{
debug "Waiting for activity on $DEVICE"
eval $CHAT_SCRIPT < $DEVICE > $DEVICE
while [ 1 ]; do
timeout 2 < $DEVICE > /dev/null && break 
done 
debug "detected!"
speed=`get_speed`
debug "Speed is: $speed"

debug "Starting $EXE"
cat <<END | unix2dos > $DEVICE

Welcome to muLinux v`cat /etc/version`!
Host [`hostname`/`fqn`], date [`date`], tty [$TTY]
END
eval $EXE < $DEVICE > $DEVICE
}

make_chat_script()
{

if [  "$HAVE_MODEM" != yes ]; then
	echo "timeout 10 && return 1; return 0" > $CHAT_SCRIPT
	return 
fi

if [ "$modem_model" = "ring" ] ; then
cat > $CHAT_SCRIPT <<END
#!/bin/sh
#while [ 1 ] ; do
exec chat -t 180 -v -r $CHAT_LOG REPORT CONNECT '' ATZ OK ATX3 OK ATL0M0 OK ATS0=2 CONNECT '\d\c'
#done
END

else

timeout=14

cat > $CHAT_SCRIPT <<END
#!/bin/sh
chat -v '' ATZ OK ATX3 OK ATL0M0 OK
while [ 1 ] ; do
chat -v -r $CHAT_LOG -t $timeout REPORT CONNECT '' ATA CONNECT '\d\c' && exit 0
done
END

fi
chmod +x $CHAT_SCRIPT 
}

get_speed()
{
[ ! -s $CHAT_LOG ] && return 1
speed=`cat $CHAT_LOG | rgrep CONNECT | sed "s/.*CONNECT//g"`
[ "$speed" ] && echo $speed
}

#---------
# Main
#---------
# defaults:
VERBOSE=
EXE=/bin/login
SPEED=115200
auth="-pap"
mode=program
modem_model=ring

wave -c 220 1
parse_command_line $@
debug "-----> mugetty (rustic mgetty) v$VERSION started at `date`"
debug "DEVICE=$DEVICE, SPEED=$SPEED, EXE=$EXE, mode=$mode, $modem_model"

init_serial
probe_modem
make_chat_script
eval start_$mode
quit
exit

# End
