#!/bin/sh
#
# Copyright (c) 2005-2019 VMware, Inc.  All rights reserved.
#
# Wrapper that adds all available libraries to LD_LIBRARY_PATH.

# BEGINNING_OF_DB_DOT_SH
#!/bin/sh

#
# Manage an installer database
#

# Add an answer to a database in memory
db_answer_add() {
  dbvar="$1" # IN/OUT
  id="$2"    # IN
  value="$3" # IN



  eval "$dbvar"'_answer_'"$id"'="$value"'

  eval 'answers="$'"$dbvar"'_answers"'
  # There is no double quote around $answers on purpose
  for i in $answers; do
    if [ "$i" = "$id" ]; then
      return
    fi
  done
  answers="$answers"' '"$id"
  eval "$dbvar"'_answers="$answers"'
}

# Remove an answer from a database in memory
db_answer_remove() {
  dbvar="$1" # IN/OUT
  id="$2"    # IN




  eval 'unset '"$dbvar"'_answer_'"$id"

  new_answers=''
  eval 'answers="$'"$dbvar"'_answers"'
  # There is no double quote around $answers on purpose
  for i in $answers; do
    if [ "$i" != "$id" ]; then
      new_answers="$new_answers"' '"$i"
    fi
  done
  eval "$dbvar"'_answers="$new_answers"'
}

# Load all answers from a database on stdin to memory (<dbvar>_answer_*
# variables)
db_load_from_stdin() {
  dbvar="$1" # OUT

  eval "$dbvar"'_answers=""'

  # read doesn't support -r on FreeBSD 3.x. For this reason, the following line
  # is patched to remove the -r in case of FreeBSD tools build. So don't make
  # changes to it.
  while read action p1 p2; do
    if [ "$action" = 'answer' ]; then
      db_answer_add "$dbvar" "$p1" "$p2"
    elif [ "$action" = 'remove_answer' ]; then
      db_answer_remove "$dbvar" "$p1"
    fi
  done
}

# Load all answers from a database on disk to memory (<dbvar>_answer_*
# variables)
db_load() {
  dbvar="$1"  # OUT
  dbfile="$2" # IN

  db_load_from_stdin "$dbvar" < "$dbfile"
}

# Iterate through all answers in a database in memory, calling <func> with
# id/value pairs and the remaining arguments to this function
db_iterate() {
  dbvar="$1" # IN
  func="$2"  # IN
  shift 2




  eval 'answers="$'"$dbvar"'_answers"'
  # There is no double quote around $answers on purpose
  for i in $answers; do
    eval 'value="$'"$dbvar"'_answer_'"$i"'"'
    "$func" "$i" "$value" "$@"
  done
}

# If it exists in memory, remove an answer from a database (disk and memory)
db_remove_answer() {
  dbvar="$1"  # IN/OUT
  dbfile="$2" # IN
  id="$3"     # IN



  eval 'answers="$'"$dbvar"'_answers"'
  # There is no double quote around $answers on purpose
  for i in $answers; do
    if [ "$i" = "$id" ]; then
      echo 'remove_answer '"$id" >> "$dbfile"
      db_answer_remove "$dbvar" "$id"
      return
    fi
  done
}

# Add an answer to a database (disk and memory)
db_add_answer() {
  dbvar="$1"  # IN/OUT
  dbfile="$2" # IN
  id="$3"     # IN
  value="$4"  # IN

  db_remove_answer "$dbvar" "$dbfile" "$id"
  echo 'answer '"$id"' '"$value" >> "$dbfile"
  db_answer_add "$dbvar" "$id" "$value"
}

# Add a file to a database on disk
# 'file' is the file to put in the database (it may not exist on the disk)
# 'tsfile' is the file to get the timestamp from, '' if no timestamp
db_add_file() {
  dbfile="$1" # IN
  file="$2"   # IN
  tsfile="$3" # IN


  if [ "$tsfile" = '' ]; then
    echo 'file '"$file" >> "$dbfile"
  else
    # We cannot guarantee existence of GNU coreutils date on all platforms
    # (e.g. Solaris).  Ignore timestamps in that case.
    date=`date -r "$tsfile" '+%s' 2> /dev/null` || true
    if [ "$date" != '' ]; then
      date=' '"$date"
    fi
    echo 'file '"$file$date" >> "$dbfile"
  fi
}

# Remove file from database
db_remove_file() {
  dbfile="$1" # IN
  file="$2"   # IN

  echo "remove_file $file" >> "$dbfile"
}

# Add a directory to a database on disk
db_add_dir() {
  dbfile="$1" # IN
  dir="$2"    # IN

  echo 'directory '"$dir" >> "$dbfile"
}
# END_OF_DB_DOT_SH

db_load 'vm_db' '/etc/vmware-tools/locations'

# So Solaris is super fantastic and doesn't always include the
# readlink utility on their systems.  So instead we use the
# basename of the dirname of $0 to figure out which directory to look
# for our application in within our LIBDIR.
#
# Also need to handle the special case for vmware-user-wrapper.  It now
# execs vmtoolsd in the sbin dir... so adjust accordingly.
binary="`basename "$0"`"
if [ "$binary" = 'vmware-user-wrapper' ]; then
   binary='vmtoolsd'
   binaryDir='sbin'
   isVmusr=1
else
   binaryDir="`dirname "$0"`"
   binaryDir="`basename "$binaryDir"`"
fi

# Find the binary that best matches the running arch using isainfo
# The order is in arch preference.
for arch in `isainfo`; do
   realBinDir="$vm_db_answer_LIBDIR"/"$binaryDir"/"$arch"
   if [ -x "$realBinDir/$binary" ]; then
      break
   fi
done
if [ ! -x $realBinDir ]; then
   echo "Unable to locate executable $binary in \"$realBinDir\"." && exit 1
fi

preserve_gtk_env() {
# Store the current environment variables
    VMWARE_GTK_EXE_PREFIX="$GTK_EXE_PREFIX"
    VMWARE_PANGO_RC_FILE="$PANGO_RC_FILE"
    VMWARE_GDK_PIXBUF_MODULE_FILE="$GDK_PIXBUF_MODULE_FILE"
    VMWARE_GTK_IM_MODULE_FILE="$GTK_IM_MODULE_FILE"
    VMWARE_GTK2_RC_FILES="$GTK2_RC_FILES"
# Export on separate lines for sh on solaris.
    export VMWARE_GTK_EXE_PREFIX
    export VMWARE_PANGO_RC_FILE
    export VMWARE_GDK_PIXBUF_MODULE_FILE
    export VMWARE_GTK_IM_MODULE_FILE
    export VMWARE_GTK2_RC_FILES

# Set up GTK environment variables
    LIBCONF="$vm_db_answer_LIBDIR"/libconf
    GTK_EXE_PREFIX=$LIBCONF
    PANGO_RC_FILE=$LIBCONF"/etc/pango/pangorc"
    GDK_PIXBUF_MODULE_FILE=$LIBCONF"/etc/gtk-2.0/gdk-pixbuf.loaders"
    GTK_IM_MODULE_FILE=$LIBCONF"/etc/gtk-2.0/gtk.immodules"
    GTK2_RC_FILES=$LIBCONF"/etc/gtk-2.0/gtkrc"
# Export on separate lines for sh on solaris.
    export GTK_EXE_PREFIX
    export PANGO_RC_FILE
    export GDK_PIXBUF_MODULE_FILE
    export GTK_IM_MODULE_FILE
    export GTK2_RC_FILES
}

vm_append_libs() {
   path="$LD_LIBRARY_PATH"

   for lib in "$vm_db_answer_LIBDIR"/lib/$arch/*; do
      if [ -d "$lib" ]; then
         path="$path:$lib"
      fi
   done

   echo "$path"
}

# Preserve the GTK Env if we are starting vmware-user
if [ -n "$isVmusr" ]; then
   preserve_gtk_env
fi

LD_LIBRARY_PATH="`vm_append_libs`"

# Solaris places some needed libraries on a different path.
if [ "$arch" = 'amd64' ]; then
    LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/sfw/lib/amd64:/usr/X11/lib/amd64"
else
    LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/sfw/lib:/usr/X11/lib"
fi

# Instead of using absolute path for the binary change our PATH
# to keep argv[0] intact since it may be used for printing
# disagnostic messages
PATH="$realBinDir:$PATH"

# The Bourne shell requires export to be its own statement
export PATH
export LD_LIBRARY_PATH
exec "$binary" "$@"
