#! /bin/sh ### Sanitize -- remove the unclean bits from a distribution or a file ### (perhaps this should be called an Exorcist?) ### ### See the file Sanitize.texi for whatever sort of documentation this ### program has. ### ### Usage: Sanitize [keep-cvs] [keep-sanitize] [test] [recover] [verbose] [-n] ... ### Note that the highest level Sanitize command-line may have arbitrary ### other options, which have meaning only within some `Do-first' or ### `Do-last' script fragment. ### ### The -n option, like make's -n option, simply shows you what the ### script *would have* done, given the other parameters you've passed ### to it. No actions are taken except traversal of the directory tree. ### ### written by K. Richard Pixley, hacked by david d `zoo' zuhn ### -n option, lots of comments added by Bill Cox ### SHELL=/bin/sh ; export SHELL ## We have three cases: ## The path given was absolute ## action: just keep it ## The name had a relative path ## action: make it absolute. ## The name had no directory components and was path searched ## action: just keep it, since the path search will *still* work case $0 in /*) sanprog=$0 ;; */*) sanprog=$0 sandir=`dirname $sanprog` sandir=`(cd $sandir; pwd)` sanprog=$sandir/`basename $sanprog` ;; *) sanprog=$0 ;; esac ### "debugger" #set -x ### Some variables and temp files; remove on any exit. workdir=/tmp cleaned=${workdir}/$$San.clean keepers=${workdir}/$$San.keep losers=${workdir}/$$San.lose sandd=${workdir}/$$San.temp sanStatus=1 trap 'rm -f ${cleaned} ${keepers} ${sandd} ${losers} ; exit $sanStatus' 0 ### Make sure there is a .Sanitize if [ ! -f .Sanitize ] ; then echo '***' No .Sanitize file in `pwd`! 1>&2 exit 1 else true fi ### check for optional things-to-lose section first if ( egrep '^Things-to-lose:$' < .Sanitize > /dev/null ) ; then losingthings=true else losingthings= fi ### Check that all trigger lines exist and are in order. if [ -n "${losingthings}" ] ; then egrep '^Do-first:$|^Things-to-keep:$|^Things-to-lose:|^Do-last:$' < .Sanitize > ${sandd} diff ${sandd} - < ${sandd} diff ${sandd} - <&2 echo '***' or out-of-order in `pwd`/.Sanitize 1>&2 exit 1 else true fi ### die on errors set -e ### set verbose if ( echo $* | egrep verbose > /dev/null ) ; then verbose=true else verbose= fi ### set no_action flag if '-n' set ### The echo ... egrep sequence didn't work ### with the leading hyphen. no_action= for opt in $* do case $opt in -n) no_action=true ;; *) ;; esac done ### cache current directory name. THISDIR=`pwd` ### Remove comments & blank lines. egrep -v "^#" < .Sanitize | sed -e '/^$/d' > ${cleaned} ### Do-first stuff. ### Note that the parameters to Sanitize are also passed ### to the fragment. The fragment may optionally set the ### variables `keep_these_too' and `lose_these_too'. sed -e '/^Things\-to\-keep:$/,$d' -e '1d' ${cleaned} > ${sandd} if [ -s ${sandd} ] ; then if [ -n "${no_action}" ] ; then echo ". ${sandd} $*" else . ${sandd} $* fi else if [ -n "${verbose}" ] ; then echo "No \`Do-first' fragment to execute." else true fi fi ### Things-to-keep: ### Just build the list of keepers for now. sed -e '1,/^Things\-to\-keep:$/d' ${cleaned} > ${sandd} if [ -n "${losingthings}" ] ; then sed -e '/^Things\-to\-lose:$/,$d' ${sandd} > ${keepers} else sed -e '/^Do-last:$/,$d' ${sandd} > ${keepers} fi if [ -n "${keep_these_too}" ] ; then for i in ${keep_these_too} ; do if [ -n "${verbose}" ] ; then echo Keeping $i else true fi echo $i >> ${keepers} done else true fi ### Things-to-lose: ### Just build the list of losers for now. if [ -n "${losingthings}" ] ; then sed -e '1,/^Things\-to\-lose:$/d' \ -e '/^Do\-last:$/,$d' ${cleaned} \ > ${losers} else cat /dev/null > ${losers} fi if [ -n "${lose_these_too}" ] ; then for i in ${lose_these_too} ; do if [ -n "${verbose}" ] ; then echo Losing $i else true fi echo $i >> ${losers} done else true fi ### catch and handle "recover" if ( echo $* | egrep recover > /dev/null ) ; then if [ -d .Recover ] ; then cd .Recover replace=`ls -a | egrep -v '^\.$|^\.\.$'` if [ -n "${no_action}" ] ; then echo "cd .Recover" echo "mv ${replace} .." echo "cd .." cd .. # Must also do this for real.. echo "rmdir .Recover" else if [ -n "${verbose}" ] ; then echo Replacing ${replace} fi mv ${replace} .. cd .. rmdir .Recover fi else true fi for i in `egrep -v CVS ${keepers} | egrep -v \\.Recover` ; do if [ -d "$i" ] ; then if [ -n "${no_action}" ] ; then echo "cd $i" else if [ -n "${verbose}" ] ; then echo Running ${sanprog} on ${THISDIR}/$i else true fi fi (cd $i ; ${sanprog} $*) | sed 's/^/ /' else true fi done sanStatus=0 exit 0 else ### catch and handle "test" if ( echo $* | egrep test > /dev/null ) ; then echo CVS >> ${keepers} echo .Sanitize >> ${keepers} echo .Recover >> ${keepers} # echo .cvsignore >> ${keepers} if [ -n "${no_action}" ] ; then echo "mkdir .Recover" else if [ -n "${verbose}" ] ; then echo Keeping CVS, .Sanitize, .cvsignore, and .Recover echo Creating ${THISDIR}/.Recover to hold unclean files... else true fi mkdir .Recover fi safe=safe else ### if not testing, then lose .Sanitize. if [ -n "${verbose}" ] ; then echo Losing .Sanitize else true fi echo .Sanitize >> ${losers} ### catch and handle "keep-cvs" if ( echo $* | egrep keep-cvs > /dev/null ) ; then if [ -n "${verbose}" ] ; then echo Keeping CVS #, .cvsignore else true fi echo CVS >> ${keepers} # echo .cvsignore >> ${keepers} else if [ -n "${verbose}" ] ; then echo Losing CVS #, .cvsignore else true fi echo CVS >> ${losers} # echo .cvsignore >> ${losers} fi fi fi ### otherwise move files away ### Issue errors for explicit losers which don't exist. tolose=`sed -e 's/[ ]*$//' ${losers}` if [ -n "${tolose}" ] ; then for i in ${tolose} ; do if [ -f $i -o -d $i ]; then if [ -n "${safe}" ] ; then if [ -n "${no_action}" ] ; then echo "mv $i .Recover" else if [ -n "${verbose}" ] ; then echo Caching $i in .Recover... else true fi mv $i .Recover fi else if [ -n "${no_action}" ] ; then echo "rm -rf $i" else if [ -n "${verbose}" ] ; then echo Removing ${THISDIR}/$i else true fi rm -rf $i fi fi else echo '***' "Can't" remove expected file/directory ${THISDIR}/$i - not found. 1>&2 fi done else true fi ### lose everything else in the directory, ### except the explicit keepers. tolose=`(ls -a | egrep -v '^\.$|^\.\.$' ; \ sed -e 's/[ ]*$//' ${keepers}) | sort | uniq -u` # $tolose is a list of files from ${keepers} or in directory but not both if [ -n "${tolose}" ] ; then for i in ${tolose} ; do if [ -f $i -o -d $i ]; then # is in directory and not in ${keepers} if [ -n "${safe}" ] ; then if [ -n "${no_action}" ] ; then echo "mv $i .Recover" else echo '***' Caching unexpected file ${THISDIR}/$i in .Recover... 1>&2 mv $i .Recover fi else if [ -n "${no_action}" ] ; then echo "rm -rf $i" else echo '***' Removing unexpected file ${THISDIR}/$i 1>&2 rm -rf $i fi fi else # is in ${keepers} but not in directory echo '***' "Can't" keep expected file ${THISDIR}/$i - not found. 1>&2 fi done else true fi ### Recurse into any subdirectories flagged as keepers. ### Do the same good deeds down there. for i in `egrep -v CVS ${keepers} | egrep -v \\.Recover` ; do if [ -d $i ] ; then if [ -n "${no_action}" ] ; then echo "cd $i" else if [ -n "${verbose}" ] ; then echo Running ${sanprog} on ${THISDIR}/$i else true fi fi (cd $i ; ${sanprog} $*) | sed 's/^/ /' else true fi done ### Do-last: sed -e '1,/^Do\-last:$/d' ${cleaned} > ${sandd} if [ -s ${sandd} ] ; then if [ -n "${no_action}" ] ; then echo ". ${sandd} $*" else . ${sandd} $* fi else if [ -n "${verbose}" ] ; then echo "No \`Do-last' fragment to execute." else true fi fi ### cleanup if ( echo $* | egrep test > /dev/null ) ; then if [ -n "${safe}" -a "`cd .Recover ; (echo empty ; ls -a) | \ egrep -v '^\.$|^\.\.$'`" = "empty" ] ; then if [ -n "${no_action}" ] ; then echo "rmdir .Recover" else if [ -n "${verbose}" ] ; then echo Removing .Recover. It was not needed. else true fi rmdir .Recover fi fi fi sanStatus=0 ### eof.