#!/bin/bash
#
# Name: condition_kernel
# Copyright: (c)2004 Hewlett-Packard
#
# Description: Conditions kernel sources to reflect the currently
#              running kernel
#
# Chad Dupuis 	01/15/04 Initial Development
# Chad Dupuis   01/29/04 Added command line parametes to specify the
#                        kernel module and kernel source directory we
#                        should be using
# Chad Dupuis   02/25/04 Fixed typo in the help message; Added code to
#                        discern the correct .config file in some
#                        Red Hat kernels that do not follow the usual format
# Chad Dupuis   04/26/04 Fixed problem in parsing algorithm for SLES 8 SP3
# Chad Dupuis   06/17/04 Added check for AMD processors so that we use the
#                        "athlon" .config files when the OS is in 32-bit mode
# Chad Dupuis   08/17/04 Added code to parse Red Hat Enterprise Linux 3 Update
#                        3 kernels with "jg3" in them
# Chad Dupuis	08/20/04 Removed kernel parsing code for RHEL 3 U3 "jg3" kernel;
#			 If .config file cannot be found, exit
# Chad Dupuis   08/26/04 Parse RHEL 3 kernels that appear in the form of 
#                        2.4.21-xx.xx.ELxxx
# Chad Dupuis   09/02/04 If architecture is x86_64 determine if we are an Intel 
#                        CPU or AMD one
# Chad Dupuis	09/08/04 Parse test or hotfix kernels for RHAS 2.1 correctly
# Chad Dupuis   09/23/04 More parse fixes for RHAS 2.1 test or hotfix kernels
# Chad Dupuis   12/01/04 Add -j option to make dep
 
# prints out a help messege

# prints command line help

print_help () {
 echo "Usage: $0 [-h -s source_directory -m module_directory ]"
 echo ""
 echo "-s: kernel source directory to use"
 echo "-m: kernel module directory to use (used to tell what kernel version we are using)"
 echo "-h: prints help"
 echo ""
 echo "example: $0 -s linux-2.4.21-9.EL -m 2.4.21-9.ELsmp"
}

# defines

USECONFIG=1
HAVECONFIG=0

if [ $# -gt 0 ]
then
 # check arguments

 SOURCEFLAG=0
 MODULEFLAG=0
 HELPFLAG=0

 # parse command line into arguments

 getopt m:s:h $* 1>/dev/null 2>/dev/null

 # check result of parsing

 if [ $? != 0 ]
 then
 	echo "Bad argument or missing argument"
 	exit 1
 fi

 set -- `getopt m:s:h $*`

 while [ $1 != -- ]
 do
 	case $1 in
		-m) MODULEFLAG=1
		    MODULEDIR=$2
		    shift;;
		-s) SOURCEFLAG=1
		    SOURCEDIR=$2
		    shift;;
		-h) HELPFLAG=1;;
		*) echo "$1 is an illegal argument"
		   exit 1;;
 	esac
 	shift   # next flag
 done

 shift   # skip --

 if [ $HELPFLAG -eq 1 ]
 then
 	print_help
 	exit 0
 elif [ $SOURCEFLAG -ne 1 ] || [ $MODULEFLAG -ne 1 ]
 then
 	echo "-m and -s arguments must both be used at the same time"
 	exit 1
 fi

 # make sure that kernel source and module directories exist

 if [ ! -d /lib/modules/${MODULEDIR} ]
 then
 	echo "/lib/modules/${MODULEDIR} does not exist"
 	exit 1
 fi

 if [ ! -d /usr/src/${SOURCEDIR} ] && [ ! -d /usr/src/${SOURCEDIR}-include ]
 then
	 echo "/usr/src/${SOURCEDIR} and /usr/src/${SOURCEDIR}-include do not exist"
	 exit 1
 fi

 # set kernel version to be what SOURCEDIR is

 KERNELVERSION=$MODULEDIR

 # OSVER is set to the kernel source directory we want to sue

 OSVER=$SOURCEDIR

 # determine if we even need to remake the kernel source dependencies

 if [ -d /usr/src/linux-2.4 ]
 then
 	# if we are red hat then we need to remake kernel source
	# dependencies

	DISTRO="red hat"
 	USECONFIG=1
 elif [ -d /usr/src/linux ]
 then
 	DISTRO="suse"

 	# we are using a SuSE distribution so
 	# we need to determine the kernel version

 	if [ `echo $KERNELVERSION | cut -c 5-6` -lt 21 ]
 	then
		# if we are using a kernel that is older than
 		# 2.4.21, we need to configure the kernel source
		# dependencies

		USECONFIG=1
 	else
 		# if we are using a kernel that is greater than 2.4.21.x,
		# we should not do any kernel source dependency configuratino

		USECONFIG=0
 		OSVER=$OSVER-include
  	fi
 fi

else

 # not arguments were given to the script, so we have to infer
 # what the kernel version and what the kernel source directory
 # should be from the current running kernel

 # check for kernel source directories

 if [ ! -h /usr/src/linux ] && [ ! -h /usr/src/linux-2.4 ]
 then
 	echo "Cannot find any kernel sources"
 	exit 1
 fi

 # determine the right directory to point OSVER to

 if [ -d /usr/src/linux-2.4 ]
 then
 	OSVER="linux-2.4"
 	DISTRO="red hat"
 	USECONFIG=1
 elif [ -d /usr/src/linux ]
 then
 	DISTRO="suse"

 	# we are using a SuSE distribution so
 	# we need to determine the kernel version

 	if [ `uname -r | cut -c 5-6` -lt 21 ]
 	then
		# if we are using a kernel that is older than
 		# 2.4.21, set OSVER to linux
 		OSVER=linux
		USECONFIG=1
 	else
 		# if we are using a kernel that is 2.4.21 or greater,
  		# we need to point OSVER to one of the precompiled
  		# header directories
  		KERNTYPE=`uname -r | awk 'BEGIN {FS="-"} {if ($4 == "") print $3; else print $3"-"$4}'`

  		# make sure that the precompiled directory we are about
  		# to use exists

  		if [ -a /usr/src/linux-include/${KERNTYPE} ]
  		then
   			OSVER="linux-include/${KERNTYPE}"
			USECONFIG=0
  		else
   			echo "The directory /usr/src/linux-include/${KERNTYPE} does not exist"
   			echo "so the compilation cannot continue"
   			exit 1
  		fi

  	fi
 fi

 # use current kernel for the kernel version

 KERNELVERSION=`uname -r`
fi

# Go through the process of updating the kernel header files
# if we are using Red Hat or an old version of SUSE

if [ $USECONFIG -eq 1 ]
then

 echo ""
 echo "Configuring kernel sources..."
 echo ""
 cd /usr/src/${OSVER}

 # if we are using a red hat distribution, copy the
 # right .config file from the configs directory

 if [ "$DISTRO" = "red hat" ]
 then
  	KERNEL=`echo $KERNELVERSION | awk 'BEGIN {FS="-"} {print $1}'`
  	ARCH=`uname -m`

	# if we are using an AMD athlon processor with the OS in 32-bit mode, the
        # architecture from uname -m may still be i686.  In this case, override
	# uname -m and manually set the ARCH to athlon

	if [ "`cat /proc/cpuinfo | grep AuthenticAMD`" != "" ]
	then
		if [ "$ARCH" = "i386" ] || [ "$ARCH" = "i486" ] || [ "$ARCH" = "i586" ] || [ "$ARCH" = "i686" ]
		then
			echo "Overriding uname -m and setting ARCH to \"athlon\""
			ARCH="athlon"
		fi
	fi

	# if uname -m returns x86_64 but we are using an Intel processor, set architecture to ia32e

	if [ "`uname -m`" = "x86_64" ] && [ "`cat /proc/cpuinfo | grep GenuineIntel`" != "" ]
	then
		echo "Overriding uname -m and setting ARCH to \"ia32e\"" 
		ARCH="ia32e"
	fi

	if test -f /etc/redhat-release && test "`cat /etc/redhat-release | grep "Advanced Server" | grep 2.1`" != ""
	then
		# Assume we are advanced server 2.1

		EXTENSION=`echo $KERNELVERSION | awk 'BEGIN {FS="-"} {print $2}' | awk 'BEGIN {FS="."} {print $2}' | cut -c 3-`

		# check for hotfix or test kernels

		if [ "`echo $KERNELVERSION | grep hotfix`" != "" ] || [ "`echo $KERNELVERSION | grep TEST`" != "" ]
                then
                        EXTENSION=`echo $KERNELVERSION | awk 'BEGIN {FS="-"} {print $2}' | awk 'BEGIN {FS="."} {print $4}' | cut -c 7-`
		elif [ "$EXTENSION" = "" ]
		then
			# if field two is empty try getting something from field 4 before we say that this is
			# a uniprocessor, default kernel

			EXTENSION=`echo $KERNELVERSION | awk 'BEGIN {FS="-"} {print $2}' | awk 'BEGIN {FS="."} {print $4}' | sed 's/[0-9]//g'`
		fi
	else
		# we are some other version of Red Hat Linux...probably Enterprise Linux 3

		EXTENSION=`echo $KERNELVERSION | awk 'BEGIN {FS="-"} {print $2}' | awk 'BEGIN {FS="."} {print $2}' | cut -c 3-`

		# some Red Hat kernels are versioned differently, like 2.4.21-10.9.ELsmp or 2.4.21-9.0.1.ELsmp.  In this case
		# the third or fourth field needs to be read 

        	if [ "`echo $KERNELVERSION | awk 'BEGIN {FS="-"} {print $2}' | awk 'BEGIN {FS="."} {print $3}' | grep EL`" != ""  ]
        	then
                	EXTENSION=`echo $KERNELVERSION | awk 'BEGIN {FS="-"} {print $2}' | awk 'BEGIN {FS="."} {print $3}' | cut -c 3-`
        	elif [  "`echo $KERNELVERSION | awk 'BEGIN {FS="-"} {print $2}' | awk 'BEGIN {FS="."} {print $4}' | grep EL`" != ""   ]
        	then
                	EXTENSION=`echo $KERNELVERSION | awk 'BEGIN {FS="-"} {print $2}' | awk 'BEGIN {FS="."} {print $4}' | cut -c 3-`
		fi
	fi

  	if [ "$EXTENSION" = "" ]
  	then
   		CONFIGFILE="kernel-$KERNEL-$ARCH.config"
  	else
   		CONFIGFILE="kernel-$KERNEL-$ARCH-$EXTENSION.config"
  	fi

	# check to make sure that the config file we want to use actually
        # exists

	if test -f /usr/src/${OSVER}/configs/${CONFIGFILE}
	then
        	echo "Using /usr/src/${OSVER}/configs/$CONFIGFILE as .config"
	else
		echo "/usr/src/${OSVER}/configs/${CONFIGFILE} does not exist"
		exit 1
	fi

	#
	# make kernel dependencies
	#

	# make mrproper first, driver may not compile correctly without it

 	echo "Executing make mrproper"
 	make mrproper 1>/dev/null 2>/dev/null

 	if [ $? -ne 0 ]
 	then
  		echo ""
  		echo "make mrproper failed"
  		exit 1
 	fi

	# copy correct .config file from configs directory

	cp /usr/src/${OSVER}/configs/${CONFIGFILE} /usr/src/${OSVER}/.config

	# kernel extraversion

	EXT=`echo $KERNELVERSION | awk 'BEGIN {FS="-"} {print $2}'`
	echo "Executing make oldconfig"
 	make EXTRAVERSION=-${EXT} oldconfig 1>/dev/null 2>/dev/null

	if [ $? -ne 0 ]
	then
		echo ""
		echo "make oldconfig failed"
		exit 1
	fi

 	echo "Executing make dep"
 	
	# get number of processors

	PROCCNT=`cat /proc/cpuinfo | grep -c processor`
	make -j${PROCCNT} EXTRAVERSION=-${EXT} dep 1>/dev/null 2>/dev/null

	if [ $? -ne 0 ]
	then
		echo ""
		echo "make dep failed"
		exit 1
	fi

 else
	# if there is currently a .config file in place, save it

 	if test -f /usr/src/${OSVER}/.config
 	then
  		mv -f /usr/src/${OSVER}/.config /tmp/.config # copy in case we need this later
 	fi

	# make mrproper

	echo "Executing make mrproper"
	make mrproper 1>/dev/null 2>/dev/null

	if [ $? -ne 0 ]
	then
		echo ""
		echo "make mrproper failed"
		exit 1
	fi

	# copy the cconfig file that was there back


	if test -f /tmp/.config
	then
		echo "Restoring saved .config file"
		mv /tmp/.config /usr/src/${OSVER}/.config
	else
		# there never was a .config file, so it has to be
		# created

		echo "You will have to manually create a /usr/src/${OSVER}/.config file"
		exit 1
	fi

	# make kernel dependencies

 	echo "Executing make oldconfig"
 	make oldconfig 1>/dev/null 2>/dev/null

	if [ $? -ne 0 ]
	then
		echo ""
		echo "make oldconfig failed"
		exit 1
	fi

 	echo "Executing make dep"
 	make dep 1>/dev/null 2>/dev/null

	if [ $? -ne 0 ]
	then
		echo ""
		echo "make dep failed"
		exit 1
	fi
 fi

 rm -f /tmp/.config # remove if it's there
fi
