#!/bin/bash
############################################################
# Copyright 2002-2012 The Lunar Linux Team                 #
############################################################
# lnet is a menu driven configurator for the networking    #
# init script                                              #
############################################################
# Hacked up by Rick Altherr for his purposes (muhuhahaha)  #
#                                                          #
# Just kidding.  This is an adaption of the network config #
# contained within the Lunar install script.               #
#                                                          #
# Copyright 2012 by Stefan Wold                            #
#                                                          #
# this code is GPLv2                                       #
############################################################

CONFIG_DIR="/etc/config.d/network"

catch_sig() {
  clear
  if [ -f /tmp/lnet.resolv.conf ]; then
    mv /tmp/lnet.resolv.conf /etc/resolv.conf
  fi
  if [ -f /tmp/lnet.$DEVICE ]; then
    mv /tmp/lnet.$DEVICE $OUT_TO
  fi

  # /tmp could have wireless WEPKEYS, so if we worked on more than one
  # device, we're only trying to save one, we're going to kill any others
  rm -f /tmp/lnet.*
  echo "Tried to restore device config file and resolv.conf from /tmp"
  echo "Ouch * that hurt you may want to double check /tmp"
  exit 1
}

msgbox() {
  if [ -z "$3" ]; then H=10; else H=$3; fi
  $DIALOG --title "$1" --msgbox "$2" $H 50
}

inputbox() {
  $DIALOG --nocancel --inputbox "$1" 0 0 "$2"
}

confirm() {
  $DIALOG $2 --yesno "$1" 8 50
}

goodbye() {
  clear
  exit  0
}

get_dev_list() {
  ls -1 $CONFIG_DIR | sort
}

get_dev_status() {
  if ip link show $1 | egrep -q '[<,]UP[,>]'; then
    echo "[ UP ]"
  else
    echo "[DOWN]"
  fi
}

systemd_disable_existing() {
  for i in $(ls -1 /etc/systemd/system/multi-user.target.wants/lnet-*@${1}.service 2> /dev/null); do
    systemctl stop ${i##*/} &> /dev/null
    rm $i &> /dev/null
  done
}

systemd_enable() {
  systemd_disable_existing $1
  ln -s $SYSTEMDUNITDIR/${2}@.service /etc/systemd/system/multi-user.target.wants/${2}@${1}.service
  systemctl start ${2}@${1}.service &> /dev/null
  # Set default gw if not already set
  if [ -f /etc/config.d/gateway ] && systemctl -q is-enabled lnet-default-gateway.service ; then
    GATEWAY=$(cat /etc/config.d/gateway)
    CURRENT_GW=$(ip route show default | grep ^default | awk '{ print $3 }')
    if [ -n $GATEWAY ] && [[ "$GATEWAY" != "$CURRENT_GW" ]]; then
      systemctl start lnet-default-gateway.service
    fi
  fi
}

systemd_disable() {
  systemctl stop ${2}@${1}.service &> /dev/null
  rm /etc/systemd/system/multi-user.target.wants/${2}@${1}.service &> /dev/null
}

systemd_gw_template() {
  cat <<EOF > /etc/systemd/system/lnet-default-gateway.service
[Unit]
Description=Network default gateway
Wants=network.target
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/ip route add default via $(/usr/bin/cat /etc/config.d/gateway)
ExecStop=/usr/sbin/ip route del default

[Install]
WantedBy=multi-user.target
EOF
}

get_systemd_servicetype() {
  local SERVICETYPE

  if [ "$ADDRESS" = "dhcp" ]; then
    SERVICETYPE="lnet-${DHCP_CLIENT}"
  else
    SERVICETYPE="lnet-static"
  fi
  echo $SERVICETYPE
}

main ()
{
  unset PROMPT

  while true; do
    COUNTER=0
    unset LIST
    unset MANAGE
    for DEVICE in `get_dev_list`; do
      if [ -L $CONFIG_DIR/$DEVICE ]; then
	      continue
	    fi
        STATUS=`get_dev_status $DEVICE`
	INTERFACES[$COUNTER]=$DEVICE
	if [ -z "$LIST" ]; then
	  LIST="$COUNTER\nEdit device $DEVICE     $STATUS\n"
	else
	  LIST="$LIST$COUNTER\nEdit device $DEVICE     $STATUS\n"
	fi
	(( COUNTER++ ))
    done
    if (( COUNTER > 0 )) ; then
        MANAGE="M\nManage network devices\n"
    fi
    COMMAND=`$DIALOG  --title "Network configuration" \
                      --ok-label "Select"            \
		      --cancel-label "Exit"          \
                      --menu                         \
		      ""                             \
                      0 0 0                          \
		      $(echo -en $LIST)              \
                      "A"  "Add a network device"    \
                      "D"  "Setup DNS configuration" \
		      "N"  "Setup host and domain name" \
		      "G"  "Setup global Gateway" \
		      $(echo -en $MANAGE)`

    if [ $? != 0 ] ; then
      return
    fi

    case $COMMAND in
      [0-9]*) ethernet_menu ${INTERFACES[$COMMAND]} ;;
      A)      ethernet_config ;;
      D)      dns_config ;;
      N)      hostname_config ;;
      G)      gateway_config ;;
      M)      ethernet_manage_menu ;;
    esac
  done
}

function dns_config() {
  RESOLV="/etc/resolv.conf"

  cp -p $RESOLV /tmp/lnet.resolv.conf

  DOMAIN_PROMPT="Enter Primary local Domain name"
  DNS1_PROMPT="Enter Primary DNS Server IP Address"
  DNS2_PROMPT="Enter Secondary DNS Server IP Address"
  SEARCH_PROMPT="Enter (optionally) domain name search order"

  DNS1="`grep nameserver $RESOLV | head -n 1 | cut -d \" \" -f2`"
  DNS2="`grep nameserver $RESOLV | head -n 2 | tail -n 1 | cut -d \" \" -f2`"
  DOMAIN="`grep domain $RESOLV | head -n 1 | cut -d \" \" -f2`"
  SEARCH="`grep search $RESOLV | head -n 1 | cut -d \" \" -f2-`"

  DNS1=${DNS1:-${IP%.*}.254}
  DOMAIN=${DOMAIN:-subd.com}

  DOMAIN=`inputbox "$DOMAIN_PROMPT" $DOMAIN`
  DNS1=`inputbox "$DNS1_PROMPT" $DNS1`

  if [ -z $DNS2 ]; then
    if [ -z $DNS1 ]; then
      DNS2=""
    else
      N_DNS=$((${DNS1##*.}+1))
      DNS2="${DNS1%.*}.$N_DNS"
    fi
  fi
  DNS2=`inputbox "$DNS2_PROMPT" "$DNS2"`
  SEARCH=`inputbox "$SEARCH_PROMPT" $SEARCH`

  (
    [ -z "$DOMAIN" ] || echo "domain $DOMAIN"
    [ -z "$DNS1" ]   || echo "nameserver $DNS1"
    [ -z "$DNS2" ]   || echo "nameserver $DNS2"
    [ -z "$SEARCH" ] || echo "search $SEARCH"
  ) > $RESOLV
}

function hostname_config()
{
   if [ -f /etc/hostname ]; then
     HOSTNAME=$(cat /etc/hostname)
   fi
   HOSTNAME=`inputbox "Enter this systems host name" "$HOSTNAME"`
   # Assume systemd is running
   if [ -n "$SYSTEMDUNITDIR" ]; then
     clear
     hostnamectl set-hostname "$HOSTNAME"
   else
     if [ -n "$HOSTNAME" ]; then
       echo "$HOSTNAME" > /etc/hostname
     else
       rm /etc/hostname
     fi
     if [ -f /etc/domainname ]; then
       DOMAINNAME=$(cat /etc/domainname)
     fi
     DOMAINNAME=`inputbox "Enter this systems domain name" "$DOMAINNAME"`
     if [ -n "$DOMAINNAME" ]; then
       echo "$DOMAINNAME" > /etc/domainname
     else
       rm /etc/domainname
     fi
  
     # and set them too:
     clear
     /etc/init.d/hostname
   fi
   sleep 2
}

function gateway_config() {
   GATEWAY_PROMPT="Enter Gateway IP Address"
   GATEWAY=$(cat /etc/config.d/gateway)
   GATEWAY=`inputbox "$GATEWAY_PROMPT" "$GATEWAY"`
   echo "$GATEWAY" > /etc/config.d/gateway
   if [ -n "$SYSTEMDUNITDIR" ]; then
     if [ -n "$GATEWAY" ]; then
       systemd_gw_template
       systemctl daemon-reload &> /dev/null
       systemctl enable lnet-default-gateway.service
     else
       systemctl disable lnet-default-gateway.service
     fi
   fi
}

function ethernet_menu() {
    PROMPT="Actions for interface $1\nDevice is: `get_dev_status $1`"
    COMMAND=`$DIALOG  --title "Modify device $1"     \
                      --ok-label "Select"            \
		      --cancel-label "Exit"          \
                      --menu                         \
		      $PROMPT                        \
                      0 0 0                          \
                      'C'  'Reconfigure'             \
                      'M'  'Manage'                  \
		      'D'  'Delete'`

    if [ $? != 0 ] ; then
      return
    fi

    case  $COMMAND  in
      C)      ethernet_config $1;;
      M)      ethernet_manage_device $1;;
      D)
        if confirm "Are you sure you wish to delete $1?" "--defaultno"; then
          if [ -n "$SYSTEMDUNITDIR" ]; then
            systemd_disable_existing ${1}
          fi
          rm -f "$CONFIG_DIR/$1"
        fi
        ;;
    esac
}

function ethernet_manage_menu() {
    NO_INTERFACES="There are no interfaces to be listed. You may want to configure a device first."

  while true; do
    unset LIST INTERFACES
    COUNTER=0
    for DEVICE in `get_dev_list`; do
	INTERFACES[$COUNTER]=$DEVICE
        STATUS=`get_dev_status $DEVICE`
	if [ -z "$LIST" ]; then
	  LIST="$COUNTER\n$DEVICE     $STATUS\n"
	else
	  LIST="$LIST$COUNTER\n$DEVICE     $STATUS\n"
	fi
	(( COUNTER++ ))
    done

    if (( COUNTER == 0 )) ; then
        msgbox "Manage Devices" "$NO_INTERFACES" 7
        return
    fi

    PROMPT="Select an interface to manage"
    DEVICE=`$DIALOG  --title "Manage Devices"       \
		     --ok-label "Select"            \
		     --cancel-label "Return"        \
		     --menu                         \
		     $PROMPT                        \
		     0 0 0                          \
		     $(echo -en $LIST)`

    case  $?  in
      0)      ethernet_manage_device ${INTERFACES[$DEVICE]} ;;
      1)      return ;;
    esac
  done
}

function ethernet_manage_device() {

    if [ ! -z $1 ]; then
        . $CONFIG_DIR/$1
    fi

    WIRELESS_MOD_PROMPT="You currently do not have the wireless tools installed required for wireless network devices.\n\nTo install these run the command:\n\n  'lin wireless_tools'\n\nYou will not be able to use this device until the module is installed."
    DHCP_TIMEOUT="If your device uses DHCP, starting a device may take an excessive amount of time if no DHCP servers are available to give an IP address.\nYou may need wait for the device to timeout if this is the case."
    ACTION_FAILED="The actions you asked to be performed have failed. You may need to check your device configuration."

    if ( [ -n "$WIRELESS_MODE" ] || [ -n "$WIRELESS_KEY" ] || [ -n "$WIRELESS_RATE" ] || [ -n "$WIRELESS_ESSID" ] && ! module_installed wireless_tools ); then
        msgbox "Warning" "$WIRELESS_MOD_PROMPT" 15
        return
    fi

  while true; do
    STATUS=`get_dev_status $1`
    if [[ "$STATUS" == "[ UP ]" ]]; then
        TOGGLE="Stop"
    else
        TOGGLE="Start"
    fi

    PROMPT="Device $1 is: $STATUS"
    COMMAND=`$DIALOG  --title "Manage Device $1"     \
		      --cancel-label "Return"        \
                      --menu                         \
		      $PROMPT                        \
                      0 0 0                          \
		      "S" "$TOGGLE Device"           \
		      "R" "Restart Device"`

    if [ $? != 0 ] ; then
      return
    fi

    $DIALOG --infobox "$DHCP_TIMEOUT" 0 0

    case  $COMMAND  in
      S)
        # Assume systemd is running
        if [ -n "$SYSTEMDUNITDIR" ]; then
          SERVICETYPE=$(get_systemd_servicetype)
          systemctl ${TOGGLE/S/s} ${SERVICETYPE}@${1}.service
        else
          /etc/init.d/network ${TOGGLE/S/s} "$1"
        fi
        ;;
      R)
        # Assume systemd is running
        if [ -n "$SYSTEMDUNITDIR" ]; then
          SERVICETYPE=$(get_systemd_servicetype)
          systemctl restart ${SERVICETYPE}@${1}.service
        else
          /etc/init.d/network restart "$1"
        fi
        ;;
    esac

    if ip link show $1 | egrep -q '[<,]UP[,>]'; then
        T=1; else T=0
    fi

    if [[ ( "$COMMAND" == "S" && "$TOGGLE" == "Start" && "$T" != "1" ) || 
          ( "$COMMAND" == "S" && "$TOGGLE" == "Stop" && "$T" != "0" ) || 
          ( "$COMMAND" == "R" && "$T" == "0" )]]; then
      msgbox "Warning" "$ACTION_FAILED" 7
    fi
  done
}

function ethernet_config()  {
# unset all variables
unset WIRELESS DEVICE AUTO MODULE MODULE_OPTIONS ADDRESS MANAGER
unset NETMASK BROADCAST GATEWAY DHCP_CLIENT DHCP_OPTIONS
unset WIRELESS_KEY WIRELESS_RATE WIRELESS_MODE WIRELESS_ESSID

if_template() {
  cat > $CONFIG_DIR/$DEVICE << EOF
#
# configuration for "$DEVICE"
# automatically generated by lnet - do not edit, run 'lnet' instead
# -- `date`
#
AUTO="${AUTO:-Y}"
MODULE="$MODULE"
MODULE_OPTIONS="$MODULE_OPTIONS"

MANAGER="${MANAGER:-manual}"

WIRELESS="${WIRELESS:-N}"
WIRELESS_KEY="$WIRELESS_KEY"
WIRELESS_RATE="$WIRELESS_RATE"
WIRELESS_MODE="$WIRELESS_MODE"
WIRELESS_ESSID="$WIRELESS_ESSID"

ADDRESS="$ADDRESS"
NETMASK="$NETMASK"
BROADCAST="$BROADCAST"
IFCONF_OPTS="$IFCONF_OPTS"

DHCP_CLIENT="${DHCP_CLIENT:-dhcpcd}"
DHCP_OPTIONS="$DHCP_OPTIONS"
EOF
}

if [ -n "$1" ]; then
    . $CONFIG_DIR/$1
fi

DHCP_MODULE_MESSAGE="The DHCP client you have chosen is not installed. Before your device will work, you will need to install the following module: "

if [ -z $1 ]; then
     while [ -z $DEVICE ]; do
         DEVICES=`get_dev_list`
         TDEV="eth0"
         for N in `seq 0 9`; do
           if [ -z `echo $DEVICES | grep "eth${N}"` ]; then
             TDEV="eth$N"
             break
           fi
         done
         DEVICE=`inputbox "For more then one device, use the menu for each of them, ie: eth0, eth1 etc.." "$TDEV"`
     
         # Generate a file immediately with some sane defaults
         AUTO="Y"
         ADDRESS="dhcp"
         if_template
         . $CONFIG_DIR/$DEVICE
     done
else
	 DEVICE=$1
fi

while true ; do
	DEFAULT=${CHOICE:-}
	CHOICE=`$DIALOG --title "Networking configuration: $1" \
				 --ok-label "Select" \
				 --cancel-label "Close" \
				 --default-item "$DEFAULT" \
				 --menu "" 0 0 0 \
				 "A" "Automatically start?    [${AUTO:-Y}]" \
         $(if [ -z "$SYSTEMDUNITDIR" ]; then
				 echo "L"
         echo "kernel module to Load   [${MODULE:-}]"
         echo "Z"
         echo "Use manager?            [${MANAGER:-manual}]"
				 if [ "${MANAGER:-manual}" == "manual" ] ; then
					echo "W"
					echo "Wireless device?        [${WIRELESS:-N}]"
				    if [ "$WIRELESS" == "Y" ]; then
					echo "M"
					echo "Mode                    [${WIRELESS_MODE:-Managed}]"
					echo "K"
					echo "Key                     [${WIRELESS_KEY:-}]"
					echo "R"
					echo "Rate                    [${WIRELESS_RATE:-auto}]"
					echo "E"
					echo "Essid                   [${WIRELESS_ESSID:-default}]"
				    fi
            fi
				  fi
					echo "D"
					echo "Dhcp enabled?           [$(echo $ADDRESS | grep -qi dhcp && echo "Y" || echo "N")]"
				  if [ "$MANAGER" != "manual" ] || [ "$ADDRESS" == "dhcp" ] ; then
					echo "C"
					echo "Dhcp client             [${DHCP_CLIENT:-dhcpcd}]"
					echo "O"
					echo "Dhcp options            [${DHCP_OPTIONS}]"
				  fi
				  if [ "$ADDRESS" != "dhcp" ] ; then
					echo "I"
					echo "IP Address              [${ADDRESS}]"
					echo "N"
					echo "Netmask                 [${NETMASK}]"
					echo "B"
					echo "Broadcast               [${BROADCAST}]"
          if [ -z "$SYSTEMDUNITDIR" ]; then
					  echo "F"
					  echo "Ifconfig options        [${IFCONF_OPTS:-}]"
          fi
				  fi

				  )`

	if [ $? != 0 ]; then
    # Assume systemd is running if SYSTEMDUNITDIR variable is set
    if [ -n "$SYSTEMDUNITDIR" ]; then
      DHCP_TIMEOUT="This device uses DHCP. If no DHCP servers are available to give an IP address\nyou may need to wait for the device to timeout."
      [ "$ADDRESS" = "dhcp" ] && $DIALOG --infobox "$DHCP_TIMEOUT" 0 0
      [ "$AUTO" = "Y" ] && systemd_enable $DEVICE $(get_systemd_servicetype) || systemd_disable_existing $DEVICE
    fi
	  return
	fi

	case $CHOICE in
	A)	if [ "$AUTO" == "Y" ]; then
			AUTO=N
		else
			AUTO=Y
		fi
		;;
	L)	MODULE=`inputbox "Enter optional kernel module to load" "$MODULE"`
		;;
	Z)	MANAGER=`$DIALOG --no-cancel --title "Select a network configuration method" \
				 --default-item "${MANAGER:-ifplugd}" \
				 --menu "" 0 0 0 \
				 "manual" "do not use ifplugd or wpa_supplicant" \
				 "ifplugd" "use ifplugd" \
				 "wpa_supplicant" "Use both ifplugd and wpa_supplicant"`
		if [ "$MANAGER" == "wpa_supplicant" ] ; then
			WIRELESS=Y
		fi
		if [ "$MANAGER" != "manual" ] ; then
			ADDRESS=dhcp
		fi
		;;
	W)	if [ "$WIRELESS" == "Y" ]; then
			WIRELESS=N
		else
			WIRELESS=Y
		fi
		;;
	M)	WIRELESS_MODE=`$DIALOG --no-cancel --title  "Wireless Modes" \
				       --default-item "${WIRELESS_MODE:-Managed}" \
				       --menu "" 0 0 0 \
				       "Managed" "" \
				       "Ad-Hoc"  ""`
		;;

	K)	WIRELESS_KEY=`inputbox "Enter WEP 64/128 bit key" "$WIRELESS_KEY"`
		;;
	R)	WIRELESS_RATE=`inputbox "Enter wireless rate" "$WIRELESS_RATE"`
		;;
	E)	WIRELESS_ESSID=`inputbox "Enter ESSID of the wireless network" "$WIRELESS_ESSID"`
		;;
	D)	if [ "$ADDRESS" == "dhcp" ]; then
			unset ADDRESS
		else
			ADDRESS=dhcp
		fi
		;;
	C)	DHCP_CLIENT=`$DIALOG --no-cancel --title "Select a DHCP client" \
				     --default-item "${DHCP_CLIENT:-dhcpcd}" \
				     --menu "" 0 0 0 \
				     "dhcpcd" "" \
				     "dhclient" ""`
		case $DHCP_CLIENT in
		dhclient) if ! module_installed dhcp; then
				msgbox "Warning" "$DHCP_MODULE_MESSAGE dhcp" 10
			fi ;;
		dhcpcd) if ! module_installed dhcpcd; then
				msgbox "Warning" "$DHCP_MODULE_MESSAGE dhcpcd" 10
			fi ;;
		esac
		;;
	O)	DHCP_OPTIONS=`inputbox "Enter extra options passed to $DHCP_CLIENT" "${DHCP_OPTIONS}"`
		;;
	I)	ADDRESS=`inputbox "Enter IP address" "$ADDRESS"`
		;;
	N)	NETMASK=`inputbox "Enter netmask" "$NETMASK"`
		;;
	B)	BROADCAST=`inputbox "Enter broadcast address" "$BROADCAST"`
		;;
	F)	IFCONF_OPTS=`inputbox "Enter extra options passed to ifconfig" "$IFCONF_OPTS"`
		;;
	esac

	# save the config
	cp -p $CONFIG_DIR/$DEVICE /tmp/lnet.$DEVICE
	if_template

done
}

. /etc/lunar/config
[ -n "$BOOTSTRAP" ] && . $BOOTSTRAP

root_check

export IFS="$TAB_ENTER_IFS"
DIALOG="dialog
--backtitle
Lunar Network Management Utility
--stdout"

trap catch_sig INT
trap ":" QUIT

# Check if we have systemd and that it is running
if module_installed systemd && [ -d /run/systemd ]; then
  SYSTEMDUNITDIR=$(pkg-config systemd --variable=systemdsystemunitdir)
fi

main
