diff options
Diffstat (limited to 'prtsweep')
-rw-r--r--[-rwxr-xr-x] | prtsweep | 273 |
1 files changed, 199 insertions, 74 deletions
@@ -1,7 +1,8 @@ #!/bin/bash # # $Id: prtsweep,v 1.2 2003/12/17 21:17:02 opel Exp $ -# (c) 2002, 2003 by Martin Opel <martin@obbl-net.de> +# (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 @@ -32,67 +33,88 @@ interrupted() { } getportdirs() { - local f - for f in /etc/ports/*.rsync /etc/ports/*.httpup; do - awk -F= '$1=="destination" || $1=="ROOT_DIR" {print $2}' $f - done -} - -keepfiles() { - local f - for f in "${KEEP_FILES[@]}"; do - if [ "$1" = "$f" ]; then - return 0 - fi - done - return 1 + 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 [ -f "$item" ]; then if [ "$dryrun" = "1" ]; then msg "removing file $item (dryrun)" else msg "removing file $item" - rm $item + rm "$item" fi - elif [ -d $item ]; then + elif [ -d "$item" ]; then if [ "$dryrun" = "1" ]; then msg "removing directory $item (dryrun)" else msg "removing directory $item" - rm -r $item + rm -r "$item" fi fi } removeemptydir() { - if [ `find $1 | wc -l` -eq 1 ]; then +# 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 "cannot remove non-empty directory '$dir'" + 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 - for i in $list; do - if [ "$i" = "$item" ]; then - return 0 + while [ "$#" -gt 0 ]; do + if [ "$item" = "$1" ]; then + excode=0 + break + else + shift fi done - - return 1 + + 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 } -sweep() { +nsweep() { dir=$1 - savedir=`pwd` - printedpwd="false" + 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!" @@ -110,81 +132,184 @@ sweep() { return fi - cd $dir - unset name version source pkgfiles - . Pkgfile + echo "sweeping the directory for port $dir" - for f in ${source[@]}; do - pkgfiles=( `basename $f` ${pkgfiles[@]} ) + # 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 - for f in `ls -a`; do - if ! keepfiles "$f"; then - if ! echo $f | grep '.*#.*\.pkg\.tar\.[gbx]z*' >/dev/null; then - if ! inlist $f ${pkgfiles[@]}; then - if [ "$printedpwd" = "false" ]; then - printedpwd="true" - info `pwd` - fi - remove $f + 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 - fi + remove $f fi done - cd $savedir + 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" ]; do - if [ "$1" = "-n" ]; then + 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 - fi - if [ "$1" = "-d" ]; then + elif [ "$1" = "-d" ]; then delete=1 shift - fi - if [ "$1" = "-a" ]; then + 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] [PORTDIR ...]" + 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 $@ -KEEP_FILES=( - "Pkgfile" "README" "pre-install" "post-install" - ".footprint" ".signature" ".32bit" ".nostrip" - "." ".." -) +# 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' -if [ -z "$ports" -a "$auto" = "1" ]; then - for portdir in `getportdirs`; do - savedir=`pwd` - cd $portdir - for dir in *; do - test -d $dir && sweep $dir - done - cd $savedir - done - exit 0 -elif [ ! -z "$ports" ]; then - for dir in $ports; do - sweep $dir - done - exit 0 +# 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 -usage -exit 1 +# 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 |