#! /bin/sh

#   Save the base version of a file in a Base subdirectory
#   and create a write-enabled copy to edit.

#   Implemented by John Walker (http://www.fourmilab.ch/) in
#   June 2004, based on an original design by Kern Sibbald
#   (http://www.sibbald.com/) in the early 1980s.  Note that
#   this script assumes that the "find" command speciied by
#   the FIND= variable below is Gnu find.

#   Options:

#   	setbase -b
#   	    List all files in base directory.

#   	setbase -d file1...
#   	    Diff the base copies of the file arguments against their
#   	    copies in the current directory.

#   	setbase -d
#   	    Diff all base files against their copies in the current
#   	    directory.

#   	setbase -m
#   	    List all modified (write-enabled) files in the current
#   	    directory.  Note that this shows both files with base
#   	    copies and newly-added files.  Since object files will
#   	    be included in this listing, you'll usually want to
#   	    delete them before using this command.

#   	setbase -mr
#   	    List all modified (write-enabled) files in the current
#   	    directory and any subdirectories.

#   	setbase -s
#   	    Set all files in current directory read-only.  This
#   	    prepares a directory for use with setbase.

#   	setbase -sr
#   	    Set all files in current directory and any subdirectories
#   	    read-only.
#   Name of base directory
BASEDIR=Base

#   How to run Gnu "find"
FIND=find

#   You shouldn't have to change anything below this line

VERSION='1.0'
DATE='2004-08-16'

#   Ensure the user specified one or more file names

if [ "x$1" = "x" -o "x$1" = "x-u" ]
then
    echo "Usage: setbase file...     Save base copy, write-enable files for editing"
    echo "       setbase -b          List files in base directory"
    echo "       setbase -d file...  Diff base against current files"
    echo "       setbase -d          Diff all base against current files"
    echo "       setbase -m          List all write-enabled files"
    echo "       setbase -mr         List all write-enabled files, recurse directories"
    echo "       setbase -s          Set all files read-only"
    echo "       setbase -sr         Set all files read-only, recurse directories"
    echo "       setbase -u          Print this message"
    echo "Version $VERSION ($DATE)"
    echo "The current version is available from http://www.fourmilab.ch/webtools/setbase/"
    echo "This program is in the public domain."
    exit 0
fi

#   Make sure we don't have a regular file named "$BASEDIR"
#   in the directory.

if [ -f $BASEDIR ]
then
    echo "A regular file named \"$BASEDIR\" exists!"
    echo "Setbase gives up.  (No harm done.)"
    exit 1
fi

#   If the "-b" option is specified, list all files in the
#   base directory.

if [ "x$1" = "x-b" ]
then
    ls -1 $BASEDIR
    exit 0
fi

#   If the "-d" option is specified, diff all subsequent
#   arguments against their saved base copies or, if no
#   arguments are given, all base files against their
#   current versions.

if [ "x$1" = "x-d" ]
then
    if [ "x$2" = "x" ]
    then
    	for f in `$FIND $BASEDIR -type f | sort`
	do
	    BF=`basename $f`
	    echo
	    echo "-- $BF --"
	    diff $f $BF
	done
    else
    	shift
	while [ "x$1" != "x" ]
	do
	    if [ ! -f $BASEDIR/$1 ]
	    then
	    	echo
	    	echo "No file $1 in the $BASEDIR directory."
	    else
		echo
		echo "-- $1 --"
		diff $BASEDIR/$1 $1
	    fi
	    shift
	done
    fi
    exit 0
fi

#   If the "-m" option is specified, list all write-enabled
#   and hence modified files in the current directory, or
#   recursively if "-mr" is specified.

if [ "x$1" = "x-m" -o "x$1" = "x-mr" ]
then
    DEPTH='-maxdepth 1'
    #	If the "-r" option was also specified, apply the
    #	change recursively to subdirectories.
    if [ "x$1" = "x-mr" ]
    then
    	DEPTH=''
    fi
    $FIND . $DEPTH -type f -type f -perm +222 -print
    exit 0
fi

#   If the "-s" option is specified, set all regular files in the
#   current directory to read-only to prepare for use
#   with setbase.  The "-sr" option sets all files in the
#   current directory tree read-only.

if [ "x$1" = "x-s" -o "x$1" = "x-sr" ]
then
    DEPTH='-maxdepth 1'
    #	If the "-r" option was also specified, apply the
    #	change recursively to subdirectories.
    if [ "x$1" = "x-sr" ]
    then
    	DEPTH=''
    fi
    $FIND . $DEPTH -type f -exec chmod a-w {} \;
    exit 0
fi

#   If a base directory does not already exist, create it.

if [ ! -d $BASEDIR ]
then
    echo "Creating base directory $PWD/$BASEDIR."
    mkdir $BASEDIR
fi

#   Iterate over arguments and process each one

while [ "x$1" != "x" ]
do
    if [ `basename $1` = $1 ]
    then
	if [ ! -f $1 ]
	then
    	    if [ -a $1 ]
	    then
    		echo "$1 is not a regular file--ignored."
	    else
    		echo "$1 does not exist--ignored."
	    fi
	else
    	    if [ -f $BASEDIR/$1 ]
	    then
		echo "$1 already in $BASEDIR--skipped."
	    else
		if [ -w $1 ]
		then
	    	    echo "Warning: $1 was already write-enabled; set read-only"
		    chmod ugo-w $1
		fi
		mv $1 $BASEDIR
		cp $BASEDIR/$1 .
		chmod u+w $1
	    fi
	fi
    else
    	echo "$1 includes path specification--ignored.  Files must be in current directory."
    fi
    shift
done
