#!/bin/bash
#
# --------------------------------------------------------------------------
# Copyright notice
# --------------------------------------------------------------------------
# Copyright: Rene Mayrhofer, Jan. 2005
#
# 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, 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; see the file COPYING.  If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# On Debian GNU/Linux systems, the complete text of the GNU General
# Public License can be found in `/usr/share/common-licenses/GPL'.
# --------------------------------------------------------------------------
#

# seconds to wait for the administrator when a network card was not found
DELAY=30
# number of pings to try
PINGS=4

. /usr/lib/gibraltar-bootsupport/common-definitions.sh

# this does only make sense if we are not in the unconfigured mode
[ -e /etc/unconfigured ] && exit 0

echo -n "Checking if all configured network interfaces could be loaded... "
error=0
failed_macs=""
working_macs=""
awk '/^ *mac .+:.+:.+:.+:.+:.+ *$/{print $3};' /etc/iftab | \
while read mac_configured; do
  if ! ip link show | grep -q "$mac_configured"; then
    # this is an error - the MAC address specified in the config file is 
    # not used by any of the loaded network adapters
    error=1
    failed_macs="$failed_macs $mac_configured"
  else
    working_macs="$working_macs $mac_configured"
  fi
done

if [ $error -eq 0 ]; then
  echo -e "${COLOR_GRREN}OK${COLOR_NORMAL}"
else
  # report the error to the user to let him decide
  echo -e "${COLOR_RED}failed${COLOR_NORMAL}"
  echo "MAC address(es) $failed_macs are no longer in the system"
  beepconsole -f 500 -l 200 -r 2 -d 200
  
  if [ -z "$working_macs" ]; then
    # but if we haven't found a single network adapter, there is no need to 
    # decide - it's the best to stop here and wait!
    echo -e "${COLOR_RED}Serious error:${COLOR_NORMAL} no network card found at all."
    echo "Stopping further bootup now."
    echo "Do you want to probe for new network cards now [y/n]?"
    wait=""
  else
    echo "Do you want to probe for new network cards now [y/n] (waiting for $DELAY seconds)?"
    wait="-t $DELAY"
  fi
  if read -n 1 -r -s; then
    # no timeout, the user has pressed a key
    if [ "$REPLY" = "y" ]; then
      /etc/setup.d/00network-cards
    else
      echo "Ok, not probing for new networks cards."
    fi
    echo
    
    # after probing for possible new network cards, now go through the list of
    # MAC addresses that are available to the system right now
    echo "Checking for MAC addresses not configured until now... "
    new_macs_found=0
    ip link | awk '/link\/ether/ {print $2};' | while read mac_available; do
      # for every such MAC addresses, check if it is "new" in the sense that
      # it has not been configured
      mac_pattern="^ *mac +$mac_available *$"
      if ! egrep -q "$mac_pattern" /etc/iftab; then
        # yes, this is a new one
        new_macs_found=1
	# figure out the name of this interface
        cur_name=`ip link | grep -B 1 "$mac_available" | head -1 | cut -d':' -f2`
        echo -n "Found MAC '$mac_available'. Do you want to configure it now [y/n]? "
	if read -n 1 -r -s && [ "$REPLY" = "y" ]; then
	  # this is a bit tricky now - present the user a pseudo-menu to select
	  # an old MAC address to overwrite
	  while true; do
  	    echo "Which of the following old configured MAC addresses do you want to replace?"
	    i=0
	    for failed_mac in $failed_macs; do
	      let i=i+1
	      echo "[$i] $failed_mac"
	    done
	    echo "Please enter 1 to $i or hit Ctrl-D to abort."
	    echo
	    if read -n 1 -r -s; then
	      if [ $REPLY -ge 1 -a $REPLY -le $i ]; then
	        # get the appropriate MAC address
		replace_old_mac=`echo $failed_macs | cut -d' ' -f$REPLY`
		# and try to replace it
		echo "Trying to replace old address $replace_old_mac by new address $mac_available:"
		# first in /etc/network/interfaces
		echo "    modifying configuration"
		cp /etc/iftab /etc/iftab.save
		sed "s/mac $replace_old_mac/mac $mac_available" \
		  /etc/iftab.save > /etc/iftab
		# then try to activate this network interface
		echo -n "    activating network interface $cur_name... "
                # first need to rename it - ifrename conveniently prints the
                # new name
		if new_name=`ifrename -i $cur_name`; then
                  echo -n "as $new_name... "
  		  if ifup $new_name; then
		    echo -e -n "${COLOR_GREEN}OK${COLOR_NORMAL}"
		    echo -n ", with IP "
		    ip addr show $new_name | awk '/inet / {print $2};'
		  else
		    echo -e "${COLOR_RED}failed to configure${COLOR_NORMAL}"
		    echo "    reverting configuration"
		    mv /etc/iftab.save /etc/iftab
		    # retry with possibly another MAC - jump back to the pseudo-menu loop
		    continue
		  fi
	      	else
		  echo -e "${COLOR_RED}failed to rename${COLOR_NORMAL}"
		  echo "    reverting configuration"
		  mv /etc/iftab.save /etc/iftab
		  # retry with possibly another MAC - jump back to the pseudo-menu loop
		  continue
		fi
		
		# now allow the user to ping some host as test
        	echo -n "Do you want to test it now [y/n]? "
		if read -n 1 -r -s && [ "$REPLY" = "y" ]; then
		  # set a strict network policy that allows the box out but nothing in or through
		  echo "    setting firewalling policy for tests"
		  iptables -P INPUT DROP
		  iptables -P FORWARD DROP
		  iptables -P OUTPUT ACCEPT
		  iptables -F
		  iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
		  # now allow the ping
		  echo -n "   Please enter an IP address that should be reachable now: "
		  if read; then
		    if ping -c $PINGS -I $newifacename -n $REPLY; then
		      echo "The MAC address replacement seems to have worked."
		    else
		      echo "The test host could not be reached."
		    fi
		    echo -n "Do you want to keep this configuration [y/n]? "
		    if read -n 1 -r -s && [ "$REPLY" = "y" ]; then
		      echo "    OK, keeping this configuration."
		      # exit the pseudo-menu
		      break
		    else
		      echo "    reverting configuration"
		      mv /etc/iftab.save /etc/iftab
		      # retry with possibly another MAC - jump back to the pseudo-menu loop
		    fi
		  else
		    echo "cancelled"
		    echo "    reverting configuration"
		    mv /etc/iftab.save /etc/iftab
		    # retry with possibly another MAC - jump back to the pseudo-menu loop
		  fi
		else
		  # OK, the network interface came up OK but the user doesn't want to test
		  # just continue with the next MAC
                  # exit the pseudo-menu
	          break
		fi
	      else
	        echo "Invalid input, please enter a number from 1 to $i."
	      fi
	    else
	      echo "Cancelled"
	      break
	    fi
	  done
	fi
      fi
    done
    if [ $new_macs_found -eq 0 ]; then
      echo "No new MAC addresses found, giving up."
      echo "Please check your hardware, it might show errors."
      echo "To continue bootup, please press Enter."
      read -s
    fi
  fi
fi

exit 0
