#!/bin/sh

if [ "`id -u`" != "0" ]; then
	cmdline="$0 "
	for i in "$@"; do
		cmdline="${cmdline} \"$i\""
	done
	echo $cmdline | su
	exit $?
fi
	

LOCALBASE=/usr/local
STATEDIR=$LOCALBASE/etc/states/
_state=$1
set -e
if [ ! -d $STATEDIR/$_state ]; then
    echo "No such state: $_state"
    exit 1
fi
if [ ! -f $STATEDIR/$1/laptop-start -o \
     ! -x $STATEDIR/$1/laptop-start ]; then
     echo "Missing laptop-start for state $_state"
     exit 1
fi

#
# Replace or add a route.
#
# Usage:
#	route_set target gateway
# 
# Example:
#	route_set default 192.168.0.1
#
route_set()
{
	if !(route -n change $1 $2 > /dev/null 2>&1 || route -n add $1 $2 > /dev/null 2>&1)
	then
		echo "Unable to set route!" 1>&2
		exit 1
	fi
}

#
# Wait until NIC is available
#
# Usage:
#	find_card nic
#
# Example:
#	find_card fxp0
#
find_card()
{
	local hasiface

	echo -n ">>> Finding network card $1"
	hasiface=NO
	for i in 1 2 3 4 5 6 7 8 9 . 1 2 3 4 5 6 7 8 9; do
		if [ "$hasiface" = "NO" ]; then
			if ifconfig $1 > /dev/null 2>&1; then
				hasiface=YES
			else
				echo -n "."
				sleep 1
			fi
		fi
	done
	echo
	if [ "$hasiface" != "NO" ]; then
		echo '>>> Network card found'
	else
		echo '>>> Network card not found - exiting'
		exit 1
	fi
	return 0
}

#
# Set up a static IP based on the variables
#	NIC	- Network interface card to use
#	netmask	- Netmask to use, default to CIDR/24
#	mainip	- The IP to set up
#	defaultrouter	- The default gateway to use
#
staticip()
{
	find_card $NIC
	echo ">>> Stopping DHCP and configuring statically"
	/usr/bin/killall dhclient 2>&1 | grep -v 'No matching process' || true
	echo ">>> Main IP:       $mainip / $netmask"
	# Work around bug in ifconfig, which does not clear the NIC when
	# an IP already on the interface is reconfigured
	ifconfig $NIC delete > /dev/null 2>&1 || true
	ifconfig $NIC $mainip netmask $netmask
	echo ">>> Default route: $defaultrouter"
	route_set default $defaultrouter
}

#
# Set up a DHCP address, including ability to override the resolv.conf we get
# from the DHCP server.
#
dynamicip()
{
	find_card $NIC
	echo ">>> Stopping and restarting DHCP"
	/usr/bin/killall dhclient 2>&1 | grep -v 'No matching process' || true
	if [ -e $STATEDIR/$_state/resolv.conf ]; then
		chflags noschg /etc/resolv.conf
		cp $STATEDIR/$_state/resolv.conf /etc/resolv.conf
		chflags schg /etc/resolv.conf
	fi
	dhclient $NIC
}

#
# Set up defaults for variables - can be overridden in laptop-start
#
if [ -e $STATEDIR/NIC ]; then
	NIC=`cat $STATEDIR/NIC`
else
	NIC=`ifconfig -l ether | sed 's| .*||'`
fi
netmask="0xffffff00"
#
# Calculate likely default route - must be fixed up to be acutally useful
#
#echo inet 62.179.129.117 netmask 0xfffffff8 broadcast 62.179.129.119| perl -ne 'm|inet\s+(\d+)\.(\d+)\.(\d+)\.(\d+)\s+netmask\s+0x(\S+)|; print "$1.$2.$3.$4\n"; $a = (($1*256 + $2)*256 + $3)*256 + $4; $a &= hex($5); $a++; printf("%d.%d.%d.%d\n", $a>>24, ($a>>16)&255, ($a>>8)&255, $a&255);'


echo ">> Switching laptop state to $_state"
echo ">>> Copying config files"
chflags noschg /etc/resolv.conf
cd $STATEDIR/$_state
tar cf - . | tar -C /etc -xpvf -
echo ">>> Executing setup script"
. /etc/laptop-start

if [ -x $LOCALBASE/sbin/postfix ]; then
	echo '>>> Doing postfix exchange'
	$LOCALBASE/sbin/postfix flush
fi

# Work around bug where suspend/resume lose the mixer state in the
# hardware, even though the software says the mixer is set.
(mixer cd `mixer cd | awk '{print $7}' 2> /dev/null`) > /dev/null 2>&1 || true
echo ">> Laptop state switch done"
