#!/bin/bash
#############################################################
# Name:        Supportutils Auto Update Client
# Description: Automatically updates the suppportutils package
#              and all supporting supportutils plugins.
# License:     GPLv2
# Authors/Contributors:
#              Jason Record (jrecord@suse.com)
# Modified:    2013 May 20
#############################################################
SVER="1.0.8"

title() {
	echo "################################################################"
	echo "# Supportutils Auto Update Client v${SVER}"
	echo "################################################################"
	echo
}

show_help() {
	echo "Usage: $BASENAME [OPTION]"
	echo
	echo "Description"
	echo "  Makes sure the supportutils and supportutils plugin packages are"
	echo "  installed and current."
	echo
	echo "Options"
	echo " -m  Install a monthly cron for updateSupportutils"
	echo " -w  Install a weekly cron for updateSupportutils"
	echo " -d  Delete all installed cron entries for updateSupportutils"
	echo " -l  List all cron entries for updateSupportutils"
	echo " -u  Force RPM update on applicable packages"
	echo " -p  Exclude supportutils plugin packages"
	echo " -v  Verbose mode"
	echo " -h  This screen"
	echo
}

runAsRoot() {
	if [ "$UID" -ne "0" ]; then
		echo "ERROR: Permisison denied for $USER ($UID)"
		echo "Run as root"
		echo
		show_help
		echo
		exit 1
	fi
}

removeOldPackages() {
	[ $DEBUG -gt 0 ] && { echo; echo ">>removeOldPackages() Removing older supportconfig packages"; }
	rpm -e ntsutils &>/dev/null
}

getUpdatedRpms() {
	printf $PFORMAT "Connecting to Update Server ... "
	UPDATED_LIST=${FILEDIR}/list.html
	if [ -x /usr/bin/wget ]; then
		if wget -q --output-document $UPDATED_LIST $SRCURL &>/dev/null; then
			if (( $NO_PLUGINS )); then
				UPDATED_RPMS=$(egrep "href.*supportutils-[[:digit:]].*rpm|href.*supportutils-plugin-updater.*rpm" $UPDATED_LIST | awk -F\" '{print $6}')
			else
				UPDATED_RPMS=$(grep "href.*supportutils.*rpm" $UPDATED_LIST | awk -F\" '{print $6}')
			fi
			echo Done
		else
			echo ERROR
			echo "wget: Cannot connect to update server"
			echo
			exit 2
		fi
	elif [ -x /usr/bin/curl ]; then
		if curl -Lso $UPDATED_LIST $SRCURL &>/dev/null; then
			if (( $NO_PLUGINS )); then
				UPDATED_RPMS=$(egrep "href.*supportutils-[[:digit:]].*rpm|href.*supportutils-plugin-updater.*rpm" $UPDATED_LIST | awk -F\" '{print $6}')
			else
				UPDATED_RPMS=$(grep "href.*supportutils.*rpm" $UPDATED_LIST | awk -F\" '{print $6}')
			fi
			echo Done
		else
			echo ERROR
			echo "curl: Cannot connect to update server"
			echo
			exit 2
		fi
	else
		echo "ERROR: Missing wget and curl"
		exit 3
	fi
}

compareVersions() {
	RC=0
	IVER=$1
	UVER=$2
	[ $DEBUG -gt 0 ] && echo " >>compareVersions() Comparing '$IVER' to '$UVER'"
	IARRAY=($(echo $IVER | sed -e 's/-/\./g;s/\./ /g'))
	UARRAY=($(echo $UVER | sed -e 's/-/\./g;s/\./ /g'))
	if [ $UPDATE -gt 0 ]; then # -u was invoked
		RC=1
	elif [ ${#UARRAY[@]} -gt ${#IARRAY[@]} ]; then # The updated version is longer than the installed version, assume update is needed
		RC=1
	else
		if [ ${#IARRAY[@]} -lt ${#UARRAY[@]} ]; then # Use the smaller of the two arrays
			LOOPARRAY=($(echo $IVER | sed -e 's/-/\./g;s/\./ /g'))
		else
			LOOPARRAY=($(echo $UVER | sed -e 's/-/\./g;s/\./ /g'))
		fi
		for (( I=0 ; I < ${#LOOPARRAY[@]} ; I++ ))
		do
			[ $DEBUG -gt 0 ] && echo " >>compareVersions() '${UARRAY[$I]}' gt? '${IARRAY[$I]}'"
			if echo ${IARRAY[$I]} | grep '[[:alpha:]]' &>/dev/null; then
				if [ "${UARRACY[$I]}" != "${IARRAY[$I]}" ]; then
					RC=1
					break
				fi
			elif echo ${UARRAY[$I]} | grep '[[:alpha:]]' &>/dev/null; then
				if [ "${UARRACY[$I]}" != "${IARRAY[$I]}" ]; then
					RC=1
					break
				fi
			elif [ ${UARRAY[$I]} -gt ${IARRAY[$I]} ]; then
				RC=1
				break
			fi
		done
	fi
	return $RC
}

pluginRequired() {
	RPM=$1 # The current available plugin
	[ $DEBUG -gt 0 ] && echo " >>pluginRequired() Determining if $RPM is needed"
	if [ "$RPM" = "supportutils" ]; then
		return 0 # always required
	elif [ "$RPM" = "supportutils-plugin-updater" ]; then
		return 0 # always required
	elif [ "$RPM" = "supportutils-plugin-hae" ]; then
		if rpm -q openais &>/dev/null; then return 0; else return 1; fi
	elif [ "$RPM" = "supportutils-plugin-idm" ]; then
		if rpm -q novell-idm &>/dev/null; then return 0; else return 1; fi # needs updating when/if available
	elif [ "$RPM" = "supportutils-plugin-groupwise" ]; then
		if rpm -qa | grep -i groupwise &>/dev/null; then return 0; else return 1; fi
	elif [ "$RPM" = "supportutils-plugin-iprint" ]; then
		if rpm -q novell-iprint-server &>/dev/null; then return 0; else return 1; fi
	elif [ "$RPM" = "supportutils-plugin-nowsbe" ]; then
		if rpm -q NOWS-copyMedia &>/dev/null; then return 0; else return 1; fi
	elif [ "$RPM" = "supportutils-plugin-ncs" ]; then
		if rpm -q novell-cluster-services &>/dev/null; then return 0; else return 1; fi
	elif [ "$RPM" = "supportutils-plugin-sentinel" ]; then
		if rpm -q novell-Sentineljre &>/dev/null; then return 0; else return 1; fi
	elif [ "$RPM" = "supportutils-plugin-slepos" ]; then
		if rpm -q slepos-release &>/dev/null; then return 0; else return 1; fi
	elif [ "$RPM" = "supportutils-plugin-susecloud" ]; then
		if rpm -q suse-cloud-release &>/dev/null; then return 0; else return 1; fi
	elif [ "$RPM" = "supportutils-plugin-susestudio" ]; then
		if rpm -q susestudio &>/dev/null; then return 0; else return 1; fi
	else
		return 1 # New plugins are automatically excluded since we currently don't know if they are required
	fi
}

downLoad() {
	PACKAGE=$1
	RETRIES="--tries=5 --waitretry=5"
	RCODE=0
	[ $DEBUG -gt 0 ] && echo " >>downLoad() Downloading $PACKAGE"
	cd $FILEDIR
	if [ $DEBUG -gt 0 ]; then
		if [ -x /usr/bin/wget ]; then
			/usr/bin/wget -Sv $RETRIES ${SRCURL}/$PACKAGE
			RCODE=$?
			echo
		elif [ -x /usr/bin/curl ]; then
			/usr/bin/curl -vL -o $PACKAGE ${SRCURL}/$PACKAGE
			RCODE=$?
			echo
		else
			echo "Download Failed: Missing wget and curl"
			RCODE=255
			echo
		fi
	else
		if [ -x /usr/bin/wget ]; then
			wget -q $RETRIES ${SRCURL}/$PACKAGE &>/dev/null
			RCODE=$?
		elif [ -x /usr/bin/curl ]; then
			/usr/bin/curl -sL -o $PACKAGE ${SRCURL}/$PACKAGE
			RCODE=$?
		else
			echo "Download Failed: Missing wget and curl"
			RCODE=255
		fi
	fi
	return $RCODE
}

upDate() {
	PACKAGE=$1
	[ $DEBUG -gt 0 ] && echo " >>upDate() Updating to $PACKAGE"
	[ $DEBUG -gt 0 ] && rpm -Uvh --force ${FILEDIR}/$PACKAGE || rpm -U --force ${FILEDIR}/$PACKAGE &>/dev/null
	return 0
}

updateSupportutils() {
	for PACKAGE in $UPDATED_RPMS
	do
		if echo $PACKAGE | grep plugin &>/dev/null; then
			RPM=$(echo $PACKAGE | sed -e 's/\(supportutils-plugin-[[:alpha:]]*\)-.*rpm/\1/g')
		else
			RPM='supportutils'
		fi
		UPDATED_VER=$(echo $PACKAGE | sed -e "s/$RPM-//g;s/\.noarch\.rpm//g")
		[ $DEBUG -gt 0 ] && 	{ echo; echo "################################################################"; }
		printf $PFORMAT "Evaluating $RPM ... "
		INSTALLED_VER=$(rpm -q --queryformat "%{VERSION}-%{RELEASE}" $RPM)
		if echo $INSTALLED_VER | grep -i package &>/dev/null; then
			if pluginRequired $RPM; then
				echo Installing
				if downLoad $PACKAGE; then
					upDate $PACKAGE
				else
					echo " - Retry Later"
				fi
			else
				echo Unused
			fi
		else
			compareVersions $INSTALLED_VER $UPDATED_VER 
			RESULT=$?
			if [ $RESULT -gt 0 ]; then
				echo "Updating to $UPDATED_VER"
				if downLoad $PACKAGE; then
					upDate $PACKAGE
				else
					echo " - Retry Later"
				fi
			else
				echo Unchanged
			fi
		fi
	done
}

cronInstallMonthly() {
	printf $PFORMAT "Installing Monthly Update Cron ... "
	if [ -d /etc/cron.monthly ]; then
		cd /etc/cron.monthly
		ln -sf /sbin/updateSupportutils
		echo Done
		echo
		exit 0
	else
		echo Error
		echo
		exit 3
	fi
}

cronInstallWeekly() {
	printf $PFORMAT "Installing Weekly Update Cron ... "
	if [ -d /etc/cron.weekly ]; then
		cd /etc/cron.weekly
		ln -sf /sbin/updateSupportutils
		echo Done
		echo
		exit 0
	else
		echo Error
		echo
		exit 3
	fi
}

cronDeleteAll() {
	printf $PFORMAT "Deleting Update Cron Entries ... "
	for i in weekly monthly
	do
		rm -f /etc/cron.${i}/$BASENAME
	done
	echo Done
	echo
	exit 0
}

cronList() {
	echo "Installed Cron Entries"
	COUNT=0
	for i in weekly monthly
	do
		FILE="/etc/cron.${i}/$BASENAME"
		if [ -e $FILE ]; then
			ls -l $FILE
			((COUNT++))
		fi
	done
	if ! (( COUNT )); then
		echo None
	fi
	echo
	exit 0
}

cleanUp() {
	rm -rf $FILEDIR
}

#############################################################
# GLOBAL VARIABLES
#############################################################
BASENAME=$(basename $0)
FILEDIR=$(mktemp -d /tmp/${BASENAME}-XXXXXXXXXXXXXXX)
UPDATED_RPMS=''
DEBUG=0 # 0 off, 1 on
UPDATE=0
NO_PLUGINS=0

#############################################################
# MAIN
#############################################################
clear
title
while getopts :hvmwdlup TMPOPT
do
	case $TMPOPT in
	\:)	case $OPTARG in
			*) echo "ERROR: Missing Argument -$OPTARG"
				;;
			esac
			echo; show_help; exit 1 ;;
	\?)	case $OPTARG in
			*) echo "ERROR: Invalid Option -$OPTARG"
				;;
			esac
			echo; show_help; exit 2 ;;
	h) show_help; exit 0 ;;
	v) DEBUG=1 ;;
	m) cronInstallMonthly ;;
	w) cronInstallWeekly ;;
	d) cronDeleteAll ;;
	p) NO_PLUGINS=1 ;;
	u) UPDATE=1 ;;
	l) cronList ;;
	esac
done
[ $DEBUG -gt 0 ] && PFORMAT="\n%-55s\n" || PFORMAT="%-55s"
VER=$(grep -i "suse linux enterprise" /etc/SuSE-release | awk '{print $5}')
case $VER in
"11") SRCURL='http://download.opensuse.org/repositories/Novell:/NTS/SLE_11_SP2/noarch/' ;;
*) SRCURL='http://download.opensuse.org/repositories/Novell:/NTS/SLE_10/noarch/' ;;
esac

runAsRoot
echo "Update Server: $SRCURL"; echo
getUpdatedRpms
removeOldPackages
updateSupportutils
cleanUp
echo

