#!/bin/tcsh -f
#

echo "`date` SCRIPT STARTED"
set n = $argv[1]
cd /etc/slip

# step 1, defaults
#

set if_addr	= ""
set if_localnet	= ""
set if_broadcast = ""
set if_netmask	= "255.255.255.0"

set f_disable	= "disable$n"
set f_restart	= "restart$n"
set f_kill	= "kill$n"
set f_pause	= "pause$n"
set f_pid	= ".pid$n"

set prefix	= "sl"
set device	= "/dev/cua0"
set speed	= "19200"
set ducmds	= ""

# sleep1 - short sleep
# sleep2 - long sleep
#

set sleep1	= 10
set sleep2	= 10
set cd1cmds	= echo
set cd0cmds	= echo

# step 2, configuration
#

if ( -f slip$n.cfg ) then
    set interface = '$interface'
    source slip$n.cfg
    unset interface
endif

# step 3, kill any existing script
#

if ( -f $f_pid ) then
    set pid = `cat $f_pid`
    if ( -d /proc/$pid ) then
        touch $f_kill
        echo -n "`date` killing existing script pid $pid: "
        set loop = ""
        sleep 5
        while ( -f $f_kill )
            if ( $loop == "00000000000000000000" ) then
                echo -n " gave up"
                break
	    endif
            sleep $sleep1
            set loop = 0$loop
            echo -n 0
        end
        echo ""
        unset loop
        rm -f $f_kill
    endif
    unset pid
endif

# step 4, setup our pid and start our script
#

echo $$ >$f_pid

set state = idle
set pid = 0
set isfailed = 0
set isdisabled = 0

while ( 1 )

    # *******************************************************************
    # KILL
    #

    if ( -f $f_kill ) then
    	break
    endif

    if ( -f $f_restart ) then
        break
    endif

    # PAUSE
    #

    if ( -f $f_pause ) then
        sleep $sleep1
        continue
    endif

    # DISABLE
    #

    if ( -f $f_disable ) then
        if ( $state == idle ) then
	    if ( $isdisabled == 0 ) then
		set isdisabled = 1
		echo "`date` DISABLED"
	    endif
	    sleep $sleep1
	    continue
	endif
    else
        if ( $isdisabled == 1 ) then
            set isdisabled = 0
            set isfailed = 0
            echo "`date` REENABLING"
        endif
    endif


    # *******************************************************************
    # STATE
    #

    # IDLE - attempt to connect
    #
    # if the connection has failed we have to sleep here because we didn't
    # in the failed state (so on disable the fail would loop to disable and
    # print the disabled message immediately)

    if ( $state == "idle" ) then
        if ( $isfailed == 0) then
	    echo "`date` dudiscdev -i $prefix -r $isfailed -d $device -s $speed $ducmds"
	else
	    echo -n "D"
	    sleep $sleep2
        endif

	set pid = `dudiscdev -i $prefix -r $isfailed -d $device -s $speed $ducmds`
	set interface = ""
	set state = "connecting"
	continue
    endif

    # CONNECTING - wait for connect to succeed or fail
    #

    if ( $state == "connecting" ) then
        if ( -d /proc/$pid ) then
	    set interface = ( `cat /proc/$pid/cmdline` )
	    set interface = $interface[1]

	    if ( "$interface" == "sl0" || \
	    	 "$interface" == "sl1" || \
	    	 "$interface" == "sl2" || \
	    	 "$interface" == "sl3" || \
	    	 "$interface" == "sl4" || \
	    	 "$interface" == "sl5" || \
	    	 "$interface" == "sl6" || \
	    	 "$interface" == "sl7" \
	    ) then
	        # sleep 1 second to allow carrier detect to be established
	        # after modem supplies CONNECT message
	        sleep 1
	     	set state = "connected"

	     	if ( $isfailed == 1) then
	     	    echo ""
	     	endif

	     	echo "`date` connected on interface $interface pid $pid"
	     	set isfailed = 0

	     	# execute cdcmds
	     	#

	     	eval $cd1cmds
	    else
	    	set interface = ""
	        sleep 5
	    endif
	else
	    # note: cd0cmds not run since cd1cmds wasn't run
	    #
	    set state = "failed"
	    set pid = 0
	    unset interface
	endif
	continue
    endif

    # CONNECTED - wait for carrier to drop
    #

    if ( $state == "connected" ) then
    	if ( -d /proc/$pid ) then
    	    if ( -f $f_disable) then
    	        kill $pid
	    else
		sleep $sleep2
    	    endif
	else
	    set state = "failed"
	    set pid = 0

	    # execute commands for cd failure
	    #

	    eval $cd0cmds
	    unset interface
	endif
	continue
    endif

    # FAILED - output message and then sleep.  Short sleep after an
    #          initial failure, long sleep otherwise.  The message
    #	       is only output on initial failure
    #

    if ( $state == "failed" ) then
	if ( $isfailed == 0 ) then
	    echo "`date` connection failure"
	else
	    echo -n "F"
	endif

        sleep 2
        set state = "idle"
        set isfailed = 1
        continue
    endif

    echo "`date` unknown state: $state"
    break
end

# KILL OR RESTART
#

if ( -f $f_restart ) then
    echo "`date` RESTART SELF pid=$$"
    set cmd = "exec $0 $argv"
else
    set cmd = "echo"
endif

if ( $pid != 0 ) then
    kill $pid
    eval $cd0cmds
    set pid = 0
    unset interface
    sleep 1
endif
rm -f $f_kill $f_restart $f_pause $f_pid
$cmd

echo "`date` SCRIPT TERMINATED"

