#!/bin/bash
#
# DESCRIPTION
#
#	This is a script to automate the switch from r8169 to r8168.
#
# AUTHORSHIP
# 	Jameson Williams
# 	www.jamesonwilliams.com
#
# CHANGELOG
#
# 	May 16, 2008: Corrected a typo on line 43 which prevented the r8169
#		module from being renamed. Thanks to linuxnotes.blogspot.com
#		for spotting it.
#
#	Jun 1, 2008: Added a bunch of checks to beef up the script a bit.
#		Removed all reliance upon the internet, as it is more than
#		likely the case that this script is being run without
#		connectivity. Added better output in case of failures.
#
#	Jun 2, 2008: Simplified many of the if statements to simpler checks.
#		Added a few more, and created the die() function.
#
#	Jun 4, 2008: Moved the stuff to removfe r8169 to the beginning.	This
#		makes the depmod command behave correctly, finally! Also fixed
#		the insmod check so that it no longer incorrectly dies. (Good
#		news!) Updated the die command to delete rogue $TMP folders in
#		case the script dies before completion. Also added more output
#		to help with debugging.
#
#	Aug 13, 2008: Updated the code to work with version 8.008.00 of the
#		Realtek driver. The new code no longer needs to be patched,
#		which was sort of the *magic* of the previous versions of this
#		script. Still a useful quick-fix script, though.
#
#   Nov 7, 2008: Updated package for 8.009.00
#
#   Aug 17, 2009: Updated package for 8.013.00, added a .ko, etc.
#
#   Oct 18, 2009: Updated package for 8.0.14.00, including a patch for
#       kernels >= 2.6.31.
#
VERSION=r8168-8.014.00


# setup a temporary directory, and save some environmental infos
PREVWD=$(pwd)
RUNPATH=$(dirname $0)
TMP=$(mktemp -d)
MODULEPATH=/lib/modules/`uname -r`/kernel/drivers/net
PATCHFILE='rtl8168_v14_net_device_ops.patch'

function die {
	# $1 is an error message to print to stderr.
	echo $1 1>&2;
	if [[ -d $TMP ]]; then
		rm -rf $TMP
	fi
	if [[ -f $MODULEPATH/r8169.ko.bak ]] && \
		[[ ! -f $MODULEPATH/r8169.ko ]] && \
			[[ $(id -u) -eq 0 ]]; then
		cp $MODULEPATH/r8169.ko.bak $MODULEPATH/r8169.ko
	fi
	exit 1
}

# check to make sure that this is running as root!
[[ $(id -u) -eq 0 ]] || die "You must run this script as root."

echo "Attempting to remove running r8168 and r8169 modules if loaded..."
[[ $(lsmod | grep -c r8169) -eq 0 ]] || rmmod r8169
[[ $(lsmod | grep -c r8168) -eq 0 ]] || rmmod r8168

echo "Attempting to move $MODULEPATH/r8169.ko to $MODULEPATH/r8169.ko.bak."
[[ ! -f $MODULEPATH/r8169.ko ]] || \
	mv $MODULEPATH/r8169.ko $MODULEPATH/r8169.ko.bak

echo "Blacklisting r8169 in /etc/modprobe.d/blacklist..."
if [[ $(grep -c "blacklist r8169" /etc/modprobe.d/blacklist) -lt 1 ]]; then
	echo -e "\nblacklist r8169\n" >> /etc/modprobe.d/blacklist
fi

DRVFILE=${VERSION}.tar.bz2

echo "Creating a tmp dir in which to build the module..."
cp "$RUNPATH"/"$DRVFILE" $TMP
cd $TMP
tar xjf "$DRVFILE"
cd ./${VERSION}/src

echo -n "Checking for gcc and linux-headers-$(uname -r)..."
[[ $(dpkg -l | grep -c linux-headers-$(uname -r )) -gt 0 ]] || \
	die "You need to install package linux-headers-$(uname -r )."

[[ $(dpkg -l | grep -c gcc) -gt 0 ]] || \
	die "You need to install the GNU C Compiler."
echo -e "\tOK"

echo -n "Attempting to build the module..."
{
    patch < $PREVWD/$PATCHFILE
	cd ..
	make clean
	make modules
	make install  # this copies the module to the appropriate /lib/modules
		      # dir.
}  &>/dev/null

[[ -f ./src/r8168.ko ]] || die "Could not build module."
echo -e "\tOK"

# Let the OS know about the new module
depmod				#update the modules.dep file

echo -n "Inserting the module into running kernel code..."
insmod ./src/r8168.ko
[[ $? ]] || die "Failed to insert module."
echo -e "\tOK"

echo -n "Attempting to rebuild the initrd to include r8168 at boot..."
mv /boot/initrd.img-`uname -r` /boot/initrd.img-`uname -r`.bak
mkinitramfs -o /boot/initrd.img-$(uname -r) $(uname -r)
[[ $? ]] || die "Could not build initrd!"
echo -e "\tOK"

# remove tmp dir and go back home
cd $PREVWD
rm -r $TMP

echo -n "All done! You should now have a "
echo "working wired ethernet connection, persistant at boot."

exit 0

