#!/bin/ksh
# @(#) waiting.ksh 1.01 93/06/29
# Under XENIX, the wait channel address printed by ps is assumed to be in 
# segment 18h (data) unless it is 6000000h, in which case it is assumed to 
# be in segment 0.
# 91/11/04 john h. dubois iii (johnd@armory.com)
# 92/02/16 added help
# 92/02/17 added PATH setting to get real awk
#          added code to make it also work under UNIX
# 93/06/29 belal -- added "-" to adb call, to ignore stray core files

# This could be written to be much faster on UNIX systems by using crash

name=${0##*/}

if [ "$1" = -h ]; then
    echo \
"$name: show what processes are waiting for.
Usage: $name [-h] [ps-options]
$name prints one line for each process that is waiting,
listing the uid, pid, ppid, tty, wait channel, and command.
The wait channel is printed as a kernel symbol name and offset.
If the offset is 0 it is not printed."
    exit 0
fi


kernels="/xenix /unix"
unset kernel

for file in $kernels; do
    if [ -f $file ]; then
	if [ -r $file ]; then
	    kernel=$file
	else
	    print -u2 "Cannot open $file."
	    exit 1
	fi
	break
    fi
done

if [ -n "$kernel" ]; then
    adb $file - |&
else
    print -u2 "Can't find a kernel."
    exit 1
fi

# To make sure we get the real awk
PATH=/bin:/usr/bin:$PATH

awk '
BEGIN {
    if (args == "")
	args = "-e"
    pspipe = "ps -lf " args
    pspipe | getline header
    if ($11 == "WCHAN") {	# XENIX ps
	WChanStart = 45
	uidpidstart = 6
	uidpidlen = 13
	ttystart = 63
	cmdstart = 73
	xenix = 1
    }
    else {			# UNIX ps
	WChanStart = 57
	uidpidstart = 7
	uidpidlen = 14
	ttystart = 75
	cmdstart = 90
    }
    while ((pspipe | getline) == 1) {
	wchan = substr($0,WChanStart,8)
	if (wchan == "   WCHAN" )
	    sym = "WAIT CHANNEL"
	else if (wchan !~ "[0-9a-z]")
	    continue
	else {
	    gsub(" ","0",wchan)
	    if (xenix == 1) {
		if (wchan == "06000000")
		    printf "0x0:0x%s =a\n",wchan
		else
		    printf "0x18:0x%s =a\n",wchan
	    }
	    else {
		printf "0x1f:0x%s =a\n",wchan
		getline	sym # unix adb echoes back command
	    }
	    getline sym		# gawk hangs on this read
	    if (sym ~ "^0x")
		sym = wchan
	    sub(/^\* /,"",sym)
	    sub(/^_/,"",sym)
	    sub(/:$/,"",sym)
	}
	if (!xenix && (sym == "e0000000"))
	    sym = "<sleep>"
	# Print UID, PID,  TTY,  wait channel, and CMD
	# XENIX 6-12 14-18 63-66                   73-
	# UNIX  7-14 16-20 75-78                   90-
	# length 7/8 5     4
	printf "%s %s %-17s %s\n",substr($0,uidpidstart,uidpidlen), \
	substr($0,ttystart,4),sym,substr($0,cmdstart) | "cat 1>&2"
    }
}
' "args=$*" 3>&1 <&p >&p 2>&3
