#!/bin/sh

DEFAULT_DIR="/tmp"

# Usage
Usage() {
	echo -e "\nUsage ${0} <directory> (Optional, Default is ${DEFAULT_DIR})\n"
	exit 1
}

# Creates a directory
MakeDir() {
	dir=$1
	mkdir -p ${dir}
	ret=$?
	if [ ${ret} != "0" ]
	then
		echo -e "\nFailed to create directory ${dir}. Error: ${ret}\n"
		exit 1
	fi
}

# Extracts debug information about the running likewise processes.
ExtractLikewise() {
	outfile="$destdir/likewise_extract.log"
	touch $outfile || return 1
	[ -z "$outfile" ] && echo "No output file?!" && return 1

	pids=`lwsm list | awk '/running/ {print $4}' | sort -u`
	[ -z "$pids" ] && echo "Likewise not running?" && return 1

	tmpf=`mktemp /tmp/pidextractXXXXXX`
	trap "rm -f ${tmpf}" HUP INT QUIT ILL TRAP ABRT BUS SEGV TERM

	# Add symbols for all of the potentially dlopen'd Likewise libraries.
	cd /usr/local/lib
	dirs="lsa-provider lsa-rpc lw-map-sec lw-svcm lwio-driver"
	for shlib in `find ${dirs} -name '*.so' -type f`; do
		echo "add-symbol-file /usr/local/lib/$shlib" >> $tmpf
	done

	echo "set height 0" >> $tmpf
	echo "thr apply all bt" >> $tmpf
	echo "quit" >> $tmpf

	# Dump basic information to the output file.
	echo "`date`: Extracting Likewise stack traces to ${outfile}"
	echo "+ lwsm list" > ${outfile}
	lwsm list >> ${outfile}
	echo "+ cat ${tmpf}" >> ${outfile}
	cat ${tmpf} >> ${outfile}
	(echo; echo) >> ${outfile}
	echo "Begin stack traces:" >> ${outfile}

	# Now attach to every pid in turn and dump their stack traces.
	for pid in $pids; do
		pid=${pid##\(} # Remove leading (
		pid=${pid%\)} # Remove trailing )
		echo " -> Process ${pid}"
		echo >> ${outfile}
		echo "+ procstat -kk ${pid}" >> ${outfile}
		procstat -kk ${pid} >> ${outfile} 2>&1
		echo >> ${outfile}
		echo "\n+gdb -x $tmpf /usr/local/sbin/lwsmd ${pid}" >> ${outfile}
		gdb -x $tmpf /usr/local/sbin/lwsmd ${pid} >> ${outfile} 2>&1
	done
	echo "`date`: Done."
	rm -f $tmpf
}

# Cores the likewise processes and restarts them.
CoreLikewise() {
	echo -e "\n`date`: Core Dumping Likewise processes to ${destdir}"
	echo " -> Setting crash dir to ${destdir}"
	sysctl kern.corefile="${destdir}/"%N-%P.core > /dev/null 2>&1
	sleep 1
	echo " -> `sysctl kern.corefile`"

	echo " -> Killing Likewise Processes"
	killall -ABRT lwsmd
	echo " -> Sleeping while core files are being generated"
	sleep 5

	echo " -> Setting crash dir back to normal"
	sysctl kern.corefile=/var/crash/%N-%P.core > /dev/null 2>&1
	sleep 1
	echo " -> `sysctl kern.corefile`"

	echo " -> Restarting Likewise Services"
	echo " -> `/usr/local/etc/rc.d/lwsmd start`"
	echo " -> `/usr/local/etc/rc.d/likewise start`"
	sleep 1

	echo " -> Gathering Likewise Objects"
	lw-lsa enum-objects >> ${destdir}/likewise_objects.out 2>&1
	echo "`date`: Done."
}

# Tars up all of the diagnostic files.
TarUpFiles() {
	cwd=`pwd`
	tarfile="${logdir}/${ts}_Likewise_Diagnostics.tgz"
	echo -e "\n`date`: Creating Tar file ${tarfile}"
	cd $logdir
	diagdir=`basename $destdir`
	tar zcf ${tarfile} ${diagdir}
	cd $cwd

	echo " -> Cleaning Up by removing ${destdir}"
	rm -rf ${destdir}

	echo " -> Please download and ftp the TAR file ${tarfile}"
	echo "`date`: Done."
}

#MAIN
directory=${DEFAULT_DIR}
# Check the Arguments
if [ $# == "1" ]
then
	if [ $1 == "-h" ]
	then
		Usage
	fi
	directory=$1
fi

echo -e "\nStarting Likewise Diagnostics Program ${directory}"
logdir="$directory/likewise_diag"
MakeDir ${logdir}
logdir=`realpath $logdir`

# Set the directory for the logs.
ts=`date "+%Y-%m-%d_%H-%M-%S"`
destdir="$logdir/${ts}"

echo " -> Creating Directory ${destdir}"
MakeDir ${destdir}

ExtractLikewise

echo -e "\n\nRun the CoreLikewise script (y/n)?"
echo -e "Note: This will restart the Likewise services, which interrupts client access"
read REPLY
case $REPLY in
	[Yy]*)	CoreLikewise
		;;
	*)	echo " -> Not Core Dumping Likewise Processes"
		;;
esac

TarUpFiles

exit 0
