misc/149335: shell script runs on Linux but not on freebsd

Paul Lambert eb30750 at gmail.com
Fri Aug 6 20:53:20 UTC 2010


Oliver,

Thanks for the reply.  I am attaching the bash output from the shell
script.  This script implements RPMs so I am sure that I need the linux
module.  I had previously found a guide on how to install RPMs on FreeBSD.
I have  a printer that has an RPM that allows it to work on Linus.  So I
would think that I will need the Linux module in the future.

I previously had made the "stat" change to the shell script and that part
works.  But, the bash shell is reporting an 'od" error.

Finally, how much performance do you lose with the linux module emulator?
Do you believe I only need the emulator to get VMware installed or will it
make other linux calls that are not part of FreeBSD?

Thanks

Paul

On Fri, Aug 6, 2010 at 1:35 PM, Oliver Fromme <olli at lurza.secnetix.de>wrote:

> Redirected to the -questions.
>
> Paul <eb30750 at gmail.com> wrote:
>  > What about matching the ' marks in this section?  I get a command error.
>  >
>  > > >   # XXX: put extraction in its own function
>  > > >   MAGIC_NUMBER=`od -An -t u4 -N 4 -j $MAGIC_OFFSET "$file" | tr -d '
> '`
>
> That command works fine for me:
>
> $ MAGIC_OFFSET=42
> $ file=/etc/motd
> $ MAGIC_NUMBER=`od -An -t u4 -N 4 -j $MAGIC_OFFSET "$file" | tr -d ' '`
> $ echo $MAGIC_NUMBER
> 540684323
>
> What's the exact error message that you get, and what are
> the values of the variables involved?
>
> By the way, when debugging shell scripts it is very helpful
> to run the shell with -vx.  Then it prints the script as it
> is being parsed, and additionally each command is printed
> after expansion.
>
> Best regards
>   Oliver
>
> --
> Oliver Fromme, secnetix GmbH & Co. KG, Marktplatz 29, 85567 Grafing b. M.
> Handelsregister: Registergericht Muenchen, HRA 74606,  Geschäftsfuehrung:
> secnetix Verwaltungsgesellsch. mbH, Handelsregister: Registergericht Mün-
> chen, HRB 125758,  Geschäftsführer: Maik Bachmann, Olaf Erb, Ralf Gebhart
>
> FreeBSD-Dienstleistungen, -Produkte und mehr:  http://www.secnetix.de/bsd
>
> "I invented Ctrl-Alt-Delete, but Bill Gates made it famous."
>        -- David Bradley, original IBM PC design team
>
-------------- next part --------------
BRSINC-VM02# kldstat
Id Refs Address            Size     Name
 1    7 0xffffffff80100000 d6aa98   kernel
 2    1 0xffffffff81022000 5ad4a    radeon.ko
 3    1 0xffffffff8107d000 115dc    drm.ko





BRSINC-VM02# bash -vx VMware-Player-3.1.0-261024.x86_64.bundle
#!/usr/bin/env bash
#
# VMware Installer Launcher
#
# This is the executable stub to check if the VMware Installer Service
# is installed and if so, launch it.  If it is not installed, the
# attached payload is extracted, the VMIS is installed, and the VMIS
# is launched to install the bundle as normal.

# Architecture this bundle was built for (x86 or x64)
ARCH=x64
+ ARCH=x64

if [ -z "$BASH" ]; then
   # $- expands to the current options so things like -x get passed through
   if [ ! -z "$-" ]; then
      opts="-$-"
   fi

   # dash flips out of $opts is quoted, so don't.
   exec /usr/bin/env bash $opts "$0" "$@"
   echo "Unable to restart with bash shell"
   exit 1
fi
+ '[' -z /usr/local/bin/bash ']'

set -e
+ set -e

ETCDIR=/etc/vmware-installer
+ ETCDIR=/etc/vmware-installer
OLDETCDIR="/etc/vmware"
+ OLDETCDIR=/etc/vmware

### Offsets ###
# These are offsets that are later used relative to EOF.
FOOTER_SIZE=52
+ FOOTER_SIZE=52

# This won't work with non-GNU stat.
FILE_SIZE=`stat -f "%z" "$0"`
stat -f "%z" "$0"
++ stat -f %z VMware-Player-3.1.0-261024.x86_64.bundle
+ FILE_SIZE=102467637
offset=$(($FILE_SIZE - 4))
+ offset=102467633

MAGIC_OFFSET=$offset
+ MAGIC_OFFSET=102467633
offset=$(($offset - 4))
+ offset=102467629

CHECKSUM_OFFSET=$offset
+ CHECKSUM_OFFSET=102467629
offset=$(($offset - 4))
+ offset=102467625

VERSION_OFFSET=$offset
+ VERSION_OFFSET=102467625
offset=$(($offset - 4))
+ offset=102467621

PREPAYLOAD_OFFSET=$offset
+ PREPAYLOAD_OFFSET=102467621
offset=$(($offset - 4))
+ offset=102467617

PREPAYLOAD_SIZE_OFFSET=$offset
+ PREPAYLOAD_SIZE_OFFSET=102467617
offset=$(($offset - 4))
+ offset=102467613

LAUNCHER_SIZE_OFFSET=$offset
+ LAUNCHER_SIZE_OFFSET=102467613
offset=$(($offset - 4))
+ offset=102467609

PAYLOAD_OFFSET=$offset
+ PAYLOAD_OFFSET=102467609
offset=$(($offset - 4))
+ offset=102467605

PAYLOAD_SIZE_OFFSET=$offset
+ PAYLOAD_SIZE_OFFSET=102467605
offset=$(($offset - 4))
+ offset=102467601

# Rest of the offsets ommitted

### End offsets ###

# Short name (ie, vmware-workstation).  This isn't technically correct
# since there could be multiple product components in a bundle.
PRODUCT_NAME=vmware-player
+ PRODUCT_NAME=vmware-player

# Called when the script exits
#
# Arguments:
#    None
#
# Side effects:
#    - VMIS_TEMP and PREPAYLOAD is removed unless VMIS_KEEP_TEMP is set
on_exit() {
   if [ -e "$VMIS_TEMP" -a -z "$VMIS_KEEP_TEMP" ]; then
      rm -rf "$VMIS_TEMP"
   fi

   if [ -e "$PREPAYLOAD" -a -z "$VMIS_KEEP_TEMP" ]; then
      rm -rf "$PREPAYLOAD"
   fi
}

trap on_exit EXIT
+ trap on_exit EXIT
trap "" USR1
+ trap '' USR1

# Retrives and sets the various lengths that are extracted from the
# footer of the file.
#
# Arguments:
#    $1 => bundle to get the lengths from
#
# Side effects:
#    - MAGIC_NUMBER, LAUNCHER_SIZE, and PAYLOAD_SIZE are set.
#
# Returns:
#    0 if successful, else 1
set_lengths() {
   local file="$1"
   if [ ! -s "$file" ]; then
      echo "$file does not exist"
      exit 1
   fi

   # XXX: put extraction in its own function
   MAGIC_NUMBER=`od -An -t u4 -N 4 -aj 
   $MAGIC_OFFSET "$file" | tr -d ' '`

   if [ "$MAGIC_NUMBER" != "907380241" ]; then
      echo "magic number does not match"
      exit 1
   fi

   LAUNCHER_SIZE=`od -An -t u4 -N 4 -j $LAUNCHER_SIZE_OFFSET "$file" | tr -d ' '`
   PAYLOAD_SIZE=`od -An -t u4 -N 4 -j $PAYLOAD_SIZE_OFFSET "$file" | tr -d ' '`
   PREPAYLOAD_SIZE=`od -An -t u4 -N 4 -j $PREPAYLOAD_SIZE_OFFSET "$file" | tr -d ' '`

   SKIP_BYTES=$(($PREPAYLOAD_SIZE + $LAUNCHER_SIZE))

   return 0
}

# Determines whether the user land is 32 or 64-bit.
#
# Side effects:
#    None.
#
# Returns:
#    "x86" or "x64" on success with error code 0.  Exits with non-zero
#    status and undefined text on failure.
get_arch() {
   # First byte is the ELF magic number.  The 5th byte is whether it's
   # a 32 or 64-bit machine (1 or 2, respectively).  See `man elf` for
   # details.
   local ELF_MAGIC=7f

   if [ "`od -N1 -An -t x1 < /bin/sh | tr -d ' '`" != "$ELF_MAGIC" ]; then
      exit 1
   fi

   local arch=`od -j4 -N1 -An -t u1 < /bin/sh | tr -d ' '`

   case $arch in
      1)
         echo "x86"
	 exit 0
	 ;;
      2)
         echo "x64"
         exit 0
	 ;;
      *)
         exit 1
         ;;
   esac
}

# Determines if path is relative.
#
# Side effects:
#    None.
#
# Returns:
#    0 if relative, otherwise 1.
is_relative() {
    local path="$1"
    shift

    [ "${path:0:1}" != "/" ]
    return
}

# Extracts the payload data into a temporary directory.
#
# Side effects:
#    - temporary directory is created
#    - VMIS_TEMP is set to temporary directory
#
# Returns:
#    None
extract_self() {
   VMIS_TEMP=`mktemp -d /tmp/vmis.XXXXXX`
   local file="$0"
   local filter=""
   local bootstrapper="$PREPAYLOAD"/bootstrapper-gtk

   if [ ! -d "$VMIS_TEMP" ]; then
      echo "Unable to create temporary directory."
      exit 1
   fi

   if is_relative "$file"; then
      file="$PWD/$file"
   fi

   if [ -e "$bootstrapper" ] && "$bootstrapper" --validate 2> /dev/null; then
      filter=' | "$PREPAYLOAD"/bootstrapper-gtk --title "VMware Installer" \
                --message "Please wait while extracting the VMware Installer..." \
                --total $PAYLOAD_SIZE"'
   else
      echo -n "Extracting VMware Installer..."
   fi

   (cd $VMIS_TEMP && dd if="$file" ibs=$SKIP_BYTES obs=1024 skip=1 2> /dev/null \
      $filter | gunzip -c 2> /dev/null | tar -xf - 2> /dev/null)

   if [ ! -e "$bootstrapper" ]; then
      echo "done."
   fi
}

extract_prepayload() {
   PREPAYLOAD=`mktemp -d /tmp/vmis.XXXXXX`
   local file="$0"

   if [ ! -d "$PREPAYLOAD" ]; then
      echo "Unable to create temporary directory."
      exit 1
   fi

   if is_relative "$file"; then
      file="$PWD/$file"
   fi

   (cd $PREPAYLOAD && dd if="$file" ibs=$LAUNCHER_SIZE obs=1024 skip=1 2> /dev/null | \
      gunzip -c 2> /dev/null | tar -xf - 2> /dev/null)
}

# Determines if a program is in the user's PATH.  This is used instead
# of the external which because Solaris' version does not work as
# expected.
#
# Side effects:
#    None
#
# Arguments:
#    $1 => program to check
#
# Returns:
#    0 if found, else 1
internal_which() {
   local binary="$1"

   for dir in `echo $PATH | tr ":" "\n"`; do
      if [ -s "$dir/$binary" -a -x "$dir/$binary" ]; then
         return 0
      fi
   done

   return 1
}


# Installs the installer and the current bundle.
#
# Arguments:
#    $1 => file source
#    $2 => true if show help
#    $3 => path to bundle
#
# Returns:
#    None
install() {
   local source="$1"/install
   shift
   local help="$1"
   shift
   local bundle="$1"
   shift

   if [ ! -d "$source" ]; then
      echo "$source does not exist" >&2
      exit 1
   fi

   export VMWARE_BOOTSTRAP="$VMIS_TEMP"/bootstrap

   cp -f "$source"/vmware-installer/bootstrap "$VMWARE_BOOTSTRAP"
   sed -i -e "s,@@LIBDIR@@,$source,g" "$VMWARE_BOOTSTRAP"
   sed -i -e "s,@@VMWARE_INSTALLER@@,$source/vmware-installer,g" "$VMWARE_BOOTSTRAP"

   . "$VMWARE_BOOTSTRAP"

   local installer="$VMWARE_INSTALLER"/vmware-installer

   if [ -n "$help" ]; then
      "$installer" --help
      exit 0
   fi

   # We must fixup the paths in Pango or the fonts will be all messed up
   local libconf="$source"/vmware-installer/lib/libconf
   for file in etc/pango/pangorc etc/pango/pango.modules etc/pango/pangox.aliases \
               etc/gtk-2.0/gdk-pixbuf.loaders etc/gtk-2.0/gtk.immodules; do
       sed -i -e "s,@@LIBCONF_DIR@@,$libconf,g" "$libconf/$file"
   done

   # Pass all options the user passed in so that the correct UI type
   # gets set.
   "$installer" --set-setting vmware-installer libconf "$libconf"   \
                --install-component "$source"/vmware-installer      \
                --install-bundle "$bundle" "$@"
   ret=$?
   if [ $ret != 0 ]; then
      exit $ret
   fi

   return 0
}


# Uninstall existing bundle installation.
#
# Arguments:
#    $1 => etcdir
#    $2 => suffix to add to vmware-uninstall (ie -vix)
#
# Returns:
#    0 on success
uninstall_bundle() {
   etcdir="$1"
   shift
   suffix="$1"
   shift

   local bootstrap="$etcdir"/bootstrap

   # If the bootstrap file exists, we are dealing with a VMIS
   # installer.
   if [ -e "$bootstrap" ]; then
      local bindir="`. $etcdir/bootstrap && echo $BINDIR`"
      local installer="$bindir"/vmware-uninstall$suffix
      # Check if this is an old style file by checking the version
      # line for 'VERSION="1.0"'  If it's found, run the blanket
      # uninstall.
      if grep -q 'VERSION="1.0"' "$bootstrap"; then
         if [ -e "$installer" ]; then
            if ! "$installer" "$@"; then
               echo "Installer did not uninstall successfully."
            fi
         fi
      fi
   fi

   return 0
}


# Uninstall a tar installation.
#
# Arguments:
#    $1 => etcdir
#    $2 => suffix to add to vmware-uninstall (ie -vix)
#
# Returns:
#    0 on success
uninstall_tar() {
   etcdir="$1"
   shift
   suffix="$1"
   shift

   locations="$etcdir"/locations

   if [ -e $locations ]; then
      local bindir=`grep "^answer BINDIR " $locations | tail -n 1 | sed 's,answer BINDIR ,,g'`
      local installer="$bindir"/vmware-uninstall$suffix.pl

      if [ -e "$installer" ]; then
         echo "Uninstalling legacy installation..."
         "$installer" -d
      else			# No uninstaller present, get rid of locations db.
         rm -f $locations
      fi
   fi
}

remove_rpm() {
   local pkg="$1"
   shift

   # If normal uninstallation fails, we want to force it out.  This
   # is likely because the preun script failed.  try again with
   # --noscripts
   if ! rpm -e $pkg; then
      echo "Uninstallation of $pkg failed.  Forcing uninstallation."
      rpm -e $pkg --noscripts
   fi
}

# Uninstalls legacy Player/Workstation.
#
# Arguments:
#    None
#
# Returns:
#    0 on success.
uninstall_legacy() {
   local etcdir="$1"
   shift

   local hosted=`echo "$PRODUCT_NAME" | grep "\(vmware-workstation\|vmware-player\|vmware-server\|vmware-vix\)"`

   if [ -n "$hosted" ]; then # Check to see if rpm is installed
      for pkg in VMwareWorkstation VMwarePlayer; do
         if rpm -q $pkg > /dev/null 2>&1; then
            remove_rpm $pkg
         fi
      done
      # Now handle the server case.  The installer is normally replacing
      # Player and/or Workstation, so there is no need to explicitly let
      # the user know that we're replacing them.  Silently replacing
      # server on the other hand is not a good idea.
      if rpm -q VMware-server > /dev/null 2>&1; then
         echo "VMware Server must be removed before installation can continue."
         echo "It will be automatically uninstalled by this installer.  Press"
         echo "ctrl-C now if you do not wish to continue or if you have running"
         echo "virtual machines that must be closed."
         echo ""
         echo "Otherwise press <enter> to continue and automatically uninstall VMware Server."
         read -e NOVAR
         rpm -e --noscripts VMware-server
      fi
   fi

   uninstall_tar "$etcdir" ""

   # config was a mess under the tar/rpm.  It always got renamed and
   # crazy things.  Clean them up.
   rm -f "$etcdir"/config.[0-9]*

   # Networking is sometimes still running after stopping services so
   # forceably kill it.  If it's still running then vmnet can't be
   # removed and network settings aren't migrated properly either.
   killall --wait -9 vmnet-netifup vmnet-dhcpd vmnet-natd vmnet-bridge \
                     vmnet-detect vmnet-sniffer 2> /dev/null || true
   /sbin/rmmod vmnet 2> /dev/null || true

   return 0
}


# Uninstalls bundle rpm for Player/Workstation.
#
# Arguments:
#    None
#
# Returns:
#    None.
uninstall_rpm() {
   local hosted=`echo "$PRODUCT_NAME" | grep "\(vmware-workstation\|vmware-player\|vmware-server\|vmware-vix\)"`

   if [ -n "$hosted" ]; then # Check to see if rpm is installed
      for pkg in VMware-Workstation VMware-Player; do
         if rpm -q $pkg > /dev/null 2>&1; then
            remove_rpm $pkg
         fi
      done
   fi
}


# Migrates networking settings for Player/Workstation.
# If called on an Iron install of Workstation, it will
# do nothing.  The locations and networking files were
# located by default in /etc/vmware, hence OLDETCDIR.
# If they were installed elsewhere, we have no way to
# find them.
#
# This only works for pre-Iron.  Iron network settings
# are stored in a different directory and upgrades handled
# by VMIS.
#
# Arguments:
#    None
#
# Returns:
#    None.
migrate_networks() {
   local locations="$OLDETCDIR"/locations
   local networking="$OLDETCDIR"/networking

   if [ -e "$networking" ]; then
      local tempNetworking=`mktemp /tmp/vmwareNetworking.XXXXXX`
      cp -f "$networking" $tempNetworking
      export VMWARE_RESTORE_NETWORKING=$tempNetworking
   elif [ -e "$locations" ]; then
      local tempLocations=`mktemp /tmp/vmwareLocations.XXXXXX`
      cp -f "$locations" $tempLocations
      export VMWARE_MIGRATE_NETWORKING=$tempLocations
   fi

   return 0
}

uninstall_old_vix() {
   # VIX used to live under vmware-vix, so we need to
   # check for an older VIX there.
   uninstall_bundle /etc/vmware-vix "-vix" "$@"

   # Uninstall old VIX versions if necessary.
   uninstall_tar /etc/vmware-vix "-vix"
}

uninstall_old() {
   # Uninstall the older .bundles
   uninstall_bundle "$OLDETCDIR" "" "$@"

   # VMWARE_SKIP_RPM_UNINSTALL will be set if we're installing
   # in an rpm context. In that case, we don't want to run any
   # rpm commands to prevent rpm deadlock.
   if [ -z "$VMWARE_SKIP_RPM_UNINSTALL" ]; then
      uninstall_rpm
   fi

   # Check if we need to run the uninstall portions of this script for earlier
   # installers.  Look for the locations database in /etc/vmware.  This file
   # will only exist for pre-Iron installs.
   if [ -e "$OLDETCDIR"/locations ]; then
      # This will uninstall legacy tar/rpm installations. Note that
      # we do not need to be concerned about checking for
      # VMWARE_SKIP_RPM_UNINSTALL since the bundle rpms are marked
      # to conflict with legacy rpms.
      uninstall_legacy $OLDETCDIR

      # Check if we need to uninstall components
      uninstall_tar $OLDETCDIR ""

      uninstall_old_vix "$@"
   fi
}


# Main entry point.  Checks whether the VMIS is installed and if so launches it.
# Otherwise extracts itself then installs the VMIS.
main() {
   local fullpath="$0"
   local help
   local extract

   if [ "`get_arch`" != "$ARCH" ]; then
      echo "This is a $ARCH bundle and does not match that of the current "
      echo "architecture.  Please download the `get_arch` bundle."
      exit 1
   fi

   if [ "$1" = "-h" -o "$1" = "--help" ]; then
      help=$1
      shift
   fi

   if [ "$1" = "-x" -o "$1" = "--extract" ]; then
      extract=$1
      shift
   fi

   if is_relative "$fullpath"; then
      fullpath="$PWD/$fullpath"
   fi

   if [ $UID -eq 0 ] && [ -z "$help" ] && [ -z "$extract" ]; then
      case "$PRODUCT_NAME" in
          vmware-workstation)
              migrate_networks
              uninstall_old_vix "$@"
              uninstall_old "$@"
              ;;
          vmware-player)
              migrate_networks
              uninstall_old "$@"
              ;;
          vmware-server)
              migrate_networks
              uninstall_old "$@"
              ;;
          vmware-vix)
              uninstall_old_vix "$@"
              ;;
          test-component)
              uninstall_bundle /etc/vmware-test -test "$@"
      esac
   fi

   if ! set_lengths "$0"; then
      echo "Unable to extract lengths from bundle."
      exit 1
   fi

   extract_prepayload
   extract_self

   install "$VMIS_TEMP" "$help" "$fullpath" "$extract" "$@"
}

main "$@"
+ main
+ local fullpath=VMware-Player-3.1.0-261024.x86_64.bundle
+ local help
+ local extract
get_arch
++ get_arch
++ local ELF_MAGIC=7f
od -N1 -An -t x1 < /bin/sh | tr -d ' '
+++ od -N1 -An -t x1
+++ tr -d ' '
++ '[' 7f '!=' 7f ']'
od -j4 -N1 -An -t u1 < /bin/sh | tr -d ' '
+++ od -j4 -N1 -An -t u1
+++ tr -d ' '
++ local arch=2
++ case $arch in
++ echo x64
++ exit 0
+ '[' x64 '!=' x64 ']'
+ '[' '' = -h -o '' = --help ']'
+ '[' '' = -x -o '' = --extract ']'
+ is_relative VMware-Player-3.1.0-261024.x86_64.bundle
+ local path=VMware-Player-3.1.0-261024.x86_64.bundle
+ shift
+ '[' V '!=' / ']'
+ return
+ fullpath=/home/VirtualMachines/VMware-Player-3.1.0-261024.x86_64.bundle
+ '[' 0 -eq 0 ']'
+ '[' -z '' ']'
+ '[' -z '' ']'
+ case "$PRODUCT_NAME" in
+ migrate_networks
+ local locations=/etc/vmware/locations
+ local networking=/etc/vmware/networking
+ '[' -e /etc/vmware/networking ']'
+ '[' -e /etc/vmware/locations ']'
+ return 0
+ uninstall_old
+ uninstall_bundle /etc/vmware ''
+ etcdir=/etc/vmware
+ shift
+ suffix=
+ shift
+ local bootstrap=/etc/vmware/bootstrap
+ '[' -e /etc/vmware/bootstrap ']'
+ return 0
+ '[' -z '' ']'
+ uninstall_rpm
echo "$PRODUCT_NAME" | grep "\(vmware-workstation\|vmware-player\|vmware-server\|vmware-vix\)"
++ echo vmware-player
++ grep '\(vmware-workstation\|vmware-player\|vmware-server\|vmware-vix\)'
+ local hosted=vmware-player
+ '[' -n vmware-player ']'
+ for pkg in VMware-Workstation VMware-Player
+ rpm -q VMware-Workstation
+ for pkg in VMware-Workstation VMware-Player
+ rpm -q VMware-Player
+ '[' -e /etc/vmware/locations ']'
+ set_lengths VMware-Player-3.1.0-261024.x86_64.bundle
+ local file=VMware-Player-3.1.0-261024.x86_64.bundle
+ '[' '!' -s VMware-Player-3.1.0-261024.x86_64.bundle ']'
od -An -t u4 -N 4 -aj 
++ od -An -t u4 -N 4 -aj
od: option requires an argument -- j
usage: od [-aBbcDdeFfHhIiLlOosvXx] [-A base] [-j skip] [-N length] [-t type]
          [[+]offset[.][Bb]] [file ...]
   $MAGIC_OFFSET "$file" | tr -d ' '
++ 102467633 VMware-Player-3.1.0-261024.x86_64.bundle
VMware-Player-3.1.0-261024.x86_64.bundle: line 111: 102467633: command not found
++ tr -d ' '
+ MAGIC_NUMBER=
+ '[' '' '!=' 907380241 ']'
+ echo 'magic number does not match'
magic number does not match
+ exit 1
on_exit
+ on_exit
+ '[' -e '' -a -z '' ']'
+ '[' -e '' -a -z '' ']'


More information about the freebsd-questions mailing list