#!/bin/bash
# $Id: ifplugd-selectif 1090 2004-09-17 07:44:56Z zoz $
#
# Priority based interface selector for ifplugd
#
# If there are multiple interfaces which should be used alternatively depending
# on which one actually has a link beat, this script will select the right one,
# set this up and all alternatives down. Interfaces are considered to be used
# alternatively if they have IFPLUGD_PRIORITY > 0 in their ifcfg-*
# configuration file. 
#
#
# Copyright (c) 2004 SuSE Linux AG Nuernberg, Germany.
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
# This program 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
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
#
# Authors: Christian Zoz <zoz@suse.de>

cd /etc/sysconfig/network
. scripts/functions
test -f ./config && . ./config

echo $0 $*

if [ -z "$1" ] || [ -z "$2" ] ; then
	echo "Wrong arguments" > /dev/stderr
	exit 1
fi

INTERFACE=$1
ACTION=$2

# Check all available interfaces if they have a ifplugd priority and collect
# two ordered lists of interfaces with minor or major priority.
unset MINOR MAJOR MINOR_A MAJOR_A
PRIORITY=`get_ifplugd_priority $INTERFACE`
if [ "$PRIORITY" -gt 0 ] ; then
	for IF in `ls /sys/class/net`; do
		test "$IF" = "$INTERFACE" && continue
		IFPRIO=`get_ifplugd_priority $IF`
		test "$IFPRIO" -eq 0 && continue
		if [ "$IFPRIO" -lt "$PRIORITY" ] ; then
			MINOR_A[$IFPRIO]="${MINOR_A[$IFPRIO]} $IF"
		else
			MAJOR_A[$IFPRIO]="${MAJOR_A[$IFPRIO]} $IF"
		fi
	done
	MINOR=${MINOR_A[*]}
	MAJOR=${MAJOR_A[*]}
fi

# for a in INTERFACE ACTION MAJOR MINOR FOUND; do
#  	printf "%10s = %s\n" "$a" "${!a}"
# done

case $ACTION in
	up)
		write_cached_config_data link yes $INTERFACE
		commit_cached_config_data $INTERFACE
		# if current interface has an ifplugd priority, then shut down
		# all minor interfaces and set up this interface if no major
		# interfaces are already connected
		for IF in $MINOR; do
			if is_connected $IF; then 
				echo ifdown $IF
				ifdown $IF
			fi
		done
		for IF in $MAJOR; do
			if is_connected $IF; then
				INTERFACE=""
			fi
		done
		if [ -n "$INTERFACE" ] ; then
			echo ifup $INTERFACE
			ifup $INTERFACE
		fi
		;;
	down)
		write_cached_config_data link no $INTERFACE
		commit_cached_config_data $INTERFACE
		# if current interface has an ifplugd priority, then shut down
		# current interface and if no major interface is actually
		# connected then set up next minor interface, which actually
		# has a link.
		for IF in $MAJOR; do
			if is_connected $IF; then
				MINOR=""
			fi
		done
		echo ifdown $INTERFACE
		ifdown $INTERFACE
		for IF in `reverse $MINOR`; do
			if has_link $IF; then
				echo ifup $IF
				ifup $IF
				# Set up only one interface. If ifup returns
				# without dhcp client looking for a lease in
				# background, we consider this as success,
				# because we know that it has a link.
				case $? in
					$R_SUCCESS|$R_DHCP_BG)
						break
						;;
				esac
			fi
		done
		;;
esac
		
exit 0
