#!/bin/sh
#
# /etc/network/if-pre-up.d/conflicts
# /etc/network/if-post-down.d/conflicts
#
# Stefan Tomanek <stefan.tomanek@wertarbyte.de>
# http://wertarbyte.de/debian/
#
# This scripts takes down specified network interfaces
# when connecting a new one. This is useful if you are
# able to connect to the same network through several ways,
# e.g. WLAN and wired interfaces
#
# Place in /etc/network/if-pre-up.d/conflicts and symlink to
# /etc/network/if-post-down.d/conflicts
#
# example configuration:
#
# iface eth0 inet dhcp
#   conflicts wlan0
#   conflicts-replace wlan0
#
# iface wlan0 inet dhcp
#   conflicts eth0
#
# Bringing one of the interfaces up shuts down the other one.
# If eth0 is controlled by ifplugd or netplugd and taken down by
# it, wlan0 will step in and replace the network connection.
# Manually taking down the interface will not trigger this
# behaviour.

called_by_pid() {
    # traverse the process tree upwards
    # and find out whether we are a descendant
    # of the named pid
    local ME="$1"
    local DADDY="$2"

    PID=$ME
    while [[ "$PID" -gt 0 ]]; do
        PID=$(ps -p $PID -o ppid=)
        # we found him
        [ "$PID" -eq "$DADDY" ] && return 0
    done
    # I could not find your daddy, I'm really sorry
    return 1
}

if [ -n "$IF_CONFLICTS" ]; then
  if [ "$MODE" = "start" ]; then
      for ENTRY in $IF_CONFLICTS; do
        if egrep -q "^$ENTRY($|=)" /etc/network/run/ifstate; then
            echo "Shutting down conflicting interface $ENTRY"
            /sbin/ifdown "$ENTRY"
        fi
      done
  else
      # maybe restore the old interface?
      # this could lead to infinite loops and
      # make it impossible to shut down networking
      # completely (think shutdown/suspend)
      if [ -n "$IF_CONFLICTS_REPLACE" ]; then
          # only replace the interface if we are called by ifplugd/netplugd
          PLUGD=""
          if [ -e "/var/run/ifplugd.${IFACE}.pid" ]; then
              PLUGD=$(cat /var/run/ifplugd.${IFACE}.pid)
          elif [ -e "/var/run/netplugd.pid" ]; then
              PLUGD=$(cat /var/run/ifplugd.${IFACE}.pid)
          fi
          if [ -n "$PLUGD" ] && called_by_pid $$ $PLUGD; then
              echo "Bringing up replacement interface $IF_CONFLICTS_REPLACE"
              /sbin/ifup "$IF_CONFLICTS_REPLACE"
          fi
      fi
  fi
fi
