#!/bin/bash

# Copyright Jean-Philippe Guillemin <jp.guillemin@free.fr>. This program is free software;
# you can redistribute it and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2 of the License,
# or (at your option) any later version. Please take a look at http://www.gnu.org/copyleft/gpl.htm

# Networkconfig is a simple GTK/NCURSES network setting tool for Zenwalk Linux


# version='1.0'  	# - 01/12/2005 Birth
# version='1.1'  	# - 03/12/2005 Added driver information
# version='1.2'  	# - 08/01/2006 Added wifi configuration
# version='1.3'  	# - 05/02/2006 Added wpa_supplicant configuration
# version='1.4'  	# - 30/04/2006 Removed wifi, now handled by wifi-radar
						# - Removed temp directory
# version='1.5'  	# - 01/05/2006 Added support to control STATUS up down
version='1.6'  	# - 18/04/2007 Fixed bug in domain name handling

# Take a look at "Xdialog" and use it instead of "dialog" in case X is running
if [[ "$DISPLAY" && "$(which Xdialog 2>&1 | grep -v "which: no")" ]]; then
	dialog="Xdialog --wrap --left"
	shortttl='3000'
	longttl='8000'
	xflag='yes'
else
	dialog="dialog"
	shortttl=''
	longttl=''
	xflag='no'
fi

# Set the locale in en_US, to avoid problems with Xlib
LANG=en_US

# Path needs to be extended in case you're only half a root :)
export PATH="${PATH}:/usr/sbin:/sbin"

# create the buffer directory
buffer="$(mktemp -d -p /tmp temp.XXXXXXXX)"

# Some globals

MAXNICS=4
inetconf='/etc/rc.d/rc.inet1.conf'
resolv='/etc/resolv.conf'
hosts='/etc/hosts'
hostnamefile='/etc/HOSTNAME'
rcinet1='/etc/rc.d/rc.inet1'
dhcpclient='/sbin/dhcpcd'

# Save some config files
cat $inetconf > $inetconf.old
cat $hosts > $hosts.old
cat $resolv > $resolv.old


###############################################
# About networkconfig ?

about() {
$dialog --title "$(basename $0)" \
--auto-placement \
--icon "networkconfig" \
--msgbox \
"\n$(basename $0) $version\n$(basename $0) is a simple Network setting tool \
with both ncurses and GTK  frontends. \
Copyright   Jean-Philippe Guillemin   <jp.guillemin@free.fr>. \
$(basename $0)  is released under the  GNU  General Public License." 12 75
}


###############################################
# Get network parameters from system

getsysteminfo() {

# Get the configuration information from /etc/rc.d/rc.inet1.conf:
. /etc/rc.d/rc.inet1.conf


for ((i=0; i <= $MAXNICS ; i++)) ; do
  [ ! -d /sys/class/net/eth${i} ] && continue

  IFNAME[$i]="${IFNAME[$i]:=eth${i}}"
  USE_DHCP[$i]="${USE_DHCP[$i]:=no}"

  if ifconfig -s | grep -q "eth${i}" ; then
    state[$i]="up"
  else
    state[$i]="down"
  fi

  STATUS[$i]="${STATUS[$i]:=${state[$i]}}"

  carrier[$i]="$( cat /sys/class/net/eth${i}/carrier 2>/dev/null )"
  if [ "${carrier[$i]}" != "0" ] ; then
    carrier[$i]="yes"
  else
    carrier[$i]="no"
  fi

  mac[$i]="$( cat /sys/class/net/eth${i}/address 2>/dev/null )"
  driver[$i]="$(ethtool -i eth$i 2>/dev/null | grep "^driver:" | cut -d ":" -f 2 )"
  duplex[$i]="$(ethtool eth$i 2>/dev/null | grep "Duplex:" | cut -d ":" -f 2 )"
  speed[$i]="$(ethtool eth$i 2>/dev/null | grep "Speed:" | cut -d ":" -f 2 )"


  [ "${DHCP_KEEPRESOLV[$i]}" != "yes" ] && DHCP_KEEPRESOLV[$i]="no"
  [ "${DHCP_KEEPGW[$i]}" != "yes" ] && DHCP_KEEPGW[$i]="no"

  IPADDR[$i]="$(ifconfig eth$i | grep inet | awk '{print $2}' | sed -e 's/^.*addr:\([0-9\.]*\)$/\1/')"
  NETMASK[$i]="$(ifconfig eth$i | grep inet | awk '{print $4}' | sed -e 's/^.*Mask:\([0-9\.]*\)$/\1/')"
    
done

# getting current Gateway
GATEWAY="$(route -n | grep "^0\.0\.0\.0.*" | sed -e 's/^[0\.]*[ \t]*\([0-9\.]*\)[ \t]*[0\.]*[ \t]*.*$/\1/')"

# getting current DNS parameters
DNS1="$( grep '^nameserver' $resolv \
| grep 'nameserver' -n | grep -e "^1:" \
| sed -e 's/1:nameserver[ \t]*\(.*\)$/\1/')"
DNS2="$( grep '^nameserver' $resolv \
| grep 'nameserver' -n | grep -e "^2:" \
| sed -e 's/2:nameserver[ \t]*\(.*\)$/\1/')"
DNS3="$( grep '^nameserver' $resolv \
| grep 'nameserver' -n | grep -e "^3:" \
| sed -e 's/3:nameserver[ \t]*\(.*\)$/\1/')"

hostname="$(hostname -s)"
domain="$(hostname -d)"

}


###############################################
# Function to record parameter $1 number $2 with new value $3

recordinet() {

  if [ "$(grep "$1\[$2\]" $inetconf)" ] ; then
    sed -i "s/^[\# \t]*$1\[$2\][ \t]*=.*$/$1[$2]=\"$3\"/" $inetconf
  else
    insertpoint="$(grep "\[$2\]" $inetconf | tail -n1 | cut -d "[" -f 1 | tr -d '\042')"
    if [ "$insertpoint" ] ; then
      sed -i "/.*$insertpoint\[$2\].*/i $1[$2]=\"$3\"" $inetconf
    else
      echo "$1[$2]=\"$3\"" >> $inetconf
    fi
  fi

}

###############################################
# Print a progress bar with message $1

progressbar() {
  touch $buffer/busy
  (echo "0" ; sleep 0.1
  echo "10" ; sleep 0.3 ; echo "15" ; sleep 0.3 ; echo "20" ; sleep 0.3 ; echo "25" ; sleep 0.3
  echo "30" ; sleep 0.2 ; echo "35" ; sleep 0.2 ; echo "40" ; sleep 0.2 ; echo "45" ; sleep 0.2
  echo "50" ; sleep 0.1 ; echo "55" ; sleep 0.1 ; echo "60" ; sleep 0.1 ; echo "65" ; sleep 0.1
  echo "70" ; sleep 0.1 ; echo "75" ; sleep 0.1 ; echo "80" ; sleep 0.1 ; echo "85" ; sleep 0.1
  echo "90" ; sleep 0.1 ; echo "95" ; sleep 0.1 ; echo "100" ; sleep 0.1 ; rm -f $buffer/busy)\
  | $dialog --auto-placement --title "In progress" --gauge "$1" 0 0
}

###############################################
# What do you want to do ?

promptaction() {

i=0
n=0
ifdialog=""
for ((i=0; i <= $MAXNICS ; i++)) ; do
  if [ "${mac[$i]}" ] ; then
    if [ "${STATUS[$i]}" = "up" ] ; then
      ifdialog="$ifdialog ${IFNAME[$i]} ${IPADDR[$i]}/${NETMASK[$i]}"
    else
      ifdialog="$ifdialog ${IFNAME[$i]} ${STATUS[$i]}"
    fi
    n=$(($n+1))
  fi
done


mode=$(${dialog} \
--stdout \
--cancel-label "Exit" \
--title "Network configuration" \
--icon "networkconfig" \
--menu \
"\n Welcome to $(basename $0), please choose an option :\n\n" \
$(($n+17)) 75 $(($n+5)) \
  ${ifdialog} \
  "DNS Servers" "$DNS1  $DNS2  $DNS3" \
  "Default Gateway" "$GATEWAY" \
  "Host and Domain" "$hostname.$domain" \
  "Restart network" " " \
  "About" " " )

[ -e $buffer/busy ] && mode=""

if [ ! "$mode" ]; then
  mode="none"
fi

}


###############################################
# Show nic info
showcardinfo() {

if [ "${STATUS[$1]}" = "up" ] ; then

  parameter=$(${dialog} --stdout --title "${IFNAME[$1]} settings" --cancel-label "Back" --icon "networkconfig" \
--menu \
"\nLinked: ${carrier[$1]}\
\nDriver:${driver[$1]}\
\nDuplex:${duplex[$1]}\
\nSpeed:${speed[$1]}"\
 21 75 9 \
"Status" "${STATUS[$1]}" \
"Use DHCP" "${USE_DHCP[$1]}" \
"DHCP timeout" "${DHCP_TIMEOUT[$1]:-10}" \
"Keep DNS" "${DHCP_KEEPRESOLV[$1]}" \
"Keep GW" "${DHCP_KEEPGW[$1]}" \
"IP address" "${IPADDR[$1]}" \
"Network mask" "${NETMASK[$1]}" \
"DHCP host" "${DHCP_HOSTNAME[$1]}" )

else

  parameter=$(${dialog} --stdout --title "${IFNAME[$1]} settings" --cancel-label "Back" --icon "networkconfig" \
--menu \
"This interface is not activated"\
 19 75 7 \
"Status" "${STATUS[$1]}" \
"Use DHCP" "${USE_DHCP[$1]}" \
"DHCP timeout" "${DHCP_TIMEOUT[$1]:-10}" \
"Keep DNS" "${DHCP_KEEPRESOLV[$1]}" \
"Keep GW" "${DHCP_KEEPGW[$1]}" \
"IP address" "${IPADDR[$1]}" \
"Network mask" "${NETMASK[$1]}" \
"DHCP host" "${DHCP_HOSTNAME[$1]}" )

fi

}

###############################################
# Set STATUS[X]

setstatus() {
  current="${STATUS[$1]}"
  newvalue="$($dialog --stdout --title "Status" --no-cancel --menu "Set the state of ${IFNAME[$1]} (up/down) :" 9 75 2 "up" "" "down" "")"
  [ "$newvalue" != "down" ] && newvalue="up"

  # save parameters
  recordinet STATUS $1 $newvalue
  
  if [ "$newvalue" != "$current" ]; then
    ifconfig ${IFNAME[$1]} $newvalue
    if [ "$newvalue" = "up" ]; then
      $rcinet1 ${IFNAME[$1]}_$newvalue 1>&2 2>/dev/null &
      progressbar "Resetting status"
    fi
  fi
  
  
  current=""
}

###############################################
# Set DHCP_KEEPRESOLV[X]

setkeepresolv() {
  current="${DHCP_KEEPRESOLV[$1]}"
  newvalue="$($dialog --stdout --title "Static DNS" --no-cancel --menu "Prevent DHCP from setting DNS (yes/no) :" 9 75 2 "yes" "" "no" "")"
  #$current")"
  [ "$newvalue" != "yes" ] && newvalue="no"

  # save parameters
  if [ "$newvalue" != "$current" ]; then
    recordinet DHCP_KEEPRESOLV $1 $newvalue
  fi
  current=""
}

###############################################
# Set DHCP_KEEPGW[X]

setkeepgw() {
  current="${DHCP_KEEPGW[$1]}"
  newvalue="$($dialog --stdout --title "Static Gw" --no-cancel --menu "Prevent DHCP from setting Gateway (yes/no) :" 9 75 2 "yes" "" "no" "")"
  [ "$newvalue" != "yes" ] && newvalue="no"

  # save parameters
  if [ "$newvalue" != "$current" ]; then
    recordinet DHCP_KEEPGW $1 $newvalue
  fi
  current=""
}

###############################################
# Set DHCP_TIMEOUT[X]

setdhcptimeout() {
  current="${DHCP_TIMEOUT[$1]:-10}"
  newvalue="$($dialog --stdout --title "DHCP timeout" --no-cancel --inputbox "Set the DHCP timeout :" 11 75 "$current")"

  # save parameters
  if [ "$newvalue" != "$current" ]; then
    recordinet DHCP_TIMEOUT $1 $newvalue
  fi
  current=""
}

###############################################
# Set USE_DHCP[X]

setusedhcp() {
  current="${USE_DHCP[$1]}"
  newvalue="$($dialog --stdout --title "Use DHCP" --no-cancel --menu "Do you want to use DHCP on ${IFNAME[$1]} :" 9 75 2 "yes" "" "no" "")"

  # save parameters
  if [ "$newvalue" != "$current" ]; then
    recordinet USE_DHCP $1 $newvalue
    if [ "${STATUS[$1]}" != "down" ] ; then
      ifconfig ${IFNAME[$1]} down
	  $rcinet1 ${IFNAME[$1]}_restart 1>&2 2>/dev/null &
      progressbar "Applying configuration"
    fi
  fi
  current=""
}

###############################################
# Set IPADDR[X]

setipaddress() {
  current="${IPADDR[$1]}"
  newvalue="$($dialog --stdout --title "IP address" --no-cancel --inputbox "Enter IP address for ${IFNAME[$1]} :" 11 75 "$current")"

  # save parameters
  if [ "$newvalue" != "$current" ]; then
    recordinet IPADDR $1 $newvalue
    if [ "${STATUS[$1]}" != "down" ] ; then
      ifconfig ${IFNAME[$1]} $newvalue 1>&2 2>/dev/null
      route del -net 0.0.0.0 1>&2 2>/dev/null
      route add -net 0.0.0.0 netmask 0.0.0.0 gw $GATEWAY 1>&2 2>/dev/null
    fi
  fi
  current=""
}

###############################################
# Set NETMASK[X]

setnetmask() {
  current="${NETMASK[$1]}"
  mask="$current"
  if [ ! "$current" ]; then
    [ "$(echo ${IPADDR[$1]} | grep -e "^192\.168" )" ] && mask='255.255.255.0'
    [ "$(echo ${IPADDR[$1]} | grep -e "^172\.16" )" ] && mask='255.255.0.0'
    [ "$(echo ${IPADDR[$1]} | grep -e "^10\." )" ] && mask='255.0.0.0'
  fi

  newvalue="$($dialog --stdout --title "Network mask" --no-cancel --inputbox "Enter Network mask for ${IFNAME[$1]} :" 11 75 "$mask")"

  # save parameters
  if [ "$newvalue" != "$current" ]; then
    recordinet NETMASK $1 $newvalue
    if [ "${STATUS[$1]}" != "down" ] ; then
      ifconfig ${IFNAME[$1]} netmask $newvalue 1>&2 2>/dev/null
    fi
  fi
  current=""
}

###############################################
# Set DHCP_HOSTNAME[X]

setdhcphost() {
  current="${DHCP_HOSTNAME[$1]}"
  newvalue="$($dialog --stdout --title "DHCP host" --no-cancel --inputbox "Enter DHCP host :" 11 75 "$current")"

  # save parameters
  if [ "$newvalue" != "$current" ]; then
    recordinet DHCP_HOSTNAME $1 $newvalue
  fi
  current=""
}


###############################################
# Set GATEWAY address

setGATEWAY() {
  current="$GATEWAY"
  newvalue="$($dialog --stdout --title "Gateway" --no-cancel --inputbox "Enter the default Gateway IP address :" 11 75 "$current")"

  # save parameters
  if [ "$newvalue" != "$current" ]; then
    if [ "$(grep "GATEWAY" $inetconf)" ] ; then
      sed -i "s/^[\# \t]*GATEWAY[ \t]*=.*$/GATEWAY=\"$newvalue\"/" $inetconf
    else
      echo "GATEWAY=\"$newvalue\"" >> $inetconf
    fi
    route del -net 0.0.0.0 1>&2 2>/dev/null
    route add -net 0.0.0.0 netmask 0.0.0.0 gw $newvalue 1>&2 2>/dev/null
  fi



  current=""
}


###############################################
# Set DNS servers

setdns() {
  current1="$DNS1"
  current2="$DNS2"
  current3="$DNS3"

  if [ ! "$dialog" = "dialog" ]; then
    newvalue="$($dialog --stdout --title "DNS servers" --no-cancel --3inputsbox "Enter DNS servers IP addresses :" 16 75 \
    "DNS1" "$current1" \
    "DNS2" "$current2" \
    "DNS3" "$current3")"
    newvalue1="$(echo $newvalue | cut -d / -f 1 )"
    newvalue2="$(echo $newvalue | cut -d / -f 2 )"
    newvalue3="$(echo $newvalue | cut -d / -f 3 )"
  else
    newvalue1="$($dialog --stdout --title "DNS servers" --no-cancel --inputbox "Enter DNS server 1 :" 11 65 "$current1")"
    newvalue2="$($dialog --stdout --title "DNS servers" --no-cancel --inputbox "Enter DNS server 2 :" 11 65 "$current2")"
    newvalue3="$($dialog --stdout --title "DNS servers" --no-cancel --inputbox "Enter DNS server 3 :" 11 65 "$current3")"
  fi

  # save parameters
    echo -n "" > $resolv
    [ "$domain" ] && echo "search $domain" >> $resolv
    [ "$domain" ] && echo "domain $domain" >> $resolv
    [ "$newvalue1" ] && echo "nameserver $newvalue1" >> $resolv
    [ "$newvalue2" ] && echo "nameserver $newvalue2" >> $resolv
    [ "$newvalue3" ] && echo "nameserver $newvalue3" >> $resolv
}

###############################################
# Set Hostname and Domain name

sethostanddomain() {
  current1="$hostname"
  current2="$domain"

  if [ ! "$dialog" = "dialog" ]; then
    newvalue="$($dialog --stdout --title "Host and domain" --no-cancel --2inputsbox "Enter the Hostname and Domain name :" 15 75 \
    "Hostname" "$current1" \
    "Domain" "$current2")"
    newvalue1="$(echo $newvalue | cut -d / -f 1 )"
    newvalue2="$(echo $newvalue | cut -d / -f 2 )"
  else
    newvalue1="$($dialog --stdout --title "Hostname" --no-cancel --inputbox "Enter the Hostname :" 11 75 "$current1")"
    newvalue2="$($dialog --stdout --title "Domain" --no-cancel --inputbox "Enter the Domain name :" 11 75 "$current2")"
  fi

  # save parameters
    # hosts file
    noloopback="$(grep -v "^127.0.0.1" $hosts)"
    echo "$noloopback" > $hosts
    echo "127.0.0.1		localhost" >> $hosts
    if [ "$newvalue2" ]; then
      echo "127.0.0.1		$newvalue1.$newvalue2 $newvalue1" >> $hosts
    else
      echo "127.0.0.1		$newvalue1" >> $hosts
    fi
    
    # HOSTNAME file
    if [ "$newvalue2" ]; then
      echo "$newvalue1.$newvalue2" > $hostnamefile
    else
      echo "$newvalue1" > $hostnamefile
    fi
    
    # resolv.conf file
    if [ "$newvalue2" ]; then
      nodomain="$(sed -e '/^search[ \t]*.*$/d' -e '/^domain[ \t]*.*$/d' $resolv)"
      echo "search $newvalue2" > $resolv
      echo "domain $newvalue2" >> $resolv
      echo "$nodomain" >> $resolv
    fi
    
    hostname -F $hostnamefile
}


###############################################
# Set network parameters for nic number $1

setnic() {

while [ "1" = "1" ] ; do
  showcardinfo $1
  if [ "$parameter" ]; then
    case $parameter in
		Name)
		  setifname $1
		  getsysteminfo
		  ;;
		Status)
		  setstatus $1
		  getsysteminfo
		  ;;
		Use\ DHCP)
		  setusedhcp $1
		  getsysteminfo
		  ;;
		Keep\ DNS)
		  setkeepresolv $1
		  getsysteminfo
		  ;;
		DHCP\ timeout)
		  setdhcptimeout $1
		  getsysteminfo
		  ;;
		Keep\ GW)
		  setkeepgw $1
		  getsysteminfo
		  ;;
		IP\ address)
		  if [ "${USE_DHCP[$1]}" = 'yes' ]; then
		    $dialog --ok-label "Close" --title "DHCP mode activated" --msgbox "Please deactivate DHCP before setting the IP address manually" 8 70
		  else
		    setipaddress $1
		    getsysteminfo
		  fi
		  ;;
      Network\ mask)
		  if [ "${USE_DHCP[$1]}" = 'yes' ]; then
		    $dialog --ok-label "Close" --title "DHCP mode activated" --msgbox "Please deactivate DHCP before setting the network mask manually" 8 70
		  else
		    setnetmask $1
		    getsysteminfo
		  fi
		  ;;
		DHCP\ host)
		  setdhcphost $1
		  getsysteminfo
    esac
  else
    break
  fi
done

}

###############################################
# main()

getsysteminfo

while [ "1" = "1" ] ; do
  n=''
  promptaction
  case $mode in
    eth*)
      n="$(echo $mode | sed -e 's/^eth\([0-9]*\)$/\1/')"
      setnic $n
      getsysteminfo
      ;;
    Default\ Gateway)
		setGATEWAY
		getsysteminfo
		;;
    DNS\ Servers)
		setdns
		getsysteminfo
		;;
    Host\ and\ Domain)
		sethostanddomain
		getsysteminfo
		;;
    Restart\ network)
      $rcinet1 restart 1>&2 2>/dev/null &
      progressbar "Restarting network"
      getsysteminfo
      ;;
    About)
      if [ "$xflag" = "yes" ] ; then
        ( sleep 1 ; about ) &
      else
        about
      fi
      ;;
    none)
      exit
  esac
done

# end
