#!/bin/sh
#
#  Troy Dawson <dawson@fnal.gov>
#  Written on September 30, 2003
#
# This is a sh shell conversion of the serialconsole
#  perl script written by Kirk Bauer.  It was converted
#  into sh because that was easier to read and modify
#  for future changes.
#
# This script makes all the changes necessary to send
#  console output to both the serial port and the screen.  This
#  also creates a login prompt on the serial port and allows root
#  to login at this prompt.
#
##################################
# VARIABLES
##################################
LILOFILE="/etc/lilo.conf"
GRUBFILE="/boot/grub/grub.conf"
INITFILE="/etc/inittab"
SECFILE="/etc/securetty"
DEVCONSOLE="/dev/ttyS0"
CONSOLESPEED="9600"
DATE=`date +%m%d%Y`
DEBUG="on"


####################################################
# function to modify securetty
####################################################
mod_securetty(){
	if [ "$DEBUG" = "on" ] ; then
		echo " $SECFILE"
	fi		
	if [ -f $SECFILE ] ; then
		SECLINE=`echo $DEVCONSOLE | cut -d'/' -f3`
		grep -q $SECLINE $SECFILE
		if [ $? -eq 0 ] ; then
			if [ "$DEBUG" = "on" ] ; then
				echo "  $SECLINE already in $SECFILE"
			fi		
		else
			if [ "$DEBUG" = "on" ] ; then
				echo "  Adding $SECLINE to $SECFILE"
			fi
			echo $SECLINE >> $SECFILE
		fi
	else
		if [ "$DEBUG" = "on" ] ; then
			echo "  File not found: $SECFILE"
		fi		
	fi
}

####################################################
# Modify /etc/inittab
####################################################
mod_inittab(){
	if [ "$DEBUG" = "on" ] ; then
		echo " $INITFILE"
	fi		
	if [ -f $INITFILE ] ; then
		INITLINE=`echo $DEVCONSOLE | cut -d'/' -f3`
		grep -q $INITLINE $INITFILE
		if [ $? -eq 0 ] ; then
			if [ "$DEBUG" = "on" ] ; then
				echo "  Console line already in $INITFILE"
			fi		
		else
			if [ "$DEBUG" = "on" ] ; then
				echo "  Adding $INITLINE to $INITFILE"
			fi
			echo "c:12345:respawn:/sbin/mingetty $INITLINE" >> $INITFILE
		fi

	else
		if [ "$DEBUG" = "on" ] ; then
			echo "  File not found: $INITFILE"
		fi		
	fi
	
}

####################################################
# function to modify lilo.conf
####################################################
mod_lilo(){
	if [ "$DEBUG" = "on" ] ; then
		echo " $LILOFILE"
	fi
	# See if we have /etc/lilo.conf or /etc/lilo.conf.anaconda
	FOUND="no"
	if [ -f $LILOFILE ] ; then
		FOUND="yes"
	elif [ -f /etc/lilo.conf.anaconda ] ; then
		FOUND="yes"
		LILOFILE="/etc/lilo.conf.anaconda"
	fi
	
	if [ "$FOUND" = "yes" ] ; then
	#real  work starts here
		if [ "$DEBUG" = "on" ] ; then
			echo "  Working on $LILOFILE"
			echo "   Editing serial line in $LILOFILE"
		fi
		#start with the serial line
		SERIALNUM=`echo $DEVCONSOLE | cut -c10`
		rm -f $LILOFILE.tempfile
		grep -q "serial=" $LILOFILE
		if [ $? -eq 0 ] ; then
			if [ "$DEBUG" = "on" ] ; then
				echo "    Previous serial line found, changing to"
				echo "      serial=${SERIALNUM},${CONSOLESPEED}n8"
			fi		
			sed -e 's/^[ 	]*serial=.*/'"serial=${SERIALNUM},${CONSOLESPEED}n8"'/' $LILOFILE > $LILOFILE.tempfile
			mv -f $LILOFILE.tempfile $LILOFILE
		else
			if [ "$DEBUG" = "on" ] ; then
				echo "    Previous serial line not found, adding line"
				echo "      serial=${SERIALNUM},${CONSOLESPEED}n8"
			fi		
			echo "serial=${SERIALNUM},${CONSOLESPEED}n8" | cat - $LILOFILE > $LILOFILE.tempfile
			mv -f $LILOFILE.tempfile $LILOFILE
		fi
		
		#now do the console line
		if [ "$DEBUG" = "on" ] ; then
			echo "   Editing console line(s) in $LILOFILE"
		fi
		SCONLINE="console=ttyS${SERIALNUM},${CONSOLESPEED}"
		cat $LILOFILE | grep image= | cut -d'=' -f2 | while read line
		do
			APP=`grubby --lilo --config-file=$LILOFILE --info=$line | grep args | cut -d'"' -f2`
			if [ "$DEBUG" = "on" ] ; then
				echo "    Working on kernel $line"
				echo "     OldAppend=$APP"
			fi		
#			echo $APP | grep -q "console=tty0"
#			if ! [ $? -eq 0 ] ; then
#				if [ "$DEBUG" = "on" ] ; then
#					echo "     Added console=tty0"
#				fi		
#				grubby --lilo  --config-file=$LILOFILE --update-kernel=$line --args="console=tty0"
#			fi
			echo $APP | grep -q "$SCONLINE"
			if ! [ $? -eq 0 ] ; then
				if [ "$DEBUG" = "on" ] ; then
					echo "     Added $SCONLINE"
				fi		
				grubby --lilo  --config-file=$LILOFILE --update-kernel=$line --args="$SCONLINE"
			fi
			if [ "$DEBUG" = "on" ] ; then
				APP=`grubby --lilo --config-file=$LILOFILE --info=$line | grep args | cut -d'"' -f2`
				echo "     NewAppend=$APP"
			fi		
			
		done

		#now finish up, run lilo only if we really are using lilo
		if [ "$(grubby --bootloader-probe)" = "lilo" ] ; then
			if [ "$LILOFILE" = "/etc/lilo.conf" ] ; then
				if [ "$DEBUG" = "on" ] ; then
					echo "  Running lilo to commit changes"
				fi
				/sbin/lilo
			else
				if [ "$DEBUG" = "on" ] ; then
					echo "  Although your bootloader says lilo ..."
					echo "   something is wrong because you dont have /etc/lilo.conf"
					echo "  Not running /sbin/lilo to commit changes"
				fi
			fi
		else
			if [ "$DEBUG" = "on" ] ; then
				echo "  You are using grub, we are not rerunning lilo"
			fi
		fi
	else
		if [ "$DEBUG" = "on" ] ; then
			echo "  File not found: $LILOFILE"
		fi		
	fi

}


####################################################
# function to modify grub.conf
####################################################
mod_grub(){
	if [ "$DEBUG" = "on" ] ; then
		echo " $GRUBFILE"
	fi		
	if [ -f $GRUBFILE ] ; then
		#real  work starts here
		if [ "$DEBUG" = "on" ] ; then
			echo "  Working on $GRUBFILE"
			echo "   Editing serial line in $GRUBFILE"
		fi
		SERIALNUM=`echo $DEVCONSOLE | cut -c10`

		#do the terminal line first, because it needs to be first
		rm -f $GRUBFILE.tempfile
		grep "terminal " $GRUBFILE  | grep -q -v "#"
		if [ $? -eq 0 ] ; then
			if [ "$DEBUG" = "on" ] ; then
				echo "    Previous terminal line found, leaving it be"
			fi		
		else
			if [ "$DEBUG" = "on" ] ; then
				echo "    Previous terminal line not found, adding line"
				echo "      terminal --timeout=10 --silent serial console"
			fi		
			echo "terminal --timeout=10 serial console" | cat - $GRUBFILE > $GRUBFILE.tempfile
			mv -f $GRUBFILE.tempfile $GRUBFILE
		fi
		
		# Then do the serial line
		rm -f $GRUBFILE.tempfile
		grep "serial --unit" $GRUBFILE | grep -q -v "#"
		if [ $? -eq 0 ] ; then
			if [ "$DEBUG" = "on" ] ; then
				echo "    Previous serial line found, changing to"
				echo "      serial --unit=${SERIALNUM} --speed=${CONSOLESPEED}"
			fi		
			sed -e 's/^[ 	]*serial .*/'"serial --unit=${SERIALNUM} --speed=${CONSOLESPEED}"'/' $GRUBFILE > $GRUBFILE.tempfile
			mv -f $GRUBFILE.tempfile $GRUBFILE
		else
			if [ "$DEBUG" = "on" ] ; then
				echo "    Previous serial line not found, adding line"
				echo "      serial --unit=${SERIALNUM} --speed=${CONSOLESPEED}"
			fi		
			echo "serial --unit=${SERIALNUM} --speed=${CONSOLESPEED}" | cat - $GRUBFILE > $GRUBFILE.tempfile
			mv -f $GRUBFILE.tempfile $GRUBFILE
		fi
		
		#now do the console line(s)
		if [ "$DEBUG" = "on" ] ; then
			echo "   Editing console line(s) in $GRUBFILE"
		fi
		SCONLINE="console=ttyS${SERIALNUM},${CONSOLESPEED}"
		cat $GRUBFILE | grep kernel | grep -v "#" | while read line
		do
			KERN=`echo $line | cut -f2 | cut -d' ' -f2`
			APP=`grubby --grub --info=$KERN | grep args | cut -d'"' -f2`
			if [ "$DEBUG" = "on" ] ; then
				echo "    Working on kernel $KERN"
				echo "     OldAppend=$APP"
			fi		
#			echo $APP | grep -q "console=tty0"
#			if ! [ $? -eq 0 ] ; then
#				if [ "$DEBUG" = "on" ] ; then
#					echo "     Added console=tty0"
#				fi		
#				grubby --grub --update-kernel=$KERN --args="console=tty0"
#			fi
			echo $APP | grep -q "$SCONLINE"
			if ! [ $? -eq 0 ] ; then
				if [ "$DEBUG" = "on" ] ; then
					echo "     Added $SCONLINE"
				fi		
				grubby --grub --update-kernel=$KERN --args="$SCONLINE"
			fi
			if [ "$DEBUG" = "on" ] ; then
				APP=`grubby --grub --info=$KERN | grep args | cut -d'"' -f2`
				echo "     NewAppend=$APP"
			fi		
		done
	else
		if [ "$DEBUG" = "on" ] ; then
			echo "  File not found: $GRUBFILE"
		fi		
	fi

}

####################################################
# function to print the help
####################################################
printHelp(){
	echo "serialconsole.sh [-h] [-q] [-d <device>] [-s <speed>]"
	echo " "
	echo " -h help      Display this help file"
	echo " -q quiet     Only send errors to the screen"
	echo " -d device    The serial device - default is /dev/ttyS0"
	echo " -s speed     Speed of the serial device - default is 9600"
	echo " "
}

####################################################
# Start of main program
####################################################
####################################################
# First check for what was passed to the program
####################################################
while test $# != 0
do
	case $1 in
		-d)  test $# -lt 2 && { printHelp ; exit 1 ; }
			DEVCONSOLE="$2" ; shift 2 ;;
		-s)  test $# -lt 2 && { printHelp ; exit 1 ; }
			CONSOLESPEED="$2" ; shift 2 ;;
		-q) DEBUG="off" ; shift 1 ;;
		-h | -help | --help | --h) printHelp ; exit 0 ;;
		*) printHelp ; break
	esac
done

TESTCONS=`echo $DEVCONSOLE | cut -c1-8`
if ! [ "$TESTCONS" = "/dev/tty" ] ; then
	echo "Device must be in the form /dev/tty??"
	exit 1;
fi

if [ "$DEBUG" = "on" ] ; then
	echo "Starting serial console configuration"
fi

mod_securetty
mod_inittab
mod_lilo
mod_grub

if [ "$DEBUG" = "on" ] ; then
	echo "serial console configuration finished"
fi

exit 0;
