#!/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
# Chad Dupuis	03/30/06 Simplify code; Only run on Red Hat 2.4 systems
# Chad Dupuis	07/28/06 Change && to || in is_red_hat
# Chad Dupuis	08/03/06 For hugemem kernels always use i686-hugemem config file

#
# Functions
#

# Check if we're running on a red hat system

is_red_hat () {
 if test ! -f /etc/redhat-release || test "`uname -r | cut -c 1-3`" != "2.4"
 then
 	exit 0
 fi
}

# Prints out a help messege

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"
}

# Set the kernel source directory and kernel version using information directly
# from the system

get_information_from_system () {

 # no 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 test ! -h /usr/src/linux-2.4
 then
 	echo "Cannot find any kernel sources"
 	exit 1
 fi

 # set kernel version directory
 OSVER=linux-2.4

 # use current kernel for the kernel version
 KERNELVERSION=`uname -r`
}

# Read command line arugments and do something with them if needed

read_args () {
 if [ $# -lt 1 ]
 then
	# There were no command line arguments; get info from system
	get_information_from_system
 else 
 	# 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
  fi
}

# Choose which .config file to use

choose_config_file () {
 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 our arch is "athlon" and the extension is "hugemem", set the arch back to "i686"

 if [ "$ARCH" = "athlon" ] && [ "$EXTENSION" = "hugemem" ]
 then
	echo "Kernel extension is \"${EXTENSION}\", setting arch back to \"i686\""
	ARCH=i686
 fi

 # Set name of config file

 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
}

# Condition kernel sources for the kernel we're about to build on

condition_kernel_sources() {
 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

 #
 # 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
}

#
# Script Main
#

# Check if we're a red hat system
is_red_hat

# Get kernel source and kernel version information
read_args $*

# Get which .config file to use from the kernel source "configs" directory
choose_config_file

# Condition the kernel header files
condition_kernel_sources

# If we've made it this far, we're good
exit 0
