cbe-install
author laca
Mon, 14 Apr 2008 10:39:56 +0000
changeset 1 102c9870ef63
child 10 a65a967018ee
permissions -rwxr-xr-x
initial import -- still incomplete

#!/bin/bash
#
# Script for setting up the common build environment for JDS on Solaris
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License, Version 1.0 only
# (the "License").  You may not use this file except in compliance
# with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2004-2005 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#

IFS=' 	
'
PKGBUILD_VERSION=1.2.0

# Set to "internal" for sun internal users, "external" for opensolaris
# No big differences really, just slightly different defaults
INT_EXT=@INT_EXT@
if [ "x$INT_EXT" != xinternal -a "x$INT_EXT" != xexternal ]; then
    INT_EXT=internal
fi

# all tarballs need a FOO_TARBALL variable here to be included in the
# CBE dist tarball
M4_TARBALL=m4-1.4.5.tar.gz
AUTOMAKE_1_9_TARBALL=automake-1.9.6.tar.bz2
AUTOMAKE_1_10_TARBALL=automake-1.10.tar.bz2
AUTOCONF_TARBALL=autoconf-2.61.tar.bz2
LIBTOOL_TARBALL=libtool-1.5.22.tar.gz
GETTEXT_TARBALL=gettext-0.14.1.tar.gz
FILEUTILS_TARBALL=fileutils-4.1.tar.gz
MAKE_TARBALL=make-3.80.tar.bz2
FLEX_TARBALL=flex-2.5.33.tar.bz2
CVS_TARBALL=cvs-1.12.5.tar.bz2
BISON_TARBALL=bison-2.3.tar.bz2
DIFF_TARBALL=diffutils-2.8.1.tar.gz
ANT_TARBALL=apache-ant-1.6.5-bin.tar.bz2
SVN_TARBALL=subversion-1.3.2.tar.bz2

# Extra packages:
RSYNC_TARBALL=rsync-2.6.8.tar.gz

# Obsolete packages to be pkgrm'd.  Mostly renamed packages.
OLD_PKGS="JDSautomake JDSautoconf JDSlibtool JDSm4 JDSgettext JDSfileutils 
          JDSmake JDSpatch CBEpatch JDSflex JDScvs SUNWpkgbuild"

# default log file.  Changed to /tmp/jds-cbe.install.log.$$ if the user
# installing is not root
LOGFILE=/var/sadm/install/logs/jds-cbe.install.log.$$

# packages that the JDS build requires.  cbe-install will check if they
# are installed and install them if not.
JDS_DEPENDENCIES="SUNWgpch SUNWi2cs SUNWi1cs SUNWi15cs SUNWceuos
    SUNWcleu SUNWeuluf SUNWdeiso1 SUNWi5cs SUNWi13cs
    SUNWi9cs SUNWeeuos SUNWi7cs SUNWesiso1 SUNWcleu2
    SUNWeu8os SUNWfriso1 SUNWale SUNWhkleu SUNWhleu
    SUNWinleu SUNWitiso1 SUNWjfpu SUNWkleu SUNWmeaos
    SUNWsmbaS SUNWnafos SUNWnamos SUNWneuos SUNWsamos
    SUNWseuos SUNWsviso1 SUNWtleu SUNWweuos SUNWgtar
    SUNWwgetr SUNWwgetu SUNWhea SUNWsfwhea
    SUNWsprot SUNWxcu4"

# all non-optional CBE packages
CBE_PKGS="SFpkgbuild CBEmake CBEcvs CBEm4 CBEautoconf CBEautomake
    CBElibtool CBEgettext CBEfileutils CBEflex CBEbison CBEdiff
    CBEant CBEsvn"

# default cbe install location
cbe_prefix=/opt/jdsbld
# this should be set to a reasonable value in install_pkgbuild()
pkgbuild_topdir=/fix/me

# default value for the "who is the build user" question
logname=${LOGNAME:-`logname`}
if [ -x /usr/xpg4/bin/id ]; then
    uid=`/usr/xpg4/bin/id -u`
    username=`/usr/xpg4/bin/id -un`
else
    uid=`/bin/id | cut -f2 -d= | cut -f1 -d'('`
    username=`/bin/id |cut -f2 -d'(' | cut -f1 -d')'`
fi
export HOME="$(eval cd ~$username; pwd)"

# compiler to use for Solaris9 builds (cc -V)
fd7_name='Forte Developer 7'
fd7_sgnome_dir='FD7'
fd7_sparc_version_string='cc: Forte Developer 7 C 5.4 2002/03/09'
fd7_i386_version_string='cc: Forte Developer 7 C 5.4 2002/03/09'

# compiler to use for Solaris10 builds (cc -V)
k2_name='Sun ONE Studio 8 (K2)'
k2_sgnome_dir='SOS8'
k2_sparc_version_string='cc: Sun C 5.5 Patch 112760-08 2004/02/20'
k2_i386_version_string='cc: Sun C 5.5 Patch 112761-06 2004/01/13'

vulcan_name='Sun Studio 10 (Vulcan)'
vulcan_sgnome_dir='vulcan-0107/opt'
if [ $INT_EXT = internal ]; then
    # compiler to use for amd64 builds + TJDS + SNV + GNOME 2.10 (S10/x86)
    # version string of the compiler in /sgnome
    vulcan_i386_version_string='cc: Sun C 5.7 Patch 117837-04 2005/05/11'
    vulcan_sparc_version_string='cc: Sun C 5.7 2005/01/07'
else
    # the current (as of 26/Sept/2005) version on opensolaris.org
    # version string of the compiler available from opensolaris.org
    vulcan_i386_version_string='cc: Sun C 5.7 Patch 117837-04 2005/05/11'
    vulcan_sparc_version_string='cc: Sun C 5.7 Patch 117836-03 2005/05/11'
fi

# Sun Studio 11 (aka venus) version strings:
venus_name='Sun Studio 11 (Venus)'
venus_sgnome_dir="ONNV-TOOLS"
venus_alt_dirs="/sgnome/onnv-tools/`uname -p`/SS11/bin /ws/onnv-tools/SUNWspro/SS11/bin"
venus_sparc_version_string="cc: Sun C 5.8 Patch 121015-02 2006/03/29"
venus_i386_version_string="cc: Sun C 5.8 Patch 121016-02 2006/03/31"

# Sun Studio 11 (aka venus) with the new patches in /ws/onnv-tools
venus_p05_name='Sun Studio 11 (Venus) + patches'
venus_p05_sgnome_dir="ONNV-TOOLS"
venus_p05_alt_dirs="/sgnome/onnv-tools/`uname -p`/SS11-new/bin /ws/onnv-tools/SUNWspro/SS11-new/bin /sgnome/onnv-tools/`uname -p`/SS11/bin /ws/onnv-tools/SUNWspro/SS11/bin"
venus_p05_sparc_version_string="cc: Sun C 5.8 Patch 121015-04 2007/01/10"
venus_p05_i386_version_string="cc: Sun C 5.8 Patch 121016-05 2007/01/10"

always_uninstall_existing=
always_skip_existing=

# write a message to the log file
# not visible to the user
log () {
    for msg in "${@}"; do
	echo "`date`: $msg" >> $LOGFILE
    done
}

# print a message to the user and also write it to the log file
msg () {
    for msg in "${@}"; do
	echo $msg
	echo "`date`: $msg" >> $LOGFILE
    done
}

# alternate root directory
rootdir=/

process_cl () {
    while [ $# != 0 ]; do
	case "$1" in
	    -R )
		shift
		if [ $# == 0 ]; then
		    echo "Option -R requires an argument."
		    exit 1
		fi
		rootdir=$1
		case "$rootdir" in
		    /* )
			;;
		    * )
			echo "The argument to -R must be an absolute path name"
			exit 1
		esac
		;;
	    -h|--help)
		echo "Usage: $0 [options]"
		echo "options:"
		echo "   -h, --help        print this usage info"
		echo "   -R rootdir        install CBE packages in alternate root directory rootdir"
		exit 0
		;;
	    *)
		echo "Unknown option: $1"
		exit 1
		;;
	esac
	shift
    done
}

# clean up if installation is aborted
tempdirs=
remove_tempdirs () {
    IFS=:
    for tdir in $tempdirs; do
	case "$tdir" in
	    /tmp/* )
                cd /tmp
		rm -rf "$tdir"
		;;
	esac
    done
}

init () {
    myos=`uname -s`
    if [ "x$myos" != xSunOS ]; then
	echo "Run this script on a Solaris system."
	exit 1
    fi
    
    umask 0022

    myos_rel=`uname -r`
    if [ "x$myos_rel" = "x5.10" -o "x$myos_rel" = "x5.10.1" -o "x$myos_rel" = "x5.11" ]; then
	if [ $INT_EXT = external ]; then
	    cc32_versions='venus_p05 venus vulcan'
	    cc64_versions='venus_p05 venus vulcan'
	else
	    cc32_versions='venus venus_p05'
	    cc64_versions='venus venus_p05'
	fi
    else
	echo "Solaris 10 or Solaris 11 required."
	exit 1
    fi

    mydir=$(cd $(dirname $0); pwd);
    tardir=$mydir/tarballs

    CBE_VERSION=`cat $mydir/CBE_VERSION`

    my_id=`/usr/xpg4/bin/id -u`
    if [ "x$my_id" != x0 ]; then
	profiles | grep 'Software Installation' > /dev/null
	if [ $? != 0 ]; then
	    echo 'Run this script as root or a user with the "Software Installation" profile'
	    echo 'See the user_attr(4) and profiles(1) manual pages for details'
	    exit 1
	fi
	LOGFILE=/tmp/jds-cbe-${CBE_VERSION}.install.log.$$
    else
	LOGFILE=/var/sadm/install/logs/jds-cbe-${CBE_VERSION}.install.log.$$
    fi

    msg "Checking for required packages..."
    check_jds_dependencies

    if ! pkginfo -R $rootdir -q 'SUNWgpch.*'; then
	echo "ERROR: pkgbuild requires the GNU patch utility (/usr/bin/gpatch)."
	echo "ERROR: please install SUNWgpch from your Solaris installation media"
	echo "ERROR: before installing the JDS CBE."
	exit 1
    fi

    if ! pkginfo -R $rootdir -q 'SUNWgtar.*'; then
	echo "ERROR: pkgbuild requires the GNU tar utility (/usr/sfw/bin/gtar)."
	echo "ERROR: please install SUNWgtar from your Solaris installation media"
	echo "ERROR: before installing the JDS CBE."
	exit 1
    fi

    if [ -f /usr/sfw/include/glib.h ]; then
	echo "WARNING: /usr/sfw/include/glib.h is in conflict with the JDS headers."
	echo "WARNING: Please remove this file or SUNWGlib to avoid build problems."
	echo
	echo "Press Enter to continue"
	read dummy
    fi

    if ! pkginfo -R $rootdir -q 'SUNWwgetu.*'; then
	echo "WARNING: pkgbuild requires wget for full functionality."
	echo "WARNING: please install SUNWwgetr and SUNWwgetu from your"
	echo "WARNING: Solaris installation media"
	echo
	echo "Press Enter to continue"
	read dummy
    fi

    log "Running on `uname -a`"
    log "My directory is $mydir"

    ENV_SET=`env | cut -f1 -d=`
    for var in $ENV_SET; do
	case $var in
	    PS1|PS2|HZ|TERM|SHELL|OLDPWD|PATH|MAIL|PWD|TZ|SHLVL|HOME|LOGNAME|PRINTER|HOSTNAME|_|CC|CXX|EDITOR|SSH_*|DISPLAY|LESS*|LS_COLORS|LS_OPTIONS|TERMINFO|PAGER|MANPATH|VISUAL)
		;;
	    *)
		val=`eval echo "\\\$$var"`
		log "Unsetting $var (=\"$val\")"
		unset $var
		;;
	esac
    done

    tempdir=/tmp/cbe-install.$$
    tempdirs="$tempdirs:$tempdir"
    trap remove_tempdirs QUIT EXIT
    logrun mkdir -p $tempdir

    if [ -f $mydir/pkgs/CBElibtool/pkginfo ]; then
	binary_install=yes
	pkg_arch=`grep '^ARCH=' $mydir/pkgs/CBElibtool/pkginfo | cut -f2 -d=`
	arch=`uname -p`
	if [ "x$arch" != "x$pkg_arch" ]; then
	    echo "ERROR: wrong architecture"
	    echo "ERROR: these JDS CBE packages must be installed on a $pkg_arch system"
	    exit 1
	fi
	cbe_prefix=/opt/jdsbld
    else
	binary_install=no
    fi
}

# ask "question" variable_name "default answer"
#
# answer is stored in variable variable_name
ask () {
    echo -n "$1"
    if [ ! -z $3 ]; then
	echo -n " [$3]: "
    else
	echo -n ": "
    fi

    read -e val
    if [ "x$val" = x ]; then
	eval "$2=\"$3\""
    else
	eval "$2=\"$val\""
    fi
}

# ask_yes_no "question" variable_name "default answer"
#
# Answer ("yes" or "no") is stored in variable variable_name.
# Keep asking the user until the answer is yes or no.
ask_yes_no () {
    yes_no_repeat=yes
    while [ $yes_no_repeat = yes ]; do
	yes_no_repeat=no
	ask "${@}"
	eval "the_ans=\"\$$2\""
	case "$the_ans" in
	    [yY]|[yY][eE][sS] )
                eval "$2=yes"
		;;
 	    [nN]|[nN][oO] )
		eval "$2=no"
		;;
	    * )
	        echo "Please answer yes or no"
		yes_no_repeat=yes
	esac
    done
}

# get_dir "question" "answer_var" "default answer" "owner"
#
# Ask for a directory name and make sure it exists or create it
# for the user
get_dir () {
    repeat=yes
    while [ $repeat = yes ]; do
	repeat=no
	ask "$1" new_dir "$3"
	case "$new_dir" in
	    /* )
                # absolute path name, nothing to do
                ;;
	    ~* )
	        if [ "x$rootdir" != x/ ]; then
		    msg "The JDS CBE is being installed to an alternate root directory."
		    msg "You need to specify the full path to directories within the alternate root."
		    repeat=yes
		    continue
	        fi
		d1=`echo "$new_dir" | cut -f1 -d/`
		d2=`echo "$new_dir/" | cut -f2- -d/`
		d1n=$(eval echo "$d1")
		test -d "$d1n" || {
		    repeat=yes
		    msg "Directory not found: $d1"
		    continue
                }
		d1n=$(cd "$d1n" 2>/dev/null && pwd) || {
		    repeat=yes
		    msg "Failed to access directory: $d1"
		    continue
		}
		msg "Directory $new_dir expanded to $d1n/$d2"
		new_dir="$d1n/$d2"
		;;
	    * )
	        if [ "x$rootdir" != x/ ]; then
		    msg "The JDS CBE is being installed to an alternate root directory."
		    msg "You need to specify the full path to directories within the alternate root."
		    repeat=yes
		    continue
	        fi
		d1=`echo "$new_dir" | cut -f1 -d/`
		d2=`echo "$new_dir/" | cut -f2- -d/`
		d1n=$(eval echo "$d1")
		test -d "$d1n" || {
		    repeat=yes
		    msg "Directory not found: $d1"
		    continue
                }
		d1n=$(cd "$d1n" 2>/dev/null && pwd) || {
		    repeat=yes
		    msg "Failed to access directory: $d1"
		    continue
		}
		msg "Directory $new_dir expanded to $d1n/$d2"
		new_dir="$d1n/$d2"
		;;
	esac
    done
    if [ "x$new_dir" != "x/" ]; then
	new_dir=`echo "$new_dir" | sed -e 's%/*$%%'`
    fi
    eval "$2=\"$new_dir\""
}

#
# ask_ccdir
#
# result in new_ccdir and cc_name and cxx_name

# The args are:
#   <cc_version>:  expected compiler version to be displayed to the user,
#               e.g. "Sun Studio 10"
#   <cc_version_string>:  expected output of cc -V
#   <sgnome_cc_version>:  compiler subdir in /sgnome (for .ireland users)
#   <ccn>:      default answer (full path to cc)
ask_ccdir () {
    if [ $INT_EXT = internal ]; then
	REC="required"
    else
	REC="recommended"
    fi
    echo "The $REC C compiler(s) for this version of the JDS CBE is/are:"
    for compiler in $cc32_versions; do
	echo "        `eval echo \\\$${compiler}_name` (`eval echo \\\$${compiler}_$(uname -p)_version_string`)"
    done

    sgnome_cc32dirs=
    for compiler in $cc32_versions; do
	sgnome_cc32dirs="$sgnome_cc32dirs /sgnome/tools/${the_cpu}-solaris/forte/`eval echo \\\$${compiler}_sgnome_dir`/SUNWspro/bin"
	sgnome_cc32dirs="$sgnome_cc32dirs `eval echo \\\$${compiler}_alt_dirs`"
    done
    for cc32dir in $sgnome_cc32dirs; do
	cc32name="$cc32dir/cc"
	test -x $cc32name && break
    done
    if [ ! -d "$cc32dir" ]; then
	CC=${CC:-`which cc`}
	if [ -x "$CC" ]; then
	    cc32dir=$(dirname $CC)
	    cc32name=$cc32dir/cc
	else
	    cc32dir=
	    cc32name=
	fi
    fi

    repeat=yes
    while [ $repeat = yes ]; do
	repeat=no
	ask "Enter the path to the C compiler" "new_ccn" "$cc32name"
	new_ccdir=$(dirname $new_ccn)
	if [ ! -e "$new_ccn" ]; then
	    echo $new_ccn not found
	    repeat=yes
	elif [ ! -f "$new_ccn" ]; then
	    echo $new_ccn is not a file
	    repeat=yes
	elif [ ! -x "$new_ccn" ]; then
	    echo $new_ccn is not executable
	    repeat=yes
	else
	    cc_name=`basename "$new_ccn"`
	    if [ "x$cc_name" = xgcc ]; then
		echo
		echo "You chose gcc as your C compiler.  Note that building JDS using gcc may be"
		echo "possible but is not tested or supported."
		echo
		echo "Press Enter to continue"
		read dummy
		cxx_name=g++
	    else
		cxx_name=CC
		version_ok=no
		for compiler in $cc32_versions; do
		    "$new_ccn" -V 2>&1 | egrep -s "`eval echo \\\$${compiler}_$(uname -p)_version_string`" && {
			version_ok=yes
			break
		    }
		done
		if [ $version_ok = no ]; then
		    echo "$new_ccn is not the $REC compiler"
		    echo "\"cc -V\" should print one of the following:"
		    for compiler in $cc32_versions; do
			echo "       `eval echo \\\$${compiler}_$(uname -p)_version_string`"
		    done

		    ask_yes_no "Would you like to use this compiler anyway?" \
			use_different_cc no
		    if [ $use_different_cc = yes ]; then
			log "User chose to use a non-standard C compiler:"
			log "`$new_ccn -V 1>&1`"
			repeat=no
		    else
			repeat=yes
		    fi
		else
		    ccls=$( cd $new_ccdir; ls -l cc )
		    case "$ccls" in
			*"cc -> ../prod/bin/cc" )
			    ;;
			* )
			    echo "cc is expected to be a symlink to ../prod/bin/cc"
			    if [ $INT_EXT = internal ]; then
				echo "See the README file for information about installing the C compiler"
				echo "or using it via NFS on SWAN"
			    fi
			    repeat=yes
			    ;;
		    esac
		fi
	    fi
	fi
    done
}

# gather info for the installation from the user
ask_defaults () {
    if [ $binary_install != yes ]; then
	repeat=yes
	while [ $repeat = yes ]; do
	    repeat=no
	    get_dir "Enter the base directory (prefix) of the cbe" \
		cbe_prefix $cbe_prefix root
	    if [ "$cbe_prefix" = "/" -o "$cbe_prefix" = "/tmp" ]; then
		echo "This directory is not allowed."
		echo "Please choose a different one as the cbe prefix"
		repeat=yes
	    fi
	done
    fi

    if [ ! -f "$HOME/.pkgbuildmacros" -a ! -d "$HOME/packages" ]; then
	# the user probably hasn't used pkgbuild >= 1.1.0 yet
	# so let's ask if they want to use a specific topdir
	# instead of $HOME/packages
	echo "Starting from pkgbuild 1.1.0 (JDS CBE 1.5) there is no system-wide"
        echo "build directory (%_topdir), instead, each user has their own."
	echo "The default directory is \$HOME/packages."
	echo "If you wish to use a different build directory, you can define it"
	echo "in \$HOME/.pkgbuildmacros as follows:"
	echo
	echo "       %_topdir    /path/to/my/build/area"
	echo
	if [ "$uid" = 0 ]; then
	    echo
	    echo Press Enter to continue
	    read dummy
	else
	    ask_yes_no "Would you like to do this now?" \
		set_topdir no
	    if [ $set_topdir = no ]; then
		log "the user chose not to change the default topdir"
		echo "The default topdir ($HOME/packages) will be used"
	    else
		get_dir "Enter your build directory" default_topdir \
		    "$cbe_prefix/packages" $logname
		log "the user selected $default_topdir for topdir"
		echo "%_topdir $default_topdir" > $HOME/.pkgbuildmacros
		log "created $HOME/.pkgbuildmacros"
	    fi
	fi
    else
	log "the user already has a .pkgbuildmacros file or ~/packages dir"
    fi

    the_cpu=`uname -p`
    if [ "x$the_cpu" != xsparc ]; then
	the_cpu=x86
    fi

    ask_ccdir

    cc32dir="$new_ccdir"
    log "32-bit C compiler:   $cc32dir/$cc_name"
    log "32-bit C++ compiler: $cc32dir/$cxx_name"

    cc64dir="$cc32dir"
    log "64-bit C compiler:   $cc64dir/$cc_name"
    log "64-bit C++ compiler: $cc64dir/$cxx_name"

    msg "This version of the CBE comes with some optional utilities."
    msg "These are not required for building the JDS code, nevertheless"
    msg "they are useful to have on your system."
    msg "Please see the README file for the list of optional utilities."

    ask_yes_no "Would you like to install the optional packages?" \
	cbe_opt yes
    if [ $cbe_opt = yes ]; then
	log "User chose to install optional packages"
    else
	log "User chose not to install optional pkgs"
    fi
}

# create an admin file for pkgadd/pkgrm
make_admin_file () {
    echo "mail="                 > $1
    echo "instance=unique" 	>> $1
    echo "conflict=nocheck"     >> $1
    echo "conflict=quit"        >> $1
    echo "setuid=nocheck"       >> $1
    echo "action=nocheck"       >> $1
    echo "partial=quit"         >> $1
    echo "space=quit"           >> $1
    if [ "$2" = "pkgrm" ]; then
	echo "idepend=nocheck"      >> $1
	echo "rdepend=nocheck"      >> $1
    else
	echo "idepend=quit"         >> $1
	echo "rdepend=quit"         >> $1
    fi
}

# run a command, redirect the output to a log file and also print it
# on stdout
logrun () {
    status_file=/tmp/.command_status.$$
    /usr/bin/rm -f $status_file
    log "running $*"
    log "*** command output follows ***"
    ( "${@}" 2>&1 ; echo $? > $status_file ) | tee -a $LOGFILE
    log "*** command output ends ***"
    status=`cat $status_file`
    /usr/bin/rm -f $status_file
    return $status
}

# check if a package is installed and if so, offer to uninstall it
check_if_installed () {
    skip_package=no

    pkginfo -R $rootdir -q "$1"'.*' || return 0

    if [ x$always_uninstall_existing != xyes -a x$always_skip_existing != xyes ]; then
      msg "Package $1 is already installed."
      ask_yes_no "Would you like uninstall it?" do_uninstall yes
      if [ $do_uninstall = yes ]; then
	  if [ x$always_uninstall_existing != xno ]; then
	      ask_yes_no "Always uninstall previously installed packages?" \
		  always_uninstall_existing yes
	      log "always_uninstall_existing = $always_uninstall_existing"
	  fi
      fi
    else
      if [ x$always_skip_existing = xyes ]; then
	  msg "Skipping package $1 -- already installed"
	  skip_package=yes
	  return 0
      else
	  do_uninstall=yes
      fi
    fi
    if [ $do_uninstall = yes ]; then
	log "User chose to uninstall $1"
	make_admin_file /tmp/pkgrm.admin.$$ pkgrm || return 1
	pkgrm_failed=no
	logrun pfexec /usr/sbin/pkgrm -R $rootdir -n -a /tmp/pkgrm.admin.$$ "$1.*" || pkgrm_failed=yes
	if [ $pkgrm_failed = yes ]; then
	    ask_yes_no "pkgrm failed. would you like to continue anyway?" pkgrm_cont no
	    if [ $pkgrm_cont = yes ]; then
		log "User chose to continue anyway"
		return 0
	    fi
	    return 1
	fi
	return 0
    else
	log "User chose not to uninstall $1"
	if [ x$always_skip_existing != xyes ]; then
	    ask_yes_no "Would you like skip to the next package?" skip_package yes
	    if [ $skip_package = yes ]; then
		log "User chose to skip package $1"
		if [ x$always_skip_existing != xno ]; then
		    ask_yes_no "Always skip packages that are already installed?" always_skip_existing yes
		    log "always_skip_existing = $always_skip_existing"
		fi
		return 0
	    fi
	else
	    skip_package=yes
	    return 0
	fi
	msg "Not uninstalling $1."
	msg "NOTE that this may cause problems later"
	ask "Press Enter to continue" dummy ""
	return 0
    fi

    return 0
}

# install a list of svr4 packages given its directory, altroot and the
# names of the packages
install_pkgs () {
    pdir=$1; shift
    rdir=$1; shift
    make_admin_file $tempdir/pkgadd.admin.$$ pkgadd

    for pkg in $*; do
	msg "Installing package $pkg"
	logrun pfexec /usr/sbin/pkgadd -R "$rdir" -n -a $tempdir/pkgadd.admin.$$ -d "$pdir" $pkg || \
	    return 1
    done
    /usr/bin/rm -f $tempdir/pkgadd.admin.$$
    return 0
}

install_all_dependencies=
solaris_pkg_dir=/cdrom/cdrom0/Solaris_11/Product
# check if the pkgs JDS requires are installed; if not install them
check_jds_dependencies () {
    retval=0
    # we're going to cp solaris pkgs from the media to this dir
    tmp_pkg_dir=`mktemp -d /tmp/cbe-pkgs-XXXX`
    # schedule this dir for removal if the installation is aborted
    tempdirs="$tempdirs:$tmp_pkg_dir"
    for pkg in $JDS_DEPENDENCIES; do
	pkginfo -R $rootdir -q "$pkg."'*' && continue
	if [ "x$install_all_dependencies" != xyes ]; then
	    msg "Package $pkg is required for building JDS"
	    ask_yes_no "Would you like to install it now?" do_inst "yes"
	    if [ $do_inst = yes ]; then
		if [ "x$install_all_dependencies" != xno ]; then
		    ask_yes_no \
			"Install all required packages?" \
			install_all_dependencies "yes"
		fi
		while /bin/true; do
		    ask "Enter the path to the Solaris packages" \
			solaris_pkg_dir "$solaris_pkg_dir"
		    # Copy all packages found in $solaris_pkg_dir to a temporary
		    # dir so that people installing from CDs don't need to
		    # swap CDs all the time...
		    for p0 in $JDS_DEPENDENCIES; do
			pkginfo -q $p0 && continue
			test -d $tmp_pkg_dir/$p0 && continue
			test -d "$solaris_pkg_dir/$p0" && \
			    /bin/cp -r "$solaris_pkg_dir/$p0" $tmp_pkg_dir && \
			    /bin/chmod -R u+w $tmp_pkg_dir/$p0
		    done
		    test -d "$solaris_pkg_dir/$pkg" && break
		    msg "$solaris_pkg_dir/$pkg not found"
		done
	    else
		log "user chose not to install required package $pkg"
		continue
	    fi
	fi
	while /bin/true; do
	    msg "Installing package $pkg"
	    make_admin_file /tmp/pkgadd.admin.$$ pkgadd
	    if [ -d $tmp_pkg_dir/$pkg ]; then
		logrun pfexec /usr/sbin/pkgadd -R $rootdir -n -a /tmp/pkgadd.admin.$$ -d "$tmp_pkg_dir" $pkg
		if [ $? != 0 ]; then
		    msg "WARNING: failed to install required package $pkg"
		    ask_yes_no "Would you like to retry?" "do_retry" "yes"
		else
		    do_retry=no_need_to
		fi
	    else
		msg "Package $pkg was not found in $solaris_pkg_dir"
		do_retry=yes
		/bin/true
	    fi
	    if [ $do_retry = yes ]; then
		while /bin/true; do
		    ask "Enter the path to the Solaris packages" \
			solaris_pkg_dir "$solaris_pkg_dir"
		    test -d "$solaris_pkg_dir/$pkg" && break
		    msg "$solaris_pkg_dir/$pkg not found"
		done
		# Copy all packages found in $solaris_pkg_dir to a temporary
		# dir so that people installing from CDs don't need to
		# swap CDs all the time...
		for p0 in $JDS_DEPENDENCIES; do
		    test -d "$solaris_pkg_dir/$p0" && \
			/bin/cp -r "$solaris_pkg_dir/$p0" $tmp_pkg_dir && \
			/bin/chmod -R u+w $tmp_pkg_dir/$p0
		done
	    elif [ $do_retry = no ]; then
		ask_yes_no "Continue installation anyway?" \
		    do_continue no
		if [ $do_continue = no ]; then
		    /bin/rm -f /tmp/pkgadd.admin.$$
		    /bin/rm -rf $tmp_pkg_dir
		    msg "Installation aborted."
		    exit 1
		else
		    break
		fi
		break
	    else
		/bin/rm -rf $tmp_pkg_dir/$pkg
		/bin/rm -f /tmp/pkgadd.admin.$$
		break
	    fi
	done
    done
    /bin/rm -rf $tmp_pkg_dir
}

# install pkgbuild from tarball to a temp location and then build a
# pkgbuild pkg using itself
install_pkgbuild () {
    check_if_installed SFpkgbuild || {
	pkgbuild_topdir=`$cbe_prefix/bin/pkgbuild -bp $cbe_prefix/lib/pkgbuild-$PKGBUILD_VERSION/get_rpm_topdir 2>&1 | grep '^TOPDIR=' | cut -f2- -d=`
	return 1
    }
    if [ $skip_package = yes ]; then
	return 0
    fi
    export PATH=/usr/ccs/bin:/usr/gnu/bin:/usr/bin:/usr/sbin:/usr/sfw/bin
    cd $tempdir || return 1
    logrun mkdir -p pkgbuild.tmp.$$/src || return 1
    cd pkgbuild.tmp.$$/src || return 1
    logrun bash -c "bzcat $tardir/pkgbuild-$PKGBUILD_VERSION.tar.bz2 | tar xvf -" || return 1
    cd pkgbuild-$PKGBUILD_VERSION || return 1
    logrun ./configure --prefix="$tempdir/pkgbuild.tmp.$$" || return 1
    logrun make install || return 1
    msg "Now rebuilding pkgbuild using itself"
    logrun mkdir -p $tempdir/pkgbuild.tmp.$$/packages/SOURCES || return 1
    logrun cp $tardir/pkgbuild-$PKGBUILD_VERSION.tar.bz2 $tempdir/pkgbuild.tmp.$$/packages/SOURCES/ || return 1
    logrun bash -c "$tempdir/pkgbuild.tmp.$$/bin/pkgbuild --define \"pkgbuild_prefix $cbe_prefix\" --define \"_topdir $tempdir/pkgbuild.tmp.$$/packages\" -ba $tempdir/pkgbuild.tmp.$$/src/pkgbuild-$PKGBUILD_VERSION/pkgbuild.spec" || return 1
    make_admin_file $tempdir/pkgadd.admin.$$ pkgadd
    logrun pfexec /usr/sbin/pkgadd -R $rootdir -n -a $tempdir/pkgadd.admin.$$ -d "$tempdir/pkgbuild.tmp.$$/packages/PKGS" SFpkgbuild || return 1
    pkgbuild_topdir=`$cbe_prefix/bin/pkgbuild -bp $cbe_prefix/lib/pkgbuild-$PKGBUILD_VERSION/get_rpm_topdir 2>&1 | grep '^TOPDIR=' | cut -f2- -d=`
    logrun mkdir -p "$rootdir/$pkgbuild_topdir/PKGS"
    logrun mkdir -p "$rootdir/$pkgbuild_topdir/SPKGS"
    logrun cp -rf "$tempdir/pkgbuild.tmp.$$/packages/SPKGS/SFpkgbuild-src" "$rootdir/$pkgbuild_topdir/SPKGS"
    logrun cp -rf "$tempdir/pkgbuild.tmp.$$/packages/PKGS/SFpkgbuild" "$rootdir/$pkgbuild_topdir/PKGS"
    cd /tmp || return 1
    logrun /usr/bin/rm -rf $tempdir/pkgbuild.tmp.$$ $tempdir/pkgbuild-$PKGBUILD_VERSION || return 1
    
    return 0
}

# build and install a package
build_pkg () {
    check_if_installed $3 || return 1
    if [ $skip_package = yes ]; then
	return 0
    fi
    logrun mkdir -p "$rootdir/$pkgbuild_topdir/SOURCES"
    if [ "x$2" != x ]; then
	log "copying tarball $2 to $rootdir$pkgbuild_topdir/SOURCES"
	fname=`basename $2`
	logrun rm -f "$rootdir$pkgbuild_topdir/SOURCES/$fname"
	logrun cp $2 "$rootdir$pkgbuild_topdir/SOURCES" 2>&1 || return 1
    fi
    export "PATH=$rootdir$cbe_prefix/bin:/usr/ccs/bin:/usr/gnu/bin:/usr/bin:/usr/sbin:/usr/sfw/bin"
    export CC="$cc32dir/$cc_name"
    export CXX="$cc32dir/$cxx_name"
    if [ "x$rootdir" != x/ ]; then
       export AC_MACRODIR="$rootdir$cbe_prefix/share/autoconf"
       sed -e "s%--prepend-include %--prepend-include $rootdir%" "$rootdir$cbe_prefix/share/autoconf/autom4te.cfg" > $tempdir/autom4te.cfg
       export AUTOM4TE_CFG="$tempdir/autom4te.cfg"
       export autom4te_perllibdir="$rootdir$cbe_prefix/share/autoconf"
       export AUTOM4TE="$rootdir$cbe_prefix/bin/autom4te"
    fi
    msg "Building package $3"
    logrun pkgbuild --define "_topdir $rootdir$pkgbuild_topdir" --define "cbe_prefix $cbe_prefix" -ba $1 || \
	    return 1
    install_pkgs "$rootdir$pkgbuild_topdir/PKGS" "$rootdir" "$3" || return 1
}

uninstall_old_cbe () {
    pkg_info=
    for pkg in $OLD_PKGS; do
	pkginfo -R $rootdir -q "$pkg."'*' && pkg_info="$pkg_info
`pkginfo -R $rootdir $pkg.'*'`"
    done
    if [ ! -z "$pkg_info" ]; then
	echo "The following packages belong to an obsolete version of the JDS CBE."
	echo "$pkg_info"
	echo 
	ask_yes_no "Would you like to uninstall them?" do_uninst yes
	if [ $do_uninst = yes ]; then
	    log "User chose to uninstall obsolete CBE pkgs"
	    make_admin_file $tempdir/pkgrm.admin.$$ pkgrm
	    pkgrm_failed=no
	    for pkg in $OLD_PKGS; do
		if pkginfo -R $rootdir -q "$pkg."'*'; then
		    logrun pfexec /usr/sbin/pkgrm -R $rootdir -n -a $tempdir/pkgrm.admin.$$ "$pkg."'*' || \
			pkgrm_failed=yes
		fi
	    done
	    rm -f $tempdir/pkgrm.admin.$$
	    if [ $pkgrm_failed = yes ]; then
		msg "Failed to remove one or more packages"
		ask_yes_no "Would you like to continue anyway?" do_cont no
		if [ $do_cont = no ]; then
		    return 1
		else
		    log "User chose to continue anyway"
		    return 0
		fi
	    fi
	fi
    fi
    return 0
}

main () {
    init
    uninstall_old_cbe || return 1
    msg "Installing the JDS Common Build Environment (CBE) version $CBE_VERSION"
    ask_defaults
    if [ $binary_install = no ]; then
	install_pkgbuild || return 1
	pkgbuild_topdir=`$cbe_prefix/bin/pkgbuild -bp $cbe_prefix/lib/pkgbuild-$PKGBUILD_VERSION/get_rpm_topdir 2>&1 | grep '^TOPDIR=' | cut -f2- -d=`
	build_pkg $mydir/make.spec "$tardir/$MAKE_TARBALL" CBEmake  || return 1
	build_pkg $mydir/cvs.spec "$tardir/$CVS_TARBALL" CBEcvs  || return 1
	if [ $cbe_opt = yes ]; then
	    build_pkg $mydir/rsync.spec "$tardir/$RSYNC_TARBALL" CBErsync  || msg "WARNING: Failed to install rsync.  Note: this is an optional CBE component."
	fi
	build_pkg $mydir/m4.spec "$tardir/$M4_TARBALL" CBEm4 || return 1
	build_pkg $mydir/autoconf.spec "$tardir/$AUTOCONF_TARBALL" CBEautoconf || \
	    return 1
	logrun rm -f "$rootdir$pkgbuild_topdir/SOURCES/$AUTOMAKE_1_9_TARBALL"
	logrun cp "$tardir/$AUTOMAKE_1_9_TARBALL" $rootdir$pkgbuild_topdir/SOURCES/ || \
	    return 1
	build_pkg $mydir/automake.spec "$tardir/$AUTOMAKE_1_10_TARBALL" CBEautomake || \
	    return 1
	logrun cp $mydir/libtool-allextract.diff $rootdir$pkgbuild_topdir/SOURCES/ || \
	    return 1
	build_pkg $mydir/libtool.spec "$tardir/$LIBTOOL_TARBALL" CBElibtool || \
	    return 1
	logrun cp $mydir/gettext.diff $rootdir$pkgbuild_topdir/SOURCES/ || \
	    return 1
	build_pkg $mydir/gettext.spec "$tardir/$GETTEXT_TARBALL" CBEgettext || \
	    return 1
	build_pkg $mydir/fileutils.spec "$tardir/$FILEUTILS_TARBALL" CBEfileutils||\
	    return 1
	build_pkg $mydir/flex.spec "$tardir/$FLEX_TARBALL" CBEflex  || return 1
	build_pkg $mydir/bison.spec "$tardir/$BISON_TARBALL" CBEbison  || return 1
	logrun cp $mydir/gendiff $rootdir$pkgbuild_topdir/SOURCES/ || \
	    return 1
	build_pkg $mydir/diff.spec "$tardir/$DIFF_TARBALL" CBEdiff  || return 1
	build_pkg $mydir/ant.spec "$tardir/$ANT_TARBALL" CBEant  || return 1
	build_pkg $mydir/subversion.spec "$tardir/$SVN_TARBALL" CBEsvn  || \
	return 1
    else
	INSTALL_CBE_PKGS=
	for pkg in $CBE_PKGS; do
	    check_if_installed $pkg || return 1
	    if [ $skip_package = no ]; then
		INSTALL_CBE_PKGS="$INSTALL_CBE_PKGS $pkg"
	    fi
	done
	install_pkgs "$mydir/pkgs" "$rootdir" $INSTALL_CBE_PKGS || return 1
	if [ $cbe_opt = yes ]; then
	    check_if_installed CBErsync || return 1
	    if [ $skip_package = no ]; then
		install_pkgs "$mydir/pkgs" "$rootdir" CBErsync || return 1
	    fi
	fi
	pkgbuild_topdir=`$cbe_prefix/bin/pkgbuild -bp $cbe_prefix/lib/pkgbuild-$PKGBUILD_VERSION/get_rpm_topdir 2>&1 | grep '^TOPDIR=' | cut -f2- -d=`
    fi
    log "Creating env.sh"
    logrun mkdir -p $rootdir$pkgbuild_topdir/SOURCES || return 1
    build_info="built on `date +%Y-%m-%d` by ${logname}@`hostname`"
    logrun bash -c "sed -e \"s%@CBE_PREFIX@%$cbe_prefix%\" \
        -e \"s%@JDS_PREFIX@%$JDS_PREFIX%\" \
	-e \"s%@CC32@%$cc32dir/$cc_name%\" \
	-e \"s%@CXX32@%$cc32dir/$cxx_name%\" \
	-e \"s%@CC64@%$cc64dir/$cc_name%\" \
	-e \"s%@CXX64@%$cc64dir/$cxx_name%\" \
	-e \"s%@CBE_VERSION@%$CBE_VERSION%\" \
        -e \"s%@BUILD_INFO@%$build_info%\" \
	$mydir/env.sh > $rootdir$pkgbuild_topdir/SOURCES/env.sh" || \
	return 1
    log "Creating env.csh"
    logrun bash -c "sed -e \"s%@CBE_PREFIX@%$cbe_prefix%\" \
        -e \"s%@JDS_PREFIX@%$JDS_PREFIX%\" \
	-e \"s%@CC32@%$cc32dir/$cc_name%\" \
	-e \"s%@CXX32@%$cc32dir/$cxx_name%\" \
	-e \"s%@CC64@%$cc64dir/$cc_name%\" \
	-e \"s%@CXX64@%$cc64dir/$cxx_name%\" \
	-e \"s%@CBE_VERSION@%$CBE_VERSION%\" \
        -e \"s%@BUILD_INFO@%$build_info%\" \
	$mydir/env.csh > $rootdir$pkgbuild_topdir/SOURCES/env.csh" || \
	return 1
    log "Copying ld-wrapper"
    logrun bash -c "cp $mydir/ld-wrapper $rootdir$pkgbuild_topdir/SOURCES" || \
	return 1
    build_pkg $mydir/CBEenv.spec "" CBEenv  || return 1
    msg "CBE setup complete"
    echo "Run"
    echo "  . $cbe_prefix/bin/env.sh"
    echo "or"
    echo "  source $cbe_prefix/bin/env.csh"
    echo "depending on your shell, to use this build environment."
}

process_cl "${@}"
main || msg "CBE setup FAILED"
echo "Installation log saved in $LOGFILE"