#!/bin/sh
# @vasm : vnetset
# @level: root
# @description: Set up a network connection
# 
# (c) Eko M. Budi, 2003
# (c) VLocity Linux, 2003
#
# Released under GNU GPL

vdir=$(dirname $0)
source $vdir/vasm-functions

dbug "Starting $0"

check_root

# Properties
rc_prefix="/etc/rc.d/rc."
inet_prefix="${rc_prefix}inet"
inet_files="${inet_prefix}?"

# Get the inet values from file
function get_inet()
{
  DEVICE=""
  NETNAME=""
  IPADDR=""
  NETMASK=""
  GATEWAY=""
  PROBE="no"
  inet_file=$1
  eval `grep -e '^DEVICE=' $inet_file`
  eval `grep -e '^IPADDR=' $inet_file`
  eval `grep -e '^NETMASK=' $inet_file`
  eval `grep -e '^GATEWAY=' $inet_file`
  eval `grep -e '^DHCP=' $inet_file`
  eval `grep -e '^PROBE=' $inet_file`
  
  HOSTNAME=`cat /etc/HOSTNAME`
}

# Set the values back
function set_inet()
{
  inet_file=$1
  cat $inet_file | sed "
  s#^DEVICE=.*#DEVICE=$DEVICE# 
  s#^IPADDR=.*#IPADDR=$IPADDR# 
  s#^NETMASK=.*#NETMASK=$NETMASK# 
  s#^GATEWAY=.*#GATEWAY=$GATEWAY# 
  s#^DHCP=.*#DHCP=$DHCP# 
  s#^PROBE=.*#PROBE=$PROBE#" > $inet_file
}

# add_host 
# add host entry to etc/hosts
# IPADDR and HOST_NAME must be set
function set_hosts()
{
    if [ ! -f /etc/hosts ]; then
	dbug "Creating a new /etc/hosts"
cat << EOF > /etc/hosts
#
# hosts	This file describes a number of hostname-to-address
#	mappings for the TCP/IP subsystem.  It is used as:
#	1. A static mapping without a DNS server for localhost
#       2. A table for dnsmasq
#
# By the way, Arnt Gulbrandsen <agulbra@nvg.unit.no> says that 127.0.0.1
# should NEVER be named with the name of the machine.  It causes problems
# for some (stupid) programs, irc and reputedly talk. :^)

# localhost loopback, must present
127.0.0.1       localhost

# hostname loopback, only if absolutely no network
#127.0.0.1 $HOST_NAME ${HOST_NAME%%.*}

EOF

    fi

    dbug "Modifying /etc/hosts"
    mv /etc/hosts /etc/hosts.bak 
    IPADDR=${IPADDR:-127.0.0.1}
    cat /etc/hosts.bak | while read line; do
	if echo $line | grep -qe '^127\.0\.0\.1.*localhost'; then
    	    # the must presents loopback
	    echo $line >> /etc/hosts
	elif echo $line | grep -qE '^#*127\.0\.0\.1 '; then
    	    # presents for NO NETWORK only
	    if [ "$IPADDR" = "127.0.0.1" ]; then
		echo "127.0.0.1   $HOST_NAME ${HOST_NAME%%.*}" >> /etc/hosts
	    else
	        echo "#127.0.0.1   $HOST_NAME ${HOST_NAME%%.*}" >> /etc/hosts
	    fi
	elif echo $line | grep -qe "^$IPADDR "; then
	    # skip our IPADDR, since we are going to add a new one
	    continue
	else
	    # write the rest
	    echo "$line" >> /etc/hosts
	fi
    done
    # add the new one if not NO NETWORK
    if [ "$IPADDR" != "127.0.0.1" ]; then
	echo "$IPADDR   $HOST_NAME ${HOST_NAME%%.*}" >> /etc/hosts
    fi
}


function build_inet_menu()
{
   count=0
   for file in $inet_files; do
     if [ -x $file ]; then
       get_inet $file
       inet=${file##${rc_prefix}}
       if [ "$DHCP" = "yes" ]; then
	  echo "$inet \"DEVICE=$DEVICE, DHCP\" \\"
       else
	  echo "$inet \"DEVICE=$DEVICE, IPADDR=$IPADDR\" \\"
       fi    	
       let count++
     fi
   done
   if [ $count == 0 ]; then
     errorbox "No network connection. Add one first, mate !"
     clean_exit 1 
   fi
}

function build_dev_menu()
{
   DUMMY=dummy0
   for DEV in `ifconfig -a | grep -e "[a-z]" | cut -f 1 -d " "`; do
      # skip loopback
      if [ "$DEV" = "lo" ] || [ "$DEV" = "dummy0" ]; then
         continue
      fi
      # add the device
      echo "\"$DEV\"" "\"Primary $DEV\" \\"
      for VDEV in 1 2 3; do
         echo "\"$DEV:$VDEV\"" "\"Alternate $DEV - $VDEV\" \\"
      done
   done
   # Add dummy
   echo 'dummy0 "Dummy interface for in-host network" \'
}


##################################################
# List active network connection, ask one to set
function menuA() {
  DIMENSION="15 60 4"
  TITLE="SET NETWORK"
  TEXT="\n
This is the list of the active network connections.\n
Select the one you want to set then press OK."

  echo '$DCMD --backtitle "$BACKTITLE" --title "$TITLE" --menu "$TEXT" $DIMENSION \' > $fmenu
  build_inet_menu >> $fmenu
  echo '2> $freply' >> $fmenu

#  cat $fmenu
  source $fmenu
  
  status=$?
  [ $status != 0 ] && return $status

  inet=$(cat $freply)
  inet_file="${rc_prefix}$inet"
  get_inet $inet_file
  return 0   
}

########################################################
# Ask a device
function menuB() {
TITLE="SET NETWORK DEVICE"
TEXT="\n
We are about to setup a TCP/IP networking for $inet. First,\n
let's select a network device. Generally, you should chose a\n
primary device (like eth0) from the list below. Use the\n
alternate device (like eth0:1) for multiple IP configuration,\n
mostly useful for a server or a laptop. Do not use the same\n
device for more then one connection.\n
If your NIC is not in the list, I'm afraid you have to reload\n
or reconfigure the kernel modules (using autosetup or manual)."
DIMENSION="20 70 5"

echo '$WCMD --backtitle "$BACKTITLE" --title "$TITLE" --menu "$TEXT" $DIMENSION \' > $fmenu
build_dev_menu >> $fmenu
echo ' 2> $freply' >> $fmenu

source $fmenu

status=$?
[ $status != 0 ] && return $status

DEVICE=$(cat $freply)
return 0
}

########################################################
# Ask Mode DHCP, STATIC, PROBE
function menuC() {
TITLE="SET NETWORK METHOD"
TEXT="\n
Now we need to know how the device $DEVICE can get its IP address.
DHCP is the automatic method. Use it if you are connected to a dynamic 
network like cable modem, DSL or your administrator tell to do so. 
Select STATIC if you surely have an IP address for this machine. 
PROBE is a STATIC method with network testing, useful for a laptop."

$WCMD --backtitle "$BACKTITLE" --title "$TITLE" --menu "$TEXT" 17 68 3 \
  "DHCP"   "Automatic using Dynamic Host Control Protocol" \
  "STATIC" "Manual TCP/IP configuration" \
  "PROBE"  "Static but only if the network is reachable" \
  2> $freply

status=$?
[ $status != 0 ] && return $status

case $(cat $freply) in
    DHCP)
      PROBE="no"
      DHCP="yes"
      infobox "Configuring network $inet with DHCP ..."
      set_inet $inet_file
      $inet_file start
      sleep 2
      clean_exit 0
      ;;
    STATIC)
      PROBE="no"
      DHCP="no"
      ;;
    PROBE)
      PROBE="yes"
      DHCP="no"
      ;;
esac
return 0
}

########################################################
# Ask an IP Address
function menuD() {
TITLE="SET NETWORK IP ADDRESS"
TEXT="\n
Let's assign a static IP for $DEVICE. If you are connected to\n
an official network (campus, office, etc), you must get the\n
IP address from the administrator.\n
However, if you are on your own network, you may assign an\n
arbitrary IP address from the standard internal IP range:\n
  192.168.0.1 - 192.168.255.254\n
  172.16.0.1  - 172.31.255.254\n
  10.0.0.1 - 10.255.255.254\n\n
Please enter the IP address:"
DIMENSION="20 70"

# Default values
IPADDR=${IPADDR:-"192.168.0.1"}

while [ 0 ]; do
  $WCMD --backtitle "$BACKTITLE" --title "$TITLE" \
  --inputbox "$TEXT" $DIMENSION $IPADDR 2> $freply

  status=$?
  [ $status != 0 ] && return $status

  reply=$(cat $freply)
  
  # check the IP
  ipmask 0.0.0.0 $reply &> /dev/null
  if [ $? = 0 ]; then
     IPADDR=$reply
     return 0  
  fi
  retrybox "Invalid IP address"
done

}

########################################################
# Ask a Netmask
function menuE() {
while [ 0 ]; do

TITLE="SET NETWORK NETMASK"
TEXT="\n
NETMASK is a pair of IPADDR. It looks kinda like this:\n
   255.255.255.0\n
You should get it from your administrator, unless\n
you are on your own network.\n\n
Please enter it now."
DIMENSION="14 60"

# Default values
NETMASK=${NETMASK:-"255.255.255.0"}

  $WCMD --backtitle "$BACKTITLE" --title "$TITLE" \
  --inputbox "$TEXT" $DIMENSION $NETMASK 2> $freply

  status=$?
  [ $status != 0 ] && return $status

  reply=$(cat $freply)
  
  # check the IP
  ipmask $reply $IPADDR &> /dev/null
  if [ $? = 0 ]; then
     NETMASK=$reply
     return 0  
  fi
  retrybox "Invalid Netmask"
done
}

########################################################
# Ask a Gateway 
function menuF() {
# Default values
if [ -z "$GATEWAY" ]; then
   GATEWAY="${IPADDR%.*}.254"
fi
while [ 0 ]; do

TITLE="SET NETWORK GATEWAY"
if [ "$PROBE" = "yes" ]; then
TEXT="\n
A gateway is the computer that forwards network traffic\n
to the bigger network (most likely the internet). You need\n
the IP address of the gateway. Since you selected PROBE\n
mode, this inet will be up if the gateway is reachable.\n\n
Please enter the IP address of the gateway:"
DIMENSION="15 66" 
else
TEXT="\n
A gateway is the computer that forwards network traffic\n
to the bigger network (most likely the internet). You\n
should get this information from your administrator.\n
Leave it empty if this inet does not have a gateway.\n\n
Please enter the IP address of the gateway:"
DIMENSION="14 66"
fi


  $WCMD --backtitle "$BACKTITLE" --title "$TITLE" \
  --inputbox "$TEXT" 17 68 $GATEWAY 2> $freply

  status=$?
  [ $status != 0 ] && return $status

  GATEWAY=$(cat $freply)
  
  # check the IP
  [ -z "$GATEWAY" ] && return 0

  if ipmask $NETMASK $GATEWAY &> /dev/null; then
     return 0  
  fi
  retrybox "Invalid Gateway"
done
}

menuG()
{
   infobox "Configuring $inet"
   set_inet $inet_file
   set_hosts
   $inet_file start
   sleep 2
   clean_exit
}

###############################################################
# MAIN 
if [ "$1" ] && [ -x "${rc_prefix}$1" ]; then
  inet=$1
  inet_file="${rc_prefix}$inet"
  get_inet $inet_file
  wizard menuB menuC menuD menuE menuF menuG
else
  wizard menuA menuB menuC menuD menuE menuF menuG
fi
clean_exit

