#!/bin/sh
#
# Copyright 2004 VMware, Inc.  All rights reserved.
#

# Basic support for IRIX style chkconfig 
# chkconfig: 3 98 08
# description: starts up assorted management agents.

# load system helper functions.
. /etc/init.d/functions
. /etc/init.d/vmware-functions

PATH=/sbin:/usr/sbin:/bin:/usr/bin
export PATH

subsys=mgmt-vmware

sslDir=$vmware_etc_dir/ssl
hostd=/usr/sbin/vmware-hostd
hostdSupport=/usr/sbin/vmware-hostd-support
watchdog=/usr/bin/vmware-watchdog
hostdName="$productName Host Agent"
VIMSH=/usr/bin/vmware-vimsh
hostdlog=/var/log/vmware/hostd.log
statusvt=11

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

   echo -n '   '"$msg"

   "$func" "$@" >/dev/null 2>&1

   if [ "$?" -gt 0 ]; then
      echo_failure
      echo
      return 1
   fi

   echo_success
   echo
   return 0
}

# Execute a macro in the background
vmware_bg_exec() {
  local msg="$1"  # IN
  local func="$2" # IN
  shift 2

  echo -n '   '"$msg"' (background)'

  "$func" "$@" 2>&1 | logger -t 'VMware[init]' -p daemon.err >/dev/null 2>&1 &

  echo_success
  echo
  return 0
}


# create_certificate()
#
# creates a certificate for use with ssl. 
# Each server needs a unique certificate.
#
create_rui_certificate() {
   local certConfFile=`mktemp -q /tmp/cert.cnf.XXXXXX`

   # web browsers get confused and use the wrong certificates
   # if they get multiple certificates with the same data, but
   # different private keys (ie you did a full reinstall, but
   # kept the hostname the same).  Use the current time as
   # a uniqifier.
   local curTime=`date +"%s"`

   # I'm not sure what this is for, but the mui certificates had it,
   # and it seems too random not to serve a purpose.
   local certUniqIdent="564d7761726520496e632e"

   # hostname must match url used to access the server, or webbrowers
   # complain.
   local hostName=`hostname -f`
   if [ -z "$hostName" ]; then
      local hostName="unknown hostname"
   fi
   cat > $certConfFile << 'END_OF_CERT_DOT_CNF'
# Conf file that the management-ui will use to generate SSL certificates.
[ req ]
default_bits            = 1024
default_keyfile         = rui.key
distinguished_name      = req_distinguished_name

#Don't encrypt the key
encrypt_key             = no
prompt                  = no

string_mask = nombstr

[ req_distinguished_name ]
countryName             = US
stateOrProvinceName     = California
localityName            = Palo Alto
0.organizationName      = VMware, Inc.
emailAddress            = ssl-certificates@vmware.com
END_OF_CERT_DOT_CNF

   echo organizationalUnitName  = $productName Certificate >> $certConfFile
   echo commonName              = $hostName >> $certConfFile
   echo unstructuredName        = $curTime,$certUniqIdent >> $certConfFile
   mkdir -p $sslDir >& /dev/null

   /usr/bin/openssl  req -new -x509 -keyout "$sslDir"'/rui.key' \
   -out "$sslDir"'/rui.crt' -config "$certConfFile" -days 7000  >&   /dev/null

   #make key readable only by root (important)
   chmod 400 "$sslDir"'/rui.key' >& /dev/null

   #cleanup
   rm -f "$certConfFile" >& /dev/null
}

  
# Terminate a process synchronously
vmware_synchrone_kill() {
  local pid="$1"    # IN
  local signal="$2" # IN
  local second

  kill -"$signal" "$pid"

  # Wait a bit to see if the dirty job has really been done
  for second in 0 1 2 3 4 5 6 7 8 9 10; do
    if [ ! -d /proc/"$pid" ]; then
      # Success
      return 0
    fi

    sleep 1
  done

  # Timeout
  return 1
}

# Start hostd
vmware_start_hostd() {
   vmware_bg_exec "$hostdName" "$watchdog" -s hostd -u 60 -q 5 -c $hostdSupport "$hostd -u"
}

# Stop hostd
vmware_stop_hostd() {
  # Shut down the hostd watchdog
  vmware_exec "$hostdName Watchdog" "$watchdog" -k hostd
  # Shut down hostd itself
  vmware_exec "$hostdName" "$VIMSH" -n -e 'internalsvc/shutdown'
  # Make sure it's really dead
  local hostdpid=`pidof vmware-hostd`
  if [ "$hostdpid" != '' ]; then
     logger -p daemon.err -t $subsys "Killing $hostd process $hostdpid since it failed to exit cleanly"
     kill -TERM $hostdpid
  fi
}

# The logrotation code stops working if its status file
# gets corrupted.  This commonly happens when the server
# runs out of diskspace, and a zero length logrotate.status
# file gets created.  Hopefully future (post 7.2) versions of
# logrotate fix this problem.  For now, deal with it here.
log_rotation_cleanup() {
   local logRotateStatus="/var/lib/logrotate.status"
   if [ -e $logRotateStatus -a ! -s $logRotateStatus ]; then
     rm -f $logRotateStatus
   fi
}

if isTSMode ; then
   # We intentionally do not start hostd when vmkernel is not
   # loaded, so exiting here is expected behavior, not an error.
   action "Skipping $productName Management services." /bin/true
   exit 0 
fi
            
# See how we were called.
case "$1" in
  start)
	echo "Starting $productName Management services:"

	# Generate SSL certificate if necessary
	if [ ! -e $sslDir/rui.key -o ! -e $sslDir/rui.crt ]; then
	    echo "Generating $productName SSL certificate..."
	    create_rui_certificate 
	fi

        if $watchdog -r hostd > /dev/null 2>&1; then
            echo "$hostdName is already running"
        else
            vmware_start_hostd
        fi

        vmware_bg_exec 'Availability report startup' "/etc/cron.daily/vmkuptimereport"
	
	[ -d /var/lock/subsys ] || mkdir -p /var/lock/subsys
        touch /var/lock/subsys/$subsys

        if [ -z "$NOCHVT" ]; then
                chvt $statusvt
        fi
        ;;
    
  stop)
	echo "Stopping $productName Management services:"
        exitcode='0'

        log_rotation_cleanup

        vmware_stop_hostd

        if [ "$exitcode" -gt 0 ]; then
           exit 1
        fi
	;;

  status)
        status vmware-hostd

	;;

  restart)
	"$0" stop && "$0" start
	;;

  *)
	echo "Usage: `basename "$0"` {start|stop|status|restart}"
	exit 1
esac

exit 0
