#!/bin/ksh
# @(#) ulock.ksh 1.0 91/08/04
# 91/01/15 john h. dubois iii (john@armory.com)
# 91/02/25: only lock ttys that being with the same letter as current tty,
#          or that begin with a digit if current tty does.
# 91/02/27: make keys dead instead of mapping to ^A; use LOCKMAP var
# 92/08/04: use ttys= instead of unset ttys
# ulock: lock all multiscreens or mscreens that the user is logged into.
# Locks ttys by using mapchan to make all keys dead keys, 
# so all characters are discarded.
# When lock exits all of the other ttys are unlocked with mapchan -n.
# Current tty is locked with "lock".

# exit on any error
set -e

if [ $# -gt 0 ]; then
	echo \
"$0: lock all multiscreens or mscreens that the user is logged into.
If the name of the current tty begins with a letter,
all ttys that the user is logged into that begin with that letter
(except the current tty) are locked with mapchan.
If the name of the current tty begins with a digit,
all ttys that the user is logged into that begin with a digit
(except the current tty) are locked with mapchan.
lock is then run to lock the current tty.
When lock exits all of the other ttys are also unlocked.
A mapchan file for locking ttys must be readable by the user.
The default lock file is /usr/lib/keyboard/lockmap;
this may be overridden by setting the environment variable LOCKMAP."
	exit
fi

# Set USER, TTY (current tty), and LOCKMAP if they are not already set
[ -z "$USER" ] && USER=`logname`
[ -z "$TTY" ] && TTY=`tty`
[ -z "$LOCKMAP" ] && LOCKMAP=/usr/lib/keyboard/lockmap
tty=${TTY#/dev/}

# Get tty type identifier (first char of tty name after /dev/tty)
ttyn=${tty#tty}
ttylet=${ttyn#?}
ttylet=${ttyn%$ttylet}

# Set tty search pattern depending on tty type
[[ $ttylet = [0-9] ]] && ttypat='tty[0-9]*' || ttypat=tty$ttylet\*

#set users to USER and ALTUSERS separated by | so they can be used as a pattern
users=`( IFS=\|; set $USER $ALTUSERS; echo "$*"; )`

echo "Looking for ttys logged into by: $USER $ALTUSERS"

# set ttys to all ttys of current type that user is logged into,
# other than current tty

# Don't unset ttys because 3.2v4 ksh gives nonzero status if it wasn't set,
# so that set -e shell will exit
ttys=
who | while read user line time; do
[[ ( ( $user = @($users) ) && ( $line != $tty ) ) && ( $line = $ttypat ) ]] \
	&& ttys="$ttys $line"
done

# sort tty list
set $tty $ttys
set -s

# If no ttys of current type other than current tty, 
# don't bother with mapchan etc.
if [ -n "$ttys" ]; then
	if [ ! -r $LOCKMAP ]; then
		echo "Cannot read $LOCKMAP."
		exit 1
	fi
	echo Locking: $*.
	# Unmap channels on normal exit or exit due to interrupt
    	trap "echo Unlocking: $*.; mapchan -n $ttys 2> /dev/null" exit
	mapchan -f $LOCKMAP $ttys
else
	echo "Locking $tty (no other ttys of current type)."
fi

# For some reason one version of lock sends sigint to shell when it exits!
# Ignore interrupt 2.
trap "" 2	

lock
