#!/bin/bash

# This file is part of Marionnet, a virtual network laboratory
# Copyright (C) 2007  Luca Saiu
# Copyright (C) 2007 2013  Jean-Vincent Loddo
# Copyright (C) 2007 2013  Université Paris 13

# 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.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

echo -n "Marionnet startup configuration... "

set -x

function append_line_if_needed {
  local LINE="$1"
  local FILE="$2"
  { test -f "$FILE" && grep -q "^${LINE}$" "$FILE"; } || echo "$LINE" >> "$FILE"
}

###########################################
#     Source-ing kernel command line      #
###########################################

# Read kernel command line variables into this shell's environment:
# Expected variables: hostname hostfs ubd0s
export $(tr </proc/cmdline ' ' '\n' | \grep "^[a-zA-Z][a-zA-Z0-9_]*[=]")


###########################################
#               hostname                  #
###########################################

# Set the hostname according to the kernel command line:
if [[ -n $hostname ]]; then
  echo $hostname > /etc/hostname
  # The script `/etc/init.d/hostname.sh' belonged to the package `initscripts'
  # on old debian systems:
  [[ -x /etc/init.d/hostname.sh ]] && /etc/init.d/hostname.sh start &>/dev/null
  # Make a correct entry in /etc/hosts:
  append_line_if_needed "127.0.0.1 $hostname" /etc/hosts
else
  echo "Warning: variable 'hostname' undefined" 1>&2
fi


###########################################
#                hostfs                   #
###########################################

# Mount the hostfs filesystem and add bindings from the hostfs file
# `boot_parameters' to this shell environment:
if [[ -n $hostfs ]]; then
  mount none /mnt/hostfs -t hostfs -o $hostfs &&
  # And also record it on the hostfs filesystem, so that we can
  # easily tell which guest machine the directory belongs to
  # *from the host*:
  [[ -n $hostname ]] && echo $hostname > /mnt/hostfs/GUESTNAME &&
  source /mnt/hostfs/boot_parameters
else
  echo "Warning: variable 'hostfs' undefined" 1>&2
fi

###########################################
#             xterm title                 #
###########################################

# Show the hostname (and its filesystem) in the terminal window title bar
if [[ -n $ubd0s ]]; then
  # Get the name of the virtual filesystem choosen by the user:
  virtualfs_name="${ubd0s##*/}"
  virtualfs_name=${virtualfs_name#router-}
  virtualfs_name=${virtualfs_name#machine-}
  echo -e '\033]0;'"$hostname ($virtualfs_name)"'\007'
else
  echo "Warning: variable 'ubd0s' undefined" 1>&2
fi


###########################################
#        Network configurations           #
###########################################

# Perform an indirect lookup of the variable $1'_eth'$2, i.e. return
# the value of the variable which is the value of the variable named
# $1'_eth'$2.
function lookup {
  echo $(eval echo '$'$1'_eth'$2)
}

# Configure network interfaces:
if [[ -n $ethernet_interfaces_no ]]; then

  for i in $(eval echo {0..$((ethernet_interfaces_no-1))}); do
    mac_address=`lookup mac_address $i`
    mtu=`lookup mtu $i`
    ipv4_address=`lookup ipv4_address $i`
    ipv4_broadcast=`lookup ipv4_broadcast $i`
    ipv4_netmask=`lookup ipv4_netmask $i`
    ipv6_address=`lookup ipv6_address $i`
    [[ -z $mac_address ]] || ifconfig eth$i hw ether $mac_address
    [[ -z $mtu ]] || ifconfig eth$i mtu $mtu
    # IPv4 configuration.
    # The variable `ipv4_address' may be defined via the Marionnet GUI with the
    # CIDR notation, i.e. in the form x.y.z.t/N. However, in order to be
    # compatible with the busybox (buildroot) implementation of `ifconfig',
    # Marionnet extracts the address into x.y.z.t and sets `ipv4_address',
    # then it computes the corresponding netmask and sets `ipv4_netmask'.
    # So, the command executed here may have a form like:
    # ifconfig eth0 192.168.0.1
    # or
    # ifconfig eth0 192.168.0.1 netmask 255.255.255.0
    if [[ -n $ipv4_address ]]; then
      if [[ -n $ipv4_netmask ]]; then
        ifconfig eth$i $ipv4_address netmask $ipv4_netmask
      else
        ifconfig eth$i $ipv4_address
      fi
    fi
    # IPv6 configuration.
    # The variable `ipv6_address' may be defined via the Marionnet GUI with the
    # CIDR notation. So, the command executed here may have a form like:
    # ifconfig eth0 inet6 add 2003:abd::1/32
    if [[ -n $ipv6_address ]]; then
        ifconfig eth$i inet6 add $ipv6_address
    fi
  done

fi

###########################################
#        Ghost interface (eth42)          #
###########################################

# Activate and immediately ghostify our special network
# interface communicating with the host:
ifconfig eth42 $ip42 up &>/dev/null
if type ghostify; then ghostify eth42; fi &>/dev/null


###########################################
#      /etc/fstab swap tuning             #
###########################################

# Add swap (the swap 'partition' was already created as a
# sparse file and initialized with mkswap from the host side):
append_line_if_needed \
  "/dev/ubdb       none            swap    sw              0       0" \
  /etc/fstab

swapon -a


###########################################
#      /etc/fstab swap tuning             #
###########################################

# TODO: think about the ssh tunnelling!
if [ -z "$xnest_display_number" ]; then
  DISPLAY_VALUE=172.23.0.254:0
else
  DISPLAY_VALUE=172.23.0.254$xnest_display_number
fi

# Find a suitable shell configuration file and append the line setting the
# variable DISPLAY:
for i in /etc/profile /etc/bash.bashrc /root/.bash_profile /root/.bashrc; do
  if [[ -f $i ]]; then
    append_line_if_needed "export DISPLAY=$DISPLAY_VALUE" $i
    break;
  fi
done

echo "done."
