#! /bin/bash
#
# Copyright (c) 2000-2001 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.
#
# This program is distributed in the hope that it would 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 the Free Software Foundation,
# Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
#
# This script emulates bsd install and also recognises
# two environment variables, with the following semantics :-
#
# $DIST_MANIFEST - if set, the name of the file to append manifest
#                  information in the following format:
#                  File     :  f mode owner group src target
#                  Directory:  d mode owner group target
#                  Symlink  :  l linkval target
#
# $DIST_ROOT     - if set, prepend to target
#
# The sematics of all combinations of these two variables
# are as follows:
#
# $DIST_MANIFEST?  $DIST_ROOT? |   Copy?  Append Manifest?
# -----------------------------+--------------------------
#       not set       not set  |    yes        no
#       not set       set      |    yes        no
#       set           not set  |    no         yes
#       set           set      |    yes        yes
#
_usage() {
    echo "Usage: $prog [-o owner] [-g group] [-m mode] -d directory"
    echo "or     $prog [-D] [-o owner] [-g group] [-m mode] file directory/file"
    echo "or     $prog [-o owner] [-g group] [-m mode] file [file ...] directory"
    echo "or     $prog -S file target  (creates \"target\" symlink)"
    echo ""
    echo "The \$DIST_MANIFEST and \$DIST_ROOT environment variables affect the"
    echo "behaviour of this command - see comments in the script."
    echo "The -D flag is only available for the second usage, and causes"
    echo "the target directory to be created before installing the file."
    echo ""
    exit 1
}

_chown ()
{
    _st=255
    if [ $# -eq 3 ] ; then
	chown $1:$2 $3
	_st=$?
	if [ $_st -ne 0 ] ; then
	    if [ $REAL_UID != '0' ] ; then
		if [ ! -f $DIST_ROOT/.chown.quite ] ; then
		    echo '==============================================='
		    echo Ownership of files under ${DIST_ROOT:-/}
		    echo cannot be changed
		    echo '==============================================='
		    if [ -n "$DIST_ROOT" ] ; then
			touch $DIST_ROOT/.chown.quite
		    fi
		fi
	       _st=0
	    fi     
	fi
    fi

    return $_st
}


_manifest ()
{ 
    echo $* | sed -e 's/\/\//\//g' >>${DIST_MANIFEST:-/dev/null}
}

prog=`basename $0`
HERE=`pwd`
dflag=false
Dflag=false
Sflag=false
DIRMODE=755
FILEMODE=644
OWNER=`id -u`
GROUP=`id -g`
REAL_UID=$OWNER

# default is to install and don't append manifest
INSTALL=true
MANIFEST=:

: ${DIST_ROOT:=${DESTDIR}}

[ -n "$DIST_MANIFEST" -a -z "$DIST_ROOT" ] && INSTALL=false
[ -n "$DIST_MANIFEST" ] && MANIFEST="_manifest"

[ $# -eq 0 ] && _usage

if $INSTALL
then
    CP=cp; LN=ln; MKDIR=mkdir; CHMOD=chmod; CHOWN=_chown
else
    CP=true; LN=true; MKDIR=true; CHMOD=true; CHOWN=true
fi

[ -n "$DIST_ROOT" -a $REAL_UID -ne 0 ] && CHOWN=true

while getopts "Dcm:d:S:o:g:" c $*
do
   case $c in
   c)
	;;
   g)
	GROUP=$OPTARG
	;;
   o)
	OWNER=$OPTARG
	;;
   m)
	DIRMODE=`expr $OPTARG`
	FILEMODE=$DIRMODE
	;;
   D) 
	Dflag=true
	;;
   S) 
	symlink=$OPTARG
	Sflag=true
	;;
   d) 
	dir=$DIST_ROOT/$OPTARG
	dflag=true
	;;
   *)
   	_usage
	;;
   esac
done

shift `expr $OPTIND - 1`

status=0
if $dflag
then
    #
    # first usage
    #
    $MKDIR -p $dir 
    status=$?
    if [ $status -eq 0 ]
    then
	$CHMOD $DIRMODE $dir
	status=$?
    fi
    if [ $status -eq 0 ]
    then
	$CHOWN $OWNER $GROUP $dir
	status=$?
    fi
    $MANIFEST d $DIRMODE $OWNER $GROUP ${dir#$DIST_ROOT}
elif $Sflag
then
    #
    # fourth usage (symlink)
    #
    if [ $# -ne 1 ]
    then
    	_usage
    else
    	target=$DIST_ROOT/$1
    fi
    $LN -s -f $symlink $target
    status=$?
    $MANIFEST l $symlink ${target#$DIST_ROOT} 
else
    list=""
    dir=""
    if [ $# -eq 2 ]
    then
	#
	# second usage
	#
	f=$1
	dir=$DIST_ROOT/$2
	if $Dflag
	then
	    mkdir -p `dirname $dir`
	fi
	$CP $f $dir
	status=$?
	if [ $status -eq 0 ]
	then 
	    if [ -f $dir/$f ]
	    then
		$CHMOD $FILEMODE $dir/$f
		status=$?
		if [ $status -eq 0 ]
		then
		    $CHOWN $OWNER $GROUP $dir/$f
		    status=$?
		fi
		$MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$f ${dir#$DIST_ROOT}/$f
	    else
		$CHMOD $FILEMODE $dir
		status=$?
		if [ $status -eq 0 ]
		then
		    $CHOWN $OWNER $GROUP $dir
		    status=$?
		fi
		$MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$dir ${dir#$DIST_ROOT}
	    fi
	fi
    else
	#
	# third usage
	#
	n=1
	while [ $# -gt 0 ]
	do
	    if [ $# -gt 1 ]
	    then
		list="$list $1"
	    else
		dir=$DIST_ROOT/$1
	    fi
	    shift
	done

	# echo DIR=$dir list=\"$list\"
	for f in $list
	do
	    $CP $f $dir
	    status=$?
	    if [ $status -eq 0 ]
	    then
		$CHMOD $FILEMODE $dir/$f
		status=$?
		if [ $status -eq 0 ]
		then
		    $CHOWN $OWNER $GROUP $dir/$f
		    status=$?
		fi
		$MANIFEST f $FILEMODE $OWNER $GROUP $HERE/$f ${dir#$DIST_ROOT}/$f
	    fi
	    [ $status -ne 0 ] && break
	done
    fi
fi

exit $status
