#!/bin/sh
# Copyright 1999  Patrick Volkerding, Moorhead, Minnesota USA 
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

usage() {
 cat << EOF

Usage: upgradepkg newpackage [newpackage2 ... ]
       upgradepkg oldpackage%newpackage [oldpackage2%newpackage2 ... ]

Upgradepkg upgrades a Slackware .tgz package from an older version to a
newer one.  It does this by INSTALLING the new package onto the system, and
then REMOVING any files from the old package that aren't in the new package.
If the old and new packages have the same name, a single argument is all that
is required.  If the packages have different names, supply the name of the
old package followed by a percent symbol (%), then the name of the new package.
Do not add any extra whitespace between pairs of old/new package names.

Before upgrading a package, save any configuration files (such as in /etc)
that you wish to keep.  Sometimes these will be preserved, but it depends on
the package structure.  If you want to force new versions of the config files
to be installed, remove the old ones manually prior to running upgradepkg.

To upgrade in a directory other than / (such as /mnt):  

   ROOT=/mnt upgradepkg package.tgz

EOF
}

# Make sure there's a proper temp directory:
TMP=/var/log/setup/tmp
# If the $TMP directory doesn't exist, create it:
if [ ! -d $TMP ]; then
  rm -rf $TMP # make sure it's not a symlink or something stupid
  mkdir $TMP
  chmod 700 $TMP # no need to leave it open
fi

# $ROOT defined?
if [ -d "$ROOT" ]; then
  export ROOT
fi

# --help or no args?
if [ "$1" = "" -o "$1" = "--help" -o "$1" = "-?" ]; then
  usage;
  exit 1;
fi

# Main processing loop:
while [ ! "$1" = "" ]; do

# Figure out the names of the old and new packages:
OLD=`echo $1 | cut -f 1 -d '%'`
NEW=`echo $1 | cut -f 2 -d '%'`
INCOMINGDIR=`dirname $NEW`
OLD=`basename $OLD .tgz`
NEW=`basename $NEW .tgz`

# Test to see if both the old and new packages are where we expect them
# to be -- skip to the next package (or package pair) if anything's wrong:

if [ ! -r $ROOT/var/log/packages/$OLD ]; then
  echo
  echo "Error:  there is no installed package named $OLD."
  echo "        (looking for $ROOT/var/log/packages/$OLD)"
  echo
  shift 1
  continue;
elif [ ! -r "$INCOMINGDIR/$NEW.tgz" ]; then
  echo
  echo "Error:  incoming package $INCOMINGDIR/$NEW.tgz not found."
  echo
  shift 1
  continue;
fi

# Showtime.  Let's do the upgrade.  First, we will backup the database info
# for the package we will be removing, stamping it so that the date/time of
# the upgrade, list of files, and installation script will all be easy to find
# in /var/log/removed_packages and /var/log/removed_scripts when the upgrade
# is complete.  These copies have to be kept out of the way during the package
# install, so that symlinks are treated correctly.

TIMESTAMP=`date +%Y-%m-%d,%T`
( cd $ROOT/var/log/packages ; cp -a $OLD $TMP/$OLD-upgraded-$TIMESTAMP )
( cd $ROOT/var/log/scripts
  if [ -r $OLD ]; then
    cp -a $OLD $TMP/$OLD-script-upgraded-$TIMESTAMP
  fi )

# Print a banner for the current upgrade:
cat << EOF

*************************************************************
*   Upgrading $OLD package using $INCOMINGDIR/$NEW.tgz
*************************************************************

EOF

# Next, the new package is installed:

installpkg $INCOMINGDIR/$NEW.tgz

# Since new libraries may have gone in, it doesn't hurt to do an ldconfig
# at this point:

ldconfig

# Then, the leftovers from the old package can go.  Pretty simple, huh? :)

# Remove redundant entries in the package database:
if [ ! "$OLD" = "$NEW" ]; then
  rm -f $ROOT/var/log/packages/$OLD
  rm -f $ROOT/var/log/scripts/$OLD
fi

# The package info we've stored in $TMP needs to go back into the database
# directories before the leftover removal can proceed:
if [ -f $TMP/$OLD-upgraded-$TIMESTAMP ]; then
  mv $TMP/$OLD-upgraded-$TIMESTAMP $ROOT/var/log/packages/$OLD-upgraded-$TIMESTAMP
fi
if [ -f $TMP/$OLD-script-upgraded-$TIMESTAMP ]; then
  mv $TMP/$OLD-script-upgraded-$TIMESTAMP $ROOT/var/log/scripts/$OLD-upgraded-$TIMESTAMP
fi

# Now remove the package using the entries we just installed:
if [ -d "$ROOT" ]; then
  chroot $ROOT removepkg $OLD-upgraded-$TIMESTAMP
else
  removepkg $OLD-upgraded-$TIMESTAMP
fi

# Again!  Again!

ldconfig

echo
echo "Package $OLD upgraded with new package $INCOMINGDIR/$NEW.tgz."
echo

# Process next parameter:
shift 1

done
