316 lines
8.5 KiB
Bash
316 lines
8.5 KiB
Bash
#!/bin/bash
|
|
#
|
|
# $Id: prtsweep,v 1.2 2003/12/17 21:17:02 opel Exp $
|
|
# (c) 2002, 2003 by Martin Opel <martin at obbl-net dot de>
|
|
# Revised 2021 by John McQuah <jmcquah at disroot dot org>
|
|
#
|
|
# May be redistributed and modified under the terms of the GPL
|
|
# only usable with CRUX Linux, version 1.0 or higher
|
|
#
|
|
# USE AT YOUR OWN RISK
|
|
#
|
|
# This script scans your supfiles in /etc/ports to find out your port
|
|
# directories and then scans all ports for old files, which are not part
|
|
# of the source-array in the Pkgfile and are not pkgfiles (name#version...).
|
|
# All these old files are removed. For details see "man 1 prtsweep".
|
|
#
|
|
|
|
info() {
|
|
echo -e "=======> $@"
|
|
}
|
|
|
|
msg() {
|
|
echo -e "+ $@"
|
|
}
|
|
|
|
error() {
|
|
info "ERROR: $@"
|
|
}
|
|
|
|
interrupted() {
|
|
info "exiting..."
|
|
exit 1
|
|
}
|
|
|
|
getportdirs() {
|
|
cat /etc/ports/*.{httpup,rsync} 2>/dev/null \
|
|
| awk -F= '$1=="destination" || $1=="ROOT_DIR" {print $2}'
|
|
}
|
|
|
|
remove() {
|
|
item=$1
|
|
if [ -f "$item" ]; then
|
|
if [ "$dryrun" = "1" ]; then
|
|
msg "removing file $item (dryrun)"
|
|
else
|
|
msg "removing file $item"
|
|
rm "$item"
|
|
fi
|
|
elif [ -d "$item" ]; then
|
|
if [ "$dryrun" = "1" ]; then
|
|
msg "removing directory $item (dryrun)"
|
|
else
|
|
msg "removing directory $item"
|
|
rm -r "$item"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
removeemptydir() {
|
|
# called if the directory lacks a Pkgfile. Still need to check whether
|
|
# it is actually empty.
|
|
local baggage
|
|
baggage=(`find $1`)
|
|
if [ ${#baggage[@]} -eq 1 ]; then
|
|
remove $1
|
|
else
|
|
info "files still remaining in port directory '$1'!"
|
|
info "okay to remove them? (y/n)"
|
|
read CONSENT
|
|
if [ "$CONSENT" = "y" ]; then
|
|
for (( f=1; f<${#baggage[@]}; f++ )); do
|
|
remove ${baggage[$f]}
|
|
done
|
|
fi
|
|
fi
|
|
}
|
|
|
|
inlist() {
|
|
local excode
|
|
item=$1
|
|
shift
|
|
list="$@"
|
|
excode=1 # assume not in the list until proven otherwise
|
|
|
|
while [ "$#" -gt 0 ]; do
|
|
if [ "$item" = "$1" ]; then
|
|
excode=0
|
|
break
|
|
else
|
|
shift
|
|
fi
|
|
done
|
|
|
|
return $excode
|
|
}
|
|
|
|
PWD_filename() {
|
|
if [[ $1 =~ ^(http|https|ftp|file)://.*/(.+) ]]; then
|
|
echo "${BASH_REMATCH[2]}"
|
|
else
|
|
echo $1
|
|
fi
|
|
}
|
|
|
|
remote_filename() {
|
|
if [[ $1 =~ ^(http|https|ftp|file)://.*/(.+) ]]; then
|
|
echo "/remote/path/${BASH_REMATCH[2]}"
|
|
else
|
|
echo $1
|
|
fi
|
|
}
|
|
|
|
nsweep() {
|
|
dir=$1
|
|
reset_keepfiles
|
|
local printedpwd="false"
|
|
local name version source renames pkgfiles packagename packagepath subdir
|
|
|
|
if [ ! -d $dir ]; then
|
|
error "'`pwd`/$dir' is not a directory!"
|
|
usage
|
|
fi
|
|
|
|
if [ ! -f $dir/Pkgfile ]; then
|
|
info `pwd`/$dir
|
|
msg "no Pkgfile found, empty port '$dir'."
|
|
if [ "$delete" = "1" ]; then
|
|
removeemptydir $dir
|
|
else
|
|
msg "use '-d' to remove empty directories."
|
|
fi
|
|
return
|
|
fi
|
|
|
|
echo "sweeping the directory for port $dir"
|
|
|
|
# read the port information from its Pkgfile and save the results in a bash array.
|
|
# This loop assumes that renaming is only applied to files downloaded over http or ftp,
|
|
# not under version control systems like rsync or httpup. To preserve this information,
|
|
# an arbitrary URI scheme is prepended before the desired filename.
|
|
pkgfiles=(`( . $dir/Pkgfile; PKGLOC=$(eval "printf '%s' $PKGGLOB"); \
|
|
PKGFILE=$(eval "printf '%s' $BLTGLOB"); \
|
|
for (( p=0; p<${#source[@]}; p++ )); do \
|
|
[ -n "${renames[$p]}" -a "${renames[$p]}" != "SKIP" ] && source[$p]="ftp://somehost/${renames[$p]}"; \
|
|
done; echo "$PKGLOC/$PKGFILE"; \
|
|
printf '%s ' "${source[@]}" )`)
|
|
|
|
cd $dir
|
|
# (new feature in v0.5) remove the package too, if the user requests it with the "-p" flag
|
|
if [ "$pkgtoo" != "1" ]; then
|
|
packagename=`basename ${pkgfiles[0]}`
|
|
packagepath=`dirname ${pkgfiles[0]}`
|
|
if [ "${packagepath:0:1}" = "/" ]; then
|
|
KEEP_FILES="${KEEP_FILES} $packagename"
|
|
elif [ "${packagepath:0:1}" != "/" ]; then
|
|
subdir=$(echo $PKGLOC | sed "s|/.*||")
|
|
KEEP_FILES="${KEEP_FILES} $subdir"
|
|
fi
|
|
fi
|
|
|
|
# Now that we're safely out of the nested subshell, the URI scheme can be replaced.
|
|
# Make the new value match the `ls -A` output unless the user has requested
|
|
# removal of source files too.
|
|
if [ "$rmsources" = 1 ]; then
|
|
for (( p=1; p<${#pkgfiles[@]}; p++ )); do
|
|
pkgfiles[$p]=`remote_filename ${pkgfiles[$p]}`
|
|
done
|
|
else
|
|
for (( p=1; p<${#pkgfiles[@]}; p++ )); do
|
|
pkgfiles[$p]=`PWD_filename ${pkgfiles[$p]}`
|
|
done
|
|
fi
|
|
|
|
unset pkgfiles[0]
|
|
for f in `ls -A`; do
|
|
if [[ ! ${KEEP_FILES} =~ "$f" ]] && ! inlist "$f" ${pkgfiles[@]}; then
|
|
if [ "$printedpwd" = "false" ]; then
|
|
printedpwd="true"
|
|
info `pwd`
|
|
fi
|
|
remove $f
|
|
fi
|
|
done
|
|
cd - &>/dev/null
|
|
}
|
|
|
|
reset_keepfiles() {
|
|
KEEP_FILES="Pkgfile README pre-install post-install
|
|
.footprint .signature .32bit .nostrip"
|
|
}
|
|
|
|
getoptions() {
|
|
while [ "$1" = "-a" -o "$1" = "-d" -o "$1" = "-n" -o "$1" = "-p" -o "$1" = "-s" -o "$1" = "-q" ]; do
|
|
if [ "$1" = "-q" ]; then
|
|
quiet=1
|
|
shift
|
|
elif [ "$1" = "-s" ]; then
|
|
rmsources=1
|
|
shift
|
|
elif [ "$1" = "-p" ]; then
|
|
pkgtoo=1
|
|
shift
|
|
elif [ "$1" = "-n" ]; then
|
|
dryrun=1
|
|
shift
|
|
elif [ "$1" = "-d" ]; then
|
|
delete=1
|
|
shift
|
|
elif [ "$1" = "-a" ]; then
|
|
auto=1
|
|
shift
|
|
fi
|
|
done
|
|
ports="$@"
|
|
|
|
if [ -z "$ports" -a "$auto" != "1" ]; then
|
|
echo "You must explicitly call for automatic mode (-a) if you"
|
|
echo "do not provide the paths of ports you want cleaned."
|
|
usage
|
|
elif [ -n "$ports" -a "$auto" = "1" ]; then
|
|
echo "Automatic mode (-a) is incompatible with providing an"
|
|
echo "explicit list of ports to clean."
|
|
usage
|
|
fi
|
|
|
|
}
|
|
|
|
usage() {
|
|
echo
|
|
echo "Usage: prtsweep [-a] [-d] [-n] [-s] [-p] [-q] [PORTDIR ...]"
|
|
echo
|
|
exit 1
|
|
}
|
|
|
|
do_sweep() {
|
|
if [ -z "$ports" -a "$auto" = "1" ]; then
|
|
for portdir in $collections; do
|
|
echo $portdir
|
|
cd $portdir
|
|
for dir in *; do
|
|
test -d $dir && nsweep $dir
|
|
done
|
|
done
|
|
elif [ -n "$ports" -a "$auto" != "1" ]; then
|
|
for dir in $ports; do
|
|
test -d $dir && nsweep $dir
|
|
done
|
|
else
|
|
usage
|
|
fi
|
|
exit 0
|
|
}
|
|
|
|
info_portsgiven() {
|
|
echo "$0 will not touch anything outside of the portdirs given on the command line,"
|
|
echo "but it looks like the debris from building your ports might be lying around somewhere else."
|
|
echo "Consider following up with another script."
|
|
echo "Press enter to continue."
|
|
read ACKNOWLEDGE
|
|
}
|
|
|
|
info_auto() {
|
|
echo "$0 will not touch anything outside of"
|
|
printf '%s\n' $collections
|
|
echo "but it looks like the debris from building your ports might be lying around somewhere else."
|
|
echo "Consider following up with another script."
|
|
echo "Press enter to continue."
|
|
read ACKNOWLEDGE
|
|
}
|
|
|
|
# Main work happens below
|
|
trap "interrupted" SIGHUP SIGINT SIGQUIT SIGTERM
|
|
|
|
getoptions $@
|
|
|
|
# First determine the directories that have been configured for downloads and built packages.
|
|
if [ -f /etc/pkgmk.conf ]; then
|
|
SRCGLOB=$(grep PKGMK_SOURCE_DIR /etc/pkgmk.conf | sed "s/[\t w]*#.*//; s/.*=//")
|
|
PKGGLOB=$(grep PKGMK_PACKAGE_DIR /etc/pkgmk.conf | sed "s/[\t w]*#.*//; s/.*=//")
|
|
COMPRESSION_MODE=$(grep COMPRESSION_MODE /etc/pkgmk.conf | sed "s/[\t w]*#.*//; s/.*=//")
|
|
fi
|
|
# No custom setting for compression mode means that pkgmk falls back to the default, gzip.
|
|
[ -n "$COMPRESSION_MODE" ] || COMPRESSION_MODE="gz"
|
|
|
|
BLTGLOB='$name#$version-$release.pkg.tar.$COMPRESSION_MODE'
|
|
|
|
# Layouts 1 and 2: If all ports share a common directory (either for the sources or for
|
|
# the built packages), then this script might need to be supplemented by further cleaning.
|
|
# Suppress the warning if option -q (quiet mode) was given.
|
|
collections=`getportdirs`
|
|
|
|
if [ "$quiet" != "1" ]; then
|
|
if [ -n "$SRCGLOB" ] && echo "${SRCGLOB}" | grep -q -v '\$name'; then
|
|
if [ -n "$ports" ]; then
|
|
info_portsgiven
|
|
elif [ "$auto" = 1 ]; then
|
|
info_auto
|
|
fi
|
|
do_sweep
|
|
fi
|
|
if [ -n "$PKGGLOB" ] && echo "${PKGGLOB}" | grep -q -v '\$name'; then
|
|
if [ -n "$ports" ]; then
|
|
info_portsgiven
|
|
elif [ "$auto" = 1 ]; then
|
|
info_auto
|
|
fi
|
|
do_sweep
|
|
fi
|
|
fi
|
|
|
|
# Layout 3: the admin has left either PKGMK_SOURCE_DIR or PKGMK_PACKAGE_DIR at its default,
|
|
# or has defined at least one of them in terms of the port name. Do the sweep
|
|
# without issuing a warning (The option -q is not applicable for this layout).
|
|
|
|
do_sweep
|