summaryrefslogtreecommitdiff
path: root/prtsweep
blob: aa68300cafcafd497574f9214020d7b372729105 (plain)
    1 #!/bin/bash
    2 #
    3 # $Id: prtsweep,v 1.2 2003/12/17 21:17:02 opel Exp $
    4 # (c) 2002, 2003 by Martin Opel <martin at obbl-net dot de>
    5 # Revised 2021 by John McQuah <jmcquah at disroot dot org>
    6 #
    7 # May be redistributed and modified under the terms of the GPL
    8 # only usable with CRUX Linux, version 1.0 or higher
    9 #
   10 # USE AT YOUR OWN RISK
   11 #
   12 # This script scans your supfiles in /etc/ports to find out your port
   13 # directories and then scans all ports for old files, which are not part
   14 # of the source-array in the Pkgfile and are not pkgfiles (name#version...).
   15 # All these old files are removed. For details see "man 1 prtsweep".
   16 #
   17 
   18 info() {
   19     echo -e "=======> $@"
   20 }
   21 
   22 msg() {
   23     echo -e "+ $@"
   24 }
   25 
   26 error() {
   27     info "ERROR: $@"
   28 }
   29 
   30 interrupted() {
   31     info "exiting..."
   32     exit 1
   33 }
   34 
   35 getportdirs() {
   36     cat /etc/ports/*.{httpup,rsync} 2>/dev/null \
   37 	   | awk -F= '$1=="destination" || $1=="ROOT_DIR" {print $2}'
   38 }
   39 
   40 remove() {
   41     item=$1
   42     if [ -f "$item" ]; then
   43         if [ "$dryrun" = "1" ]; then
   44             msg "removing file $item (dryrun)"
   45         else
   46             msg "removing file $item"	    
   47             rm "$item"
   48         fi
   49     elif [ -d "$item" ]; then
   50         if [ "$dryrun" = "1" ]; then
   51             msg "removing directory $item (dryrun)"
   52         else
   53             msg "removing directory $item"
   54             rm -r "$item"
   55         fi
   56     fi
   57 }
   58 
   59 removeemptydir() {
   60 # called if the directory lacks a Pkgfile. Still need to check whether
   61 # it is actually empty.
   62     local baggage
   63     baggage=(`find $1`)
   64     if [ ${#baggage[@]} -eq 1 ]; then
   65         remove $1
   66     else
   67         info "files still remaining in port directory '$1'!"
   68 	info "okay to remove them? (y/n)"
   69 	read CONSENT
   70 	if [ "$CONSENT" = "y" ]; then
   71 		for (( f=1; f<${#baggage[@]}; f++ )); do
   72 			remove ${baggage[$f]}
   73 		done
   74 	fi
   75     fi
   76 }
   77 
   78 inlist() {
   79     local excode
   80     item=$1
   81     shift
   82     list="$@"
   83     excode=1 # assume not in the list until proven otherwise
   84 
   85     while [ "$#" -gt 0 ]; do
   86         if [ "$item" = "$1" ]; then
   87 	    excode=0
   88 	    break
   89         else
   90 	    shift
   91         fi
   92     done
   93     
   94     return $excode
   95 }
   96 
   97 PWD_filename() {
   98 	if [[ $1 =~ ^(http|https|ftp|file)://.*/(.+) ]]; then
   99 		echo "${BASH_REMATCH[2]}"
  100 	else
  101 		echo $1
  102 	fi
  103 }
  104 
  105 remote_filename() {
  106 	if [[ $1 =~ ^(http|https|ftp|file)://.*/(.+) ]]; then
  107 		echo "/remote/path/${BASH_REMATCH[2]}"
  108 	else
  109 		echo $1
  110 	fi
  111 }
  112 
  113 nsweep() {
  114     dir=$1
  115     reset_keepfiles
  116     local printedpwd="false"
  117     local name version source renames pkgfiles packagename packagepath subdir
  118 
  119     if [ ! -d $dir ]; then
  120         error "'`pwd`/$dir' is not a directory!"
  121         usage
  122     fi
  123 
  124     if [ ! -f $dir/Pkgfile ]; then
  125         info `pwd`/$dir
  126         msg "no Pkgfile found, empty port '$dir'."
  127         if [ "$delete" = "1" ]; then
  128             removeemptydir $dir
  129         else
  130             msg "use '-d' to remove empty directories."
  131         fi
  132         return
  133     fi
  134     
  135     echo "sweeping the directory for port $dir"
  136     
  137     # read the port information from its Pkgfile and save the results in a bash array.
  138     # This loop assumes that renaming is only applied to files downloaded over http or ftp,
  139     # not under version control systems like rsync or httpup. To preserve this information,
  140     # an arbitrary URI scheme is prepended before the desired filename.
  141     pkgfiles=(`( . $dir/Pkgfile; PKGLOC=$(eval "printf '%s' $PKGGLOB"); \
  142 	    PKGFILE=$(eval "printf '%s' $BLTGLOB"); \
  143 	    for (( p=0; p<${#source[@]}; p++ )); do \
  144 	[ -n "${renames[$p]}" -a "${renames[$p]}" != "SKIP" ] && source[$p]="ftp://somehost/${renames[$p]}"; \
  145 	done; echo "$PKGLOC/$PKGFILE"; \
  146 	printf '%s ' "${source[@]}" )`)
  147 
  148     cd $dir
  149     # (new feature in v0.5) remove the package too, if the user requests it with the "-p" flag
  150     if [ "$pkgtoo" != "1" ]; then
  151 	    packagename=`basename ${pkgfiles[0]}`
  152 	    packagepath=`dirname ${pkgfiles[0]}`
  153 	    if [ "${packagepath:0:1}" = "/" ]; then
  154 	         KEEP_FILES="${KEEP_FILES} $packagename"
  155 	    elif [ "${packagepath:0:1}" != "/" ]; then
  156 		 subdir=$(echo $PKGLOC | sed "s|/.*||")
  157 	         KEEP_FILES="${KEEP_FILES} $subdir"
  158 	    fi
  159     fi
  160 
  161     # Now that we're safely out of the nested subshell, the URI scheme can be replaced.
  162     # Make the new value match the `ls -A` output unless the user has requested
  163     # removal of source files too.
  164     if [ "$rmsources" = 1 ]; then
  165     for (( p=1; p<${#pkgfiles[@]}; p++ )); do
  166 	    pkgfiles[$p]=`remote_filename ${pkgfiles[$p]}`
  167     done
  168     else
  169     for (( p=1; p<${#pkgfiles[@]}; p++ )); do
  170 	    pkgfiles[$p]=`PWD_filename ${pkgfiles[$p]}`
  171     done
  172     fi
  173 
  174     unset pkgfiles[0]
  175     for f in `ls -A`; do
  176         if [[ ! ${KEEP_FILES} =~ "$f" ]] && ! inlist "$f" ${pkgfiles[@]}; then
  177                 if [ "$printedpwd" = "false" ]; then
  178                        printedpwd="true"
  179                        info `pwd`
  180                 fi
  181             remove $f
  182         fi
  183     done
  184     cd - &>/dev/null
  185 }
  186 
  187 reset_keepfiles() {
  188     KEEP_FILES="Pkgfile README pre-install post-install
  189                 .footprint .signature .32bit .nostrip"
  190 }
  191 
  192 getoptions() {
  193     while [ "$1" = "-a" -o "$1" = "-d" -o "$1" = "-n" -o "$1" = "-p" -o "$1" = "-s" -o "$1" = "-q" ]; do
  194 	if [ "$1" = "-q" ]; then
  195 	    quiet=1
  196 	    shift
  197         elif [ "$1" = "-s" ]; then
  198 	    rmsources=1
  199 	    shift
  200 	elif [ "$1" = "-p" ]; then
  201 	    pkgtoo=1
  202 	    shift
  203 	elif [ "$1" = "-n" ]; then
  204             dryrun=1
  205             shift
  206         elif [ "$1" = "-d" ]; then
  207             delete=1
  208             shift
  209         elif [ "$1" = "-a" ]; then
  210             auto=1
  211             shift
  212         fi
  213     done
  214     ports="$@"
  215 
  216     if [ -z "$ports" -a "$auto" != "1" ]; then
  217 	    echo "You must explicitly call for automatic mode (-a) if you"
  218 	    echo "do not provide the paths of ports you want cleaned."
  219 	    usage
  220     elif [ -n "$ports" -a "$auto" = "1" ]; then
  221 	    echo "Automatic mode (-a) is incompatible with providing an"
  222 	    echo "explicit list of ports to clean."
  223 	    usage
  224     fi
  225 	    
  226 }
  227 
  228 usage() {
  229     echo 
  230     echo "Usage: prtsweep [-a] [-d] [-n] [-s] [-p] [-q] [PORTDIR ...]"
  231     echo
  232     exit 1
  233 }
  234 
  235 do_sweep() {
  236     PKGGLOB=$(echo "$PKGGLOB" | sed 's/PortName/$name/')
  237     BLTGLOB='$name#$version-$release.pkg.tar.$COMPRESSION_MODE'
  238 
  239     if [ -z "$ports" -a "$auto" = "1" ]; then
  240 	for portdir in $collections; do
  241 		echo $portdir
  242 		cd $portdir
  243 		for dir in *; do
  244 			test -d $dir && nsweep $dir
  245 		done
  246 	done
  247     elif [ -n "$ports" -a "$auto" != "1" ]; then
  248         for dir in $ports; do
  249             test -d $dir && nsweep $dir
  250         done
  251     else
  252 	    usage
  253     fi
  254     exit 0
  255 }
  256 
  257 info_portsgiven() {
  258         echo "$0 will not touch anything outside of the portdirs given on the command line,"
  259 	echo "but it looks like the debris from building your ports might be lying around somewhere else."
  260 	echo "Consider following up with another script."
  261 	echo "Press enter to continue."
  262 	read ACKNOWLEDGE
  263 }
  264 
  265 info_auto() {
  266 	echo "$0 will not touch anything outside of"
  267 	printf '%s\n' $collections
  268 	echo "but it looks like the debris from building your ports might be lying around somewhere else."
  269 	echo "Consider following up with another script."
  270 	echo "Press enter to continue."
  271 	read ACKNOWLEDGE
  272 }
  273 
  274 # Main work happens below
  275 trap "interrupted" SIGHUP SIGINT SIGQUIT SIGTERM
  276 
  277 getoptions $@
  278 
  279 # First determine the directories that have been configured for downloads and built packages.
  280 # Replace any references to $name so an unset shell variable won't cause information loss.
  281 if [ -f /etc/pkgmk.conf ]; then
  282     eval $(grep PKGMK_SOURCE_DIR /etc/pkgmk.conf | tail -n 1 | \
  283 	    sed 's/PKGMK_SOURCE_DIR/SRCGLOB/; s/\$name/PortName/')
  284     eval $(grep PKGMK_PACKAGE_DIR /etc/pkgmk.conf | tail -n 1 | \
  285 	    sed 's/PKGMK_PACKAGE_DIR/PKGGLOB/; s/\$name/PortName/')
  286     eval $(grep COMPRESSION_MODE /etc/pkgmk.conf | tail -n 1 | \
  287 	    sed 's/PKGMK_//')
  288 fi
  289 # No custom setting for compression mode means that pkgmk falls back to the default, gzip.
  290 [ -n "$COMPRESSION_MODE" ] || COMPRESSION_MODE="gz"
  291 
  292 # Layouts 1 and 2: If all ports share a common directory (either for the sources or for
  293 #  the built packages), then this script might need to be supplemented by further cleaning.
  294 #  Suppress the warning if option -q (quiet mode) was given.
  295 collections=`getportdirs`
  296 
  297 if [ "$quiet" != "1" ]; then
  298    if [ -n "$SRCGLOB" ] && echo "${SRCGLOB}" | grep -q -v 'PortName'; then
  299       if [ -n "$ports" ]; then
  300 	info_portsgiven
  301       elif [ "$auto" = 1 ]; then
  302 	info_auto
  303       fi
  304       do_sweep
  305    fi
  306    if [ -n "$PKGGLOB" ] && echo "${PKGGLOB}" | grep -q -v 'PortName'; then
  307       if [ -n "$ports" ]; then
  308 	info_portsgiven
  309       elif [ "$auto" = 1 ]; then
  310 	info_auto
  311       fi
  312       do_sweep
  313    fi
  314 fi
  315 
  316 # Layout 3: the admin has left either PKGMK_SOURCE_DIR or PKGMK_PACKAGE_DIR at its default,
  317 # or has defined at least one of them in terms of the port name. Do the sweep
  318 # without issuing a warning (The option -q is not applicable for this layout).
  319 
  320 do_sweep

Generated by cgit