Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@cdrw-nutyx
Forked from ruario/pkgtrack
Created January 29, 2019 15:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cdrw-nutyx/fd4833d453e792f92d433a8b71a9b1ae to your computer and use it in GitHub Desktop.
Save cdrw-nutyx/fd4833d453e792f92d433a8b71a9b1ae to your computer and use it in GitHub Desktop.
#!/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