summaryrefslogtreecommitdiffstats
path: root/testing/source/pkgtools/scripts/upgradepkg
diff options
context:
space:
mode:
Diffstat (limited to 'testing/source/pkgtools/scripts/upgradepkg')
-rw-r--r--testing/source/pkgtools/scripts/upgradepkg417
1 files changed, 417 insertions, 0 deletions
diff --git a/testing/source/pkgtools/scripts/upgradepkg b/testing/source/pkgtools/scripts/upgradepkg
new file mode 100644
index 000000000..f53d21d99
--- /dev/null
+++ b/testing/source/pkgtools/scripts/upgradepkg
@@ -0,0 +1,417 @@
+#!/bin/bash
+# Copyright 1999 Patrick Volkerding, Moorhead, Minnesota, USA
+# Copyright 2001, 2002, 2003 Slackware Linux, Inc., Concord, California, USA
+# Copyright 2009, 2015 Patrick J. Volkerding, Sebeka, MN, USA
+# Copyright 2015 Michal Nazarewicz <mina86@mina86.com>
+# 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.
+#
+# Mon Jun 4 21:17:58 UTC 2018
+# Use /var/lib/pkgtools, not /var/log.
+#
+# Thu May 24 20:23:55 UTC 2018
+# Added --terselength option to set the line length in --terse mode.
+# Use a lockfile to prevent output collisions in --terse mode.
+#
+# Wed May 23 03:35:28 UTC 2018
+# Added --terse, which limits screen output to one line per package.
+#
+# Sat 17 Jan 16:21:32 UTC 2015 mina86
+# Various optimisation mostly resolving around avoiding having to fork
+# and call cut, basename and other helper commands. Slight
+# refactoring of code calling removepkg.
+#
+# 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.
+#
+# Added --dry-run, Sat Apr 26 18:13:29 PDT 2003
+#
+# Added --install-new and --reinstall, Fri May 31 14:11:14 PDT 2002 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
+#
+# Modified to handle either old 8.3 or new package-version-arch-build.tgz
+# packages, Sat Nov 17 14:25:58 PST 2001 volkerdi
+
+# Return a package name that has been stripped of the dirname portion
+# and any of the valid extensions (only):
+pkgbase() {
+ PKGRETURN=${1##*/}
+ case "$PKGRETURN" in *.t[gblx]z)
+ PKGRETURN=${PKGRETURN%.*}
+ esac
+ echo "$PKGRETURN"
+}
+
+usage() {
+ cat << EOF
+
+Usage: upgradepkg [options] <newpackage> ...
+ upgradepkg [options] <oldpackage%newpackage> ...
+
+Upgrade, install, or reinstall Slackware packages (.tgz, .tbz, .tlz, .txz).
+
+To operate on an alternate directory, such as /mnt:
+ ROOT=/mnt upgradepkg package.txz
+
+Options:
+ --dry-run only display what would be done
+ --install-new install new packages also
+ --reinstall upgrade packages of the same version
+ --terse display a single line for each package operation
+ --terselength <length> maximum line length of terse output
+ --verbose display all the gory details of the upgrade
+ --help display this help
+
+For more details see upgradepkg(8).
+EOF
+}
+
+# Set the prefix for the package database directories (packages, scripts).
+ADM_DIR="$ROOT/var/lib/pkgtools"
+
+# Make sure there's a proper temp directory:
+TMP=$ADM_DIR/setup/tmp
+# If the $TMP directory doesn't exist, create it:
+if [ ! -d $TMP ]; then
+ mkdir -p $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
+else
+ unset ROOT
+fi
+
+# --help or no args?
+if [ "$1" = "" -o "$1" = "-help" -o "$1" = "--help" -o "$1" = "-?" ]; then
+ usage;
+ exit 1;
+fi
+
+# Create a lockfile directory if it doesn't exist. We can use it to prevent
+# output line collisions in --terse mode.
+INSTLOCKDIR=${INSTLOCKDIR:-/run/lock/pkgtools}
+if [ ! -d $INSTLOCKDIR ]; then
+ mkdir -p $INSTLOCKDIR
+fi
+
+# Set default line length for terse mode:
+if tty -s && which tput 1> /dev/null 2> /dev/null ; then
+ TERSELENGTH=$(tput cols)
+else
+ TERSELENGTH=80
+fi
+
+# Arg processing loop. These must come before any packages are listed.
+while [ 0 ]; do
+ if [ "$1" = "-no-paranoia" -o "$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" -o "$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" -o "$1" = "--reinstall" ]; then
+ # Reinstall packages even if the installed one is the same version.
+ REINSTALL="true"
+ shift 1
+ elif [ "$1" = "-verbose" -o "$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" -o "$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
+ elif [ "$1" = "-terse" -o "$1" = "--terse" ]; then
+ # Output one line per installed/upgraded package by calling installpkg
+ # with --terse. Use TERSE=0 for true, so we can check with test.
+ TERSE=0
+ shift 1
+ elif [ "$1" = "-terselength" -o "$1" = "--terselength" ]; then
+ # Set line length in --terse mode:
+ TERSELENGTH=$2
+ shift 2
+ else # no more args
+ break;
+ fi
+done # processing args
+
+# A couple not-really-documented features to adjust the behavior of --terse
+# mode. These need to be used in addition to --terse, and passed in as
+# environment variables.
+# PLAINTERSE=0 (This outputs the standard terse line from installpkg, rather
+# than prefixing it with "Upgrading:" or "Installing:")
+# INFOBOX=0 (This outputs the installpkg --infobox instead of a terse line)
+
+# 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")
+ case "$STRING" in
+ *-*-*-*)
+ # At least four segments, strip version arch and build and return name:
+ echo "${STRING%-*-*-*}"
+ # cruft for later ;)
+ # BUILD=${STRING##*-}
+ # STRING=${STRING%*-}
+ # ARCH=${STRING##*-}
+ # STRING=${STRING%*-}
+ # VER=${STRING%*-}
+ ;;
+ *)
+ # Old style package name with one segment or we don't have four
+ # segments: return the old-style (or out of spec) package name.
+ echo $STRING
+ esac
+}
+
+ERRCODE=0
+
+# Main processing loop:
+for ARG; do
+ OLD=${ARG%'%'*} # first segment, = $ARG if no %
+ NEW=${ARG#*'%'} # second segment, = $ARG if no %
+
+ # Simple package integrity check:
+ if ! [ -f "$NEW" ]; then
+ ERRCODE=4
+ echo "Cannot install $NEW: file not found"
+ continue;
+ fi
+
+ # Figure out the names of the old and new packages:
+ INCOMINGDIR=$(dirname $NEW)
+ # These are the package names with the extension:
+ NNAME=${NEW##*/}
+ ONAME=${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 $OLD: invalid package extension"
+ continue;
+ fi
+
+ # Check and fix the old package name:
+ SHORT="$(package_name $OLD)"
+ if [ ! -r $ADM_DIR/packages/$OLD ]; then
+ if ls $ADM_DIR/packages/$SHORT* 1> /dev/null 2> /dev/null ; then
+ for installed_package in $ADM_DIR/packages/$SHORT* ; do
+ if [ "$(package_name $installed_package)" = "$SHORT" ]; then # found one
+ OLD="${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 $ADM_DIR/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
+ ! [ $TERSE ] && echo
+ echo "Error: there is no installed package named $OLD."
+ ! [ $TERSE ] && echo " (looking for $ADM_DIR/packages/$OLD)"
+ ! [ $TERSE ] && 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
+ if [ $PLAINTERSE ]; then
+ /sbin/installpkg --terse --terselength $TERSELENGTH $INCOMINGDIR/$NNAME
+ elif [ $INFOBOX ]; then
+ /sbin/installpkg --infobox $INCOMINGDIR/$NNAME
+ elif [ $TERSE ]; then
+ OUTPUTLINE="$(/sbin/installpkg --terse --terselength $(expr $TERSELENGTH - 12) $INCOMINGDIR/$NNAME)"
+ ( flock 9 || exit 11
+ echo "Installing: ${OUTPUTLINE}"
+ ) 9> $INSTLOCKDIR/outputline.lock
+ else
+ cat << EOF
+
++==============================================================================
+| Installing new package $INCOMINGDIR/$NNAME
++==============================================================================
+
+EOF
+ /sbin/installpkg $INCOMINGDIR/$NNAME
+ fi
+ fi
+ fi
+ continue;
+ elif [ ! -r "$INCOMINGDIR/$NNAME" ]; then
+ if [ "$DRY_RUN" = "true" ]; then
+ echo "$NEW incoming package not found (command line)."
+ else
+ ! [ $TERSE ] && echo
+ echo "Error: incoming package $INCOMINGDIR/$NNAME not found."
+ ! [ $TERSE ] && echo
+ fi
+ 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
+ if ! [ $TERSE ]; then
+ cat << EOF
+
++==============================================================================
+| Skipping package $NEW (already installed)
++==============================================================================
+
+EOF
+ fi
+ fi
+ 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 $ADM_DIR/packages/$SHORT* ; do
+ if [ "$(package_name $installed_package)" = "$SHORT" ]; then
+ echo -n "$(pkgbase $installed_package)"
+ fi
+ done
+ echo
+ continue
+ fi
+ for installed_package in $ADM_DIR/packages/$SHORT* ; do
+ if [ "$(package_name $installed_package)" = "$SHORT" ]; then
+ mv $installed_package ${installed_package}-upgraded-$TIMESTAMP
+ fi
+ done
+ for installed_script in $ADM_DIR/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:
+ if ! [ $TERSE ]; then
+ cat << EOF
+
++==============================================================================
+| Upgrading $OLD package using $INCOMINGDIR/$NNAME
++==============================================================================
+EOF
+ fi
+ # Next, the new package is pre-installed:
+ if [ "$VERBOSE" = "verbose" ]; then
+ if ! [ $TERSE ]; then
+ /sbin/installpkg $INCOMINGDIR/$NNAME
+ RETCODE=$?
+ else
+ /sbin/installpkg $INCOMINGDIR/$NNAME 1> /dev/null
+ RETCODE=$?
+ fi
+ else
+ if [ $PLAINTERSE ]; then
+ /sbin/installpkg --terse --terselength $TERSELENGTH $INCOMINGDIR/$NNAME
+ elif [ $INFOBOX ]; then
+ /sbin/installpkg --infobox $INCOMINGDIR/$NNAME
+ elif [ $TERSE ]; then
+ OUTPUTLINE="$(/sbin/installpkg --terse --terselength $(expr $TERSELENGTH - 12) $INCOMINGDIR/$NNAME)"
+ RETCODE=$?
+ ( flock 9 || exit 11
+ echo "Upgrading: ${OUTPUTLINE}"
+ ) 9> $INSTLOCKDIR/outputline.lock
+ else
+ echo "Pre-installing package $NEW..."
+ /sbin/installpkg $INCOMINGDIR/$NNAME 1> /dev/null
+ RETCODE=$?
+ fi
+ 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 15
+ # Skip this package, but still try to proceed. Good luck...
+ continue;
+ fi
+ # Now, the leftovers from the old package(s) can go. Pretty simple, huh? :)
+ ( flock 9 || exit 11
+ for rempkg in "$ADM_DIR/packages/"*"-$TIMESTAMP"; do
+ if [ "$VERBOSE" = "verbose" ]; then
+ /sbin/removepkg "${rempkg##*/}"
+ elif ! [ $TERSE ]; then
+ /sbin/removepkg "${rempkg##*/}" | grep -v 'Skipping\.\|Removing files:'
+ else
+ /sbin/removepkg "${rempkg##*/}" > /dev/null
+ fi
+ done
+ ) 9> $INSTLOCKDIR/removepkg.lock
+ # 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
+ if ! [ $TERSE ]; then
+ /sbin/installpkg $INCOMINGDIR/$NNAME
+ else
+ /sbin/installpkg $INCOMINGDIR/$NNAME 1> /dev/null
+ fi
+ fi
+ ! [ $TERSE ] && echo "Package $OLD upgraded with new package $INCOMINGDIR/$NNAME."
+ ERRCODE=0
+done
+exit $ERRCODE