#!/bin/bash
# netcardconfig - A very light-weight text-based network configuration tool.
# (C) Klaus Knopper Nov 2002
# License: GPL
# This program was modified by B2D team (http://ftp3.tnc.edu.tw/b2d/netcardconfig/netcardconfig).
# 2007/09/18 Modified by Steven Shiau to be used in clonezilla live.

# Load DRBL setting and functions
DRBL_SCRIPT_PATH="${DRBL_SCRIPT_PATH:-/usr/share/drbl}"

. $DRBL_SCRIPT_PATH/sbin/drbl-conf-functions
. /etc/drbl/drbl-ocs.conf
. $DRBL_SCRIPT_PATH/sbin/ocs-functions

# Load the config in ocs-live.conf. This is specially for Clonezilla live. It will overwrite some settings of /etc/drbl/drbl-ocs.conf, such as $DIA...
[ -e "/etc/ocs/ocs-live.conf" ] && . /etc/ocs/ocs-live.conf

# Default settings
default_dns_server="8.8.8.8"
# default_link_det_timeout is loaded from drbl-ocs.conf
default_IP="192.168.120.1"
default_NM="255.255.255.0"
config_gw="yes"
config_dns="yes"
# ocs_nic_type can be from boot parameters, or assigned in command line.
# It will used in ask_nic_dev. 
ocs_nic_type_def="wired"  # Default to use wired network device.

#
check_if_root

# Functions
bailout(){
  rm -f "$TMP"
  exit $1
}
USAGE() {
   echo "Usage: $0 [OPTION] MODE [MODE2]"
   echo "OPTION"
   dialog_like_prog_help_prompt
   echo " -i, --ip-add  IP_ADD    Assign the IP address shown in the dialog as IP_ADD."
   echo " -n, --netmask NETMASK   Assign the netmask shown in the dialog as NETMASK."
   echo " -g, --gateway GATEWAY   Assign the gateway shown in the dialog as GATEWAY."
   echo " -s, --dns     DNS       Assign the domain name server shown in the dialog as DNS."
   echo " -t, --timeout TIME      Assign the timeout to get the linking status of each NIC. Unit: sec. Default is $default_link_det_timeout secs."
   echo " --ignore-gw             Do not set default gateway."
   echo " --ignore-dns            Do not set domain name server."
   echo " -r, --ignore-dv  DV     Do not config network device DV, such as 'eth1 eth2'."
   echo " -w, --nic-type TYPE     Use TYPE (wired or wireless) for the network deivce."
}
#
cfg_by_dhcp(){
  local dhclient_verbose_opt
  # Before using dhclient, we create /etc/resolv.conf to suppress the warning! Since /etc/resolv.conf is removed when Debian Live is created by live package.
  touch /etc/resolv.conf
  echo "$msg_send_dhcp_request_from $DV"
  # Test if "-v" is supported by dhclient
  # For version 4,
  # Usage: dhclient [-4|-6] [-SNTP1dvrx] [-nw] [-p <port>] [-s server]
  #                 [-cf config-file] [-lf lease-file][-pf pid-file] [-e VAR=val]
  #      	    [-sf script-file] [interface]
  # For version 3,
  # Usage: dhclient [-1dqrx] [-nw] [-p <port>] [-s server]
  #                 [-cf config-file] [-lf lease-file][-pf pid-file] [-e VAR=val]
  #       	    [-sf script-file] [interface]
  # 
  if [ -n "$(LC_ALL=C dhclient --help 2>&1 | grep -Ewo -- "-[[:alnum:]]*v[[:alnum:]]*")" ]; then
   dhclient_verbose_opt="-v"
  fi
  # Force to make timeout as 60. Debian uses 60, but Ubuntu uses 300. Too long.
  # Thanks to Cecile, Adam (Adam.Cecile _at_ hitec lu) for reporting this.
  perl -pi -e "s/^timeout.*/timeout 60;/g" /etc/dhcp/dhclient.conf
  dhclient $dhclient_verbose_opt $DV
  rc="$?"
  if [ "$rc" != "0" ]; then
    echo "$msg_failed"
    echo -n "$msg_press_enter_to_exit "
    read a
  else
    echo -n "OK. Now writing the setting to network config file... "
    # Debian: Add dhcp broadcast entry
    if [ -w /etc/network/interfaces ]; then
      # we need loopback device, otherwise portmap & nfs-common will fail
      if ! grep -E -q -e "^auto[[:space:]]+lo" /etc/network/interfaces; then
        cat >/etc/network/interfaces <<EOF
# The loopback network interface
auto lo
iface lo inet loopback
EOF
        # turn it on now.
        ifconfig lo up
      fi
      rm -f "$TMP"
      awk '/iface/{if(/'"$DV"'/){found=1}else{found=0}}
           {if(!found){print}}
           END{print "\niface '"$DV"' inet dhcp\n\n"}' \
           /etc/network/interfaces >"$TMP"
      # Add an "auto" entry
      if grep -E -q -e "^auto[ 	]+.*$DV" /etc/network/interfaces; then
        cat "$TMP" >/etc/network/interfaces
      else
        awk '{if(/^auto/){print $0 " '"$DV"'"}else{print}}' "$TMP" > /etc/network/interfaces
      fi
      rm -f "$TMP"
    fi
    echo "Done!"
  fi
  return $rc
} # end of cfg_by_dhcp
#
cfg_static_ip() {
# RedHat
if [ -f "/etc/sysconfig/network-scripts/ifcfg-$DV" ]
  then
  . "/etc/sysconfig/network-scripts/ifcfg-$DV"
  IP="$IPADDR"
  NM="$NETMASK"
fi

# RedHat
if [ -f "/etc/sysconfig/network" ]; then
  . "/etc/sysconfig/network"
  DG="$GATEWAY"
fi

# Debian
if [ -f /etc/network/interfaces ]; then
  awk '/iface/{if(/'"$DV"'/){found=1}else{found=0}} 
       /address/{if(found){address=$NF}}
       /netmask/{if(found){netmask=$NF}}
       /gateway/{if(found){gateway=$NF}}
     END{print address" "netmask" "broadcast" "gateway}' /etc/network/interfaces >"$TMP"
  read IP NM DG <"$TMP"
  rm -f "$TMP"
fi

#
if [ -f "/etc/resolv.conf" ]; then
  NS="$(awk '/^nameserver/{printf "%s ",$2}' /etc/resolv.conf)"
fi

# if IP address is assigned as a parameter
[ -n "$ip_add_prompt" ] && IP="$ip_add_prompt"
[ -n "$netmask_prompt" ] && NM="$netmask_prompt"
[ -n "$gateway_prompt" ] && DG="$gateway_prompt"
[ -n "$dns_prompt" ] && NS="$dns_prompt"

$DIA --inputbox "$msg_enter_IP_add_for_this_nic $DV" 10 45 "${IP:-$default_IP}" 2>"$TMP" || bailout 1
read IP <"$TMP" ; rm -f "$TMP"

$DIA --inputbox "$msg_enter_netmask_for_this_nic $DV" 10 45 "${NM:-$default_NM}" 2>"$TMP" || bailout 1
read NM <"$TMP" ; rm -f "$TMP"

# Steven commented this one. System can get broadcast from IP address and netmask. Therefore it's not necessary to ask.
#$DIA --inputbox "$MESSAGE8 $DV" 10 45 "${BC:-${IP%.*}.255}" 2>"$TMP" || bailout 1
#read BC <"$TMP" ; rm -f "$TMP"

if [ "$config_gw" = "yes" ]; then
  $DIA --inputbox "$msg_enter_default_gateway" 10 45 "${DG:-${IP%.*}.254}" 2>"$TMP"
  read DG <"$TMP" ; rm -f "$TMP"
else
  DG=""
fi

if [ "$config_dns" = "yes" ]; then
  $DIA --inputbox "$msg_enter_dns_server" 10 45 "$default_dns_server" 2>"$TMP"
  read NS <"$TMP" ; rm -f "$TMP"
else
  NS=""
fi

CMD="ifconfig $DV $IP netmask $NM up"
echo "$CMD"
$CMD

# Add entry for Redhat init scripts
if [ -d /etc/sysconfig/network-scripts ]; then
  cat >/etc/sysconfig/network-scripts/ifcfg-$DV <<EOF
DEVICE=$DV
IPADDR=$IP
NETMASK=$NM
ONBOOT=yes
EOF
  chmod 755 /etc/sysconfig/network-scripts/ifcfg-$DV
fi

if [ -n "$DG" ]; then
  CMD="route add default gw $DG"
  echo "$CMD"
  $CMD
  # Add entry to /etc/sysconfig/network
  if [ -w /etc/sysconfig/network ]; then
    grep -v ^GATEWAY /etc/sysconfig/network >"$TMP"
    cat >"$TMP" <<EOF
GATEWAY=$DG
GATEWAYDEV=$DV
EOF
    cat "$TMP" > /etc/sysconfig/network
    rm -f "$TMP"
  fi
fi

# Debian
if [ -w /etc/network/interfaces ]; then
  # we need loopback device, otherwise portmap & nfs-common will fail
  if ! grep -E -q -e "^auto[[:space:]]+lo" /etc/network/interfaces; then
    cat >/etc/network/interfaces <<EOF
# The loopback network interface
auto lo
iface lo inet loopback
EOF
    # turn it on now.
    ifconfig lo up
  fi

  awk '/iface/{if(/'"$DV"'/){found=1}else{found=0}}
       {if(!found){print}}
       END{print "\niface '"$DV"' inet static\n\taddress '"$IP"'\n\tnetmask '"$NM"'\n\t";if("'"$DG"'"!=""){print "\tgateway '"$DG"'"};print "\n"}' \
       /etc/network/interfaces >"$TMP"
  # Add an "auto" entry
  if grep -E -q -e "^auto[ 	]+.*$DV" /etc/network/interfaces; then
    cat "$TMP" >/etc/network/interfaces
  else
    awk '{if(/^auto/){print $0 " '"$DV"'"}else{print}}' "$TMP" > /etc/network/interfaces
  fi
fi

if [ -n "$NS" ]; then
  more=""
  for i in $NS; do
    if [ -z "$more" ]; then
      more=yes
      echo "$msg_put_dnsserver_to_resolv_conf $i"
      echo "nameserver $i" >/etc/resolv.conf
      else
      echo "$msg_append_dnsserver_to_resolv_conf $i"
      echo "nameserver $i" >>/etc/resolv.conf
    fi
  done
fi

echo "Done."
sleep 0.5
} # end of cfg_static_ip
#
cfg_pppoe(){
  pppoeconf
} # end of cfg_pppoe

##############
#### MAIN ####
##############

#
while [ $# -gt 0 ]; do
  case "$1" in
    -l|--language)
        shift
        if [ -z "$(echo $1 |grep ^-.)" ]; then
          # skip the -xx option, in case 
	  specified_lang="$1"
          shift
        fi
	;;
    -d0|--dialog)   DIA="dialog"; shift;;
    -d1|--Xdialog)  DIA="Xdialog"; shift;;
    -d2|--whiptail) DIA="whiptail"; shift;;
    -d3|--gdialog)  DIA="gdialog"; shift;;
    -d4|--kdialog)  DIA="kdialog"; shift;;
    -i|--ip-add)
	shift
        if [ -z "$(echo $1 |grep ^-.)" ]; then
          # skip the -xx option, in case 
	  ip_add_prompt="$1"
	  shift
        fi
	;;
    -n|--netmask)
	shift
        if [ -z "$(echo $1 |grep ^-.)" ]; then
          # skip the -xx option, in case 
	  netmask_prompt="$1"
	  shift
        fi
	;;
    -g|--gateway)
	shift
        if [ -z "$(echo $1 |grep ^-.)" ]; then
          # skip the -xx option, in case 
	  gateway_prompt="$1"
	  shift
        fi
	;;
    -s|--dns)
	shift
        if [ -z "$(echo $1 |grep ^-.)" ]; then
          # skip the -xx option, in case 
	  dns_prompt="$1"
	  shift
        fi
	;;
    -t|--timeout)
	shift
        if [ -z "$(echo $1 |grep ^-.)" ]; then
          # skip the -xx option, in case 
	  ocs_netlink_timeout="$1"
	  shift
        fi
	;;
    --ignore-gw)  config_gw="no"; shift;;
    --ignore-dns) config_dns="no"; shift;;
    -r|--ignore-dv)
	shift
        if [ -z "$(echo $1 |grep ^-.)" ]; then
          # skip the -xx option, in case 
          skip_nic_dv="$1"
	  shift
        fi
	;;
    -w|--nic-type) 
	shift
        if [ -z "$(echo $1 |grep ^-.)" ]; then
          # skip the -xx option, in case 
          ocs_nic_type="$1"
	  shift
        fi
	;;
    -*) echo "${0}: ${1}: invalid option" >&2
        USAGE >& 2
        exit 2 ;;
    *)  break ;;
  esac
done
DV="$*"

#
ask_and_load_lang_set $specified_lang

# check DIA
check_DIA_set_ESC $DIA

# 
TMP="$(mktemp /tmp/netmenu.XXXXXX)"
trap "[ -f "$TMP" ] && rm -f $TMP" HUP INT QUIT TERM EXIT

[ -z "$ocs_netlink_timeout" ] && ocs_netlink_timeout="$default_link_det_timeout"

netdev_type_on_system="$(get_netdev_type_on_system)"
[ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
echo "Found NIC type on this system: $netdev_type_on_system"
[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL

if [ -z "$ocs_nic_type" ]; then
  # Another way to detect is /proc/net/wireless, and its content is like:
  # Inter-| sta-|   Quality        |   Discarded packets               | Missed | WE
  #  face | tus | link level noise |  nwid  crypt   frag  retry   misc | beacon | 22
  # wlp4s0: 0000   68.  -42.  -256        0      0      0      0    154        0
  # However, /proc/net/wirless seems to be not working well for USB wireless
  # device. Even when it's plugged, it's not shown in /proc/net/wirless.
  case $netdev_type_on_system in
    "wired")    ocs_nic_type="wired";;
    "wireless") ocs_nic_type="wireless";;
    "none") 
      show_nic_dev_status_on_system
      echo "$msg_program_stop!"
      my_ocs_exit 1
      ;;
    "both")
      # Ask which one to use
      $DIA  --title  \
      "Wired or wireless network" --menu "$msg_choose_wired_or_wireless" \
      0 0 0 $DIA_ESC \
      "wired"    "$msg_use_wired" \
      "wireless" "$msg_use_wireless" \
      "exit"     "$msg_exit" \
      2> $TMP
      ocs_nic_type="$(cat $TMP)"
      [ -f "$TMP" ] && rm -f $TMP
      ;;
  esac
fi
if [ "$ocs_nic_type" = "exit" ]; then
  echo "$msg_program_stop!"
  exit 5
fi
[ -z "$ocs_nic_type" ] && ocs_nic_type="$ocs_nic_type_def"
# Make ocs_nic_type as a global variable so that ocs-live-nicbonding can use it.
export ocs_nic_type

#
if [ -z "$DV" ]; then
  ask_nic_dev -e "$msg_choose_nic?" menu 1 # Obtain $chosen_nics
  DV="$chosen_nics"
else
  nic_no="$(echo $DV | wc -w)"
  if [ "$nic_no" -ne 1 ]; then
     [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
     echo "You can only configure one network interface card each time."
     echo "The chosen device: $DV"
     [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
     echo "$msg_program_stop!"
     my_ocs_exit 1
  fi
fi

# Check input NIC
if [ -z "$DV" ]; then
  [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
  echo "No network interface card was assigned."
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
  echo "$msg_program_stop!"
  my_ocs_exit 1
fi

# TODO: Check if $DV exists
if [ "$DV" = "bond0" ]; then
  ocs-live-nicbonding
fi

# Use mtui for wifi connection
if [ "$ocs_nic_type" = "wireless" ]; then
  service NetworkManager start
  nmtui
  rc=$?
  exit $rc
fi

#
if [ "$ocs_net_show_pppoe" != "no" ]; then
  pppoe_msg_1="pppoe"
  pppoe_msg_2="$(rep_whspc_w_udrsc "$msg_use_pppoe_conf")"
fi
if [ "$ocs_net_show_enter_shell" != "no" ]; then
  enter_shell_msg_1="enter_shell"
  enter_shell_msg_2="$(rep_whspc_w_udrsc "$msg_enter_cml. $msg_do_it_manually")"
fi

#
$DIA  --title  \
"$msg_Network_config" --menu "$msg_choose_mode_to_setup_net: $DV" \
0 0 0 $DIA_ESC \
"dhcp"  "$msg_use_dhcp_broadcast" \
"static" "$msg_use_static_ip" \
$pppoe_msg_1 $pppoe_msg_2 \
$enter_shell_msg_1 $enter_shell_msg_2 \
2> $TMP
net_setup_mode="$(cat $TMP)"
[ -f "$TMP" ] && rm -f $TMP

case "$net_setup_mode" in
  dhcp) cfg_by_dhcp;;
  static) cfg_static_ip;;
  pppoe) cfg_pppoe;;
  enter_shell) 
      echo $msg_enter_another_shell_hint_wo_netcfg_prompt
      echo -n "$msg_press_enter_to_continue..."
      read
      /bin/bash
      ;;
esac

rc=$?
if [ "$rc" -eq 0 ]; then
  echo $msg_delimiter_star_line
  echo "$msg_time_sync_via_internet"
  echo -n "[Y/n] "
  read time_sync
  case "$time_sync" in
      n|N|[nN][oO]) time_sync="no" ;;
      *)            time_sync="yes" ;;
  esac 
  [ "$time_sync" = "yes" ] && ocs-live-time-sync
fi

exit $rc
