#!/usr/bin/env bash
#
# Copyright (C) 2008 VMware, Inc.  All Rights Reserved.
#

# Manages the configuration and deconfiguration of vmxnet and hgfs.

# Must come before set -e.
. "`dirname $0`"/functions

set -e

#
# constant definitions
#
VMHGFS_MOUNTPOINT="/mnt/hgfs"
UPDATEDBCONF_PATH="/etc/updatedb.conf"

configure_vmhgfs()
{
   # create hgfs mountpoint
   if ! mkdir -p $VMHGFS_MOUNTPOINT; then
      echo "Could not create the '$VMHGFS_MOUNTPOINT' directory."
   fi

   # if not yet in PRUNEFS add vmhgfs to it in $UPDATEDBCONF_PATH
   if [ -e $UPDATEDBCONF_PATH ] && \
      ! grep -q "^PRUNEFS.*vmhgfs" $UPDATEDBCONF_PATH; then
      replace 's/^\(PRUNEFS.*\".*\)\"/\1 vmhgfs\"/' \
	  $UPDATEDBCONF_PATH
   fi
}

deconfigure_vmhgfs()
{
   # remove hgfs mountpoint
   if [ -d $VMHGFS_MOUNTPOINT ]; then
      rmdir $VMHGFS_MOUNTPOINT
   fi

   # if vmhgfs is in PRUNEFS in $UPDATEDBCONF_PATH remove it
   if [ -e $UPDATEDBCONF_PATH ] && \
      grep -q "^PRUNEFS.*vmhgfs" $UPDATEDBCONF_PATH; then
      replace 's/^\(PRUNEFS.*\".*\)vmhgfs\(.*\)\"/\1\2\"/' \
	  $UPDATEDBCONF_PATH
   fi
}

get_module_type()
{
   if `get_modprobe_file > /dev/null`; then
      echo "modprobe"
   elif `get_modutil_file > /dev/null`; then
      echo "modutil"
   else
      exit 1
   fi

   exit 0
}

get_modutil_file()
{
   find_first_exists /etc/modules.conf /etc/conf.modules
}

get_modprobe_file()
{
  # modprobe looks for module info first in modprobe.conf and then
  # in modprobe.d/<vmware-tools>.  However, SLES9 includes a new
  # wrinkle: the file modprobe.conf.local.  That gets included into
  # modprobe.conf and SLES9 wants user modified entries in that
  # local file.
   local modprobeFile

   if [[ -d "/etc/modprobe.d" ]]; then
      modprobeFile="/etc/modprobe.d/vmware-open-vm-tools-kmod.conf"
   else
      modprobeFile="`find_first_exists /etc/modprobe.conf.local /etc/modprobe.conf`"
   fi

   echo "$modprobeFile"
   [ -n "$modprobeFile" ]
   exit
}

get_initrd_file()
{
   find_first_exists "/etc/initramfs-tools/modules"
}

update_initramfs()
{
   update-initramfs -u -k @@KERNEL@@
}

configure_initrd()
{
   local file="$1"
   shift

   echo "vmxnet" >> "$file"

   update_initramfs
}

deconfigure_initrd()
{
   local file="$1"
   shift

   replace "/^vmxnet/d" "$file"

#  update_initramfs is now done in postrm
}

configure_modprobe()
{
   local file="$1"
   shift

   # vmware_load_module() will first try to install the vmxnet module
   # from /lib/modules/$(uname -r)/, then fallback to PMWV if failed.
   local cmd='/bin/sh -c ". /usr/lib/vmware-tools/install/vmware-open-vm-tools-kmod/functions && vmware_load_module vmxnet"'
   if is_rhel; then
      # On RHEL systems, we don't load pcnet32 if loading vmxnet
      # succeeded. Ideally we'd behave this way on all systems, but SLES
      # at least will loop infinitely if we try this. For now we're only
      # targeting RHEL. Separate with an "or". See bug #449673.
      cmd="${cmd} ||"
   elif is_sles; then
      # SLES loops infinitely with "or"; load both drivers, separate with an
      # unconditional semicolon.
      cmd="${cmd};"
   else
      cmd="/sbin/modprobe -q --ignore-install vmxnet;"
   fi

   local line="install pcnet32 $cmd /sbin/modprobe \
               -q --ignore-install pcnet32 $CMDLINE_OPTS; /bin/true"
   echo "$line" >> "$file"
}

deconfigure_modprobe()
{
   local file="$1"
   shift

   replace "/^install pcnet32/d" "$file"
}

configure_modutil()
{
   local file="$1"
   shift

   # Convert all alias lines for network devices to alias vmnics
   # instead of pcnet32.
   replace "s/^alias \(eth[0-9]\).*/alias \1 vmnics/g" "$file"

   echo "probeall vmnics vmxnet pcnet32" >> "$file"
}

deconfigure_modutil()
{
   local file="$1"
   shift

   replace "s/^alias \(eth[0-9]\).*/alias \1 pcnet32/g" "$file"
   replace "/^probeall vmnics/d" "$file"
}

configure_vmxnet()
{
   local moduleType=`get_module_type`
   configure_$moduleType `get_${moduleType}_file`

   # Only applies to Ubuntu right now.
   local initrdFile=`get_initrd_file` || true

   if [[ -n $initrdFile ]]; then
      configure_initrd $initrdFile
   fi
}

deconfigure_vmxnet()
{
   local moduleType=`get_module_type`
   deconfigure_$moduleType `get_${moduleType}_file`

   # Only applies to Ubuntu right now.
   local initrdFile=`get_initrd_file` || true

   if [[ -n $initrdFile ]]; then
      deconfigure_initrd $initrdFile
   fi

   # Remove the file if we create it in configure_vmxnet()
   if [ -f /etc/modprobe.d/vmware-open-vm-tools-kmod.conf ]; then
      rm /etc/modprobe.d/vmware-open-vm-tools-kmod.conf
   fi
}

# See how we were called.
case "$1" in
   install)
      configure_vmxnet
      configure_vmhgfs
      ;;
   uninstall)
      deconfigure_vmxnet
      deconfigure_vmhgfs
      ;;
   *)
      error "Usage: `basename "$0"` {install|uninstall}"
      ;;
esac
