# $Id: functions,v 1.12 2005/05/26 23:03:56 ldv Exp $

green()
{
	local msg="$1"
	
	echo -e "\033[32m$1\033[0m"
}

red()
{
	local msg="$1"
	
	echo -e "\033[31m$1\033[0m"
}

define()
{
	local arg="$3"
	if [ -z "${arg##*[\"\$\`\\]*}" ]; then
		arg=$(printf %s "$arg" | gsed -e 's/["$`\]/\\&/g')
	fi
	eval "$1_$2=\"$arg\""
}

lookup()
{
	eval "$1=\"\$$2_$3\""
}

validate()
{
	printf %s "$1" | grep -q '^[a-z0-9_]*$'
}

register()
{
	local value=
	lookup value REGISTERED "$1"
	[ -z "$value" ] || return
	define REGISTERED "$1" yes
	test -z "$NAME_LIST" && NAME_LIST="$1" || NAME_LIST="$NAME_LIST $1"
}

new_fmode()
{
	register "$1"
	define NAME_TO_FMODE "$1" "$2"
	define NAME_TO_OWNER "$1" "$3:$4"
	define FMODE_OWNER_TO_NAME "$2_$3_$4" "$1"
}

new_subst()
{
	register "$1"
	define NAME_TO_REGEX "$1" "$2"
	define NAME_TO_SUBST "$1" "$3"
}

stat()
{
	local PATHNAME="$1"
	local BASEPATH="${PATHNAME%/*}"
	gfind "$BASEPATH" -maxdepth 1 -path "$PATHNAME" -printf '%m_%u_%g'
}

control_fmode()
{
	local FILE="$1" REQUEST="$2"
	local STAT NAME FMODE OWNER

	case "$REQUEST" in
	list)
		echo "$NAME_LIST"
		;;
	status|'')
		STAT="`stat "$FILE"`"
		NAME=
		validate "$STAT" && lookup NAME FMODE_OWNER_TO_NAME "$STAT"
		if [ -n "$NAME" ]; then
			echo "$NAME"
		else
			echo "unknown"
		fi
		;;
	*)
		FMODE=
		OWNER=
		if validate "$REQUEST"; then
			lookup FMODE NAME_TO_FMODE "$REQUEST"
			lookup OWNER NAME_TO_OWNER "$REQUEST"
		fi
		if [ -n "$FMODE" -a -n "$OWNER" ]; then
			chown "$OWNER" "$FILE" || return 1
			chmod "$FMODE" "$FILE" || return 1
		else
			echo "${0##*/}: Invalid mode: $REQUEST" >&2
			return 1
		fi
		;;
	esac
}

control_subst()
{
	local FILE="$1" REQUEST="$2"
	local NAME REGEX SUBST TMPFILE

	case "$REQUEST" in
	list)
		echo "$NAME_LIST"
		;;
	status|'')
		for NAME in $NAME_LIST; do
			lookup REGEX NAME_TO_REGEX "$NAME"
			test -n "$REGEX" || continue
			if grep -Eq "$REGEX" "$FILE"; then
				echo "$NAME"
				return
			fi
		done
		echo "unknown"
		;;
	*)
		SUBST=
		validate "$REQUEST" && lookup SUBST NAME_TO_SUBST "$REQUEST"
		if [ -z "$SUBST" ]; then
			echo "${0##*/}: Invalid mode: $REQUEST" >&2
			return 1
		fi
		if [ "`control_subst "$FILE" status`" = "$REQUEST" ]; then
			return
		fi
		TMPFILE="`mktemp "$FILE.control.XXXXXX"`" || return 1
		while :; do
			cp -p "$FILE" "$TMPFILE" || break
			gsed "$SUBST" < "$FILE" > "$TMPFILE" || break
			ln -f "$FILE" "$FILE.control.orig" || break
			mv -f "$TMPFILE" "$FILE" || break
			return
		done
		rm "$TMPFILE"
		return 1
		;;
	esac
}
