#! /bin/bash
#
# network       Bring up/down networking
#
# chkconfig: 345 15 90
# description: Activates/Deactivates all network interfaces configured to \
#              start at boot time.
# probe: true

shopt -s extglob
CONFIGS="/etc/config.d/network"
IFPLUGD=$(which ifplugd 2> /dev/null)
WPA_SUPPLICANT=$(which wpa_supplicant 2> /dev/null)
IFCONFIG=$(which ifconfig 2> /dev/null)
IWCONFIG=$(which iwconfig 2> /dev/null)
ROUTE=$(which route 2> /dev/null)
PPPD=$(which pppd 2> /dev/null)

chkresult()
{
	if [ $? -eq "255" ] ; then
		echo -e $RESULT_FAIL
	elif [ $? -eq "253" ]; then
		echo -e $RESULT_WARN
	else
		echo -e $RESULT_OK
	fi
}

function start_dhcp()
{
	# include config file for interface
	source $CONFIGS/$1
	
	case $DHCP_CLIENT in
			[dD][hH][cC][pP][cC][dD])
			PIDFILE=/var/run/dhcpcd-$1.pid
			RUNFILE=$(which dhcpcd 2> /dev/null)
		;;
			
			[dD][hH][cC][lL][iI][eE][nN][tT])
			PIDFILE=/var/run/dhclient-$1.pid
			RUNFILE=$(which dhclient 2> /dev/null)
			DHCP_OPTIONS="$DHCP_OPTIONS -pf $PIDFILE -lf /var/state/dhcp/dhclient-$1.leases"
		;;
			
			[uU][dD][hH][cC][pP][cC])
			PIDFILE=/var/run/udhcpc-$1.pid
			RUNFILE=$(which udhcpc 2> /dev/null)
			DHCP_OPTIONS="$DHCP_OPTIONS -p $PIDFILE -i"
		;;
	esac

	if [ ! -x $RUNFILE ]; then
		echo -n " $DHCP_CLIENT not installed"
		return 255
	fi

	if [ -e $PIDFILE ]; then
		if [ $(ps ax | grep `cat $PIDFILE` | grep $DHCP_CLIENT | grep -v grep | wc -l) -ge 1 ]; then
			echo -n " $DHCP_CLIENT already started"
			return 253
		else
			rm -f $PIDFILE
		fi
	fi

	# This is where the magic happens
	$RUNFILE $DHCP_OPTIONS $1 > /dev/null 2>&1
	DHCP_EXIT=$?
	sleep 1

	if [ ! -e $PIDFILE ]; then
		if [ $DHCP_EXIT -eq 0 ]; then
			echo -n "DHCP exited cleanly"
			return 253
		else
			echo -n "DHCP failed"
			return 255
		fi
	fi
}

function stop_dhcp()
{
	# Include configuration file
	source $CONFIGS/$1
	
	case $DHCP_CLIENT in
			[dD][hH][cC][pP][cC][dD])
			KILLCMD="dhcpcd -k $1"
			PIDFILE=/var/run/dhcpcd-$1.pid
		;;
		
			[dD][hH][cC][lL][iI][eE][nN][tT])
			PIDFILE=/var/run/dhclient-$1.pid
		;;

			[uU][dD][hH][cC][pP][cC])
			PIDFILE=/var/run/udhcpc-$1.pid
		;;
	esac

	if [ -e $PIDFILE ]; then
		if [ -z "$KILLCMD" ]; then
			kill `cat $PIDFILE`
		else
			$KILLCMD
		fi

		if [ -e $PIDFILE ]; then
			rm -f $PIDFILE
		fi
		sleep 1
	fi
}

function device_start()
{
	if [ ! -e "$CONFIGS/$1" ]; then
		echo  -n "missing config file"
		exit 1
	fi

	# include config file for interface
	source $CONFIGS/$1

        # be sure that the interface is ment to be started on boot
	if [ "$2" == "auto" ] ; then
		case "$AUTO" in
		    [!yY])
		    echo -n "not started automatically"
			return 254
		    ;;
		esac
	fi

	# load module if specified
	if [ -n "$MODULE" ]; then
		modprobe $MODULE $MODULE_OPTIONS
	fi

	if [ "$MANAGER" == "wpa_supplicant" ] ; then
		if [ -x $WPA_SUPPLICANT ] && [ -x $IFPLUGD ] ; then
			# bring the interface up
			$IFCONFIG $1 up

			# remove any and all essid
			$IWCONFIG $1 essid any

			# enable D-Bus control interface if D-Bus is running
			if [ -x "/etc/init.d/messagebus" ]; then
				if (/etc/init.d/messagebus status | grep OK) &>/dev/null; then
					WPA_SUPPLICANT_FLAGS="$WPA_SUPPLICANT_FLAGS -u"
				fi
			fi

			# FIXME: Make the config file configurable. 
			# Also, rely on the configuration to determine whether or not the interface is enabled
			$WPA_SUPPLICANT $WPA_SUPPLICANT_FLAGS -B -Dwext -i$1 -c/etc/wpa_supplicant.conf

			# finally start ifplugd
			if ! $IFPLUGD -c -i $1 &> /dev/null ; then
				$IFPLUGD -I -i $1 -f -r /etc/ifplugd/ifplugd-lunar.action
			fi

		else
			echo -n " ERROR: wpa_supplicant and/or ifplugd are missing!"
			return 255
		fi

	elif [ "$MANAGER" == "ifplugd" ] ; then
		if [ -x $IFPLUGD ] ; then
			if ! $IFPLUGD -c -i $1 &> /dev/null ; then
				$IFPLUGD -I -i $1 -f -r /etc/ifplugd/ifplugd-lunar.action
			fi
		else
			echo -n " ERROR: ifplugd is missing!"
		fi

	elif [ "$MANAGER" == "pppd" ] ; then
		if [ -x $PPPD ] ; then
			ps     -C     pppd     >  /dev/null  &&
			pkill  -15  "^pppd$"                 &&
			sleep   5
			$PPPD call $1 &> /dev/null
		else
			echo -n " ERROR: pppd is missing!"
		fi

	elif [ "$MANAGER" == "manual" ] || [ -z "$MANAGER" ] ; then
		if [ "$WIRELESS" == "Y" ] && [ -x $IWCONFIG ] ; then
			if [ ! "x$WIRELESS_MODE" == "x" ] ; then
				$IWCONFIG $1 mode $WIRELESS_MODE
			fi

			if [ ! "x$WIRELESS_KEY" == "x" ] ; then
				$IWCONFIG $1 key $WIRELESS_KEY
			fi

			if [ ! "x$WIRELESS_RATE" == "x" ] ; then
				$IWCONFIG $1 rate $WIRELESS_RATE
			fi

			if [ ! "x$WIRELESS_ESSID" == "x" ] ; then
				$IWCONFIG $1 essid $WIRELESS_ESSID
			fi
		elif [ "$WIRELESS" == "Y" ] ; then
			echo -n " ERROR: wireless_tools not installed!"
			return 255
		fi
	  
		# Assume direct DHCP/static IPs if no manager/manual is set
		if [ "$ADDRESS" == "dhcp" ] && [ ! "x${DHCP_CLIENT}" == "x" ] ; then
				start_dhcp $1
		elif [ ! "x${ADDRESS}" == "x" ] ; then
			if [ ! "x$NETMASK" == "x" ]; then
				NETMASK="netmask $NETMASK"
			fi

			if [ ! "x$BROADCAST" == "x" ]; then
				BROADCAST="broadcast $BROADCAST"
			fi

			# If there is an address then ifconfig will be able to bring up the device anyway
			# so no error handling here
			$IFCONFIG $1 ${ADDRESS} $IFCONF_OPTS $NETMASK $BROADCAST up >/dev/null 2>&1
		fi
	else
		echo -n " ERROR: No address specified and DHCP not configured!"
		return 255
	fi

	# Now for the static routes
	# FIXME: This is not configurable through lnet anymore

        for ROUTECMD in "$ROUTE_1" "$ROUTE_2" "$ROUTE_3" "$ROUTE_4" ; do
		if [ ! "x$ROUTECMD" == "x" ] ; then
			echo -e "\n    adding route: $ROUTECMD"
			$ROUTE $ROUTECMD
		fi
	done
}

function device_stop()
{
	if [ ! -e "$CONFIGS/$1" ]; then
		echo -n " missing config for $1"
		return 255
	fi

	# Source configuration file
	source $CONFIGS/$1

	for ROUTECMD in "$ROUTE_4" "$ROUTE_3" "$ROUTE_2" "$ROUTE_1" ; do
		if [ -n "$ROUTECMD" ] ; then
			if $(echo $ROUTECMD | grep -q "^add ") ; then
				ROUTECMD=$(echo $ROUTECMD | sed 's/^add /del /')
			elif $(echo $ROUTECMD | grep -q "^del ") ; then
				ROUTECMD=$(echo $ROUTECMD | sed 's/^del /add /')
			fi
			echo -e "\n    deleting route: $ROUTECMD"
		$ROUTE $ROUTECMD
		fi
	done

	if [ `ifconfig | grep $1 | wc -l` -ne 1 ]; then
		case $AUTO in
		    [!yY])
			echo -n " not started"
			return 255
		    ;;
		esac
	fi

	if [ "$MANAGER" == "ifplugd" ] || [ "$MANAGER" == "wpa_supplicant" ] || [ "$MANAGER" == "pppd" ]; then
		case $MANAGER in
		    ifplugd)
			$IFPLUGD -r /etc/ifplugd/ifplugd-lunar.action -i $1 -k
			sleep 1
		    ;;
		    wpa_supplicant)
			$IFPLUGD -r /etc/ifplugd/ifplugd-lunar.action -i $1 -k
			kill `ps ax | grep wpa_supplicant | grep "$1" | awk '{print $1}'`
			sleep 1
		    ;;
		    pppd)
			pkill -15 "^pppd$"
			sleep 1
		    ;;
		esac
	fi

	if [ "$ADDRESS" == "dhcp" ] && [ ! "x${DHCP_CLIENT}" == "x" ] ; then
		stop_dhcp $1
	fi
	
        if [ ! "${1:0:3}" == "ppp" ] ; then
                $IFCONFIG $1 down
        fi

	if [ -n "$MODULE" ]; then
		modprobe -r $MODULE
	fi
}

export -f device_start device_stop start_dhcp stop_dhcp

start()
{
	# Do startup for all interfaces if none is specified
	if [ -z "$2" ]; then
		echo "Starting network:"
		# Add routing entry for loopback interface
		if [ ! $($ROUTE -n | grep 127.0.0.0 | wc -l) -ge 1 ]; then
			echo -n " * Starting lo: "
			$IFCONFIG lo 127.0.0.1 netmask 255.0.0.0
			$ROUTE add -net 127.0.0.0 netmask 255.0.0.0 dev lo
			echo -e $RESULT_OK
		fi

		for device in `ls -1 $CONFIGS | cut -d"-" -f1 | uniq`; do
			echo -n " * Starting $device: "
			device_start $device auto
			chkresult
		done

		if [ -e /etc/config.d/gateway ]; then
			GATEWAY=`cat /etc/config.d/gateway`
			if [ -n "$GATEWAY" ] && ! ($ROUTE -n | grep -q "^0\.0\.0\.0.*UG.*$") ; then
				echo -n " * setting default route: "
				$ROUTE add default gateway $GATEWAY
			fi

			if [ `route -n | grep $GATEWAY | wc -l` -lt 1 ]; then
				echo -n "failed to set gateway"
				echo -e $RESULT_FAIL
			else
				echo -e $RESULT_OK
			fi
		fi
	else
		echo -n " * Starting $2: "
		device_start $2
		chkresult
	fi
}

stop()
{
	if [ -z "$2" ]; then
		echo "Stopping network:"
		for device in `$IFCONFIG | cut -d" " -f1 | uniq | grep -E [a-z0-9]+ | grep -v lo | sort -r`; do
			echo -n " * Stopping $device: "
			device_stop $device auto
			chkresult
		done
	else
		echo -n " * Stopping $2: "
		device_stop $2
		chkresult
	fi
}

restart()
{
	if [ -z "$2" ]; then
		echo "Restarting network:"
		for device in `ls -1 $CONFIGS | cut -d"-" -f1 | uniq`; do
			echo -n " * Stopping $device: "
			device_stop $device auto
			chkresult
			echo -n " * Starting $device: "
			device_start $device auto
			chkresult
		done
	else
		echo -n " * Stopping $2: "
		device_stop $2
		chkresult
		echo -n " * Starting $2: "
		device_start $2
		chkresult
	fi
}

dhcp_up()
{
	start_dhcp $2
}

dhcp_down()
{
	stop_dhcp $2
}

case "$1" in
	start|stop|dhcp_up|dhcp_down|restart)
		;;
	
	*)
		echo "Usage: $0 {start|stop|restart} [device]"
		exit 0
		;;
esac

. /lib/lsb/init-functions
