#!/bin/ksh 

trapper( )
{
	[ -r "$CMD_FILE" ] && rm -f "$CMD_FILE" >/dev/null 2>&1
	[ -r "$LIST" ] && rm -f "$LIST" >/dev/null 2>&1
	exit 1
}

#*************************************************************** SET_TABS() ***
set_tabs( ) 
{
	if echo $TERM | grep -q ansi ; then
		TABSIZE=$1
		COLS=`echo "$(stty -g | sed -e 's/ /\\\n/g')" | grep rows= | cut -d"," -f2`
		test -z $COLS && COLS=80;
		let COLS=$COLS-$TABSIZE
		printf "\x1B[3g\r"
		let c=0
		while [ $c -lt $COLS ]; do
			let c=$c+$TABSIZE
			printf "%-${TABSIZE}s\033H" " "
		done
		printf "\r"
	else
		echo "attach: warning: Unable to set tab stops."
	fi
}

if [ $# -eq 0 ]; then
	echo "Attach to a process using gdb"
	echo "usage:"
	echo "   attach [options] <process_name|pid> [gdb_command1 [ gdb_command2 [...]]]"
	echo "where options:"
	echo "    -p n    change gdb priority before the start to n(see renice)"
	exit 1
fi

#********************************************************************* MAIN ***
typeset -i N_PROCS=0
typeset -i PID=0

ok=1

while getopts "p:" opt $*
do 
	case $opt in
    	p)  PRIO=$OPTARG
    		renice $PRIO -p $$
    		;;
	    *)  ok=0
    		;;
	esac 
done

if test $OPTIND -gt 1; then
    let OPTIND=OPTIND-1
    shift $OPTIND
fi

[ $ok -ne 1 ] && exit 1

trap trapper SIGTERM SIGINT SIGHUP

# Check if argument is a number 
echo "$1" | grep -q -E "^[0-9]+$"

if [ $? -eq 0 ]; then
	PID="$1"
	pidin -p $PID -F"%n" 2>/dev/null 1>&2
	if [ $? -ne 0 ]; then
		echo "attach: unable to find '$PID'";
		exit 1;
	fi
	# Obtain the name of the specified process
	NAME=$(pidin -p $PID -F"%n" 2>/dev/null | tail -1)
	NAME="${NAME%* }"
else

	N_PROCS=`pidin -F"%a %n" | grep "[/ ]$1 $" | wc -l`

	case $N_PROCS in 
	0)
		echo "attach: unable to find process '$1'";
		exit 2;
		;;
		
	1)
		( pidin -F"%a %n" | grep "[/ ]$1 $" ) |&
		read PID NAME <&p
		;;
    *)
		echo "There is a few processes with the specified name, choose one:"
		LIST="${TMPDIR:-/tmp}/list.$$"
		pidin -F"%a %n" | grep "[/ ]$1 $" >$LIST
		cat $LIST |&
		let i=1
		while read PID NAME <&p
		do
			INFO=`pidin -p$PID -F"%A" | tail -n1 -l`
			printf "[%2d]: $PID $INFO\n" $i
			let i=$i+1
		done
		echo "Process number: \c"
		read N
		if [ $N -lt 1 -o $N -ge $i ]; then
			echo "Invalid number!"
			exit 3
		else
			let N="($i-$N)"
			tail -l -n$N $LIST |&
			read PID NAME <&p
		fi
		rm -f $LIST >/dev/null 2>&1
		LIST=""
		;;
	esac
fi

if [ $PID -ne 0 ]; then
	CMD_FILE="${TMPDIR:-/tmp}/attach.$$"
	
	echo "Attaching to $PID ($NAME)..."
	# I have to cut out the /proc/boot from the library path
	# because it is definitely not the place to look at.
	LD_LIBRARY_PATH=$( echo "$LD_LIBRARY_PATH" | sed -e 's|/proc/boot:||' );
	echo "set solib-search-path $LD_LIBRARY_PATH" >$CMD_FILE
	echo "attach $PID" >>$CMD_FILE
	if [ $# -gt 1 ]; then
		# Skip the first argument
		shift 
		while [ $# -ne 0 ]; do
			echo "$1" >>$CMD_FILE
			shift
		done
	fi
	
	# Set tab size of the current terminal to 4 spaces
	set_tabs 4
	
	if [ "A$NAME" = "A" ]; then
		gdb -x $CMD_FILE
	else
		# Try to detect where the binary file is located
		[ ! -r "$NAME" ] && [ -r "/$NAME" ] && NAME="/$NAME"
		[ ! -r "$NAME" ] && NAME=$(which "$NAME" 2>/dev/null)
		if [ -z "$NAME" ]; then
			gdb -x $CMD_FILE
		else
			gdb --se=$NAME -x $CMD_FILE
		fi
	fi
	rm -f $CMD_FILE >/dev/null 2>&1
fi

