#! /bin/sh
#######################################################################
#
#   Smalltalk package installer
#
#
#######################################################################


#######################################################################
#
# Copyright 1999,2000,2001,2002
# Free Software Foundation, Inc.
# Written by Paolo Bonzini.
#
# This file is part of GNU Smalltalk
#
# GNU Smalltalk is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2, or (at
# your option) any later version.
# 
# The GNU Smalltalk is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with the GNU Smalltalk; see the file COPYING.
# If not, write to the Free Software Foundation, 59 Temple Place - Suite
# 330, Boston, MA 02110-1301, USA.  
#
#######################################################################"


: ${prefix:=/usr/local}
: ${exec_prefix:=${prefix}}
: ${AWK:=gawk}
: ${GST_LOAD:=${exec_prefix}/bin/gst-load}

IMAGE_PATH=${SMALLTALK_IMAGE:-${prefix}/share/smalltalk}
(cd $IMAGE_PATH 2> /dev/null && IMAGE_PATH=`pwd`)

request_help=false
request_version=false
options_error=false
load=:
install=:
dist=false
list_files=
uninstall=false
dry_run=false
DESTDIR=
srcdir=.
files=

# Command line parsing.

while [ -n "$1" ]; do
  case $1 in
	--v | --ve | --ver | --vers | --versi | --versio | \
	--version)	 request_version=:		   ;;

	--h | --he | --hel | \
	--help)		 request_help=:			   ;;

	--no-l | --no-lo | --no-loa | \
	--no-load)	 load=false			   ;;

	--no-i | --no-in | --no-ins | --no-inst | \
	--no-insta | --no-instal | \
	--no-install)	 install=false			   ;;

	--u | --un | --uni | --unin | --unins | --uninst | \
	--uninsta | --uninstal | \
	--uninstall)     load=false; uninstall=:           ;;

	--di | --dis | \
	--dist)		 load=false; dist=:	  	   ;;

	--l=* | --li=* | --lis=* | --list=* | --list-=* | \
	--list-f=* | --list-fi=* | --list-fil=* | --list-file=* | \
	--list-files=*)	 list_files="$list_files `echo $1 | sed s/.*=//`"
							   ;;

	--l | --li | --lis | --list | --list- | \
	--list-f | --list-fi | --list-fil | --list-file | \
	--list-files)	 shift; list_files="$1"		   ;;

	--s | --sr | --src | --srcd | --srcdi | \
	--srcdir)	 shift; srcdir="$1"		   ;;

	--s=* | --sr=* | --src=* | --srcd=* | --srcdi=* | \
	--srcdir=*)	 srcdir="`echo $1 | sed s/.*=//`"  ;;

	--de | --des | --dest | --destd | --destdi | \
	--destdir)	 shift; DESTDIR="$1"		   ;;

	--de=* | --des=* | --dest=* | --destd=* | --destdi=* | \
	--destdir=*)	 DESTDIR="`echo $1 | sed s/.*=//`" ;;

	-n | --dr | --dry | --dry- | --dry-r | --dry-ru | \
  	--dry-run)	 dry_run=:			   ;;

	-*)		 options_error=:		   ;;

  	*)		 files="$files $1"		   ;;
  esac
  shift
done

# Do --help and --version.

if [ -z "$files" ] || $request_help || $options_error; then
  cat <<EOF
Syntax: gst-package [OPTION]... FILES...

    -n, --dry-run         print commands rather than running them
	--no-load         don't load the Smalltalk files in the image
        --no-install      don't copy the files
        --uninstall       remove the packages mentioned in the FILES
        --dist            create symbolic links of non-built files
        --list-files PKG  just output the list of files in the package
	--srcdir DIR      look for non-built files in directory DIR
	--destdir DIR	  prefix the destination directory with DIR

	--help            display this message and exit
	--version         print version information and exit

Except in uninstall and list files mode, gst-package requires write
access to the \`packages.xml' file in the GNU Smalltalk image directory,
and merges the XML package files on the command line with that file.

The image path is $IMAGE_PATH.

EOF
  # Unless --help was passed, return an error.
  $request_help && exit 0
  exit 1
fi

if $request_version; then
  echo GNU Smalltalk package installer, version 2.2
  exit 0
fi

# Process --list-files now, then exit.

if [ -n "$list_files" ]; then
  for i in $list_files; do
    dir="`sed -ne '/<name>'"$i"'<.name>/,/<.*package>/!d' \
	     -e 's,.*<directory>\([^<]*\)<.directory>,\1,p' $files | sed 1q`"

    list="`sed -ne '/<name>'"$i"'<.name>/,/<.*package>/!d' \
	      -e 's,.*<built-file>\([^<]*[^/]\)<.built-file>,\1,p' $files `"

    for j in $list; do
      echo $dir/$j
    done

    list="`sed -ne '/<name>'"$i"'<.name>/,/<.*package>/!d' \
	      -e 's,.*<file>\([^<]*[^/]\)<.file>,\1,p' $files `"

    for j in $list; do
      echo $dir/$j
    done
  done
  exit 0
fi

# Extract the name of the packages to be (un)installed.

pkgs=`sed -e '/<name>/!d' \
          -e 's,.*<name>\([^<]*\)<.name>,\1 ,' $files `

if $uninstall; then
  for i in $pkgs; do
    dir="`sed -ne '/<name>'"$i"'<.name>/,/<.*package>/!d' \
	     -e 's,.*<directory>\([^<]*\)<.directory>,\1,p' $files | sed 1q`"

    list="`sed -ne '/<name>'"$i"'<.name>/,/<.*package>/!d' \
	      -e 's,.*<built-file>\([^<]*[^/]\)<.built-file>,\1,p' $files `"
    for j in $list; do
      case $j in
        /*) dest=$DESTDIR$j ;;
	*) dest="$DESTDIR$IMAGE_PATH/$dir/$j" ;;
      esac

      echo "rm -f $dest"
      $dry_run || rm -f "$dest"
    done

    list="`sed -ne '/<name>'"$i"'<.name>/,/<.*package>/!d' \
	      -e 's,.*<file>\([^<]*[^/]\)<.file>,\1,p' $files `"
    for j in $list; do
      dest="$DESTDIR$IMAGE_PATH/$dir/$j"
      echo "rm -f $dest"
      $dry_run || rm -f "$dest"
    done
  done
  exit 0
fi

# If we are installing, add packages.xml to the list
# and merge the supplied packages files with it

if $dist; then
  :
else
  base="$DESTDIR$IMAGE_PATH/packages.xml"
  if test -f $base; then
    for i in $files; do
      if test $i -ef $base; then
        add=
        break
      fi
    done
    files="$base${base:+ }$files"
  fi

  echo "Merging $files..."
  $dry_run || {
    sed -e '$i\
</packages>' -e '/<.packages>/,/<packages>/d' \
      $files > packages.tmp

    mv packages.tmp $DESTDIR$IMAGE_PATH/packages.xml
  }
fi

if $install; then
  for i in $pkgs; do
    dir="`sed -ne '/<name>'"$i"'<.name>/,/<.*package>/!d' \
	     -e 's,.*<directory>\([^<]*\)<.directory>,\1,p' $files | sed 1q`"
    dirs="`sed -ne '/<name>'"$i"'<.name>/,/<.*package>/!d' \
	      -e 's,.*<built-file>\([^<]*\)/<.built-file>,\1,p' \
	      -e 's,.*<file>\([^<]*\)/<.file>,\1,p' $files `"

    for j in . $dirs; do
      case $j in
        /*) dest=$DESTDIR$j ;;
	*) dest=$DESTDIR$IMAGE_PATH/$dir/$j ;;
      esac

      # The following part emulates the mkinstalldirs script
      set fnord `echo "$dest" | sed -e 's/^\///' -e 's/\// /g'`
      shift
  
      case $dest in
	/*) pathcomp= ;;
	*) pathcomp=. ;;
      esac
      for d
      do
        pathcomp="$pathcomp/$d"
        case "$pathcomp" in
          -* ) pathcomp=./$pathcomp ;;
        esac

        if test ! -d "$pathcomp"; then
	  echo mkdir "$pathcomp"
	  mkdir "$pathcomp"
        fi
      done
    done

    if $dist; then
      list="`sed -ne '/<name>'"$i"'<.name>/,/<.*package>/!d' \
	        -e 's,.*<file>\([^<]*[^/]\)<.file>,\1,p' $files `"

      wd=`cd $srcdir && pwd`
      for j in $list; do
        case $j in
          /*) dest=$DESTDIR$j ;;
	  *) dest="$DESTDIR$IMAGE_PATH/$dir/$j" ;;
        esac

        echo ln -s -f "$wd/$dir/$j" "$dest"
        $dry_run || ln -s -f "$wd/$dir/$j" "$dest"
      done

    else
      list="`sed -ne '/<name>'"$i"'<.name>/,/<.*package>/!d' \
	        -e 's,.*<built-file>\([^<]*[^/]\)<.built-file>,\1,p' $files `"
      for j in $list; do
        case $j in
          /*) dest=$DESTDIR$j ;;
	  *) dest="$DESTDIR$IMAGE_PATH/$dir/$j" ;;
        esac

        echo "/usr/bin/install -c -o root -g wheel -m 644 $dir/$j $dest"
        $dry_run || (rm -f "$dest" && cp "$dir/$j" "$dest" && chmod 644 "$dest")
      done

      list="`sed -ne '/<name>'"$i"'<.name>/,/<.*package>/!d' \
	        -e 's,.*<file>\([^<]*[^/]\)<.file>,\1,p' $files `"
      for j in $list; do
        case $j in
          /*) dest=$DESTDIR$j ;;
	  *) dest="$DESTDIR$IMAGE_PATH/$dir/$j" ;;
        esac

        echo "/usr/bin/install -c -o root -g wheel -m 644 $srcdir/$dir/$j $dest"
        $dry_run || (rm -f "$dest" && cp "$srcdir/$dir/$j" "$dest" && chmod 644 "$dest")
      done
    fi
  done
fi

if $load && [ -n "$pkgs" ]; then
  echo ${GST_LOAD} $pkgs
  $dry_run || ${GST_LOAD} $pkgs
fi

exit 0
