-
-
Save cdrw-nutyx/fd4833d453e792f92d433a8b71a9b1ae to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# Version: 1.2 | |
# | |
# This script provides a method for tracking software installed from | |
# source. Run it as follows for more information: | |
# | |
# pkgtrack -h | |
# | |
# Copyright 2018 Ruari Odegaard, Oslo, Norway | |
# 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 COPYRIGHT HOLDERS AND CONTRIBUTORS | |
# "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 COPYRIGHT | |
# HOLDER 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. | |
helptext () { | |
cat << EOH | |
Script usage: | |
$OWNNAME [options] [installation command] | |
Script options: | |
-h, --help Print this help text. | |
-n, --name [package name] Specify the name of the package, | |
otherwise the parent directory | |
name will be used. | |
-l, --list List installed packages | |
-s, --show-contents Show a list of files contained | |
within the package. | |
-ip, --install-package Install a previously backed up | |
package. | |
-id, --install-directory Install the contents of the current | |
directory to root (/) and log it. | |
-u, --uninstall Remove a package you installed | |
previously. | |
-b, --backup Create a backup archive of a | |
previously installed package. | |
Examples: | |
\$ $OWNNAME make install | |
\$ $OWNNAME --name foo ./install-foo.sh | |
\$ $OWNNAME --list | |
\$ $OWNNAME -n foo -s | |
\$ $OWNNAME --uninstall -n foo | |
\$ $OWNNAME -b -n foo | |
\$ $OWNNAME --install-package -n foo.pkg.tar.gz | |
\$ $OWNNAME --install-directory --name foo | |
EOH | |
} | |
noname () { | |
printf "\n\"$PKGNAME\" is not installed, specify a valid name with the \"--name\" option.\n\n" >&2 | |
} | |
extract_dirs () { | |
sed 's,\(.*\)/.*,\1,' "$1" | sort -u | \ | |
while read d; do | |
while echo "$d" | grep -vx .; do | |
d=$(dirname "$d") | |
done | |
done | sort -ur | grep -vxE \ | |
-e '(/s?bin|/etc|/lib(32|64)?|/opt|/var)' \ | |
-e '/usr((/local)?(/s?bin|/doc|/include|/info|/lib(32|64)?|/man(/man[1-9n])?|/share(/doc|/info|/man(/man[1-9n])?)?|/src)?)?' \ | |
-e '/usr/local/etc' | |
} | |
removefiles () { | |
while read f; do | |
# '-e' alone would not find broken symlinks | |
if [ -e "$f" -o -h "$f" ]; then | |
if [ -d "$f" ]; then | |
if ! ls -A "$f" | grep -q ^; then | |
# Don't remove a symlink pointing to a directory, as it could have | |
# been created by the user or the distribution | |
if [ ! -h "$f" ]; then | |
rmdir -v "$f" | |
fi | |
fi | |
else | |
rm -v "$f" | |
fi | |
fi | |
done | |
} | |
listfiles () { | |
ROOTDIRS=$(find / -maxdepth 1 -type d -regextype posix-egrep -regex '/(etc|s?bin|lib.*|opt|usr)') | |
find $ROOTDIRS ! -type d -print > $1 | |
} | |
# Handle options | |
SHOWHELP=n | |
PKGUNINSTALL=n | |
PKGLIST=n | |
PKGSHOW=n | |
PKGINSTALL=n | |
PKGBACKUP=n | |
PKGINSTDIR=n | |
while [ 0 ]; do | |
if [ "$1" = "-h" -o "$1" = "--help" ]; then | |
SHOWHELP=y | |
shift 1 | |
elif [ "$1" = "-n" -o "$1" = "--name" ]; then | |
PKGNAME="$2" | |
shift 2 | |
elif [ "$1" = "-u" -o "$1" = "--uninstall" ]; then | |
shift 1 | |
PKGUNINSTALL=y | |
elif [ "$1" = "-l" -o "$1" = "--list" ]; then | |
shift 1 | |
PKGLIST=y | |
elif [ "$1" = "-s" -o "$1" = "--show-contents" ]; then | |
shift 1 | |
PKGSHOW=y | |
elif [ "$1" = "-ip" -o "$1" = "--install-package" ]; then | |
shift 1 | |
PKGINSTALL=y | |
elif [ "$1" = "-id" -o "$1" = "--install-directory" ]; then | |
shift 1 | |
PKGINSTDIR=y | |
elif [ "$1" = "-b" -o "$1" = "--backup" ]; then | |
shift 1 | |
PKGBACKUP=y | |
else | |
break | |
fi | |
done | |
OWNNAME=$(basename "$0") | |
if [ "$SHOWHELP" = "y" ]; then | |
helptext | |
exit 0 | |
fi | |
if [ "$PKGLIST" = "y" ]; then | |
ls /var/lib/footprints | grep "$1" | |
exit 0 | |
fi | |
if [ -z "$PKGNAME" ]; then | |
PKGNAME=$(basename "$(pwd)") | |
echo "The \"--name\" option was not used so the package name has been set to the name of the directory: $PKGNAME" >&2 | |
fi | |
if echo "$PKGNAME" | grep -Fq '/'; then | |
echo 'The package name must not contain "/". Use "--name" to specify another name.' >&2 | |
exit 1 | |
fi | |
if [ "$PKGSHOW" = "y" ]; then | |
if [ -r "/var/lib/footprints/$PKGNAME" ]; then | |
echo "@${PKGNAME}:" | |
cat "/var/lib/footprints/$PKGNAME" | |
exit 0 | |
else | |
noname | |
helptext | |
exit 1 | |
fi | |
fi | |
if [ "$PKGINSTALL" = "y" ]; then | |
if [ -r "$PKGNAME" ]; then | |
tar -C / -xvf "$PKGNAME" | |
exit 0 | |
else | |
noname | |
helptext | |
exit 1 | |
fi | |
fi | |
if [ "$PKGINSTDIR" = "y" ]; then | |
if [ -r "/var/lib/footprints/$PKGNAME" ]; then | |
echo "$PKGNAME is already installed" >&2 | |
helptext | |
exit 1 | |
else | |
echo "Installing ${PKGNAME}:" | |
mkdir -p /var/lib/footprints | |
find . ! -type d | grep -vF "./var/lib/footprints/$PKGNAME" | \ | |
cpio --quiet -pmdv / 2>&1 | sed 's,^//\.,,' | tee "/var/lib/footprints/$PKGNAME" | |
echo "/var/lib/footprints/$PKGNAME" | tee -a "/var/lib/footprints/$PKGNAME" | |
exit 0 | |
fi | |
fi | |
if [ "$PKGBACKUP" = "y" ]; then | |
if [ -r "/var/lib/footprints/$PKGNAME" ]; then | |
if command -v xz >/dev/null 2>&1; then | |
EXT=xz | |
elif command -v bzip2 >/dev/null 2>&1; then | |
EXT=bz2 | |
else | |
EXT=gz | |
fi | |
sed 's,^/,,' "/var/lib/footprints/$PKGNAME" | tar -C / --format=pax -cvvaf "${PKGNAME}.pkg.tar.$EXT" -T- | |
echo "Created: ${PKGNAME}.pkg.tar.$EXT" | |
exit 0 | |
else | |
noname | |
helptext | |
exit 1 | |
fi | |
fi | |
if [ "$PKGUNINSTALL" = "y" ]; then | |
if [ -r "/var/lib/footprints/$PKGNAME" ]; then | |
PKGUNINSTALL_LIST=$(mktemp -t remove.XXXXXX) | |
cat "/var/lib/footprints/$PKGNAME" > "$PKGUNINSTALL_LIST" | |
extract_dirs "/var/lib/footprints/$PKGNAME" >> "$PKGUNINSTALL_LIST" | |
removefiles < "$PKGUNINSTALL_LIST" | |
rm -f "$PKGUNINSTALL_LIST" | |
exit 0 | |
else | |
noname | |
helptext | |
exit 1 | |
fi | |
fi | |
if [ -z "$1" ]; then | |
echo "You must specify an installation command (e.g. \"$OWNNAME make install\")" >&2 | |
helptext | |
exit 1 | |
fi | |
# The original tracking script, before I added all the fancy stuff above! ;) | |
BEFORE=$(mktemp -t before.XXXXXX) | |
AFTER=$(mktemp -t after.XXXXXX) | |
listfiles $BEFORE | |
$@ | |
listfiles $AFTER | |
mkdir -p /var/lib/footprints | |
diff --normal $BEFORE $AFTER | sed -n 's/^> //p' > "/var/lib/footprints/$PKGNAME" | |
echo "/var/lib/footprints/$PKGNAME" >> "/var/lib/footprints/$PKGNAME" | |
rm -f $BEFORE $AFTER | |
echo "Created log: /var/lib/footprints/$PKGNAME" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment