#!/usr/bin/env bash
#
# Copyright 2015 VMware, Inc.  All rights reserved.
#
# This script manages the VMware USB Arbitrator service
#

### BEGIN INIT INFO
# Provides: vmware-USBArbitrator
# Required-Start: localfs
# Required-Stop: localfs
# X-Start-Before: 
# X-Stop-After: 
# Default-Start: 2 3 4
# Default-Stop: 0 6
# Short-Description: This services starts and stops the USB Arbitrator.
### END INIT INFO


if [ -f /etc/vmware/bootstrap ]; then
   # Load bootstrapper info
   . /etc/vmware/bootstrap
else
   BINDIR=/usr/bin
fi

# This defines $rc_done and $rc_failed on S.u.S.E.
if [ -f /etc/rc.config ]; then
   # Don't include the entire file: there could be conflicts
   rc_done=`(. /etc/rc.config; echo "$rc_done")`
   rc_failed=`(. /etc/rc.config; echo "$rc_failed")`
else
   # Make sure the ESC byte is literal: Ash does not support echo -e
   rc_done='[71G done'
   rc_failed='[71Gfailed'
fi

# This defines echo_success() and echo_failure() on RedHat
if [ -r "$INITSCRIPTDIR"'/functions' ]; then
   . "$INITSCRIPTDIR"'/functions'
fi

vmware_failed() {
  if [ "`type -t 'echo_failure' 2>/dev/null`" = 'function' ]; then
    echo_failure
  else
    echo -n "$rc_failed"
  fi
}

vmware_success() {
  if [ "`type -t 'echo_success' 2>/dev/null`" = 'function' ]; then
    echo_success
  else
    echo -n "$rc_done"
  fi
}

# Execute a macro
vmware_exec() {
  local msg="$1"  # IN
  local func="$2" # IN
  shift 2

  # On Caldera 2.2, SIGHUP is sent to all our children when this script exits
  # I wanted to use shopt -u huponexit instead but their bash version
  # 1.14.7(1) is too old
  #
  # Ksh does not recognize the SIG prefix in front of a signal name
  if [ "$VMWARE_DEBUG" = 'yes' ]; then
    (trap '' HUP; "$func" "$@")
  else
    (trap '' HUP; "$func" "$@") >/dev/null 2>&1
  fi
  if [ "$?" -gt 0 ]; then
    vmware_failed
    echo
    return 1
  fi

  vmware_success
  echo
  return 0
}

# Create socket dir for usbd
vmwareCreateUDSDirForUsbd() {
   for user in `awk -F'[/:]' '{if ($3 == 0 || ($3 >= 500 && $3 != 65534)) print $1}' /etc/passwd`
   do
      aUser=$user
      aGroup=`id -g $aUser`
      aUID=`id -u $aUser`
      if ! [ -d /var/run/vmware/"$aUID" ] ; then
         mkdir -p /var/run/vmware/"$aUID"
         chown -R -- "$aUser":"$aGroup" /var/run/vmware/"$aUID"
         chmod 700 /var/run/vmware/"$aUID"
      fi
   done
}

# Remove socket dir for usbd
vmwareRemoveUDSDirForUsbd() {
   for uid in `awk -F'[/:]' '{if ($3 == 0 || ($3 >= 500 && $3 != 65534)) print $3}' /etc/passwd`
   do
      if [ -d /var/run/vmware/"$uid" ] ; then
         rm -f /var/run/vmware/"$uid"/*
         rmdir /var/run/vmware/"$uid"
      fi
   done

   rmdir /var/run/vmware
}

# Start the virtual machine USB Arbitrator service
vmwareStartUSBArbitrator() {
   vmwareCreateUDSDirForUsbd
   # The executable checks for already running instances, so it
   #  is safe to just run it.
   "$BINDIR"/vmware-usbarbitrator
}

# Stop the virtual machine USB Arbitrator service
vmwareStopUSBArbitrator() {
    # The service knows how to stop itself.
    "$BINDIR"/vmware-usbarbitrator --kill
    # Do some cleaning job.
    vmwareRemoveUDSDirForUsbd
}

vmwareService() {
   case "$1" in
      start)
         vmware_exec 'VMware USB Arbitrator' vmwareStartUSBArbitrator
         exitcode=$(($exitcode + $?))
         if [ "$exitcode" -gt 0 ]; then
            exit 1
         fi
         ;;
      stop)
         vmware_exec 'VMware USB Arbitrator' vmwareStopUSBArbitrator
         exitcode=$(($exitcode + $?))
         if [ "$exitcode" -gt 0 ]; then
            exit 1
         fi
         ;;
      restart)
         "$SCRIPTNAME" stop && "$SCRIPTNAME" start
         ;;
      *)
         echo "Usage: $BASENAME {start|stop|restart}"
         exit 1
   esac
}

SCRIPTNAME="$0"
BASENAME=`basename "$SCRIPTNAME"`

# Check permissions
if [ "`id -ur`" != '0' ]; then
   echo 'Error: you must be root.'
   echo
   exit 1
fi

vmwareService "$1"

exit 0
