mirror of
git://slackware.nl/current.git
synced 2024-12-30 10:24:23 +01:00
ca85aab953
a/pkgtools-15.0-noarch-20.txz: Rebuilt. Move pkgtools database to /var/lib/pkgtools/. Move removed logs to /var/log/pkgtools/. a/sysvinit-2.90-x86_64-1.txz: Upgraded. ap/cups-filters-1.20.3-x86_64-3.txz: Rebuilt. Recompiled against poppler-0.66.0. kde/calligra-2.9.11-x86_64-22.txz: Rebuilt. Recompiled against poppler-0.66.0. l/dbus-python-1.2.8-x86_64-1.txz: Upgraded. l/gc-7.6.6-x86_64-1.txz: Upgraded. l/harfbuzz-1.8.1-x86_64-1.txz: Upgraded. l/poppler-0.66.0-x86_64-1.txz: Upgraded. Shared library .so-version bump. l/pulseaudio-12.0-x86_64-1.txz: Upgraded. n/dhcpcd-7.0.6-x86_64-1.txz: Upgraded. n/php-7.2.7-x86_64-1.txz: Upgraded. Added support for libedit. t/texlive-2017.171108-x86_64-7.txz: Rebuilt. Recompiled against poppler-0.66.0. x/libwacom-0.30-x86_64-1.txz: Upgraded. xfce/exo-0.12.2-x86_64-1.txz: Upgraded. xfce/tumbler-0.2.1-x86_64-4.txz: Rebuilt. Recompiled against poppler-0.66.0. xfce/xfce4-settings-4.12.4-x86_64-1.txz: Upgraded.
438 lines
15 KiB
Bash
438 lines
15 KiB
Bash
#!/bin/sh
|
|
# Slackware remove package script
|
|
#
|
|
# Copyright 1994, 1995, 1998 Patrick Volkerding, Moorhead, Minnesota USA
|
|
# Copyright 2001, Slackware Linux, Inc., Concord, CA USA
|
|
# Copyright 2009, 2015, 2016, 2018 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.
|
|
#
|
|
|
|
# Tue Jun 5 20:04:45 UTC 2018
|
|
# Use /var/lib/pkgtools for the package database, not /var/log.
|
|
# Logs of the removed packages and scripts will remain in /var/log, but moved
|
|
# into /var/log/pkgtools.
|
|
#
|
|
# Sun May 27 18:02:23 UTC 2018
|
|
# Added --terse mode to print one line per removed package.
|
|
#
|
|
# Wed May 23 17:31:23 UTC 2018
|
|
# Use file locking to prevent more than one copy of ldconfig from running at
|
|
# a time.
|
|
#
|
|
# Thu Sep 15 17:46:28 UTC 2016 <volkerdi>
|
|
# If removepkg is called with a short package name (no -$VERSION-$ARCH-$BUILD),
|
|
# remove the most recently installed matching package, not the oldest one.
|
|
#
|
|
# Thu Sep 15 08:09:01 BST 2016 <mozes>
|
|
# - Handle finding >1 match for a package. Thanks to SeB on LQ for the feedback.
|
|
#
|
|
# Wed Sep 14 20:44:00 BST 2016 <mozes>
|
|
# - Modify package_name function to cater for package file names that contain
|
|
# >=4 hyphens.
|
|
# Thanks to coralfang on LQ for the report and to Jim Hawkins for the patch.
|
|
# - Modified to handle packages that contain file names with backslashes
|
|
# Thanks to aaazen on LQ for the report and the patch.
|
|
#
|
|
# Thu Sep 24 03:31:58 UTC 2015 <alphageek>
|
|
# extract_links() sed adjusted to handle symlinks with spaces.
|
|
#
|
|
# Sun Sep 6 21:58:36 BST 2009
|
|
# Replaced pkgbase & package_name code with 'sed' script by Jim Hawkins.
|
|
#
|
|
# Sat Apr 25 21:18:53 UTC 2009 (12.34567890b)
|
|
# Converted to use new pkgbase() function to remove pathname and
|
|
# valid package extensions.
|
|
#
|
|
# Revision 12.34567890 Sun Apr 5 20:59:32 CDT 2009 <volkerdi>
|
|
# - Support packages with the extensions: .tgz, .tbz, .tlz, .txz
|
|
#
|
|
# Revision 1.9 Wed Oct 31 14:04:28 CDT 2007 volkerding
|
|
# - Fix problem removing packages with a large number of fields.
|
|
# Thanks to Niki Kovacs for noticing this, and to Piter Punk
|
|
# for the patch.
|
|
# - Use LC_ALL=C locale, which is much faster with "sort".
|
|
# Thanks to Tsomi.
|
|
# - Don't try to remove any package that starts with '-'. This
|
|
# is not a proper package name (usually a typo), and results
|
|
# in the package database being broken. Thanks to Jef Oliver.
|
|
# - Patched cat_except() to allow the last Slackware package on
|
|
# a partition to be removed (using ROOT=, of course)
|
|
# Thanks to Selkfoster for the patch, and to everyone else who
|
|
# proposed solutions before. This issue really wasn't given
|
|
# the highest priority before, but I figured while I'm in here...
|
|
#
|
|
# Revision 1.8 Thu Nov 22 14:00:13 PST 2001 volkerding Rel $
|
|
# - Move $TMP underneath $ROOT
|
|
# - Understand the idea of a base package name, so that packages
|
|
# can be removed with any of these notations:
|
|
# removepkg foo-1.0-i386-1.tgz
|
|
# removepkg foo-1.0-i386-1
|
|
# removepkg foo.tgz
|
|
# removepkg foo
|
|
#
|
|
# Revision 1.7 2001/03/30 12:36:28 volkerding
|
|
# - Strip extra ".tgz" from input names.
|
|
#
|
|
# Revision 1.6 1999/03/25 18:26:41 volkerding
|
|
# - Use external $ROOT variable, like installpkg.
|
|
#
|
|
# Revision 1.5.1 1998/03/18 15:37:28 volkerding
|
|
# - Since removepkg is always run by root, the temp directory has been
|
|
# moved from /tmp to a private directory to avoid symlink attacks from
|
|
# malicious users.
|
|
#
|
|
# Revision 1.5 1997/06/26 12:09:53 franke
|
|
# - Fixed old bug in TRIGGER regex setting
|
|
# - -preserve/-copy options now preserve non-unique files
|
|
# and empty directories also
|
|
#
|
|
# Revision 1.4 1997/06/09 13:21:36 franke
|
|
# - Package file preserve (-preserve, -copy) added.
|
|
# - Don't execute "rm -rf" lines from doinst.sh, removing links explicit.
|
|
# - Warning on no longer existing files added.
|
|
# - Warning on files changed after package installation added.
|
|
# - Intermediate file preserve (-keep) added.
|
|
# - Check for required files/links now done on a combined list.
|
|
# - Write access to /var/log/{packages,scripts} no longer necessary for -warn.
|
|
#
|
|
# Revision 1.3 1997/06/08 13:03:05 franke
|
|
# Merged with revision 1.1.1.1
|
|
#
|
|
# Revision 1.2 1996/06/01 20:04:26 franke
|
|
# Delete empty directories & formated manual pages added
|
|
#
|
|
# Revision 1.1.1.1 1995/12/18 21:20:42 volkerding
|
|
# Original Version from Slackware 3.1
|
|
#
|
|
# Revision 1.1 1995/06/05 22:49:11 volkerding
|
|
# Original Version from Slackware 3.0
|
|
#
|
|
|
|
# Needed to find package names within the 'remove_packages' function:
|
|
shopt -s extglob
|
|
|
|
# Return a package name that has been stripped of the dirname portion
|
|
# and any of the valid extensions (only):
|
|
pkgbase() {
|
|
# basename + strip extensions .tbz, .tgz, .tlz and .txz
|
|
echo "$1" | sed 's?.*/??;s/\.t[bglx]z$//'
|
|
}
|
|
|
|
# This makes "sort" run much faster:
|
|
export LC_ALL=C
|
|
|
|
# Set the prefix for the package database directories (packages, scripts).
|
|
ADM_DIR="$ROOT/var/lib/pkgtools"
|
|
|
|
# Set the prefix for the removed packages/scripts log files:
|
|
LOG_DIR="$ROOT/var/log/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
|
|
PRES_DIR=$TMP/preserved_packages
|
|
|
|
# Lock directory for ldconfig... share it with installpkg so that upgradepkg
|
|
# becomes properly ldconfig-locked, too.
|
|
INSTLOCKDIR=${INSTLOCKDIR:-/run/lock/pkgtools}
|
|
if [ ! -d $INSTLOCKDIR ]; then
|
|
mkdir -p $INSTLOCKDIR
|
|
fi
|
|
|
|
# This simple cat_except() should be used on the installer,
|
|
# since the busybox "find" can't handle the complex find
|
|
# syntax:
|
|
#cat_except() {
|
|
# ( cd "$1" && cat $(ls * | sed "/^$2\$/d"))
|
|
#}
|
|
|
|
# This version of cat_except() allows the last package to be
|
|
# removed when ROOT= is used:
|
|
cat_except() {
|
|
( cd "$1" && \
|
|
if [ $(find . -type f -maxdepth 1 2> /dev/null | wc -l) -ne 1 ]; then
|
|
cat $(find . -type f -maxdepth 1 2> /dev/null | grep -v "$2") 2> /dev/null
|
|
fi
|
|
)
|
|
}
|
|
|
|
extract_links() {
|
|
sed -n 's,^[ ]*( [ ]*cd[ ]* \(.*\) [ ]*; [ ]*rm [ ]*-rf[ ]* \(.*\) [ ]*)[ ]*$,\1/\2,p'
|
|
}
|
|
|
|
preserve_file() {
|
|
if [ "$PRESERVE" = "true" ]; then
|
|
F="$(basename "$1")"
|
|
D="$(dirname "$1")"
|
|
if [ ! -d "$PRES_DIR/$PKGNAME/$D" ]; then
|
|
mkdir -p "$PRES_DIR/$PKGNAME/$D" || return 1
|
|
fi
|
|
cp -p "$ROOT/$D/$F" "$PRES_DIR/$PKGNAME/$D" || return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
preserve_dir() {
|
|
if [ "$PRESERVE" = "true" ]; then
|
|
if [ ! -d "$PRES_DIR/$PKGNAME/$1" ]; then
|
|
mkdir -p "$PRES_DIR/$PKGNAME/$1" || return 1
|
|
fi
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
keep_files() {
|
|
while read FILE ; do
|
|
if [ ! -d "$ROOT/$FILE" ]; then
|
|
if [ -r "$ROOT/$FILE" ]; then
|
|
! [ $TERSE ] && echo " --> $ROOT/$FILE was found in another package. Skipping."
|
|
preserve_file "$FILE"
|
|
else
|
|
if [ "$(echo $FILE | cut -b1-8)" != "install/" ]; then
|
|
! [ $TERSE ] && echo "WARNING: Nonexistent $ROOT/$FILE was found in another package. Skipping."
|
|
fi
|
|
fi
|
|
else
|
|
preserve_dir "$FILE"
|
|
fi
|
|
done
|
|
}
|
|
|
|
keep_links() {
|
|
while read LINK ; do
|
|
if [ -L "$ROOT/$LINK" ]; then
|
|
! [ $TERSE ] && echo " --> $ROOT/$LINK (symlink) was found in another package. Skipping."
|
|
else
|
|
! [ $TERSE ] && echo "WARNING: Nonexistent $ROOT/$LINK (symlink) was found in another package. Skipping."
|
|
fi
|
|
done
|
|
}
|
|
|
|
delete_files() {
|
|
local unset LC_ALL # Locally (within this delete_files function) allow handling of backslashes
|
|
while read -r AFILE ; do # do not expand backslashes on read
|
|
FILE=$(printf "%b" "$AFILE") # unescape octal characters
|
|
if [ ! -d "$ROOT/$FILE" ]; then
|
|
if [ -r "$ROOT/$FILE" ]; then
|
|
if [ "$ROOT/$FILE" -nt "$ADM_DIR/packages/$PKGNAME" ]; then
|
|
! [ $TERSE ] && echo "WARNING: $ROOT/$FILE changed after package installation."
|
|
fi
|
|
if [ ! "$WARN" = "true" ]; then
|
|
! [ $TERSE ] && echo " --> Deleting $ROOT/$FILE"
|
|
preserve_file "$FILE" && rm -f "$ROOT/$FILE"
|
|
else
|
|
! [ $TERSE ] && echo " --> $ROOT/$FILE would be deleted"
|
|
preserve_file "$FILE"
|
|
fi
|
|
else
|
|
! [ $TERSE ] && echo " --> $ROOT/$FILE no longer exists. Skipping."
|
|
fi
|
|
else
|
|
preserve_dir "$FILE"
|
|
fi
|
|
done
|
|
}
|
|
|
|
delete_links() {
|
|
while read LINK ; do
|
|
if [ -L "$ROOT/$LINK" ]; then
|
|
if [ ! "$WARN" = "true" ]; then
|
|
! [ $TERSE ] && echo " --> Deleting symlink $ROOT/$LINK"
|
|
rm -f "$ROOT/$LINK"
|
|
else
|
|
! [ $TERSE ] && echo " --> $ROOT/$LINK (symlink) would be deleted"
|
|
fi
|
|
else
|
|
! [ $TERSE ] && echo " --> $ROOT/$LINK (symlink) no longer exists. Skipping."
|
|
fi
|
|
done
|
|
}
|
|
|
|
delete_dirs() {
|
|
sort -r | \
|
|
while read DIR ; do
|
|
if [ -d "$ROOT/$DIR" ]; then
|
|
if [ ! "$WARN" = "true" ]; then
|
|
if [ $(ls -a "$ROOT/$DIR" | wc -l) -eq 2 ]; then
|
|
! [ $TERSE ] && echo " --> Deleting empty directory $ROOT/$DIR"
|
|
rmdir "$ROOT/$DIR"
|
|
else
|
|
! [ $TERSE ] && echo "WARNING: Unique directory $ROOT/$DIR contains new files"
|
|
fi
|
|
else
|
|
! [ $TERSE ] && echo " --> $ROOT/$DIR (dir) would be deleted if empty"
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
|
|
delete_cats() {
|
|
sed -n 's,/man\(./[^/]*$\),/cat\1,p' | \
|
|
while read FILE ; do
|
|
if [ -f "$ROOT/$FILE" ]; then
|
|
if [ ! "$WARN" = "true" ]; then
|
|
! [ $TERSE ] && echo " --> Deleting $ROOT/$FILE (fmt man page)"
|
|
rm -f $ROOT/$FILE
|
|
else
|
|
! [ $TERSE ] && echo " --> $ROOT/$FILE (fmt man page) would be deleted"
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
|
|
# Conversion to 'comm' utility by Mark Wisdom.
|
|
# is pretty nifty! :^)
|
|
remove_packages() {
|
|
for PKGLIST in $*
|
|
do
|
|
PKGNAME=$(pkgbase $PKGLIST)
|
|
# If we don't have a package match here, then we will attempt to find
|
|
# a package using the long name format (name-version-arch-build) for
|
|
# which the base package name was given. On a properly-managed machine,
|
|
# there should only be one package installed with a given basename, but
|
|
# we don't enforce this policy. If there's more than one, only one will
|
|
# be removed. If you want to remove them all, you'll need to run
|
|
# removepkg again until it removes all the same-named packages.
|
|
if [ ! -e $ADM_DIR/packages/$PKGNAME ]; then
|
|
# Short name not found - finally try looking for full name - e.g. foo-1.0-arm-1
|
|
pushd $ADM_DIR/packages > /dev/null
|
|
# Don't set PKGNAME if there are no matches:
|
|
if [ ! "$( ls -1 $PKGNAME-+([^-])-+([^-])-+([^-]) 2>/dev/null | wc -l )" = "0" ]; then
|
|
# If there is more than one package with the same name, set PKGNAME to the
|
|
# most recently installed version. This does not affect the behavior of
|
|
# upgradepkg, which always removes all other existing versions of the
|
|
# same package.
|
|
PKGNAME=$( ls -1t $PKGNAME-+([^-])-+([^-])-+([^-]) 2> /dev/null | head -n1 )
|
|
fi
|
|
popd > /dev/null
|
|
fi
|
|
|
|
if [ -r $ADM_DIR/packages/$PKGNAME ]; then
|
|
if [ ! "$WARN" = true ]; then
|
|
echo "Removing package: $(basename $ADM_DIR/packages/$PKGNAME)"
|
|
fi
|
|
if fgrep "./" $ADM_DIR/packages/$PKGNAME 1> /dev/null 2>&1; then
|
|
TRIGGER="^\.\/"
|
|
else
|
|
TRIGGER="FILE LIST:"
|
|
fi
|
|
if [ ! "$WARN" = true ]; then
|
|
! [ $TERSE ] && echo "Removing files:"
|
|
fi
|
|
sed -n "/$TRIGGER/,/^$/p" < $ADM_DIR/packages/$PKGNAME | \
|
|
fgrep -v "FILE LIST:" | sort -u > $TMP/delete_list$$
|
|
# Pat's new-new && improved pre-removal routine.
|
|
cat_except $ADM_DIR/packages $PKGNAME | sort -u > $TMP/required_list$$
|
|
if [ -r $ADM_DIR/scripts/$PKGNAME ]; then
|
|
extract_links < $ADM_DIR/scripts/$PKGNAME | sort -u > $TMP/del_link_list$$
|
|
cat_except $ADM_DIR/scripts $PKGNAME | extract_links | \
|
|
sort -u > $TMP/required_links$$
|
|
mv $TMP/required_list$$ $TMP/required_files$$
|
|
sort -u $TMP/required_links$$ $TMP/required_files$$ > $TMP/required_list$$
|
|
comm -12 $TMP/del_link_list$$ $TMP/required_list$$ | keep_links
|
|
comm -23 $TMP/del_link_list$$ $TMP/required_list$$ | delete_links
|
|
else
|
|
cat $ADM_DIR/scripts/* 2> /dev/null | extract_links | \
|
|
sort -u > $TMP/required_links$$
|
|
mv $TMP/required_list$$ $TMP/required_files$$
|
|
sort -u $TMP/required_links$$ $TMP/required_files$$ >$TMP/required_list$$
|
|
fi
|
|
comm -12 $TMP/delete_list$$ $TMP/required_list$$ | keep_files
|
|
comm -23 $TMP/delete_list$$ $TMP/required_list$$ > $TMP/uniq_list$$
|
|
delete_files < $TMP/uniq_list$$
|
|
delete_dirs < $TMP/uniq_list$$
|
|
delete_cats < $TMP/uniq_list$$
|
|
if [ ! "$KEEP" = "true" ]; then
|
|
rm -f $TMP/delete_list$$ $TMP/required_files$$ $TMP/uniq_list$$
|
|
rm -f $TMP/del_link_list$$ $TMP/required_links$$ $TMP/required_list$$
|
|
fi
|
|
if [ "$PRESERVE" = "true" ]; then
|
|
if [ -r $ADM_DIR/scripts/$PKGNAME ]; then
|
|
if [ ! -d "$PRES_DIR/$PKGNAME/install" ]; then
|
|
mkdir -p "$PRES_DIR/$PKGNAME/install"
|
|
fi
|
|
cp -p $ADM_DIR/scripts/$PKGNAME $PRES_DIR/$PKGNAME/install/doinst.sh
|
|
fi
|
|
fi
|
|
if [ ! "$WARN" = "true" ]; then
|
|
# We won't assume that anything in /var/log can be trusted to remain there,
|
|
# so we'll remake the directories and symlinks first:
|
|
mkdir -p $LOG_DIR/removed_packages $LOG_DIR/removed_scripts
|
|
for symlink in removed_packages removed_scripts ; do
|
|
if [ ! -L $LOG_DIR/../$symlink ]; then
|
|
rm -rf $LOG_DIR/../$symlink
|
|
( cd $LOG_DIR/.. ; ln -sf pkgtools/$symlink . )
|
|
fi
|
|
done
|
|
# Now that we know we have log directories, move the files:
|
|
mv $ADM_DIR/packages/$PKGNAME $LOG_DIR/removed_packages
|
|
if [ -r $ADM_DIR/scripts/$PKGNAME ]; then
|
|
mv $ADM_DIR/scripts/$PKGNAME $LOG_DIR/removed_scripts
|
|
fi
|
|
fi
|
|
else
|
|
echo "No such package: $(basename $ADM_DIR/packages/$PKGNAME). Can't remove."
|
|
fi
|
|
# In the case where a library and symlink are removed but an earlier version
|
|
# remains on the machine, this will link it up and save potential problems:
|
|
if [ "$ROOT" = "" ] && [ -x /sbin/ldconfig ]; then
|
|
( flock 9 || exit 11
|
|
/sbin/ldconfig 2> /dev/null
|
|
) 9> $INSTLOCKDIR/ldconfig.lock
|
|
fi
|
|
done
|
|
}
|
|
|
|
if [ "$#" = "0" ]; then
|
|
echo "Usage: $(basename $0) [--copy] [--keep] [--preserve] [--terse] [--warn] packagename ..."; exit 1
|
|
fi
|
|
|
|
while : ; do
|
|
case "$1" in
|
|
-copy | --copy) WARN=true; PRESERVE=true; shift;;
|
|
-keep | --keep) KEEP=true; shift;;
|
|
-preserve | --preserve) PRESERVE=true; shift;;
|
|
-terse | --terse) TERSE=0; shift;;
|
|
-warn | --warn) WARN=true; shift;;
|
|
-* | --*) echo "Usage: $(basename $0) [-copy] [-keep] [-preserve] [-warn] packagename ..."; exit 1;;
|
|
*) break
|
|
esac
|
|
done
|
|
|
|
if [ "$WARN" = "true" ]; then
|
|
unset TERSE
|
|
echo "Only warning... not actually removing any files."
|
|
if [ "$PRESERVE" = "true" ]; then
|
|
echo "Package contents is copied to $PRES_DIR."
|
|
fi
|
|
echo "Here's what would be removed (and left behind) if you"
|
|
echo "removed the package(s):"
|
|
echo
|
|
else
|
|
if [ "$PRESERVE" = "true" ]; then
|
|
echo "Package contents is copied to $PRES_DIR."
|
|
fi
|
|
fi
|
|
|
|
remove_packages $*
|