#!/bin/sh
# ============================================================================
# FLIP Configuration Script.
# ----------------------------------------------------------------------------
# Copyright (c) 1996, Sangoma Technologies Inc.  All rights reserved.
# ============================================================================
# Rev.#	Date		Who	Details
# -----	---------------	-------	----------------------------------------------
#  2.30	Oct.16,1996	GK	Uses meta-configuration file wanpipe.rc.
#  2.10	Jun.19,1996	GK	
#  2.00	May 01,1996	GK	
#  1.00	Apr.22,1996	GK	Initial version.
# ============================================================================

PATH=/usr/bin:/usr/sbin:/bin:/sbin
WANPIPE_RC=/etc/wanpipe.rc
DEVNAME=flip
FLIPCONF=/etc/flip.conf
SDLACONF=/etc/sdla.conf
TMPFILE1=/tmp/T$$.001
APPLY=0
CMD=
SEL=

####### FUNCTION DEFINITIONS #################################################

# ----------------------------------------------------------------------------
# Clear the screen, if possible.
# ----------------------------------------------------------------------------
clearscr() {
	# check if the terminal environment is set up
	[ "$TERM" ] && clear 2> /dev/null
}

# ----------------------------------------------------------------------------
# Prompt user for input.
# ----------------------------------------------------------------------------
prompt() {
	echo -e "\n$*\c"
	read CMD rest
	return 0
}

# ----------------------------------------------------------------------------
# Pause.
# ----------------------------------------------------------------------------
pause() {
	[ $# -ne 0 ] && echo -e $*
	echo -e "Press [Enter] to continue...\c"
	read tmp
	return 0
}

# ----------------------------------------------------------------------------
# Get Yes/No
# ----------------------------------------------------------------------------
getyn() {
		while echo -e "$* (y/n) \c" >&2
		do read yn rest
		case $yn in
			[yY])	return 0
 				;;
			[nN])	return 1
				;;
			*)	echo -e "\nPlease answer y or n" >&2
				;;
		esac
	done
}

# ----------------------------------------------------------------------------
# Select an item from the list.
# Return:	0 - selection is in $SEL
#		1 - quit or empty list
# ----------------------------------------------------------------------------
select_list() {
  cnt=0
  SEL=

  [ $# -eq 0 ] && return 1
  for option in $*
  do
    cnt=`expr $cnt + 1`
    echo -e "\t${cnt}) ${option}\c"
    [ $# -lt 16 -o `expr $cnt % 2` -eq 0 ] && echo ""
  done
  echo -e "\tq) quit\n"

  while echo -e "Please enter your selection (1 .. $cnt or q) ->\c"
  do
    read tmp rest
    case ${tmp:="0"} in
      q|Q)	return 1
		;;
      [0-9]|[0-9][0-9])	[ "$tmp" -ge 1 -a "$tmp" -le "$cnt" ] 2>/dev/null && {
		  until [ "$tmp" = 1 ]
		  do
		    shift
		    tmp=`expr $tmp - 1 2>/dev/null`
		  done
		  SEL=$1
		  return 0
		}
		;;
    esac
  done
}

# ----------------------------------------------------------------------------
# Check to see if a value belongs to the list.
# Return:	0 - yes
#		1 - no
# ----------------------------------------------------------------------------
check_list() {
	val=$1
	shift
	for i in $*
	do [ "$val" = $i ] && return 1
	done
	return 0
}

# ----------------------------------------------------------------------------
# Display error message.
# ----------------------------------------------------------------------------
error() {
	echo -e "\nError: $*!"
	return 0
}

# ----------------------------------------------------------------------------
# Get minor device number from device node name.
#	$1	device
# ----------------------------------------------------------------------------
getdevminor() {
	[ -b "$1" -o -c "$1" ] || return 1
	ls -l $1 | while read \
		DEVPERM DEVLINKS DEVOWNER DEVGROUP DEVMAJOR DEVMINOR rest
	do echo "" 2> /dev/null
	done
}

# ----------------------------------------------------------------------------
# Display banner.
# ----------------------------------------------------------------------------
banner() {
	clearscr
	cat << ENDOFTEXT
	----------------------------------------------------------
	  Sangoma FLIP Driver Configuration Script. Version 2.10
	    Copyright (c) 1995-1996, Sangoma Technologies Inc.
	----------------------------------------------------------

ENDOFTEXT
	return 0
}

# ----------------------------------------------------------------------------
# Add FLIP Interface.
# ----------------------------------------------------------------------------
add_interface() {

  banner
  if [ "$CONF_UNITS" -eq 0 ]
  then
  cat << ENDOFTEXT
	No SDLA cards are bound to the FLIP driver!

	You must bind SDLA cards to FLIP driver first using WANPIPE
	configuration script.  Refer to WANPIPE User's Manual for
	details.
ENDOFTEXT
    pause ""
    return 0
  fi

  until

    echo -e "\tSelect SDLA card for this interface:"
    select_list $CONF_NODES || return 0
    WRK_NODE=$SEL

    banner
    WRK_DLCI=
    while [ -z "$WRK_DLCI" ]
    do
      echo -e -n "\tEnter DLCI for this interface (1 .. 4096) or q to quit ->"
      read WRK_DLCI rest
      [ "foo$WRK_DLCI" = fooq -o "foo$WRK_IFNO" = fooQ ] && return 0
      if [ "$WRK_DLCI" -ge 1 -a "$WRK_DLCI" -le 4096 ] 2> /dev/null
      then grep -q "^$WRK_NODE	$WRK_DLCI" $FLIPCONF && {
        echo -e "\n\tThis SDLA/DLCI pair is already in use!\n"
        WRK_DLCI=
      }
      else WRK_DLCI=
      fi
    done

    banner
    cat <<ENDOFTEXT
	FLIP interfaces are numbered from 0 to 999.  Interface number
	is an arbitrary decimal integer used to construct unique
	interface names by concatenating base name 'flip' with that
	number (without leading zeroes).  I.e. interface number 21
	will result in the interface being named 'flip21'.

ENDOFTEXT
    WRK_IFNO=
    while [ -z "$WRK_IFNO" ]
    do
      echo -e -n "\tEnter interface number (0 .. 999) or q to quit ->"
      read WRK_IFNO rest
      [ "foo$WRK_IFNO" = fooq -o "foo$WRK_IFNO" = fooQ ] && return 0
      if [ "$WRK_IFNO" -ge 0 -a "$WRK_IFNO" -le 999 ] 2> /dev/null
      then grep -q "^[^#]*	$WRK_IFNO\$" $FLIPCONF && {
        echo -e "\n\tThis interface number already exists!\n"
        WRK_IFNO=
      }
      else WRK_IFNO=
      fi
    done

    # Confirm selection.
    banner
    echo -e "\tYou are about to define a new FLIP interface:\n"
    echo -e "\tInterface name: flip$WRK_IFNO"
    echo -e "\tSDLA card:      /dev/$WRK_NODE"
    echo -e "\tDLCI:           $WRK_DLCI"
    getyn "\nIs this correct?"
  do
    banner
  done

  # Modify configuration file.
  echo -e "$WRK_NODE	$WRK_DLCI	$WRK_IFNO" >> $FLIPCONF

  # Update current configuration data.
  get_config
  APPLY=1
  return 0
}

# ----------------------------------------------------------------------------
# Delete FLIP Interface.
# ----------------------------------------------------------------------------
del_interface() {

  banner
  if [ "$CONF_IFNUM" -eq 0 ]
  then
    echo -e "\tNo FLIP interfaces configured!"
    pause ""
    return 0
  fi

  until
    TMP_IFNO=
    while [ -z "$TMP_IFNO" ]
    do
      echo -e -n "\tEnter interface number (0 .. 999) or q to quit ->"
      read TMP_IFNO rest
      [ "foo$TMP_IFNO" = fooq -o "foo$TMP_IFNO" = fooQ ] && return 0
      if [ "$TMP_IFNO" -ge 0 -a "$TMP_IFNO" -le 999 ] 2> /dev/null
      then
        while read WRK_NODE WRK_DLCI WRK_IFNO rest
        do [ "foo$WRK_NODE" != foo# -a "foo$WRK_IFNO" = foo$TMP_IFNO ] && break
        done < $FLIPCONF
        [ $? -ne 0 ] && {
          echo -e "\n\tThis interface number does not exists!\n"
          TMP_IFNO=
        }
      else TMP_IFNO=
      fi
    done

    # Confirm selection.
    banner
    echo -e "\tYou are about to delete a FLIP interface:\n"
    echo -e "\tInterface name: flip$WRK_IFNO"
    echo -e "\tSDLA card:      /dev/$WRK_NODE"
    echo -e "\tDLCI:           $WRK_DLCI"
    getyn "\nIs this correct?"
  do
    banner
  done

  # Edit configuration file.
  cp $FLIPCONF $TMPFILE1
  sed '/^'$WRK_NODE\	$WRK_DLCI\	$WRK_IFNO'/d' $TMPFILE1 > $FLIPCONF

  # Update current configuration data.
  get_config
  APPLY=1

  return 0
}

# ----------------------------------------------------------------------------
# Show Configuration.
# ----------------------------------------------------------------------------
show_config() {

  banner
  if [ "$CONF_UNITS" -eq 0 ]
  then echo -e "\tNo SDLA cards are bound to the FLIP driver!"
  else
    echo -e "\tCurrently $CONF_UNITS SDLA card(s) are bound to FLIP driver:\n"
    for val in $CONF_NODES; do echo -e "\t/dev/$val"; done
    if [ "$CONF_IFNUM" -eq 0 ]
    then echo -e "\n\tNo FLIP interfaces configured!"
    else
      echo -e "\n\tCurrently configured $CONF_IFNUM FLIP interface(s)"
      getyn "\nWould you like to view configured interfaces" && {
        clearscr
        echo -e "device\tDLCI\tinterface number" 
        echo -e "------\t----\t----------------"
        grep -v "^#" $FLIPCONF | more
      }
    fi
  fi
  pause ""
  return 0
}

# ----------------------------------------------------------------------------
# Apply Changes.
# ----------------------------------------------------------------------------
apply_changes() {

  banner
  cat << ENDOFTEXT
	FLIP configuration file has been updated.  For the configuration
	changes to take an effect you should restart either WANPIPE or
	just FLIP subsystem.

	To restart FLIP subsytem only, down all FLIP network interfaces
	(flipNNN), then re-initialize FLIP subsystem by executing the
	following commands:

		/usr/lib/wanpipe/init/flip stop
		/usr/lib/wanpipe/init/flip start
ENDOFTEXT
  pause ""
  return 0
}

# ----------------------------------------------------------------------------
# Main Menu.
# ----------------------------------------------------------------------------
main_menu() {
  while
    banner
    echo -e "\t1) add interface"
    echo -e "\t2) delete interface"
    echo -e "\t3) show configuration"
    echo -e "\tq) quit"
    prompt "Please enter your selection (1 .. 3 or q) ->"
    case $CMD in
      1)	add_interface 	;;
      2)	del_interface	;;
      3)	show_config	;;
      q|Q)	[ "${APPLY}" -eq 0 ] || apply_changes
		break
		;;
    esac
  do
    echo ""
  done
  return 0
}

# ----------------------------------------------------------------------------
# Get current configuration.
# ----------------------------------------------------------------------------
get_config() {

  # Get a list of available FLIP ports.
  CONF_UNITS=0
  CONF_NODES=
  CONF_AVAIL=
  while read NODE TYPE PORT MEM IRQ CLK SFM BIND rest
  do [ -c /dev/$NODE ] && {
    case foo$BIND in
      foo$DEVNAME)
	CONF_UNITS=`expr $CONF_UNITS + 1`
	CONF_NODES="$CONF_NODES $NODE"
	;;

      foo-)
	CONF_AVAIL="$CONF_AVAIL $NODE"
	;;
    esac
  }
  done < $SDLACONF

  # Get FLIP interfaces configuration.
  CONF_IFNUM=`grep "^sdla[0-7]	[0-9]*	[0-9]*" $FLIPCONF | wc -l`

  return 0
}

# ----------------------------------------------------------------------------
# Prepare configuration files, etc.
# ----------------------------------------------------------------------------
prepare() {

  # Create FLIP configuration file if one does not exist.
  [ -f "$FLIPCONF" ] || {
    cat > $FLIPCONF <<-ENDOFTEXT
	# Sangoma FLIP configuration file
	# -------------------------------
	# dev	DLCI	interface number
	# ---	----	----------------
	# sdla0	16	0
ENDOFTEXT
  }
  return 0
}

# ----------------------------------------------------------------------------
# Remove temporary files, etc.
# ----------------------------------------------------------------------------
cleanup() {
  rm -f /tmp/T$$.* 2> /dev/null
}

###### MAIN ##################################################################
# set -x

# Check user permissions.
[ "$LOGNAME" = root ] || {
	error "You should be logged in as a superuser to run this script"
	exit 1
}

# Read meta-configuration file.
[ -f $WANPIPE_RC ] || {
	error "Configuration file $WANPIPE_RC not found"
	exit 1
}
. $WANPIPE_RC

# Set default configuration.
WANPIPE_VERSION=${WANPIPE_VERSION:=0.0.0}
WANPIPE_HOME=${WANPIPE_HOME:=/usr/lib/wanpipe}
WANPIPE_LOG=${WANPIPE_LOG:=/var/log/wanpipe}
WANPIPE_LOCK=${WANPIPE_LOCK:=/var/lock/wanpipe}

# Check WANPIPE configuration file presence.
[ -f "$SDLACONF" ] || {
	error "WANPIPE configuration file $SDLACONF not found"
	exit 1
}

trap '' 2
banner
prepare || exit 1
get_config
main_menu
cleanup
clearscr
exit 0
