#!/usr/local/sbin/slipsh
#
# Sample slips script. Customize by setting the variables below
# to apropriate values. Mode can be one of SLIP, CSLIP, ADAPTIVE,
# and SLIP6.
#
# This script takes up two SLIP links, and enables Don Becker's slave
# load balancing. It waits until the master link comes down, or
# until the link pair has been idle for some predefined time.
#
# First, the master connection
set m_device	ttyS1
set m_telno	555-1234
set m_login	joedoe
set m_passwd	melrose
set m_mode	CSLIP
set m_local	myhost.fnord.org
set m_remote	otherhost.foobar.com
# Here comes the slave connection
set s_device	ttyS2
set s_telno	555-1235
set s_login	joedoe-slave
set s_passwd	melrose
set s_mode	$m_mode
set s_local	$m_local
set s_remote	$m_remote
set inactive	360

set retries	6
set slave_ok	1

source /usr/local/lib/slipsh/common.tcl

#
# lock and open m_devices
#
tty lock $m_device
tty lock $s_device
set m_ttyfd [tty open -user root -group tty -mode 0664 $m_device]
set s_ttyfd [tty open -user root -group tty -mode 0664 $s_device]

#
# First, dial up the master and log in
#
set dial [dialup $m_device $m_ttyfd $m_telno $m_login $m_passwd $retries];
if {$dial != ""} {
        tty close $m_ttyfd
        tty unlock $m_device
        exit 2
}

#
# Now, dial up the slave. If this fails, we run a normal SLIP link
# without load balancing.
#
set dial [dialup $s_device $s_ttyfd $s_telno $s_login $s_passwd $retries];
if {$dial != ""} {
	puts stderr "Failed to connect to SLIP server on slave line";
	puts stderr "$chatFailCode";
	puts stderr "Continuing with one line only"
        tty close $s_ttyfd
        tty unlock $s_device
	set slave_ok 0
}

#
# Convert line to SLIP, set slave mode, and add standard set of routes.
#
set m_iface [setslip $m_mode $m_ttyfd $m_local $m_remote]
route add $m_remote dev $m_iface
route add default gw $m_remote

if {$slave_ok != 0} {
	set s_iface [setslip $s_mode $s_ttyfd $s_local $s_remote]
	ifconfig $m_iface slave $s_iface
}

#
# Become daemon. We first install the HUP handler, then fork and make
# the master device the controlling tty.
# This is followed by some tricky code that deals with monitoring of
# the slave line.
#
sys signal SIGHUP \
	"tty close $m_ttyfd; tty unlock $m_device;\
	 tty close $s_ttyfd; tty unlock $s_device;"

set pid [sys fork -tty $m_ttyfd];

if {$pid != 0} {
	# We're the parent process. Write the system lock and exit.
	set fd [open "/tmp/slips.$remote" "w"];
	puts $fd "$pid"
	exit 0
}

# 
# Okay, we're now the daemon process, and we have the master tty
# as our controlling tty. If the slave is operational, we fork another
# process that has the slave tty as its ctty.
#
if {$slave_ok != 0} {
	set pid [sys fork -tty $s_ttyfd];
	if {$pid != 0} {
		# We're the master daemon
		sys signal SIGHUP \
			"tty close $m_ttyfd; tty unlock $m_device;\
			 sys signal SIGCHLD {};\
			 sys kill SIGHUP $pid;"
		sys signal SIGCHLD {
			 puts stderr "Ooops, the slave daemon just died.."
			 }
	} else {
		# We're the slave daemon
		sys signal SIGHUP "tty close $s_ttyfd; tty unlock $s_device;"
		sys pause
	}
}

#
# Loop and check the interface stats every $inactive seconds.
#
# Note that only the master daemon monitors traffic on the link.
# This is because in a low-traffic situation (e.g. where the
# the link is kept open only by a ping process), the slave may
# not see any packets for a very long time, but the link should
# still be kept up.

net ifstats -ipackets ipkt -opackets opkt $m_iface
while 1 {
	sys sleep $inactive
	net ifstats -ipackets ipktnew -opackets opktnew $m_iface
	if {$ipkt == $ipktnew && $opkt == $opktnew} {
		# harikari!
		sys kill SIGHUP 0
	}
	set ipkt $ipktnew
	set opkt $opktnew
}
