#!/bin/bash
#
# $Id: testap,v 1.5 2004/10/19 01:04:06 andrew Exp $
#
# by Andrew McMillan, Catalyst IT Ltd, (c) 2004 licensed
# for use under the GPL version 2
#
# This script uses "iwlist ${INTERFACE} scan" to see if we can connect to
# a useful local WLAN.
#
###############################################
# NOTE:  This script is something of a work in progress.  I can't have experience
# with all possible WLAN hardware, so if you need help getting it working with what
# you happen to use, feel free to call upon me.
###############################################
#
# Parameters:
#   -  first form: [<interface>,]scan
#   - second form: (<ESSID pattern>)[,WEP key]
#   -  third form: [<interface>,](<ESSID pattern>),WEP key
#
# <interface> 	Interface to test.  If omitted, use INTERFACE variable (from detect.conf)
#
# scan       	Normally we just use the last scan details (if they're less than 10 secs
#               old), but sometimes we may want to force a scan.
#
# <ESSID pattern>  A pattern that should match the ESSID we are looking for.
#
# WEP key       A WEP key like 12345bcdef (40-bit), 123456789abcdef0123456789a (128 bit),
#               or any other format accepted by "iwconfig".  This is only applied
#               if the pattern match is successful.
#
# If only two parameters are supplied, the are assumed to be the pattern and
# the WEP key to be assigned if the pattern match is successful.
#
# Environment variables:
#
# INTERFACE	Default interface name to use if not specified
# DEBUGWHEREAMI Turn on debugging output (0 for debug msgs, 1 for execution tracing)
# 
# Examples:
#     testap eth1,scan
#     set INTERFACE eth1
#     testap scan
#     testap eth1,othercap
#     testap eth1,apother,12345bcdef
#     testap friendap,12345bcdef
#     set INTERFACE ath0
#     testap mywlan
#

STATEDIR=${STATEDIR:-"/var/lib/whereami"}
WHEREAMILOCK=$LOCKDIR/whereami.started

######################################################
# Perform the actual scan, which gets all nearby AP
# details into a file we will use for subsequent calls
######################################################
scan_for_ap()
{
  IFSTATE="`ifconfig | egrep \"^${INTERFACE}[\t ]\"`"
  if [ "$IFSTATE" = "" ] ; then
    ifconfig ${INTERFACE} up
    # We seem to need a sleep here to accumulate the
    # scan data - for madwifi, at least.
    sleep 5
  fi

  /sbin/iwlist ${INTERFACE} scan >${STATEFILE}

  # Be a tidy kiwi, and put the interface back how we found it...
  if [ "$IFSTATE" = "" ] ; then
    ifconfig ${INTERFACE} down
  fi
}

######################################################
# Utility to do pattern match, with awkward quoting
######################################################
ap_pattern_match()
{
  egrep "ESSID:\"$1\"" "${STATEFILE}"
}

######################################################
# Test if there is an AP in our scan that matches
######################################################
test_which_ap()
{
  ap_pattern_match "$1" >/dev/null
}

######################################################
# Assign the first ESSID that matched the pattern
######################################################
assign_matching_essid()
{
  FIRST_SSID="`ap_pattern_match \"$1\" | head -n1 | cut -f2 -d'\"'`"
  if [ "" != "${FIRST_SSID}" ] ; then
    iwconfig ${INTERFACE} essid "${FIRST_SSID}"
  fi
}



# Turn on execution tracing, for debugging...
[ -n "$DEBUGWHEREAMI" ] && set -o xtrace

WEPKEY=""
PATTERN=""
ACTION="test"
INTERFACE=${INTERFACE:-eth0}
case $1 in
  *,scan)
    # First form
    INTERFACE=${1/,scan}
    ACTION="scan"
    ;;
  scan)
    # First form
    INTERFACE=${INTERFACE:-eth0}
    ACTION="scan"
    ;;
  *,*,*)
    # Third form
    INTERFACE=${1/,*}
    WEPKEY="${1/*,}"
    PATTERN=${1/$INTERFACE,}
    PATTERN=${PATTERN/,$WEPKEY}
    ;;
  *,*)
    # Second form
    PATTERN=${1/,*}
    WEPKEY=${1/*,}
    ;;
  *)
    # Second form
    PATTERN="$1"
    ;;
esac

STATEFILE=$STATEDIR/iwlist.$INTERFACE
mkdir -p $STATEDIR

STATUS=1
if [ "$ACTION" = "scan" ] ; then
  scan_for_ap
  STATUS=$?
fi

if [ "$PATTERN" != "" ];then
  test_which_ap "$PATTERN"
  STATUS=$?
  if [ "${STATUS}" -eq 0 ] ; then
    # We found a match, so assign that ESSID
    assign_matching_essid "${PATTERN}"

    # And apply the appropriate WEP key, or turn it off
    if [ "${WEPKEY}" = "" ] ; then
      iwconfig $INTERFACE enc off
    else
      iwconfig $INTERFACE key "${WEPKEY}"
    fi
  fi
fi

exit $STATUS
