#!/bin/sh
#
# rpmupgrade - upgrade RHS rpms from supplied RPM list(s)
#
# Usage: rpmupgrade NewList [OldList]
#
# Author: Richard A. Brown (rab@mhz.njit.edu)
# Version 1.0 Wed Jun 10 14:14:53 EDT 1998
#
#########################################################################	
# This software is distributed in the hope that it will be useful
# but WITHOUT ANY WARRANTY. The author(s) do not accept responsibility
# to anyone for the consequences of using it or for whether it serves
# any particular purpose or works at all. No warranty is made about
# the software or its performance.
#########################################################################	

#
# Usage/Help Functions:
#

function Usage () {
	echo "Usage: rpmupgrade [options] NewList [OldList]"
	echo "Try \"rpmupgrade -h\" for more information"
#	exit 2
 }

function Help () {
cat <<'EOM'

   rpmupgrade - upgrade installed rpm files from supplied list(s)

   Usage:

	rpmupgrade [options] NewList [OldList] 

   Synopsis:
	
	This script does a semi-automatic upgrade of all packages supplied
	in the file NewList. This file is a list of all available
	packages.  For FTP upgrades, the easiest way to generate this
	file is to redirect the output of the "ls" command to a file. For
	example, using NcFtp, the command "ls > new.lst" would list all
	the files in the current remote directory into the file called
	"new.lst". The file should contain one RPM file per line.

	The list of packages to upgrade is contained in the file OldList.
	If this file is not supplied, it will be generated by rpmupgrade;
	however, it is often useful to generate the list manually
	(using "rpm -qa > old.lst") to remove certain packages, such as
	the kernel and include files.

	The source for the new RPM files may be set absolutely (using the
	-s option), or constructed from a specified (or default) source
	root path (using the -r option), which then assumes the 'standard'
	RedHat directory structure.  If the '-u' option is given, then
	the source path is constructed by appending "/updates/i386" to the
	source root path; otherwise, "/i386/RedHat/RPMS" is appended.

   Options:

	-r	Set source root for package files
		[ftp://sunsite.unc.edu/pub/Linux/distributions/redhat/redhat-5.1]
	-u	Use RedHat updated RPMS
	-s	Set absolute source for package files (i.e., override above)
	-q	quiet mode
	-n	Ignore RPM dependencies
	-v	verbose mode
	-h	this message

   Files

   	Packages which were not upgraded are written to the file
	"notupgraded.txt". This may be used as input to rpmupgrade.

	Errors are written to "rpmupgrade.errs" as well as to stderr.

   Bugs

	rpmupgrade isn't smart.
	The verbose and quiet options don't do much ;-0

   Author:
	
	Richard A. Brown (rab@mhz.njit.edu)
EOM
	exit 0
}

#
# Defaults: change RootDefault as needed.
#

NoDeps=0
#RootDefault=ftp://sunsite.unc.edu/pub/Linux/distributions/redhat/redhat-5.1
RootDefault=ftp://ftp-nog.rutgers.edu/pub/linux/distributions/redhat/redhat-5.1

#
# Handle command line options:
#

set -- `getopt hvquns:r: $*`
if test $? != 0
then
	Usage
	exit 2
fi
for i; do
	case "$i"
	in
		-h)
			Help; shift;;
		-v)
			verbose=1; shift;;
		-q)
			quiet=1; shift;;
		-u)
			UseUpdates=1; shift;;
		-n)
			NoDeps=1; shift;;
		-s)
			source=$2; shift; shift;;
		-r)
			root=$2; shift; shift;;
		-o)
			oflag=1; output=$2; shift; shift;;
		--)
			shift; break;;
	esac
done

#
# Construct source path for RPMs:
#

if test $source"x" = "x" ; then

	if test $root"x" = "x" ; then
		root=$RootDefault
	fi

	if test $UseUpdates ; then
		source=$root"/updates/i386"
	else
		source=$root"/i386/RedHat/RPMS"
	fi

fi

	if test $verbose; then
		echo "source: \"$source\""
	fi

#
# Sanity check:
#

if test $# -eq 1; then
	GenOld=1
	OldList=/tmp/rpmupgrade.old.tmp
	rpm -qa > $OldList
	# rpm -qa --queryformat '%-30{NAME} %{NAME}-%{VERSION}-%{RELEASE}\n' > $OldList
elif test $# -eq 2 ; then
	OldList=$2
else
	Usage
	exit 2
fi

#
# Do the work:
#

# First: for efficiency, make new file from new package list, containing
# package name and then package file name:

awk -F- '{
	pkg=$1
	for (i=2 ; i < NF-1 ; i++)
		pkg=pkg"-"$i
	print pkg, $0
}' $1 > /tmp/rpmupgrade.new.tmp

# Now, open old file and make package name, look up new version, and
# process it:

awk '{
	# Construct package name:
	old=$1
	n=split($1, a, "-")
	pkg=a[1]
	for (i=2 ; i < n-1 ; i++)
		pkg=pkg"-"a[i]
	#print "Searching for ", pkg

	# Now search for package in new list:
	do {
		status = getline < "/tmp/rpmupgrade.new.tmp"
	} while ( status > 0 && $1 != pkg )
	close("/tmp/rpmupgrade.new.tmp")

	if( status <= 0 ) {
		printf "WARNING: no new package found for %s.\n", pkg > "/dev/stderr"
		printf "WARNING: no new package found for %s.\n", pkg >> "rpmupgrade.errs"
		print old >> "notupgraded.txt"
	} else {
		new=$2
		#print pkg, old, new
		#print old, new

		if( old == substr(new, 1, length(old)))
			printf "Package %s already installed.\n", old > "/dev/stderr"
		else {
			if( NoDeps == 1 )
				syscmd=sprintf("rpm -Uv --nodeps %s/%s", source, new)
			else
				syscmd=sprintf("rpm -Uv %s/%s", source, new)
			if( verbose ) print syscmd
			printf "%s:\n", pkg
			status = system(syscmd)
			if( status != 0 )
				print old >> "notupgraded.txt"
		}
	}

}' source=$source NoDeps=$NoDeps $OldList

# Clean up:

/bin/rm -f /tmp/rpmupgrade.new.tmp /tmp/rpmupgrade.old.tmp

# fin
