mirror of
git://slackware.nl/current.git
synced 2024-12-30 10:24:23 +01:00
b76270bf9e
Wed May 19 08:58:23 UTC 2010 Slackware 13.1 x86_64 stable is released! Lots of thanks are due -- see the RELEASE_NOTES and the rest of the ChangeLog for credits. The ISOs are on their way to replication, a 6 CD-ROM 32-bit set and a dual-sided 32-bit/64-bit x86/x86_64 DVD. We are taking pre-orders now at store.slackware.com, and offering a discount if you sign up for a subscription. Consider picking up a copy to help support the project. Thanks again to the Slackware community for testing, contributing, and generally holding us to a high level of quality. :-) Enjoy!
387 lines
12 KiB
Bash
387 lines
12 KiB
Bash
#!/bin/sh
|
|
# Copyright 1999 Patrick Volkerding, Moorhead, Minnesota, USA
|
|
# Copyright 2001, 2002, 2003 Slackware Linux, Inc., Concord, California, USA
|
|
# Copyright 2009 Patrick J. Volkerding, Sebeka, MN, 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.
|
|
#
|
|
# Modified to handle either old 8.3 or new package-version-arch-build.tgz
|
|
# packages, Sat Nov 17 14:25:58 PST 2001 volkerdi
|
|
#
|
|
# Rewritten to clean out _all_ old packages of a given basename, not just
|
|
# the first one found, Thu Apr 4 01:01:05 PST 2002 volkerdi
|
|
#
|
|
# Added --install-new and --reinstall, Fri May 31 14:11:14 PDT 2002 volkerdi
|
|
# Added --dry-run, Sat Apr 26 18:13:29 PDT 2003
|
|
#
|
|
# Sat Apr 25 21:18:53 UTC 2009
|
|
# Support new compression types and package extensions.
|
|
# Converted to use new pkgbase() function to remove pathname and
|
|
# valid package extensions.
|
|
|
|
# Return a package name that has been stripped of the dirname portion
|
|
# and any of the valid extensions (only):
|
|
pkgbase() {
|
|
PKGEXT=$(echo $1 | rev | cut -f 1 -d . | rev)
|
|
case $PKGEXT in
|
|
'tgz' )
|
|
PKGRETURN=$(basename $1 .tgz)
|
|
;;
|
|
'tbz' )
|
|
PKGRETURN=$(basename $1 .tbz)
|
|
;;
|
|
'tlz' )
|
|
PKGRETURN=$(basename $1 .tlz)
|
|
;;
|
|
'txz' )
|
|
PKGRETURN=$(basename $1 .txz)
|
|
;;
|
|
*)
|
|
PKGRETURN=$(basename $1)
|
|
;;
|
|
esac
|
|
echo $PKGRETURN
|
|
}
|
|
|
|
usage() {
|
|
cat << EOF
|
|
|
|
Usage: upgradepkg newpackage [newpackage2 ... ]
|
|
upgradepkg oldpackage%newpackage [oldpackage2%newpackage2 ... ]
|
|
|
|
Upgradepkg upgrades a Slackware package (.tgz, .tbz, .tlz, .txz) 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. 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 (or .tbz, .tlz, .txz)
|
|
|
|
EOF
|
|
}
|
|
|
|
# Make sure there's a proper temp directory:
|
|
TMP=$ROOT/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
|
|
|
|
# This script expects an 022 umask:
|
|
umask 022
|
|
|
|
# $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
|
|
|
|
# Arg processing loop. These must come before any packages are listed.
|
|
while [ 0 ]; do
|
|
if [ "$1" = "--no-paranoia" ]; then
|
|
# Enable --no-paranoia mode. This is so not-recommended that we're
|
|
# not even going to document it. ;) If a file used to be directly
|
|
# managed and now is moved into place, using --no-paranoia will cause
|
|
# it to improperly disappear. It does slightly speed things up, though.
|
|
# Don't use it.
|
|
NOT_PARANOID="true"
|
|
shift 1
|
|
elif [ "$1" = "--install-new" ]; then
|
|
# Install packages that do not already have an installed version.
|
|
# The usual default is to skip them.
|
|
INSTALL_NEW="yes"
|
|
shift 1
|
|
elif [ "$1" = "--reinstall" ]; then
|
|
# Reinstall packages even if the installed one is the same version.
|
|
REINSTALL="true"
|
|
shift 1
|
|
elif [ "$1" = "--verbose" -o "$1" = "-v" ]; then
|
|
# We're adding a --verbose mode that doesn't filter removepkg as much
|
|
VERBOSE="verbose"
|
|
shift 1
|
|
elif [ "$1" = "--dry-run" ]; then
|
|
# Output a report about which packages would be installed or upgraded
|
|
# but don't actually perform the upgrades.
|
|
DRY_RUN="true"
|
|
shift 1
|
|
else # no more args
|
|
break;
|
|
fi
|
|
done # processing args
|
|
|
|
# Here's a function to figure out the package name from one of those
|
|
# new long filenames. We'll need this to double check the name of the
|
|
# old package.
|
|
|
|
package_name() {
|
|
STRING=$(pkgbase $1)
|
|
# Check for old style package name with one segment:
|
|
if [ "$(echo $STRING | cut -f 1 -d -)" = "$(echo $STRING | cut -f 2 -d -)" ]; then
|
|
echo $STRING
|
|
else # has more than one dash delimited segment
|
|
# Count number of segments:
|
|
INDEX=1
|
|
while [ ! "$(echo $STRING | cut -f $INDEX -d -)" = "" ]; do
|
|
INDEX=$(expr $INDEX + 1)
|
|
done
|
|
INDEX=$(expr $INDEX - 1) # don't include the null value
|
|
# If we don't have four segments, return the old-style (or out of spec) package name:
|
|
if [ "$INDEX" = "2" -o "$INDEX" = "3" ]; then
|
|
echo $STRING
|
|
else # we have four or more segments, so we'll consider this a new-style name:
|
|
NAME=$(expr $INDEX - 3)
|
|
NAME="$(echo $STRING | cut -f 1-$NAME -d -)"
|
|
echo $NAME
|
|
# cruft for later ;)
|
|
#VER=$(expr $INDEX - 2)
|
|
#VER="$(echo $STRING | cut -f $VER -d -)"
|
|
#ARCH=$(expr $INDEX - 1)
|
|
#ARCH="$(echo $STRING | cut -f $ARCH -d -)"
|
|
#BUILD="$(echo $STRING | cut -f $INDEX -d -)"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
ERRCODE=0
|
|
|
|
# Main processing loop:
|
|
while [ ! "$1" = "" ]; do
|
|
|
|
# Simple package integrity check:
|
|
if [ ! -f $(echo $1 | cut -f 2 -d '%') ]; then
|
|
ERRCODE=4
|
|
echo "Cannot install $1: file not found"
|
|
shift 1
|
|
continue;
|
|
fi
|
|
|
|
# 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)
|
|
# These are the package names with the extension:
|
|
NNAME=$(basename $NEW)
|
|
ONAME=$(basename $OLD)
|
|
# These are the package names without the extension:
|
|
OLD=$(pkgbase $OLD)
|
|
NEW=$(pkgbase $NEW)
|
|
|
|
# Make sure the extension is valid:
|
|
if [ "$NNAME" = "$NEW" ]; then
|
|
# We won't throw an ERRCODE for this, but the package is skipped:
|
|
echo "Cannot install $1: invalid package extension"
|
|
shift 1
|
|
continue;
|
|
fi
|
|
|
|
# Check and fix the old package name:
|
|
SHORT="$(package_name $OLD)"
|
|
if [ ! -r $ROOT/var/log/packages/$OLD ]; then
|
|
if ls $ROOT/var/log/packages/$SHORT* 1> /dev/null 2> /dev/null ; then
|
|
for installed_package in $ROOT/var/log/packages/$SHORT* ; do
|
|
if [ "$(package_name $installed_package)" = "$SHORT" ]; then # found one
|
|
OLD="$(basename $installed_package)"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
fi
|
|
|
|
# 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
|
|
if [ ! "$INSTALL_NEW" = "yes" ]; then
|
|
if [ "$DRY_RUN" = "true" ]; then
|
|
echo "$OLD would not be upgraded (no installed package named $SHORT)."
|
|
else
|
|
echo
|
|
echo "Error: there is no installed package named $OLD."
|
|
echo " (looking for $ROOT/var/log/packages/$OLD)"
|
|
echo
|
|
fi
|
|
ERRCODE=1
|
|
else # --install-new was given, so install the new package:
|
|
if [ "$DRY_RUN" = "true" ]; then
|
|
echo "$NEW would be installed (new package)."
|
|
else
|
|
cat << EOF
|
|
|
|
+==============================================================================
|
|
| Installing new package $INCOMINGDIR/$NNAME
|
|
+==============================================================================
|
|
|
|
EOF
|
|
/sbin/installpkg $INCOMINGDIR/$NNAME
|
|
fi
|
|
fi
|
|
shift 1
|
|
continue;
|
|
elif [ ! -r "$INCOMINGDIR/$NNAME" ]; then
|
|
if [ "$DRY_RUN" = "true" ]; then
|
|
echo "$NEW incoming package not found (command line)."
|
|
else
|
|
echo
|
|
echo "Error: incoming package $INCOMINGDIR/$NNAME not found."
|
|
echo
|
|
fi
|
|
shift 1
|
|
ERRCODE=1
|
|
continue;
|
|
fi
|
|
|
|
# Unless --reinstall was given, compare the package names
|
|
# and skip any exact matches:
|
|
if [ ! "$REINSTALL" = "true" ]; then
|
|
if [ "$OLD" = "$NEW" ]; then
|
|
if [ "$DRY_RUN" = "true" ]; then
|
|
echo "$NEW would be skipped (already installed)."
|
|
else
|
|
cat << EOF
|
|
|
|
+==============================================================================
|
|
| Skipping package $NEW (already installed)
|
|
+==============================================================================
|
|
|
|
EOF
|
|
fi
|
|
shift 1
|
|
continue;
|
|
fi
|
|
fi
|
|
|
|
# Showtime. Let's do the upgrade. First, we will rename all the
|
|
# installed packages with this basename to make them easy to remove later:
|
|
|
|
TIMESTAMP=$(date +%Y-%m-%d,%T)
|
|
SHORT="$(package_name $OLD)"
|
|
if [ "$DRY_RUN" = "true" ]; then
|
|
echo -n "$NEW would upgrade: "
|
|
for installed_package in $ROOT/var/log/packages/$SHORT* ; do
|
|
if [ "$(package_name $installed_package)" = "$SHORT" ]; then
|
|
echo -n "$(pkgbase $installed_package)"
|
|
fi
|
|
done
|
|
echo
|
|
shift 1
|
|
continue
|
|
fi
|
|
for installed_package in $ROOT/var/log/packages/$SHORT* ; do
|
|
if [ "$(package_name $installed_package)" = "$SHORT" ]; then
|
|
mv $installed_package ${installed_package}-upgraded-$TIMESTAMP
|
|
fi
|
|
done
|
|
for installed_script in $ROOT/var/log/scripts/$SHORT* ; do
|
|
if [ "$(package_name $installed_script)" = "$SHORT" ]; then
|
|
if [ -r $installed_script ]; then
|
|
mv $installed_script ${installed_script}-upgraded-$TIMESTAMP
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Print a banner for the current upgrade:
|
|
cat << EOF
|
|
|
|
+==============================================================================
|
|
| Upgrading $OLD package using $INCOMINGDIR/$NNAME
|
|
+==============================================================================
|
|
|
|
EOF
|
|
|
|
# Next, the new package is pre-installed:
|
|
if [ "$VERBOSE" = "verbose" ]; then
|
|
/sbin/installpkg $INCOMINGDIR/$NNAME
|
|
RETCODE=$?
|
|
else
|
|
echo "Pre-installing package $NEW..."
|
|
/sbin/installpkg $INCOMINGDIR/$NNAME 1> /dev/null
|
|
RETCODE=$?
|
|
fi
|
|
# Make sure that worked:
|
|
if [ ! $RETCODE = 0 ]; then
|
|
echo "ERROR: Package $INCOMINGDIR/$NNAME did not install"
|
|
echo "correctly. You may need to reinstall your old package"
|
|
echo "to avoid problems. Make sure the new package is not"
|
|
echo "corrupted."
|
|
sleep 30
|
|
# Skip this package, but still try to proceed. Good luck...
|
|
shift 1
|
|
continue;
|
|
fi
|
|
|
|
# Now, the leftovers from the old package(s) can go. Pretty simple, huh? :)
|
|
if [ -d "$ROOT" ]; then
|
|
( cd $ROOT/var/log/packages
|
|
for rempkg in *-$TIMESTAMP ; do
|
|
if [ "$VERBOSE" = "verbose" ]; then
|
|
ROOT=$ROOT /sbin/removepkg $rempkg
|
|
else
|
|
ROOT=$ROOT /sbin/removepkg $rempkg | grep -v "Skipping\." | grep -v "Removing files:"
|
|
fi
|
|
done
|
|
)
|
|
else
|
|
( cd /var/log/packages
|
|
for rempkg in *-$TIMESTAMP ; do
|
|
if [ "$VERBOSE" = "verbose" ]; then
|
|
/sbin/removepkg $rempkg
|
|
else
|
|
/sbin/removepkg $rempkg | grep -v "Skipping\." | grep -v "Removing files:"
|
|
fi
|
|
done
|
|
)
|
|
fi
|
|
echo
|
|
|
|
# Again! Again!
|
|
# Seriously, the reinstalling of a package can be crucial if any files
|
|
# shift location, so we should always reinstall as the final step:
|
|
if [ ! "$NOT_PARANOID" = "true" ]; then
|
|
/sbin/installpkg $INCOMINGDIR/$NNAME
|
|
fi
|
|
|
|
echo "Package $OLD upgraded with new package $INCOMINGDIR/$NNAME."
|
|
ERRCODE=0
|
|
|
|
# Process next parameter:
|
|
shift 1
|
|
|
|
done
|
|
|
|
if [ ! "$DRY_RUN" = "true" ]; then
|
|
echo
|
|
fi
|
|
exit $ERRCODE
|