# tcsh-like watch for bash
# $Id: .bash_watch,v 1.22 2003/12/12 13:49:38 simigern Exp $
#
# To use put the following in your shell-init-file:
# source ~/.bash_watch
# PROMPT_COMMAND="watch_fn 300"
# (This executes watch_fn every 300 seconds)
# Use the "log" command to show all current logins

watch_fn()
{
	local WATCH_SPLAY="$1"

	if [ "${WATCH_SPLAY}" = "" ]; then
		WATCH_LAST_TIME=0
		WATCH_SPLAY=0
	fi

	if [ "${WATCH_LAST_TIME}" = "" -o "$((SECONDS-WATCH_SPLAY))" -gt "$((WATCH_LAST_TIME))" ]; then
		local -a WATCH_CURRENT_USERS WATCH_TERMS
		local WATCH_INDEX WATCH_STATE WATCH_TMP WATCH_USER WATCH_TERM WATCH_DATE1 WATCH_DATE2 WATCH_TIME WATCH_FROM WATCH_FOUND WATCH_MUELL IFS
		WATCH_LAST_TIME="${SECONDS}"
		IFS=$' \t\n'
		WATCH_INDEX=0
		WATCH_CURRENT_USERS=(`\
		/usr/bin/who | \
			while read WATCH_USER WATCH_TERM WATCH_DATE1 WATCH_DATE2 WATCH_TIME WATCH_FROM WATCH_MUELL; do
				#This for is needed due to buggy Linux-who which sometimes displays
				#Terminals twice!
				for WATCH_TMP in "${WATCH_TERMS[@]}"; do
					if [ "${WATCH_TMP}" = "${WATCH_TERM}" ]; then
						continue 2
					fi
				done
				if [ "${WATCH_FROM}" != "" ]; then
					WATCH_FROM=${WATCH_FROM:1:$[${#WATCH_FROM}-2]}
					#Only cut hostnames after first dot
					if [ "${WATCH_FROM/#[a-zA-Z]}" != "${WATCH_FROM}" ]; then
						WATCH_FROM=${WATCH_FROM/\.*}
					else
						WATCH_FROM=${WATCH_FROM/#::ffff:}
					fi
					echo -n "${WATCH_TERM}\\$${WATCH_FROM} ${WATCH_USER} "
				else
					echo -n "${WATCH_TERM} ${WATCH_USER} "
				fi
				WATCH_TERMS[${WATCH_INDEX}]="${WATCH_TERM}"
				WATCH_INDEX=$((WATCH_INDEX+1))
			done`)

		if [ "${WATCH_LAST_USERS[*]}" != "${WATCH_CURRENT_USERS[*]}" ]; then
			WATCH_STATE="0"
			for WATCH_TMP in "${WATCH_CURRENT_USERS[@]}"; do
				if [ "${WATCH_STATE}" = "0" ]; then
					WATCH_TERM="${WATCH_TMP}"
					WATCH_STATE="1"
				else
					WATCH_STATE="0"
					WATCH_USER="${WATCH_TMP}"
					WATCH_INDEX=0
					WATCH_FOUND=0
					while [ "${WATCH_INDEX}" -lt "${#WATCH_LAST_USERS[@]}" ]; do
						if [ "${WATCH_LAST_USERS[${WATCH_INDEX}]/\$*}" = "${WATCH_TERM/\$*}" ]; then
							WATCH_FOUND=1
							if [ "${WATCH_LAST_USERS[$((WATCH_INDEX+1))]}" != "${WATCH_USER}" -o "${WATCH_LAST_USERS[${WATCH_INDEX}]}" != "${WATCH_TERM}" ]; then
								echo "${WATCH_USER} has replaced ${WATCH_LAST_USERS[$((WATCH_INDEX+1))]} on ${WATCH_TERM/\$/ from }."
							fi
							break
						fi
						WATCH_INDEX=$((WATCH_INDEX+2))
					done
					if [ "${WATCH_FOUND}" = "0" ]; then
						echo "${WATCH_USER} has logged on ${WATCH_TERM/\$/ from }."
					fi
				fi
			done
			WATCH_STATE="0"
			for WATCH_TMP in "${WATCH_LAST_USERS[@]}"; do
				if [ "${WATCH_STATE}" = "0" ]; then
					WATCH_TERM="${WATCH_TMP}"
					WATCH_STATE="1"
				else
					WATCH_STATE="0"
					WATCH_USER="${WATCH_TMP}"
					WATCH_INDEX=0
					WATCH_FOUND=0
					while [ "${WATCH_INDEX}" -lt "${#WATCH_CURRENT_USERS[@]}" ]; do
						if [ "${WATCH_CURRENT_USERS[${WATCH_INDEX}]/\$*}" = "${WATCH_TERM/\$*}" ]; then
							WATCH_FOUND=1
							break
						fi
						WATCH_INDEX=$((WATCH_INDEX+2))
					done
					if [ "${WATCH_FOUND}" = "0" ]; then
						echo "${WATCH_USER} has logged off ${WATCH_TERM/\$/ from }."
					fi
				fi
			done
	
			unset WATCH_LAST_USERS
			WATCH_LAST_USERS=("${WATCH_CURRENT_USERS[@]}")
		fi
	fi
}

log()
{
	unset WATCH_LAST_USERS
	watch_fn
}

#vim: set filetype=sh :
