#!/bin/bash
#
# $Id: getpatch,v 2.0 1996/01/15 06:07:04 hamilton Exp hamilton $
#
# getpatch written by Jon Hamilton (hamilton@mixcom.com) in a fit of
# boredom.  A crude hack, but it works.
#
# This will check to see which version of the kernel you are running, and
# get all the patches between there and the current release.  If you're
# not running linux, or if you want to specify some other "current version",
# you can say so on the command line, e.g.  ``getpatch 1.3.51'' will cause
# it to behave as if you are currently running 1.3.51.
#
# $PATCH_FTPDIR can be set if you don't like the default location, which
# is ~/kernel_patches.  The script will make sure that you don't already
# have a patch before ftping it.
#
# Be careful; there's not much error checking in this script.  Use at
# your own risk, etc.
#
# There are also some limitations, namely in the way $GETLIST is built, but
# it works for most "sane" uses.
#
# You may do with this as you like, but please leave the attribution and
# the instructional comments above in anything you modify or distribute.
#
###############################################################################
# Getpatch v2.21 by Kent Robotti <robotti@godmail.com> (4-24-2004)
#
# This version of getpatch has borrowed considerably from a similar bash 
# script called "getkernel-1.1.1" by Richard Harman Jr.
#
# You need 'wget' and 'bzip2' to use getpatch.
#
# You also need 'finger' to use getpatch with the -k, -p, or -sp options.
#
# You can see the output from 'wget' by pressing: left-[Alt] [F9]
#
# getpatch -p          <Get the patches needed to bring kernel up to date>
# getpatch -sp 2.6.5   <Get patches starting with kernel i specify, this
#                       example would assume you have kernal 2.6.5, and 
#			get patches 2.6.6 etc. if they exist>
# getpatch -k          <Get the complete latest stable kernel source>
# getpatch -sk 2.6.5   <Get the complete kernel source i specify>
# getpatch             <Help!>
##############################################################################

# Configuration is here, you can change some things.

# Get kernel or patches from one of these sites.

PING() {
if [ -x "`type -path ping`" ]; then
if `ping -c 1 ftp.kernel.org >/dev/null 2>&1` ; then
FTP_HOST="ftp://ftp.kernel.org"  
elif `ping -c 1 ftp.ca.kernel.org >/dev/null 2>&1` ; then
FTP_HOST="ftp://ftp.ca.kernel.org"  
else
echo "Can't connect to ftp.kernel.org, try later."
exit
fi
else
FTP_HOST="ftp://ftp.kernel.org"  
fi
}

FTP="wget -bc --dot-style=binary -o /dev/tty9"  # You have to use wget.
FTP_DIR="/pub/linux/kernel"  
FINGER="@zeus-pub.kernel.org"  # Finger here to get latest kernel version.
LOCAL1="/usr/src"              # Put complete kernel here, you can change this.
LOCAL2="/usr/src/kernel-patches"  # Put patches here, you can change this.
				  
# Config ends here.
##############################################################################
##############################################################################

PATH=/bin:/usr/bin:/sbin:/usr/sbin
export PATH

# Usage function show help menu.

usage(){
cat <<EOF
===============================================================================
Getpatch v2.21 (4-24-2004) by Kent Robotti <robotti@godmail.com>  

Getpatch will determine your present kernel source version, and get any 
patches needed to bring it up to date, requires (wget, bzip2, and finger).

You can see the output from \`wget' by pressing: left-[Alt] [F9]

Usage: getpatch -p   <Get patches to bring present kernel source up to date>
       getpatch -sp 2.6.5   <Get patches starting with kernel i specify, this
                             example would assume you have kernel 2.6.5, and
                             get patches 2.6.6 etc. if they exist>
       getpatch -k          <Get the complete latest stable kernel source>
       getpatch -sk 2.6.5   <Get the complete kernel source i specify>
       
Any patches will be put in /usr/src/kernel-patches.
/usr/src/kernel-patches# bzip2 -tv *.bz2   <Test patches then apply> 
/usr/src/linux# scripts/patch-kernel . ../kernel-patches

Any kernels will be put in /usr/src.
/usr/src# bzip2 -tv linux-2.x.x.tar.bz2              <Test for errors>
/usr/src# rm -rf linux                               <Remove old kernel source>
/usr/src# bzip2 -dc linux-2.x.x.tar.bz2 | tar xvf -  <Extract new kernel>
===============================================================================
EOF
}

# Show help menu.

if [ "$1" = "" ]; then
usage
exit 
fi

if [ ! `whoami` = "root" ]; then
echo "[`whoami`] You need to run this script as root."
exit 
fi

# Check system for 'wget' & 'finger' if not found say so and exit.

WGET() {
if [ ! -x "`type -path wget`" ]; then
echo "Can't find 'wget' on your system." 
echo "You need 'wget' to use getpatch."
exit 
fi
}

FINGER() {
if [ ! -x "`type -path finger`" ]; then
echo "Can't find 'finger' on your system."
echo "You need 'finger' to use 'getpatch' with -k, -p, or -sp options."
exit 
fi
}

BZIP2() {
if [ ! -x "`type -path bzip2`" ]; then
echo "Can't find 'bzip2' on your system." 
echo "You need 'bzip2' to use getpatch."
exit 
fi
}

# Create /tmp directory if it doesn't exist.

if [ ! -d /tmp ]; then
mkdir /tmp
chmod 1777 /tmp
fi

# GET function.

GET() {
if [ ! -d $LOCAL2 ]; then
mkdir -p $LOCAL2
fi

# If patch-kernel exists and is not executable, make executable.

if [ -f /usr/src/linux/scripts/patch-kernel ]; then 
if [ ! -x /usr/src/linux/scripts/patch-kernel ]; then 
chmod 755 /usr/src/linux/scripts/patch-kernel    
fi
fi

PING 
WGET
FINGER
BZIP2

# Finger kernel.org to get the latest STABLE version.

FINGERSTRING="`finger $FINGER | grep -i "The latest stable version" | awk '{print $10}'`" 

if ! echo $FINGERSTRING | grep -q $1 2>/dev/null ; then 
FINGERSTRING="`finger $FINGER | grep -i "The latest $1 version" | awk '{print $10}'`" 
fi

# Parse out the version, patch and sublevel.

GOTVERSION="`echo $FINGERSTRING | awk -F'.' '{print $1}'`"
GOTPATCHLEVEL="`echo $FINGERSTRING | awk -F'.' '{print $2}'`"
GOTSUBLEVEL="`echo $FINGERSTRING | awk -F'.' '{print $3}'`"

# Oops! We've already got it!  Kernel is up to date.

if [ "$SUBLEVEL" = "$GOTSUBLEVEL" ]; then
	echo
        echo "The latest ($GOTVERSION.$GOTPATCHLEVEL) kernel is ($GOTVERSION.$GOTPATCHLEVEL.$GOTSUBLEVEL), your kernel is up to date."
	echo
	exit 
fi

# We only need one patch to bring the kernel up to date.

if [ "$[$SUBLEVEL+1]" = "$GOTSUBLEVEL" ]; then
        echo
        echo "The kernel is out of date by ($[$GOTSUBLEVEL-$SUBLEVEL]) patch."
        echo
        echo -n "Do you want to get the patch? (Y/n) : "
        read ans
        if [ "$ans" = "n" -o "$ans" = "N" ]; then
        echo "Cancelled."
        exit 
        fi

	PATCH="patch-$GOTVERSION.$GOTPATCHLEVEL.$GOTSUBLEVEL.bz2"
        echo "$FTP_HOST$FTP_DIR/v$VERSION.$PATCHLEVEL/$PATCH" > /tmp/wget.patch
	echo
	echo "Connecting to: $FTP_HOST"
	echo
	$FTP -P $LOCAL2 -i /tmp/wget.patch || exit
	exit 

else

# We need a couple patches.. Because we've been behind in our ftp'ing.

# Tell user number of patches needed to bring kernel up to date, and give 
# user chance to bail out.

echo
echo "The kernel is out of date by ($[$GOTSUBLEVEL-$SUBLEVEL]) patches."
echo
echo -n "Do you want to get the patches? (Y/n) : "
read ans
if [ "$ans" = "n" -o "$ans" = "N" ]; then
echo "Cancelled."
exit 
fi

# Get patches to bring kernel up to date.

rm -f /tmp/wget.patch
    
export COUNT="$[$SUBLEVEL+1]"
export END="$[$GOTSUBLEVEL+1]"

        while [ "$COUNT" != "$END" ]
	do
		PATCH="patch-$GOTVERSION.$GOTPATCHLEVEL.$COUNT.bz2"
                echo "$FTP_HOST$FTP_DIR/v$VERSION.$PATCHLEVEL/$PATCH" >> /tmp/wget.patch
                export COUNT=$[$COUNT+1]
	done
		echo
        	echo "Connecting to: $FTP_HOST"
		echo
    	        $FTP -P $LOCAL2 -i /tmp/wget.patch || exit 
		exit 
fi
} 

# End of GET function.

# Find out what kernel user has and get any patches to bring it up to date.
# Check for /usr/src/linux/Makefile, if it doesn't exist say so and exit.

if [ "$1" = "-p" ]; then
if [ -f /usr/src/linux/Makefile ]; then
MAKEFILE=/usr/src/linux/Makefile

VERSION="`cat $MAKEFILE | grep "^VERSION = " | awk '{print $3}'`"
PATCHLEVEL="`cat $MAKEFILE | grep "^PATCHLEVEL = " | awk '{print $3}'`"
SUBLEVEL="`cat $MAKEFILE | grep "^SUBLEVEL = " | awk '{print $3}'`"
EXTRAVERSION="`cat $MAKEFILE | grep "^EXTRAVERSION = " | awk '{print $3}'`"

if [ ! "$EXTRAVERSION" = "" ]; then
echo
echo "The current kernel version in /usr/src/linux is: $VERSION.$PATCHLEVEL.$SUBLEVEL $EXTRAVERSION"
echo "That's not an official kernel version. I can't get patches for it."
echo "An official kernel version would be 2.4.17, 2.4.18, etc."
echo
exit
fi

echo
echo "The current kernel version in /usr/src/linux is: $VERSION.$PATCHLEVEL.$SUBLEVEL"
GET $VERSION.$PATCHLEVEL
else
echo
echo "I can't determine your present kernel version, no /usr/src/linux/Makefile."
echo "Your only option is to specify a kernel version: getpatch -sp 2.4.17"
echo "The above example would assume you have kernel 2.4.17 and get patches"
echo "2.4.18 etc. if they exist."
echo
exit 
fi

# Get patches starting with kernel user specifies.

elif [ "$1" = "-sp" -a ! "$2" = "" ]; then
LEVEL=`echo $2 | cut -b7`
if [ ! "$LEVEL" = "" ]; then
echo
echo "That's not an official kernel version \`$2'."
echo "I can't get patches for it."
echo "An official kernel version would be 2.4.17, 2.4.18, etc."
echo
exit
fi
VERSION="`echo $2 | awk -F'.' '{print $1}'`"
PATCHLEVEL="`echo $2 | awk -F'.' '{print $2}'`"
SUBLEVEL="`echo $2 | awk -F'.' '{print $3}'`"
echo
echo "You say you have kernel ($2) i'll get any patches after this version."
GET $VERSION.$PATCHLEVEL

# Find out what the complete latest stable kernel is and get it if user wants.

elif [ "$1" = "-k" ]; then
PING
FINGER
WGET
BZIP2

FINGERSTRING="`finger $FINGER | grep -i "The latest stable version" | awk '{print $10}'`" 
GOTVERSION="`echo $FINGERSTRING | awk -F'.' '{print $1}'`"
GOTPATCHLEVEL="`echo $FINGERSTRING | awk -F'.' '{print $2}'`"
GOTSUBLEVEL="`echo $FINGERSTRING | awk -F'.' '{print $3}'`"

echo
echo "The latest stable kernel is: linux-$GOTVERSION.$GOTPATCHLEVEL.$GOTSUBLEVEL.tar.bz2"
echo
echo -n "Do you want to get? linux-$GOTVERSION.$GOTPATCHLEVEL.$GOTSUBLEVEL.tar.bz2 (Y/n) : "
read ans
if [ "$ans" = "n" -o "$ans" = "N" ]; then
echo "Cancelled."
exit 
else
echo "$FTP_HOST$FTP_DIR/v$GOTVERSION.$GOTPATCHLEVEL/linux-$GOTVERSION.$GOTPATCHLEVEL.$GOTSUBLEVEL.tar.bz2" > /tmp/wget.kernel
echo
echo "Connecting to: $FTP_HOST"
echo
$FTP -P $LOCAL1 -i /tmp/wget.kernel || exit 
fi
exit 

# Get complete kernel user specifies.

elif [ "$1" = "-sk" -a ! "$2" = "" ]; then

LEVEL=`echo $2 | cut -b7`
if [ ! "$LEVEL" = "" ]; then
echo
echo "That's not an official kernel version \`$2'. I can't get it."
echo "An official kernel version would be 2.4.17, 2.4.18, etc."
echo
exit
fi

PING
WGET
BZIP2

VERSION="`echo $2 | awk -F'.' '{print $1}'`"
PATCHLEVEL="`echo $2 | awk -F'.' '{print $2}'`"
SUBLEVEL="`echo $2 | awk -F'.' '{print $3}'`"

echo
echo -n "Do you want to get kernel? linux-$VERSION.$PATCHLEVEL.$SUBLEVEL.tar.bz2 (Y/n) : "
read ans
if [ "$ans" = "n" -o "$ans" = "N" ]; then
echo "Cancelled."
exit 
else
echo "$FTP_HOST$FTP_DIR/v$VERSION.$PATCHLEVEL/linux-$VERSION.$PATCHLEVEL.$SUBLEVEL.tar.bz2" > /tmp/wget.kernel
echo
echo "Connecting to: $FTP_HOST"
echo
$FTP -P $LOCAL1 -i /tmp/wget.kernel || exit 
fi
exit 

# Exit show usage.

else
usage
exit 
fi

