#!/bin/sh
# Name: setup
# Project: Sharity
# Author: Christian Starkjohann <cs@obdev.at>
# Creation Date: 1999-04-29
# Tabsize: 4
# Copyright: (c) 1999 by Christian Starkjohann, all rights reserved.
#     For details of the license see the file doc/License.txt.
# This Revision: $Id: setup,v 1.9 2001/04/02 13:07:21 cs Exp $

# General Description:
# This script installs all files at the appropriate destinations. The list
# of files and destinations is taken from the file 'filelist'.
# Must be started in the current directory (with ./setup)!


PATH=$PATH:/etc:/usr/ucb:/sbin:/usr/sbin     # extend search path

uninstlist=/tmp/setup-uilist-`whoami`-$$
tmpfile=/tmp/setup-tmp-`whoami`-$$
globalUninstallScript=""
packageName=unknown
quietOption=n

while [ $# -gt 0 ]; do
	case $1 in
		-q)	quietOption=y ;;
		*)	echo "Option $1 not known." ; exit 1 ;;
	esac
	shift
done


whereis()
{
	echo $PATH | tr ':' '\012' | {
		while read path; do
			if [ -x "$path/$1" ]; then
				echo "$path/$1"
				break
			fi
		done
	}
}

setup_removeaction()
{
	touch "$uninstlist"		# this file must exist
	rmactiontmp="$uninstlist.tmp"
	echo "$1" | cat - "$uninstlist" >"$rmactiontmp"
	rm -f "$uninstlist"
	mv "$rmactiontmp" "$uninstlist"
}

setup_directory()
{
    destination="$1"
    owner="$2"
    mode="$3"
    if [ '!' -d "$destination" ]; then
        echo "Creating directory: $destination"
        mkdir "$destination"
		if [ $? != 0 ]; then
			echo "*** Error creating directory $destination."
			echo "Maybe the parent directory does not exist. Please correct any errors"
			echo "and retry the installation."
			exit
		fi
		if [ -n "$owner" -a "$notroot" != yes ]; then
			chown "$owner" "$destination"
		fi
		if [ -n "$mode" ]; then
			chmod "$mode" "$destination"
		fi
		setup_removeaction "rmdir '$destination' 2>/dev/null"
    fi
}

# parameters: "name of file"
findsource()
{
	if [ -r "./$1" ]; then
		echo "./$1"
	elif [ -r "./packages/$1" ]; then
		echo "./packages/$1"
	fi
}

# parameters: source, dest
substitute()
{
	source="$1"
	dest="$2"
	# first search for all variables that are addressed in the file
	variables=`sed -n -e 's|%\([a-zA-Z_0-9]*\)%| %\1% |gp' < "$source" \
				| awk '{for(i=1;i<=NF;i++)print $i}' \
				| sed -n -e 's|%\([a-zA-Z_0-9]*\)%|\1|gp' \
				| sort \
				| uniq`
	if [ -z "$variables" ]; then
		cp "$source" "$dest"	# no substitution needed
	else
		# build search-and-replace script for all variables
		cmd="sed"
		for i in $variables; do
			val="echo \"\$$i\""
			val=`eval "$val"`
			cmd="$cmd -e 's|%$i%|$val|g'"
		done
		# execute search and replace
		eval "$cmd <\"$source\" >\"$dest\""
	fi
}

# parameters: source-filename, destination-path, owner, mode, doLocalize
setup_file()
{
    source="$1"
    destination="$2"
    owner="$3"
    mode="$4"
	doLocalize="$5"
	from=`findsource "$source"`
	if [ -z "$from" ]; then
		echo "*** File \"$source\" missing in package, skipped."
	else
		if [ "$doLocalize" = yes ]; then
			rm -f $tmpfile
			substitute "$from" "$tmpfile"
			from="$tmpfile"
		fi
		rm -f "$destination"
		echo "Installing file: $destination"
		cp -p "$from" "$destination"
		chmod "$mode" "$destination"
		if [ "$notroot" != yes ]; then
			chown "$owner" "$destination"
		fi
		chmod "$mode" "$destination"
		setup_removeaction "rm -f '$destination'"
	fi
}

# parameters: source-tree, destination-path, owner, mode
setup_tree()
{
    source="$1"
    destination="$2"
    owner="$3"
    mode="$4"
	from=`findsource "$source"`
	if [ -z "$from" ]; then
		echo "*** Tree $source not in package, skipped."
	else
		rm -rf "$destination"
		echo "Installing tree: $destination"
		cp -rp "$from" "$destination"
		chmod -R "$mode" "$destination"
		if [ "$notroot" != yes ]; then
			chown -R "$owner" "$destination"
		fi
		setup_removeaction "rm -rf '$destination'"
	fi
}

# parameters: source-path destination-path
setup_link()
{
	source="$1"
	destination="$2"
	echo "Installing link: $destination"
	rm -f "$destination"
	ln -s "$source" "$destination"
	setup_removeaction "rm -f '$destination'"
}

# parameters: variable-name, default-value  2< help-Text
setup_defvar()
{
	variable="$1"
	eval "value=\"\$default$variable\""
	if [ -z "$value" ]; then
		value="$2"
	fi
	if [ "$quietOption" '!=' y ]; then
		echo
		echo "----"
		if tty -s <&2; then
			echo "*** No help text for variable \"$variable\" available"
		else
			cat <&2	# echo the help text from fd 2 to stdout
		fi
		echo
		echo "Please enter the value (default: \"$value\"):"
		read newValue
		if [ -n "$newValue" ]; then
			value="$newValue"
		fi
	fi
	eval "$variable=\"\$value\""
}

setup_uninstallscript()
{
	globalUninstallScript="$1"
	setup_removeaction "rm -f '$globalUninstallScript'"
}

setup_setname()
{
	packageName="$1"
}

###############################################################################
#                            the main program
###############################################################################

notroot=no
if [ `whoami` != root ]; then
	echo
	echo "$0 should be run as root. If you run it as user, $0 probably"
	echo "can't access all installation pathes and can't set ownerships."
	echo
	echo "Should we continue anyway? [y/n]"
	read answer
	if [ "$answer" != y -a "$answer" != Y ]; then
		echo "*** Installation aborted."
		exit
	fi
	notroot=yes
fi

file=setup_file
tree=setup_tree
directory=setup_directory
link=setup_link
defvar=setup_defvar
removeaction=setup_removeaction
setname=setup_setname
uninstallscript=setup_uninstallscript
{
	filelist=`findsource filelist`
    if [ -z "$filelist" ]; then
        echo "*** ERROR: could not find list of files!" 1>&2
        echo "Aborting installation." 1>&2
        exit 1
    fi
    . "$filelist"
	if [ -n "$globalUninstallScript" ]; then
		cat > "$globalUninstallScript" <<EOF
#!/bin/sh
# This script was automatically generated at `date`
# during installation. It removes the $packageName software package.

	echo "Do you really want to uninstall $packageName? [y/N]"
	read answer
	if [ "\$answer" != y -a "\$answer" != Y ]; then
		echo "Uninstall aborted."
		exit 1
	fi
	if [ $notroot != yes -a \`whoami\` != root ]; then
		echo "You must be root to uninstall."
		echo "Uninstall aborted."
		exit 1
	fi
	uibackup="/tmp/$packageName-uninstall"
	echo "A backup of the uninstall script is made to \$uibackup."
	echo "If the uninstall fails, you can correct the problem and restart"
	echo "the uninstallation script at the backup location, if the original"
	echo "has already been deleted."
	echo
	sleep 5
	if [ -f "$globalUninstallScript" ]; then
		rm -f "\$uibackup"
		cp -p "$globalUninstallScript" "\$uibackup"
	fi
	
EOF
		cat "$uninstlist" >> "$globalUninstallScript"
		chmod a+x "$globalUninstallScript"
	fi
	rm -f "$uninstlist"
	rm -f "$tmpfile"
}   # you may add redirections here
