#!/bin/bash
# Begin $network-devices/services/wpa-service
# wpa-service 0.21
# Based on dhcpcd script adapted for wpa networks with or without dhcp support
# Rewritten by Eloi Primaux  - eloi AT bliscat DOT org
# 2006-02-20 First script
# 2006-03-31 wpa-service is functional
# 2006-08-21 version by Maarten Lankhorst - m.b.lankhorst.(@).gmail.com
# 2006-10-15 0.2 release by Eloi Primaux
#	     merging Maarten work into configure_network function
#	     can use both wpa_cli -a function and ifplugd.
# 2007-02-14 0.21 ifplugd support removed
#            wait_for_up removed
#            status* and available_network* functions removed

IFACE=$1
BRING=$2

. /etc/sysconfig/rc
. $rc_functions
. $IFCONFIG
. /etc/sysconfig/wpa-service/wpa-service.conf

function get_real_pid {
	if [ -e $1 ]; then
	RET=`fuser $1` 2> /dev/null
	else
	return 1
	fi
}

function wpa_is_up {
	get_real_pid $WPA_GLOBAL_FILE
	if [ $? != 0 ]; then
		return 2
	fi
}

function wpa {
	wpa_is_up
	if [ $? != 0 ]; then
		verbose '' "$WPA_DAEMON_NAME isn't running, please check why"
		if [ $BRING != "UP" ]; then
			return 1
		else
			exit 1
		fi
	fi
}

function is_iface_not_managed {
	[ -n "`get_real_pid $WPA_ACCESS_DIR/$IFACE`" ] && return 2
}

function verbose {
	[ "$VERBOSE" == "YES" ] && boot_mesg $1 "$2"
}

function test_fail {
	[ "$1" != 0 ] && RET="FAIL:$1"
	verbose '' " $RET"
	if [[ $RET = FAIL* ]]; then
		echo_failure ; return 2
	else
		return $1
	fi
}

function add_iface {
	verbose -n "$WPA_CLIENT_NAME -g$WPA_GLOBAL_FILE interface_add $IFACE '' $WPA_DRIVER $WPA_ACCESS_DIR :"
	RET=`$WPA_CLIENT_NAME -g$WPA_GLOBAL_FILE interface_add $IFACE '' $WPA_DRIVER $WPA_ACCESS_DIR` 2> /dev/null
	test_fail $?
}

function ctrl_iface {
	verbose -n "$WPA_CLIENT_NAME -i$IFACE $@ :"
	RET=`$WPA_CLIENT_NAME -i$IFACE $@` 2> /dev/null
	test_fail $?
}

function remove_iface {
	verbose -n "$WPA_CLIENT_NAME -g$WPA_GLOBAL_FILE interface_remove $IFACE :"
	RET=`$WPA_CLIENT_NAME -g$WPA_GLOBAL_FILE interface_remove $IFACE` 2> /dev/null
	test_fail $?
}

function configure_network {
	#Read the wpa config file
	LINENUMBER=0
	CONFIGFILE="$WPA_KEY_DIR/$WPA_KEY_FILE"
	LINES="$(wc -l $CONFIGFILE | sed 's/ .*//')"
	while [ "$LINENUMBER" -lt "$LINES" ]
	do
		verbose '' "NETWORK=$NETWORK"
		# Increase line number
		let ++LINENUMBER
		verbose '' "Parsing line ${LINENUMBER}"
		# Fetch a line
		preline="$(head -n $LINENUMBER $CONFIGFILE | tail -n 1)"
		# Remove everything after a '#' (comment)
		line="$(echo $preline | sed -e 's/#.*//')"

		#echo "Parsing $LINENUMBER: '$preline' => '$line'"

		if [ -z "`echo $line`" ]; then
		# ignore now empty lines
			continue
		elif [ "$line" = "network={" ]; then
		# creating a new network configuration,
		# saving network number to NETWORK
			ctrl_iface add_network
			NETWORK="$RET"
		elif [ "$line" = "}" ]; then
		# now the network is configured, enabling it
			ctrl_iface "enable_network $NETWORK"
			unset NETWORK
		elif [ -n "$( echo "$line" | grep -v "ctrl_interface")" ]; then
			# all others lines should be network parameters...
			# i need to replace the first '=' character by a pace
			line="`echo "$line" | sed 's,=, ,'`"
			verbose '' "ctrl_iface set_network $NETWORK $line"
			RET="`$WPA_CLIENT_NAME -i $IFACE set_network $NETWORK $line`"
			#ctrl_iface set_network $NETWORK $line
		fi
		if [[ $RET = FAIL* ]]; then
			boot_mesg "Parse error on line ${LINENUMBER}"
			remove_iface 
			echo_failure
			return 2
		fi
	done
}

function wait_for_events {
# This is a new wpa_supplicant function: really usefull
# but requires an additional action file to handle CONNECTED/DISCONNECTED events
	ctrl_iface -a$WPA_ACTION_FILE &
}


function real_fail {
	[ "$1" != 0 ] && RET="FAIL:$1"
	verbose '' " $RET"
	if [[ $RET = FAIL* ]]; then
		exit $1
	else
		return $1
	fi
}


function iface_up {
	wpa
	is_iface_not_managed
	if [ $? = 0 ]; then
		verbose '' "Interface already managed, skipping"
	else
		add_iface
		real_fail $?
	fi
	configure_network
	real_fail $?
	wait_for_events
	}


function iface_down {
	wpa
	ctrl_iface disconnect
	test_fail $?
		verbose '' "wpa_cli -a will exit when interface will be removed"
		$WPA_ACTION_FILE $IFACE DISCONNECTED
	test_fail $?
	wpa_cli -g$WPA_GLOBAL_FILE interface_remove $IFACE
	test_fail $?	
}

case "$2" in
	up)
	iface_up
	;;
	down)
	iface_down
	;;
esac

