#! /bin/sh
# Programme de selection de profil réseau
# Copyright 2004,2006 Olivier Rossiny

CONFIG_FILES="/etc/netswitch/switch.conf"
GETTEXT="gettext -e netswitch "

usage()
{
  echo -n "Netswitch"
  $GETTEXT ": Network profile manager by"
  echo " Olivier Rossiny, 2004, 2006"
  return
}

bitTomask()
{
  num=$1
  p=0
  while [ $num -gt 0 ]; do
    p=$(($p+1))
    if [ $p -gt 1 ]; then
      res="${res}."
    fi
    if [ $num -gt 7 ]; then
      num=$(($num-8))
      res="${res}255"
    else
      if [ $num -eq 7 ]; then
        res="${res}254"
      elif [ $num -eq 6 ]; then
        res="${res}252"
      elif [ $num -eq 5 ]; then
        res="${res}248"
      elif [ $num -eq 4 ]; then
        res="${res}240"
      elif [ $num -eq 3 ]; then
        res="${res}224"
      elif [ $num -eq 2 ]; then
        res="${res}192"
      elif [ $num -eq 1 ]; then
        res="${res}128"
      fi
      num=0
    fi
  done
  while [ $p -lt 4 ]; do
    p=$(($p+1))
    res="${res}.0"
  done
  echo $res
}

for fichiers in $CONFIG_FILES ; do
  if [ -f "$fichiers" ]; then
    source $fichiers
  else
    [ -z "$TG" ] && $GETTEXT "Can't find the configuration file " >&2 && echo $fichiers
  fi
done

Activation()
{
  if [ -n "$3" ]; then
    $IWBIN $*
    return $?
  else
    return 1
  fi
}

Start_Device()
{
  if [ -n "`$IWBIN ${1} 2>/dev/null`" ]; then
    Activation $1 mode "$MODE"
    if [ -n "$NICKNAME" ]; then
      Activation $1 nick "$NICKNAME"
    else
      Activation $1 nick "`hostname`"
    fi
    Activation $1 nwid "$NWID"
    Activation $1 rate "$RATE"
    Activation $1 sens "$SENS"
    Activation $1 rts "$RTS"
    Activation $1 frag "$FRAG"
    if  [ "$MODE" != "Managed" ]; then
      # On se fatigue moins vu que tout est automatique
      Activation $1 freq "$FREQ"
      Activation $1 channel "$CHANNEL"
    fi
    # Gestion des clés WEP
    CLE=0
    if [ -z "$KEY_MODE" ]; then
      KEY_MODE="open"
    fi
    KEY_NUM=1
    macle=`eval echo '$KEY'${KEY_NUM}`
    while [ -n "$macle" ]; do
      if [ "$SENDKEY" = "$KEY_NUM" ]; then
        $IWBIN $1 key [$KEY_NUM] $macle $KEY_MODE
        BON=$?
      else
        $IWBIN $1 key [$KEY_NUM] $macle
        BON=$?
      fi
      if [ $BON -eq 0 ]; then
        CLE=1
      fi
      KEY_NUM=$(($KEY_NUM+1))
      macle=`eval echo '$KEY'${KEY_NUM}`
    done
    if [ $CLE -eq 1 ]; then
      if [ -z "$SENDKEY" ]; then
        $IWBIN $1 key [1] $KEY_MODE
      fi
    elif [ -z "$WPA" ]; then
      $IWBIN $1 key off
    fi
    if [ -n "$ESSID" ]; then
      $IWBIN $1 essid "$ESSID"
    else
      $IWBIN $1 essid any
    fi
  fi
  if [ -n "$HARDWARE" ]; then
    $IFBIN hw ether $HARDWARE
  fi
  if [ -z "$IPADDR" ]; then
    if [ "$PEERDNS" = "no" ]; then
      # Do not modify the file resolv.conf (only dhcpcd)
      DHCP_ARGS="$DHCP_CLIENT_ARGS"
    fi
    $DHCP_CLIENT $DHCP_ARGS $1 >/dev/null 2>&1
    OK=$?
    if [ -z "`LC_ALL=C $IFBIN|grep -C 1 $1|grep inet`" ]; then
      OK=1
      echo
      $GETTEXT "dhcp command failed"
    fi
  else
    OPTION="$IPADDR"
    if [ -n "$NETMASK" ]; then
      OPTION="$OPTION netmask `bitTomask $NETMASK`"
    fi
    if [ -n "$BROADCAST" ]; then
      OPTION="$OPTION broadcast $BROADCAST"
    fi
    $IFBIN $1 $OPTION
    OK=$?
    if [ $OK -eq 0 ]; then
      if [ -n "$GATEWAY" ]; then
        if [ -n "$METRIC" -a -z "`$IWBIN $1 2>/dev/null`" ]; then
          OPTION="metric $METRIC"
        else
          OPTION=""
        fi
        $ROUTEBIN del default 2>/dev/null
        $ROUTEBIN add default gw $GATEWAY $OPTION
        OK=$?
      fi
    fi
  fi
  if [ -n "$DOMAIN" -o -n "$NAMESERVER1" ]; then
    rm -f $RESOLV_FILE
    if [ -n "$DOMAIN" ]; then
      echo "search $DOMAIN" >>$RESOLV_FILE
    fi
    NUM=1
    SRV=$NAMESERVER1
    until [ -z "$SRV" ]; do
      echo "nameserver $SRV" >> $RESOLV_FILE
      NUM=$(($NUM+1))
      SRV=`eval echo '$NAMESERVER'${NUM}`
    done
  fi
  return $OK
}

Stop_Device()
{
  $GETTEXT "Shutting the profile for "
  echo -n $1
  #if [ -f "${ACTIF}.$1" ]; then
    $IFBIN $1 down 2>/dev/null
  #fi
  if [ -n "`ps -ef|grep dhcpcd|grep $1|grep -v grep`" ]; then
    `which dhcpcd` -k $1 2>/dev/null
    sleep 2
  fi
  if [ -n "`pgrep dhclient`" ]; then
    kill `ps -ef|grep dhclient|grep $1|grep -v grep|awk '{print $2}'` >/dev/null 2>&1
  fi
  rm -f /var/run/dhclient-${1}.pid /var/run/dhcpcd-${1}.pid $ACTIF.$1
  if [ -n "`grep $1 /proc/net/route|awk '$2 == "00000000" {print "Yes"}'`" ]; then
    $ROUTEBIN del default 
  fi
  rm -f $ACTIF.$1 2>/dev/null
  $GETTEXT " down\n"
  return 0
}

authTest(){
  MY_GROUPS="`id -G -n 2>/dev/null`"
  ME="`id -u -n 2>/dev/null`"
  if [ xroot = x$ME ]; then
    if [ ! -d "$CONFIG_PREFIX" ]; then
      mkdir $CONFIG_PREFIX || echo "No config directory found"
    fi
    return 0
  fi
  $GETTEXT "You must be root to run this program\n"
  exit 1
}

case "$1" in
  "check")
    [ -d "$SMTPDIR" ] && echo -n "SMTP "
    [ -d "$INITDIR" ] && echo -n "SVC "
    [ -n "$DHCP_CLIENT" ] && echo -n "DHCP "
    [ -x "$IWBIN" ] && echo -n "WIFI "
    [ -x "$PPPBIN" ] && echo -n "PPP "
    [ -x "$WPABIN" ] && echo -n "WPA "
    echo
    ;;
  "scan")
    authTest
      if [ -n "$IWLIST" ]; then
        LC_ALL=C $IWLIST scan 2>/dev/null|awk '/Address/ {print "BSSID=" $5}
		  /ESSID/ {sub(":"," ");gsub("\""," ");print "ESSID=" $2}
		  /Protocol/ {sub(":"," ");print "PROTO="$2" "$3" "$4}
		  /Channel/ {sub(":"," ");print "CH=" $2}
		  /Mode/ {sub(":"," ");print "MODE=" $2}
		  /Encryption key/ {sub(":"," ");print "ENC=" $3}
		  /Bit Rate/ {sub(":"," ");print "RATE=" $3}
		  /Signal/ {gsub(":"," "); gsub("="," ");gsub("-"," ");
		    for (i=1;i<=NF;i++) {
		       if ($i == "Signal") {
		         print "SIGNAL="$(i+2);
		         i=i+2;
		       } else if ($i == "Quality") {
		         print "QUALITY="$(i+1);
		         i=i+1;
		       }
		    };
		  }
		 '
	exit 0
      fi
    ;;
  "auto")
    authTest
      INT="`$IWBIN 2>/dev/null|head -n 1|awk '{print $1}'`"
      if [ -z "$INT" ]; then
        $GETTEXT "No wireless device\n"
        exit
      fi
      RES=`$IWLIST scan 2>/dev/null|awk '/ESSID/ {gsub("\""," ");print $2}'`
      for j in $RES; do
        if [ -n "`echo $DEJA|grep $j`" -o "<hidden>" = "$j" ]; then
          continue
        fi
        for i in /etc/netswitch/profiles/*.$INT; do
          ESSID=`grep "ESSID=" $i`
          if [ "$ESSID" = "ESSID=$j" ]; then
            netswitch profile on $INT `basename $i|awk -F. '{print $1}'`
	    if [ $? -eq 0 ]; then
	      exit 0
	    fi
          fi
        done
        DEJA="$DEJA $j"
      done
      exit 1
    ;;
  "info")
    if [ -z "$2" ]; then
      $GETTEXT "Specify an interface\n"
    elif [ -n "`$IFBIN $2`" ]; then
      echo "HWADDR=`$IFBIN $2|awk -F'HWaddr' '{print $2}'|awk '{print $1}'`"
      if [ -n "`$IFBIN|grep $2`" ]; then
        echo "STATUS=on"
        if [ -n "`$IWBIN $2 2>/dev/null`" ]; then
          LINK=`LC_ALL=C $IWBIN $2|awk '/Link/ {sub("="," ");sub("/"," "); print $3}'`
          echo "WFLK=$LINK"
          if [ x$LINK = x0 ]; then exit 0; fi
	  SSID=`LC_ALL=C $IWBIN $2|awk '/ESSID/ {sub(":"," ");gsub("\""," "); print $5}'`
          if [ -n "$SSID" ]; then
            echo "WFID=$SSID"
          fi
        fi
	LC_ALL=C $IFBIN $2|awk '\
		/inet addr/ {gsub(":", " "); print "IPADDR=" $3} \
		/Bcast/ {gsub(":", " "); print "IPBRD=" $5} \
		/Mask/ {gsub(":", " "); print "IPNET=" $7} \
		'
        $ROUTEBIN -n|awk "/^0.0.0.0(.*)$2/ {print \"IPGW=\" \$2}"
      else
        echo "STATUS=off"
      fi
    else
      $GETTEXT "Network interface "
      echo -n $2
      $GETTEXT " doesn't exists\n"
    fi
    ;;
  "profiles")
    PREM=1
    for DEV in $NET_INTERFACES; do
      if [ -n "$2" -a ! "$2" = "$DEV"  ]; then
        continue
      fi
      if [ x$PREM = x0 ]; then
        echo
      else
        PREM=0
      fi
      if [ -n "`$IWBIN ${DEV} 2>/dev/null`" ]; then
        echo -e "[Wifi:$DEV]"
      else
        echo -e "[Eth:$DEV]"
      fi
      ls $CONFIG_PREFIX/*$DEV 2>/dev/null| awk -F/ '{sub(".'$DEV'$",""); print $NF}'
    done
    ;;
  "profile")
    shift
    authTest
    EXISTS="false"
    for DEV in $NET_INTERFACES; do
      if [ x$DEV = x$2 ]; then
        EXISTS="true"
        break
      fi
    done
    if [ "$1" = "get" -o "$1" = "put" -o "$1" = "del" ]; then
      if [ $# -eq 3 -a x$EXISTS = xtrue ]; then
        cmd=$1
      else
        cmd="bad"
        if [ $# -eq 3 ]; then
          $GETTEXT "Network interface "
          echo -n $2
          $GETTEXT " doesn't exists\n"
          exit 1
        fi
      fi
    else
      cmd=$1
    fi
    case "$cmd" in
      "get")
        if [ -f "$CONFIG_PREFIX/$3.$2" ]; then
          cat "$CONFIG_PREFIX/$3.$2"
	else
          $GETTEXT "Profile "
          echo -n $3
          $GETTEXT " doesn't exists\n"
	fi
        ;;
      "del")
        if [ -f "$CONFIG_PREFIX/$3.$2" ]; then
          rm -f "$CONFIG_PREFIX/$3.$2"
	else
          $GETTEXT "Profile "
          echo -n $3
          $GETTEXT " doesn't exists\n"
	fi
        ;;
      "put")
        PROFIL=`echo $3|awk -F/ '{print $NF}'`
        if [ -f "$3" ]; then
          mv "$3" "$CONFIG_PREFIX/$PROFIL.$2"
        else
          $GETTEXT "Profile "
          echo -n $PROFIL
          $GETTEXT " doesn't exists\n"
        fi
        ;;
      "on")
        if [ $# -eq 2 ]; then
          CONFIG="$CONFIG_PREFIX/$2."
          PROFILE=$2
        else
          CONFIG="$CONFIG_PREFIX/$3."
          PROFILE=$3
          ONLY=$2
        fi
        MODIF=0
	OK=1
        for DEV in $NET_INTERFACES ; do
          if [ ! -r "${CONFIG}${DEV}" -o -n "$ONLY" -a ! x$DEV = x$ONLY ]; then
            continue
          fi
	  if [ -f "$ACTIF.$DEV" ]; then
            Stop_Device $DEV
	  fi
          MODIF=1
	  IPADDR=""
	  MODE=""
          source "${CONFIG}${DEV}"
          OK=0
          $GETTEXT "Bringing up interface " && echo -n $DEV
          Start_Device $DEV
          OK=$?
          COUNT_LIMIT=1
          if [ x`$IWBIN ${DEV} 2>/dev/null|awk '/Link/ {sub(":"," ");sub("/"," ");print $3}'` = x0 -a "$MODE" = "Managed" -a -n "$IPADDR" ]; then
	    sleep 2
            LINK=`$IWBIN $DEV|awk '/Link/ {sub(":"," ");sub("/"," "); print $3}'`
            until [ ! x$LINK = x0 -o $COUNT_LIMIT -gt 5 ]; do
              COUNT_LIMIT=$(($COUNT_LIMIT+1))
              echo -n .
              sleep 5
              Start_Device $DEV
              OK=$?
              LINK=`$IWBIN $DEV|awk '/Link/ {sub(":"," ");sub("/"," "); print $3}'`
            done
          fi
          echo
          if [ $OK -eq 0 -a $COUNT_LIMIT -lt 6 ]; then
            echo $PROFILE > "$ACTIF.$DEV"
            if [ -d "$SMTPDIR" -a -n "$SMTP_HOST" ]; then
              echo "#Generated by netswitch" > $SMTPDIR/remotes
              echo -n "$SMTP_HOST smtp" >> $SMTPDIR/remotes
              [ -n "$SMTP_PORT" ] && echo -n " --port=$SMTP_PORT" >> $SMTPDIR/remotes
              [ -n "$SMTP_USER" -a -n "$SMTP_PASS" ] && echo -n " --auth=$SMTP_USER,$SMTP_PASS" >> $SMTPDIR/remotes
              echo >> $SMTPDIR/remotes
              hostname > $SMTPDIR/me
              echo "$SMTP_DOMAIN" >> $SMTPDIR/defaultdomain
              if [ -x "$SMTP_SCRIPT" ]; then
                $SMTP_SCRIPT restart
              fi
            fi
	    for script in $SCRIPTS_ACTIVATION_OFF; do
	      $SCRIPT_PREFIX/$script stop
	    done
	    for script in $SCRIPTS_ACTIVATION_ON; do
	      $SCRIPT_PREFIX/$script start
	    done
          else
            Stop_Device $DEV
            $GETTEXT "Profile "
            echo -n $PROFILE
            $GETTEXT " can't be initialized on "
            echo $DEV
          fi
        done
        if [ $MODIF -eq 0 ]; then
          $GETTEXT "Profile "
          echo -n $PROFILE
          $GETTEXT " doesn't exists\n"
        fi
        ;;
      "off")
        if [ $# -eq 1 ]; then
          for DEV in $NET_INTERFACES ; do
            Stop_Device $DEV
          done
	elif [ $# -eq 2 -a x$EXISTS = xtrue ]; then
            Stop_Device $2
        elif [ x$EXISTS = xtrue -o -f "$CONFIG_PREFIX/${3}.$2" ]; then
          Stop_Device $2
        else
          CNT=0
          for DEV in $NET_INTERFACES ; do
            if [ -f $CONFIG_PREFIX/${2}.$DEV ]; then
              Stop_Device $DEV
              CNT=1
            fi
          done
          if [ x$CNT = x0 ]; then
            $GETTEXT "Profile "
            if [ $# -eq 2 ]; then
              echo -n $2
            else
              echo -n $3
            fi
            $GETTEXT " doesn't exists\n"
          fi
        fi
        ;;
      *)
        usage
        $GETTEXT "\tget <iface> <profile>\tPrint infos about a profile\n"
        $GETTEXT "\tput <iface> <profile>\tInstall an existing profile\n"
        $GETTEXT "\tdel <iface> <profile>\tDelete a profile\n"
        echo
        $GETTEXT "\toff\t\t\tSwitch off all profiles on all interfaces\n"
        $GETTEXT "\toff <iface>\t\tSwitch off an interface\n"
        $GETTEXT "\toff <profile>\t\tSwitch off a profile on all interfaces\n"
        $GETTEXT "\ton  <iface> <profile>\tSwitch on an interface\n"
        $GETTEXT "\ton  <profile>\t\tSwitch on a profile\n"
      esac
      ;;
  "list")
    for DEV in $NET_INTERFACES ; do
      if [ -z "$2" ]; then
        echo -ne "${DEV}\t"
      elif [ ! "$DEV" = "$2" ]; then
        continue
      fi
      if [ -f $ACTIF.$DEV ]; then
        TXT=`cat $ACTIF.$DEV`
        if [ -n "$TXT" -a -r "${CONFIG_PREFIX}/${TXT}.$DEV" ]; then
	  IPADDR=""
          source $CONFIG_PREFIX/$TXT.$DEV
          if [ -n "$IPADDR" -a "`$IFBIN|grep -C 1 $DEV|awk '/inet/ {sub(":"," ");print $3}'`" = "$IPADDR" ]; then
            cat $ACTIF.$DEV
          elif [ -z "$IPADDR" -a -n "`ps -ef|grep -e \"$DHCP_CLIENT\"|grep -v grep`" ]; then
            cat $ACTIF.$DEV
          elif [ -z "$2" ]; then
            echo
          fi
        elif [ -z "$2" ]; then
          echo
        fi
      elif [ -z "$2" ]; then
        echo
      fi
    done
    ;;
  *)
    usage
    $GETTEXT "\tscan\t\tSearch for a wifi network around\n"
    $GETTEXT "\tinfo <DEV>\tPrint interface information\n"
    $GETTEXT "\tlist [DEV]\tLists the profiles enabled\n"
    $GETTEXT "\tprofiles [DEV]\tLists the profiles detected\n"
    $GETTEXT "\tprofile ...\tWork with a profile\n"
esac
