summaryrefslogtreecommitdiff
path: root/build/mac/install-pcp
diff options
context:
space:
mode:
Diffstat (limited to 'build/mac/install-pcp')
-rwxr-xr-xbuild/mac/install-pcp837
1 files changed, 837 insertions, 0 deletions
diff --git a/build/mac/install-pcp b/build/mac/install-pcp
new file mode 100755
index 0000000..8578789
--- /dev/null
+++ b/build/mac/install-pcp
@@ -0,0 +1,837 @@
+#! /bin/sh
+#
+# Copyright (c) 2003-2004 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program 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 of the License, or (at your
+# option) any later version.
+#
+# This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Process a gendist-like idb file to collect, install, upgrade
+# and remove files.
+#
+# The format of the IDB file is:
+#
+# The first line must contain a version string "# Version 1"
+#
+# All following lines must contain:
+# d|f|h|s mode owner group destination source option
+#
+# One of:
+# d directory to be created at destination (source ignored)
+# f file to be installed from source to destination
+# h hard link to be created at destination to source
+# s soft link to be created at destination to source
+#
+# mode four digit mode bits
+# owner file's owner
+# group file's group
+# destination create file/directory/link here
+# source where file came from, or what link points to
+#
+# One of these options: replace, update, suggest, check or noupdate.
+#
+# Optionally, a os version number (uname -r), which ensures the file will only
+# get installed on that os version, or a minimum and a maximum version number (inclusive).
+#
+# If the target does not exist, all options just install the file.
+#
+# If the target already exists, the options do the following:
+#
+# Option Type Operation
+# --------- ---- ---------------------------------------------------
+# replace d update permissions
+# fhs remove and install replacement
+#
+# update d hs illegal option
+# f move existing file to file.bak, install new file
+#
+# suggest d hs illegal option
+# f install new file as file.new
+#
+# check dfhs do nothing
+#
+# noupdate dfhs do nothing
+#
+#
+# If removing the target, the target is removed unless the option is
+# noupdate. Directories will not be removed if they are not empty.
+#
+# Lines starting with '#' or empty lines are ignored.
+#
+
+tmp=`mktemp -d /tmp/pcp.XXXXXXXXX` || exit 1
+prog=`basename $0`
+status=1
+result=0 # non-fatal errors will set this to 1
+now=`date`
+host=`hostname`
+dump_mesg=false
+
+trap "rm -rf $tmp; exit \$status" 0 1 2 15
+
+MKDIR=/bin/mkdir
+CP=/bin/cp
+MV=/bin/mv
+LN=/bin/ln
+RM=/bin/rm
+RMDIR=/bin/rmdir
+CHMOD=/bin/chmod
+CHOWN=/usr/sbin/chown
+CHGRP=/usr/bin/chgrp
+DIRNAME=/usr/bin/dirname
+TEE=/usr/bin/tee
+JOIN=/usr/bin/join
+SED=/usr/bin/sed
+AWK=/usr/bin/awk
+SORT=/usr/bin/sort
+UNAME=/usr/bin/uname
+
+OS_VERSION=`$UNAME -r`
+
+_usage()
+{
+ cat << EOF
+Usage: $prog [-cinpr] [-C os_version] [-l logfile] [-u origidb] [-R root] idbfile
+
+ -l logfile Save important output to logfile
+ -n Show actions but do not execute
+ -R root Collect or install files using root rather
+ than WORKAREA or /
+ -v Verbose output
+ -C os_ver (Only used for collect phase) Only collect files which will be used for os_ver
+
+ One of:
+ -c Collect source files into current dir
+ -i Install files from current directory
+ -p Parse and check idb is valid
+ -r Remove installed files.
+ -u origidb Remove files not in new IDB and then install
+EOF
+ exit 1
+}
+
+_echo()
+{
+ if $log
+ then
+ echo "$*" | $TEE -a $logfile
+ else
+ echo "$*"
+ fi
+}
+
+_error()
+{
+ _echo "$prog: Error: $*" | $TEE -a $mesg
+ dump_mesg=true
+ result=1
+ exit 1
+}
+
+_warn()
+{
+ _echo "$prog: Warning: $*" | $TEE -a $mesg
+ dump_mesg=true
+}
+
+_debug()
+{
+ sed -e "s/^/$prog: Debug: /" | $TEE -a $mesg
+ dump_mesg=true
+}
+
+_mesg_head()
+{
+ _echo "$*" | $TEE -a $mesg
+}
+
+_mesg()
+{
+ _echo "$prog: $*" | $TEE -a $mesg
+ dump_mesg=true
+}
+
+_note()
+{
+ _echo "$prog: Note: $*"
+}
+
+_cmd()
+{
+ $verbose && _echo "$*"
+ $*
+}
+
+_get_numeric_version()
+{
+ echo $1 | awk '
+ { n = split($0, v, ".");
+ if (n == 2)
+ v[2] = 0;
+ print (v[0] * 100) + (v[1] * 10) + v[2]; }
+ '
+}
+
+_test_version()
+{
+ local _min_numeric
+ local _max_numeric
+ local _os_numeric
+ local _min_version=$1
+ local _max_version=$2
+ local _temp_numeric
+
+ if [ -z "$_min_version" -o "$_min_version" = "$OS_VERSION" ]; then
+ # No version, or exact match
+ return 0
+ elif [ -z "$_max_version" ]; then
+ # No max and no exact match with min
+ return 1
+ else
+ # max and min without exact match, so test range
+ _min_numeric=`_get_numeric_version $_min_version`
+ _max_numeric=`_get_numeric_version $_max_version`
+ _os_numeric=`_get_numeric_version $OS_VERSION`
+ if [ $_min_numeric -gt $_max_numeric ]; then
+ _temp_numeric=$_min_numeric
+ _min_numeric=$_max_numeric
+ _max_numeric=$_temp_numeric
+ fi
+ if [ $_os_numeric -ge $_min_numeric -a $_os_numeric -le $_max_numeric ]; then
+ return 0
+ else
+ return 1
+ fi
+ fi
+}
+
+_remove_file()
+{
+ if _test_version $2 $3
+ then
+ if [ -f $root/$1 ]
+ then
+ if ! _cmd $RM $root/$1
+ then
+ _warn "Unable to remove $root/$1, continuing"
+ fi
+ else
+ _note "$root/$1 does not exist for removal, skipping"
+ fi
+ fi
+}
+
+_remove_dir()
+{
+ if _test_version $2 $3
+ then
+ if [ -d $root/$1 ]
+ then
+ if ! _cmd $RMDIR $root/$1
+ then
+ _warn "Unable to remove $root/$1, continuing"
+ fi
+ else
+ _note "$root/$1 does not exist for removal, skipping"
+ fi
+ fi
+}
+
+# $1 is path to file in tree
+# $2 is path to the file in the workarea
+# path is created in current directory and the file is copied
+#
+_collect_file()
+{
+ file=$root/$1
+ dir=`$DIRNAME $2`
+
+ if [ ! -z "$collect_version" ]; then
+ # override the OS_VERSION, which is used in test_version()
+ OS_VERSION=$collect_version
+ if ! _test_version $3 $4
+ then
+ # version doesn't match, so skip it
+ return
+ fi
+ fi
+
+ if [ ! -r $file ]
+ then
+ _error "Unable to find $file"
+ fi
+
+ if [ ! -d $dir ]
+ then
+ if _cmd $MKDIR -p $dir
+ then
+ :
+ else
+ _error "Unable to create $dir"
+ fi
+ fi
+
+ if ! _cmd $CP $file $2
+ then
+ _error "Unable to copy $file"
+ fi
+}
+
+# Takes the idb line
+# d|f|h|s mode owner group destination source option
+_install_file()
+{
+ type=$1
+ target=$root/$5
+ source=$6
+ option=$7
+ chopts=
+
+ if _test_version $8 $9
+ then
+ # Set to true if we need to set mode, uid and gid
+ installed=false
+
+ if [ $type = "d" ]
+ then
+ if [ ! -d $target ]
+ then
+ if _cmd $MKDIR -p $target
+ then
+ installed=true
+ else
+ _error "Unable to create dir $target"
+ fi
+ elif [ -f $target ]
+ then
+ if [ $option = "replace" ]
+ then
+ if ! _cmd $RM $target
+ then
+ _error "Unable to replace existing $target with directory"
+ fi
+ if _cmd $MKDIR -p $target
+ then
+ installed=true
+ else
+ _error "Unable to create dir $target"
+ fi
+ else
+ _error "$target exists but is not a directory"
+ fi
+ fi
+ elif [ $type = "f" ]
+ then
+ if [ ! -f $source ]
+ then
+ echo "cwd=`pwd`" >$tmp/debug
+ echo "source dir=`dirname $source`" >>$tmp/debug
+ ls -l `dirname $source` >>$tmp/debug
+ _debug <$tmp/debug
+ _error "Unable to find file ($source) for $target"
+ fi
+ if [ -f $target ]
+ then
+ case $option in
+ replace)
+ if ! _cmd $RM $target
+ then
+ _warn "Unable to remove existing $target, continuing"
+ fi
+ if _cmd $MV $source $target
+ then
+ installed=true
+ else
+ _error "Unable to install $target"
+ fi
+ ;;
+ update)
+ if ! _cmd $CP $target $target.bak
+ then
+ _warn "Unable to copy existing $target to $target.bak, continuing"
+ fi
+
+ if ! _cmd $RM $target
+ then
+ _warn "Unable to remove existing $target, continuing"
+ fi
+
+ if _cmd $MV $source $target
+ then
+ _mesg "Update to $target installed, original backed up at $target.bak"
+ installed=true
+ else
+ if _cmd $CP $target.bak $target
+ then
+ _error "Unable to install $target, original moved back"
+ else
+ _error "Unable to install $target, original now $target.bak"
+ fi
+ fi
+ ;;
+
+ suggest)
+ if _cmd $MV $source $target.new
+ then
+ _mesg "Suggested update to $target installed at $target.new"
+ installed=true
+ target=$target.new
+ else
+ _warn "Unable to install $target as $target.new, continuing"
+ fi
+ ;;
+
+ check)
+ # Nothing to do if file exists
+ ;;
+ noupdate)
+ # Nothing to do if file exists
+ ;;
+ *)
+ _error "Unsupported IDB option ($option) for $target"
+ ;;
+ esac
+ elif [ -d $target ]
+ then
+ _error "$target exists but is a directory"
+ else
+ if _cmd $MV $source $target
+ then
+ installed=true
+ else
+ _error "Unable to install $target"
+ fi
+ fi
+ elif [ $type = "h" ]
+ then
+ if [ -f $target ]
+ then
+ case $option in
+ replace)
+ if ! _cmd $RM $target
+ then
+ _warn "Unable to remove existing $target, continuing"
+ fi
+ if _cmd $LN $root/$source $target
+ then
+ installed=true
+ else
+ _error "Unable to install $target"
+ fi
+ ;;
+ update)
+ _error "Illegal update option for hard link $target to $root/$source"
+ ;;
+ suggest)
+ _error "Illegal suggest option for hard link $target to $root/$source"
+ ;;
+ check)
+ # Nothing to do if file exists
+ ;;
+ noupdate)
+ # Nothing to do if file exists
+ ;;
+ esac
+ elif [ -d $target ]
+ then
+ _error "$target exists but is a directory"
+ else
+ if _cmd $LN $root/$source $target
+ then
+ installed=true
+ else
+ _error "Unable to install $target"
+ fi
+ fi
+ elif [ $type = "s" ]
+ then
+ chopts="-h"
+ if [ -f $target ]
+ then
+ case $option in
+ replace)
+ if ! _cmd $RM $target
+ then
+ _warn "Unable to remove existing $target, continuing"
+ fi
+ if _cmd $LN -s -f $root/$source $target
+ then
+ installed=true
+ else
+ _error "Unable to install $target"
+ fi
+ ;;
+ update)
+ _error "Illegal update option for soft link $target to $root/$source"
+ ;;
+ suggest)
+ _error "Illegal suggest option for soft link $target to $root/$source"
+ ;;
+ check)
+ # Nothing to do if file exists
+ ;;
+ noupdate)
+ # Nothing to do if file exists
+ ;;
+ esac
+ elif [ -d $target ]
+ then
+ _error "$target exists but is a directory"
+ else
+ if _cmd $LN -s -f $root/$source $target
+ then
+ installed=true
+ else
+ _error "Unable to install $target"
+ fi
+ fi
+ else
+ _error "Unrecognised file type ($type)"
+ fi
+
+ if $installed
+ then
+ if [ "$type" != "s" ] ; then
+ if ! _cmd $CHMOD $2 $target
+ then
+ _warn "Unable to change mode of $target to $2, continuing"
+ fi
+ fi
+ if ! _cmd $CHOWN $chopts $3 $target
+ then
+ _warn "Unable to change ownership of $target to $3, continuing"
+ fi
+ if ! _cmd $CHGRP $chopts $4 $target
+ then
+ _warn "Unable to change group of $target to $4, continuing"
+ fi
+ fi
+ fi
+}
+
+_remove()
+{
+ #
+ # Directories are removed after all files are removed
+ # If directory is not empty, default is to ignore and move on
+ #
+ sort -k1r,1 -k5r,5 $1 < $1 \
+ | $AWK >> $tmp/cmds '
+$7 == "noupdate" { next }
+$1 == "d" { printf("_remove_dir %s %s %s\n", $5, $8, $9); next }
+ { printf("_remove_file %s %s %s\n", $5, $8, $9) }
+'
+}
+
+_install()
+{
+ #
+ # Directories are installed before all files are installed
+ # Links are installed after normal files
+ #
+ sed < $tmp/idb >> $tmp/cmds -e 's/^/_install_file /'
+}
+
+show=false
+collect=false
+install=false
+remove=false
+upgrade=false
+verbose=false
+logfile=
+log=false
+mesg=$tmp/mesg
+root=
+collect_version=
+parse=false
+if set -- `getopt cC:il:nprR:u:v $*`
+then
+ for i in $*
+ do
+ case $i in
+ -C)
+ $install && _usage
+ $remove && _usage
+ $upgrade && _usage
+ $parse && _usage
+ collect=true
+ collect_version=$2
+ echo "Collecting for $collect_version"
+ shift 2;;
+ -c)
+ $install && _usage
+ $remove && _usage
+ $upgrade && _usage
+ $parse && _usage
+ collect=true
+ shift;;
+ -i)
+ $collect && _usage
+ $remove && _usage
+ $upgrade && _usage
+ $parse && _usage
+ install=true
+ shift;;
+ -l)
+ log=true
+ logfile=$2
+ touch $logfile
+ if [ ! -w $logfile ]
+ then
+ log=false
+ _warn "Unable to open logfile ($logfile)"
+ fi
+ shift 2;;
+ -n)
+ show=true
+ shift;;
+ -p)
+ $collect && _usage
+ $install && _usage
+ $upgrade && _usage
+ $remove && _usage
+ parse=true
+ shift;;
+ -r)
+ $collect && _usage
+ $install && _usage
+ $upgrade && _usage
+ $parse && _usage
+ remove=true
+ shift;;
+ -R)
+ root=$2
+ shift 2;;
+ -u)
+ $collect && _usage
+ $install && _usage
+ $remove && _usage
+ $parse && _usage
+ upgrade=true
+ oidb=$2
+ shift 2;;
+ -v)
+ verbose=true
+ shift;;
+ --)
+ break
+ shift;;
+ esac
+ done
+ shift
+else
+ _usage
+fi
+
+if [ $# -ne 1 ]
+then
+ _usage
+fi
+
+idb=$1
+
+if [ ! -r $idb ]
+then
+ echo "$prog: Unable to open $idb"
+ exit 1
+fi
+
+$AWK < $idb > $tmp/err -v prog=$prog -v idb=$idb '
+BEGIN { fail = 0; version = 0; entries = 0 }
+
+NR == 1 && ( NF != 3 || $1 != "#" || $2 != "Version" || $3 != "1" ) {
+ printf("%s: Error: Line %d of %s has an invalid version string (%s)\n",
+ prog, NR, idb, $0);
+ fail = 1;
+ exit(1);
+}
+
+NR == 1 { version = 1; next }
+/^#/ { next }
+NF == 0 { next }
+
+NF != 7 && NF != 8 && NF != 9 {
+ printf("%s: Error: Line %d of %s does not have 7 or 8 or 9 entries (%d)\n",
+ prog, NR, idb, NF);
+ fail = 1;
+ exit(1);
+}
+
+$1 != "d" && $1 != "f" && $1 != "h" && $1 != "s" {
+ printf("%s: Error: Line %d of %s has invalid file type (%s)\n",
+ prog, NR, idb, $1);
+ fail = 1;
+ exit(1);
+}
+
+$7 != "replace" && $7 != "update" && $7 != "suggest" && $7 != "check" && $7 != "noupdate" {
+ printf("%s: Error: Line %d of %s has invalid file option (%s)\n",
+ prog, NR, idb, $7);
+ fail = 1;
+ exit(1);
+}
+
+$1 != "f" && ($7 == "update" || $7 == "suggest") {
+ printf("%s: Error: Line %d of %s has unsupported combination of %s and %s\n",
+ prog, NR, idb, $1, $7);
+ fail = 1;
+ exit(1);
+}
+
+$5 ~ "^/" {
+ printf("%s: Error: Line %d of %s does not have relative path (%s)\n",
+ prog, NR, idb, $5);
+ fail = 1;
+ exit(1);
+}
+
+$6 ~ "^/" {
+ printf("%s: Error: Line %d of %s does not have relative path (%s)\n",
+ prog, NR, idb, $6);
+ fail = 1;
+ exit(1);
+}
+
+ { entries++ }
+
+END {
+ if (!fail) {
+ if (!version) {
+ printf("%s: Error: No version string in %s\n",
+ prog, idb);
+ exit(1);
+ }
+ if (!entries) {
+ printf("%s: Error: No entries in %s\n",
+ prog, idb);
+ exit(1);
+ }
+ }
+}
+'
+
+if [ -s $tmp/err ]
+then
+ echo "$prog: Invalid IDB file detected:"
+ cat $tmp/err
+ exit 1
+elif $parse
+then
+ status=0
+ exit
+fi
+
+$RM -f $tmp/dirs $tmp/cmds $tmp/files $tmp/idb $tmp/tidb
+touch $tmp/dirs $tmp/cmds $tmp/files
+
+sed < $idb -e '/^#/d' -e '/^$/d' \
+| $SORT -k1,1 -k5,5 \
+> $tmp/idb
+
+cat << EOF > $mesg
+
+=======================================================================
+Installation issues that may require further investigation:
+EOF
+
+if $remove
+then
+
+ _mesg_head "Removing all installed PCP files"
+ _mesg_head "Date: "`date`
+ _mesg_head "User: $USER"
+ _remove $tmp/idb
+
+
+#
+# Collect files out of source tree and copy here using the same
+# directory structure
+#
+
+elif $collect
+then
+ _mesg_head "Collecting all files to be included in package"
+ _mesg_head "Date: "`date`
+ _mesg_head "User: $USER"
+
+ [ "X$root" = "X" ] && root=$WORKAREA
+
+ if [ "X$root" = "X" ]
+ then
+ _error "Neither \$WORKAREA or -R were set"
+ exit 1
+ fi
+
+ $AWK < $tmp/idb > $tmp/cmds '
+$1 == "f" { printf("_collect_file %s %s %s %s\n", $5, $6, $8, $9) }'
+
+#
+# Install files assuming that they do not already exist
+#
+elif $install
+then
+ _mesg_head "Installing PCP files"
+ _mesg_head "Date: "`date`
+ _mesg_head "User: $USER"
+ _install
+
+elif $upgrade
+then
+ _mesg_head "Upgrade of PCP files"
+ _mesg_head "Date: "`date`
+ _mesg_head "User: $USER"
+
+ # Determine which files need to be removed since they
+ # are not in the new set of files. Files which are
+ # in both sets will be upgraded depending on their
+ # IDB option.
+
+ if [ ! -r $oidb ]
+ then
+ _warn "Upgrade in progress but cannot find old inventory ($oidb) to delete files that are no longer required"
+ else
+ sed < $oidb -e '/^#/d' -e '/^$/d' \
+ | $SORT -k1,1 -k5,5 \
+ > $tmp/oidb
+
+ # explicity name all fields so that the extra os_version field doesnt confuse join
+ $JOIN -t' ' -v 2 -1 5 -2 5 $tmp/idb $tmp/oidb > $tmp/extra
+ if [ -s $tmp/extra ]
+ then
+ _remove $tmp/extra
+ else
+ _note "No files need to be removed before upgrade"
+ fi
+ fi
+ _install
+
+else
+ echo "$prog: Must select one of -r, -c, -i or -u options"
+ exit 1
+fi
+
+if $show
+then
+ cat $tmp/cmds
+else
+ $verbose && cat $tmp/cmds
+. $tmp/cmds
+fi
+
+if $dump_mesg
+then
+ $log && cat $mesg >> $logfile
+ cat $mesg
+fi
+
+status=$result