#!/bin/sh
# ifupdown hook script for enhanced MadWifi (madwifi-ng) support in
# Debian and Debian-based distributions
#
# $Id: madwifi 30 2006-09-27 10:31:23Z mrenzmann $
#
# Copyright (c) 2006 Michael Renzmann <mrenzmann@otaku42.de>
# Portions Copyright (c) 2005 Matt Brown <matt@mattb.net.nz>
#
# For further information see:
# http://projects.otaku42.de/wiki/madwifi-ifupdown
#
# This is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License version 2 as published by the Free
# Software Foundation.
#
# This is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# the madwifi-ifupdown package; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
LIBDIR=/etc/madwifi
if [ ! -d "$LIBDIR" ]; then
	echo "ERROR: $LIBDIR: no such directory"
	exit 1
fi

if [ ! -f $LIBDIR/defaults ]; then
	echo "ERROR: $LIBDIR/defaults: no such file"
	exit 1
fi
. $LIBDIR/defaults

if [ ! -f "$LIBDIR/functions.inc.sh" ]; then
	echo "ERROR: unable to load functions.inc.sh" >&2
	exit 1
fi
. $LIBDIR/functions.inc.sh


[ -x "$WLANCONFIG" ] || exit 0
[ -x "$HOSTAPD" ] || exit 0
[ -x "$IWPRIV" ] || exit 0

if [ "$VERBOSITY" -eq "0" ]; then
	exec 1>/dev/null
fi

if [ -n "$IF_ATH_PARENT" ]; then
	# the following stuff is only valid if the current interface actually is
	# recognized to be madwifi-driven

	# check if the interface has been created successfully during pre-up phase
	#
	# this is necessary because ifupdown completely ignores whether run-parts
	# reported an error or not and would continue to configure a (possibly not
	# existing) interface
	if ! $IFCONFIG $IFACE &>/dev/null; then
		error "interface creation failed in previous phase"
	fi


	# see if we need to bring up the interface
	if [ "$METHOD" = "manual" ]; then
		ifconfig $IFACE up
	fi


	# now it's time to eventually set the TX power
	if [ -n "$IF_ATH_TXPOWER" ]; then
		if isdigit $IF_ATH_TXPOWER; then
			$IWCONFIG $IFACE txpower $IF_ATH_TXPOWER || \
				error "failed to set the TX power" \
				      "to $IF_ATH_TXPOWER"
		# else: in case txpower is invalid, we already complained
		# about that in the pre-up phase
		fi
	fi


	# determine some settings that we will need for the next step(s)
	if [ -n "$IF_ATH_VAPTYPE" ]; then
		IF_ATH_VAPTYPE=$(echo $IF_ATH_VAPTYPE | tr [A-Z] [a-z])
		if [ "$IF_ATH_VAPTYPE" = "ap" ] ||
		   [ "$IF_ATH_VAPTYPE" = "master" ]; then
			VAPTYPE=ap
		else
			VAPTYPE=other
		fi
	# else use default from $LIBDIR/defaults
	fi

	if [ -n "$IF_ATH_SECURITY" ]; then
		IF_ATH_SECURITY=$(echo $IF_ATH_SECURITY | tr [A-Z] [a-z])
		case "$IF_ATH_SECURITY" in
		wpa1and2|wpa2|wpa1|wpa)
			SECURITY=wpa
		;;
		*)
			SECURITY=other
		;;
		esac
	# else use default from $LIBDIR/defaults
	fi


	# If the interface is an AP VAP, is using WPA and is NOT added to a bridge,
	# then we start hostapd here unconditionally. But if that VAP IS a bridge
	# member, then we will need to delay hostapd startup for the VAP until the
	# bridge is brought up.
	if [ "$SECURITY" = "wpa" ] && [ "$VAPTYPE" = "ap" ]; then
		if ! isbridged; then
			HOSTAPD_CFGFILE=$HOSTAPD_CFGDIR/hostapd-$IFACE.conf
			$HOSTAPD -B $HOSTAPD_CFGFILE || \
				error "failed to start hostapd"
		fi
	fi
else
	# For all other interfaces types (i.e. everything that seems not to be
	# driven by MadWifi), we need to find out if they are a bridge interface
	# and have a VAP as member. If that's the case, and if that VAP is setup
	# to use hostapd, then we can kick off hostapd now.
	if [ -n "$IF_BRIDGE_PORTS" ]; then
		vapname=
		vaptype=
		security=
		start_hostapd=
		
		while read a b rest; do
			a=$(echo $a | tr [A-Z] [a-z])
	
			case "$a" in
			iface)
				# beginning of an interface definition reached, so first
				# check if the previous definition triggers the start of
				# hostapd for it.
				if [ -n "$vapname" ] && 
				   [ "$vaptype" = "ap" ] &&
				   [ "$security" = "wpa" ]; then
					start_hostapd="$start_hostapd $vapname"
				fi
				
				# now reset the information from the previous definition
				# and start with the new one
				vapname=$b
				vaptype=
				security=
			;;
			ath_vaptype)
				b=$(echo $b | tr [A-Z] [a-z])
				if [ "$b" = "ap" ] || [ "$b" = "master" ]; then
					vaptype=ap
				else
					vaptype=other
				fi
			;;
			ath_security)
				b=$(echo $b | tr [A-Z] [a-z])
				case "$b" in
				wpa1and2|wpa2|wpa1|wpa)
					security=wpa
				;;
				*)
					security=other
				;;
				esac
			;;
			esac
		done < /etc/network/interfaces

		# the end of the interfaces-file is reached, now we only need to
		# take the last interface definition into account
		if [ -n "$vapname" ] && 
		   [ "$vaptype" = "ap" ] &&
		   [ "$security" = "wpa" ]; then
			start_hostapd="$start_hostapd $vapname"
		fi

		# now start hostapd for any interface listed in start_hostapd
		for i in $start_hostapd; do
			HOSTAPD_CFGFILE="$HOSTAPD_CFGDIR/hostapd-$i.conf"
			
			if [ ! -f $HOSTAPD_CFGFILE ] &&
			   [ ! -L $HOSTAPD_CFGFILE ]; then
				error "can not start hostapd for $i:" \
				      "$HOSTAPD_CFGFILE not found"
			fi
			if ! $IFCONFIG $vapname &>/dev/null; then
				error "can not start hostapd for $i:" \
				      "no such interface"
			fi
			
			$HOSTAPD -B $HOSTAPD_CFGFILE || \
				error "failed to start hostapd for $i"
		done
	fi
fi

# that's all, folks!
exit 0
