Skip to content

Instantly share code, notes, and snippets.

@ruario

ruario/getupdates

Last active Oct 10, 2017
Embed
What would you like to do?
A script to fetch updates for Slackware stable
#!/bin/sh
#
# getupdates (0.9.6) - A script to fetch updates for Slackware stable
#
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
# Version 2, December 2004
#
# Copyright (C) 2017 Ruari Oedegaard, Oslo, Norway
#
# Everyone is permitted to copy and distribute verbatim or modified
# copies of this license document, and changing it is allowed as long
# as the name is changed.
#
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
#
# 0. You just DO WHAT THE FUCK YOU WANT TO.
# Automatically gather some information about the Slackware release
case `uname -m` in
i?86) SLACKTYPE="slackware" ;;
x86_64) SLACKTYPE="slackware64" ;;
arm) SLACKTYPE="slackwarearm" ;;
*) printf "\n\n$SLACKTYPE is not supported.\n" ; exit 1 ;;
esac
SLACKVERSION=`awk -F'[ .]' '{print $2"."$3}' /etc/slackware-version`
# Read the 3 variables from the environment or set them to defaults
SLACKMIRROR=${SLACKMIRROR:-https://mirrors.slackware.com/slackware}
LOCALPATCHDIR=${LOCALPATCHDIR:-$HOME/patches}
SAVEMETADATA=${SAVEMETADATA:-NO}
# Create working directory structure if not yet present
mkdir -p "$LOCALPATCHDIR/.metadata"
cd "$LOCALPATCHDIR/.metadata"
# Optionally clean temporary update metadata on exit
cleanmeta ()
{
if [ "$SAVEMETADATA" = "NO" ]; then
rm -fr "$LOCALPATCHDIR/.metadata"
else
echo "Note: The metadata directory (\"$LOCALPATCHDIR/.metadata\") was retained"
fi
}
# Fetch the latest package checksums
rm -f CHECKSUMS.md5*
if ! wget -q $SLACKMIRROR/${SLACKTYPE}-${SLACKVERSION}/patches/CHECKSUMS.md5; then
echo "There were problems accessing $SLACKMIRROR/patches/CHECKSUMS.md5" 2>&1
cleanmeta
exit 1
fi
# See if cryptographic verification is possible
if command -v gpg >/dev/null 2>&1; then
if gpg --list-keys 2>/dev/null | grep -Fq 'security@slackware.com'; then
SIGNATURE=YES
else
SIGNATURE=NO
fi
else
SIGNATURE=NO
fi
# If possible verify CHECKSUMS.md5's signature
if [ "$SIGNATURE" = "YES" ]; then
wget -q $SLACKMIRROR/${SLACKTYPE}-${SLACKVERSION}/patches/CHECKSUMS.md5.asc
if ! gpg --verify CHECKSUMS.md5.asc 2>/dev/null; then
echo "ERROR: Could not verify CHECKSUMS.md5! Aborting!" >&2
cleanmeta
exit 1
fi
fi
# If there is no blacklist file present, make a blank one as the file
# is expected and read by this script later on
if [ ! -e "$LOCALPATCHDIR/blacklist" ]; then
touch "$LOCALPATCHDIR/blacklist"
# Provide some guidence on blacklist creation to the first time user
cat <<EOBL> "$LOCALPATCHDIR/blacklist.README.txt"
To blacklist updates, open the blacklist file found in this directory
and add a regex for any package updates you wish to avoid. The file will
be read by grep (in extended regex mode) to filter out updates.
NOTE: Do not add any any other lines (including comments or blank
lines) to the blacklist file as these extra lines will be counted as a
regex, potentially matching and blocking updates!
e.g. to block by package name, use the following format:
packagename(-[[:alnum:]\.\+_]+){3}
Simply adjust "packagename" to the name of the package you wish to
block, e.g. to block kernel-huge-smp:
kernel-huge-smp(-[[:alnum:]\.\+_]+){3}
Or to block all kernel packages:
^kernel
To block updates to all packages created by Alien Bob (e.g. to preserve
multilib packages), you could do the following:
[0-9]+alien$
EOBL
fi
# Create a regex filter of pre-installed packages that aren't
# blacklisted
/bin/ls /var/log/packages \
| grep -Evf "$LOCALPATCHDIR/blacklist" \
| sed -nr 's#^([[:graph:]]+)(-[[:alnum:]\.\+_]+){3}$#[[:alnum:]]{32} \1(-[[:alnum:]\\.\\+_]+){3}\\.t.z(\\.asc)*#p' \
> filter
# Filter CHECKSUMS.md5 for only the upgrades we are interested in
sed -rn 's#([[:alnum:]]{32} )\./packages/#\1#p' CHECKSUMS.md5 \
| grep -xEf filter \
> md5sums.new
# Exit if none of the potential package updates we might want are
# present on the server
if ! grep -q '.' md5sums.new; then
echo "No updates available"
cleanmeta
exit 0
fi
# Create md5sums for any package updates that are already present
# locally
( cd "$LOCALPATCHDIR"; md5sum *.t?z* 2>/dev/null ) \
> md5sums.local
# Syncronise package updates, only if there are changes
if diff md5sums.local md5sums.new > md5sums.diff; then
echo "The directory \"$LOCALPATCHDIR\" was already up to date."
cleanmeta
exit 0
else
for old in $( sed -rn 's#^< [[:alnum:]]{32} ##p' md5sums.diff ); do
rm -v "$LOCALPATCHDIR/$old"
done
for new in $( sed -rn 's#^> [[:alnum:]]{32} ##p' md5sums.diff ); do
wget $SLACKMIRROR/${SLACKTYPE}-${SLACKVERSION}/patches/packages/$new -P "$LOCALPATCHDIR"
done
fi
# Provide a warning for when cryptographic verification is not possible
# (to use below)
verificationwarning ()
{
echo "Note: Because the security@slackware.com signing key was not available" >&2
echo "the packages cannot be cryptographically verified. Import the key to" >&2
echo "rectify this situation." >&2
}
# Use md5sums to check that the files downloaded correctly
cd "$LOCALPATCHDIR"
if md5sum --quiet -c .metadata/md5sums.new; then
echo "The directory \"$LOCALPATCHDIR\" is now up to date!"
else
if [ "$SIGNATURE" = "YES" ]; then
echo "Note: Exiting early due to failed checksum(s), without checking signatures!" >&2
cleanmeta
exit 1
else
# Note: The md5sum check will print errors itself but add a warning
# about cryptographic verification not being possible anyway.
verificationwarning
cleanmeta
exit 1
fi
fi
# Check security signatures, if the Slackware signing key is available
if [ "$SIGNATURE" = "YES" ]; then
echo -n "Checking security signatures ... "
for sig in *.asc; do
if ! gpg --verify $sig 2>/dev/null; then
echo -e "\nERROR: Verification failed while testing \"$sig\"! Further processing has been aborted!" >&2
cleanmeta
exit 1
fi
done
echo "Done!"
echo "No problems detected. :)"
else
verificationwarning
fi
# Final cleanup if not done elsewhere
cleanmeta
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment