#!/bin/bash

# $1 - needle
exists_in_text()
{
  [ "$1" = "" ] && return 0

  IFS=" 	
"

  for x in $( cat ) ; do
    [ "$1" = "$x" ] && return 0
  done

  return 1
}

# $1 - device name
device_is_up()
{
  if [ -x /usr/bin/grep ]; then
    /sbin/ifconfig ${1} | grep -q "UP"
  else
    /sbin/ifconfig ${1} 2>&1 | exists_in_text "UP"
  fi
}

# $* - parameters for iwconfig, except device name
# to be called from _do_device_up
_set_wlan()
{
  iwconfig $DEV $* &&
  IWC="$IWC $*"
}

_do_device_up()
{
    # collect settings for iwconfig
    local IWC=
    [[ -n "$WIFI_NWID" ]] && _set_wlan nwid $WIFI_NWID
    [[ -n "$WIFI_ESSID" ]] && _set_wlan essid $WIFI_ESSID
    [[ -n "$WIFI_RATE" ]] && _set_wlan rate $WIFI_RATE
    [[ -n "$WIFI_MODE" ]] && _set_wlan mode $WIFI_MODE
    [[ -n "$WIFI_KEY1" ]] && _set_wlan key $WIFI_KEY1 '[1]'
    [[ -n "$WIFI_KEY2" ]] && _set_wlan key $WIFI_KEY2 '[2]'
    [[ -n "$WIFI_KEY3" ]] && _set_wlan key $WIFI_KEY3 '[3]'
    [[ -n "$WIFI_KEY4" ]] && _set_wlan key $WIFI_KEY4 '[4]'
    [[ -n "$WIFI_DEFAULTKEY" ]] && _set_wlan key "[$WIFI_DEFAULTKEY]"
    [[ -n "$WIFI_SECMODE" ]] && _set_wlan key $WIFI_SECMODE
    [[ -n "$WIFI_KEY" ]] && _set_wlan key $WIFI_KEY

    # make sure the wifi settings are applied if any of them are present
    [[ -n "$IWC" ]] && iwconfig $DEV commit && sleep 2

    case "$MODE" in
    dynamic )
      sed -i 's/MODE=.*/MODE=dynamic_set_hostname/' $netdevdir/$DEV.dev &&
      echo "Fixed error in $DEV.dev"
      . /etc/sysconfig/dhcpcd
      ARGS="-h $HOSTNAME"

      echo "Starting dhcpcd on $DEV ..."
      if [ -e $DHCPCD_PATH$DEV.pid ]; then
        dhcpcPid=`cat $DHCPCD_PATH$DEV.pid`
        dhcpcd -k $DEV 1>/dev/null 2>&1 &&
        renice 10 $dhcpcPid 1>/dev/null 2>&1 || rm -f $DHCPCD_PATH$DEV.pid &&
        sleep 1
      fi &&
      dhcpcd -t $TIMEOUT $ARGS $OPTIONS $DEV
    ;;
    dynamic_set_hostname )
      . /etc/sysconfig/dhcpcd
      ARGS="-h $HOSTNAME"

      echo "Starting dhcpcd on $DEV ..."
      if [ -e $DHCPCD_PATH$DEV.pid ]; then
        dhcpcPid=`cat $DHCPCD_PATH$DEV.pid`
        dhcpcd -k $DEV 1>/dev/null 2>&1 &&
        renice 10 $dhcpcPid 1>/dev/null 2>&1 || rm -f $DHCPCD_PATH$DEV.pid &&
        sleep 1
      fi &&
      dhcpcd -t $TIMEOUT $ARGS $OPTIONS $DEV
    ;;
    dynamic_get_hostname )
      . /etc/sysconfig/dhcpcd
      ARGS="-H"

      echo "Starting dhcpcd on $DEV ..."
      if [ -e $DHCPCD_PATH$DEV.pid ]; then
        dhcpcPid=`cat $DHCPCD_PATH$DEV.pid`
        dhcpcd -k $DEV 1>/dev/null 2>&1 &&
        renice 10 $dhcpcPid 1>/dev/null 2>&1 || rm -f $DHCPCD_PATH$DEV.pid &&
        sleep 1
      fi &&
      dhcpcd -t $TIMEOUT $ARGS $OPTIONS $DEV
    ;;
    static )
      echo "Setting up static networking on $DEV..."
      ARGS=""
      if [ "$POINTOPOINT" != "" ] ; then
        ARGS="$ARGS pointopoint $POINTOPOINT"
      fi
      if [ "$MTU" != "" ] ; then
        ARGS="$ARGS mtu $MTU"
      fi

      ifconfig $DEV $IP broadcast $BROADCAST netmask $NETMASK $ARGS
    ;;
    * )
      echo "There are errors in $netdevdir/$DEV.dev"
      exit 1
    ;;
  esac
}

_do_route_up()
{
  # check if GATEWAY is set; gateway is set by PPP or other software in some
  # cases
  if [ "$GATEWAY" ]; then
    route add default gw $GATEWAY dev $DEV
  fi 
}

_on_up()
{
  true
}

# Handles function "overloading"
run_func() {
  # If for example do_route_up exists then run it, otherwise run _do_route_up
  if [ "$( type -t $1 )" = function ] ; then
    $1
  else
    _$1
  fi
}

netdevdir=/etc/sysconfig/network

#change this if your .pid file hides somewhere else
DHCPCD_PATH="/var/run/dhcpcd-"
DEV=$1

if [ -z $DEV ]; then
  echo "Usage: ifup <device>"
  exit 2
fi

if [ ! -f $netdevdir/$DEV.dev ]; then
  echo "$DEV: no such network device"
  exit 1
fi

if device_is_up $DEV ; then
  echo "$DEV already up"
  exit 0
fi

unset MODE MODULE IP BROADCAST NETMASK GATEWAY POINTOPOINT MTU UP_ON_BOOT MAC NEEDS
unset WIFI_NWID WIFI_ESSID WIFI_RATE WIFI_MODE WIFI_SECMODE WIFI_ENCKEY
unset do_device_up do_route_up on_up

. $netdevdir/$DEV.dev

for needed_device in ${NEEDS}; do
  echo -n "Checking if $needed_device is up... "
  if ( ifconfig | grep -q $needed_device ); then
     echo "yes it is" ;
  else
     echo "NO, it's not! Aborting!"
     exit 1 ;
  fi
done

if [ -z "$MODE" ]; then
  echo "There are errors in $netdevdir/$DEV.dev"
  exit 1
fi

if [ "${_OBEY_UP_ON_BOOT}" = 1 -a "$UP_ON_BOOT" = no ] ; then
  exit 0
fi

if [ "$MODULE" ] && ! /sbin/lsmod | exists_in_text "$MODULE" ; then
  echo "Loading module $MODULE for $DEV ..."
  modprobe  $MODULE
fi &&

if [ "$WIFI" ]; then
  echo "Configuring wifi for $DEV ..."
  sleep 1 # to give the card time to start, needed on some cards.
  iwconfig $DEV ${WIFI}
fi &&

if [ "$MAC" ]; then
  echo "Setting custom MAC address for $DEV ..."
  if ( ifconfig $DEV | grep -q Ethernet ); then
     ifconfig $DEV hw ether $MAC
     echo "Custom MAC set for device $DEV";
  else
     echo "Can't set custom MAC for non-ethernet device $DEV";
  fi
fi

run_func do_device_up 
run_func do_route_up 
run_func on_up
