#!/bin/sh
#		R C S B A C K U P
#		-----------------
#
# Description:
#	Backup files into rcs archives.
#
# Options:
#	-v		- Turn on verbose mode.
#	-d <dir>	- Specify root of backup directory.
#	-f <file>	- Specify file that contains list of files
#			  and/or directories to backup.
#
# Arguments:
#	<file/dir> ...	- Directories or files to backup.
#
# By:
#	Lars Berntzon
#
# Email:
#	lab@cap.se
#
# rcsbackup,v
# Revision 1.9  1997/09/05 13:22:59  lasse
# Now breaks locks by others if any
#
# Revision 1.6  1995/02/08  14:28:42  qdtlarb
# *** empty log message ***
#
# Revision 1.5  1993/09/19  20:48:10  lasse
# Shipment 1.0 second try.
#
# Revision 1.4  1993/09/19  20:23:39  lasse
# Shipment V1.0
#
# Revision 1.3  1993/09/19  18:56:51  lasse
# Added a couple of examples.
#
# Revision 1.2  1993/09/19  18:36:39  lasse
# It might work now.
#
# Revision 1.1  1993/09/19  18:02:42  lasse
# First test version
#
# @(#) /home/lasse/.CVSROOT/src/satools/satools/rcsbackup/rcsbackup,v 1.9 1997/09/05 13:22:59 lasse Exp
#
IFS=" 	
"; export IFS
prog="`basename $0`"
verbose() { :; }
export RCSBACKUPDIR

#
##################################################################
#
#		U S A G E
#		---------
# Description:
#	Print usage of program and exit.
#
##################################################################
usage()
{
    echo "usage: $prog [-d <dir> ] [-f <file> | <file/dir> ...]" >&1
    exit 1
}

#
##################################################################
#		E X P A N D
#		-----------
# Description:
#	Read directories and files and produce list of
#	pure files.
#
##################################################################
expand()
{
    while read item
    do
	if [ -z "$item" ]; then
	    continue
	fi
    
	if [ -d $item ]; then
	    find $item/. -type f -print
	elif [ -c $item -o -b $item -o -p $item ]; then
	    echo "$item: unsupported file type" >&2
	else
	    for i in $item
	    do
		echo $i
	    done
	fi
    done | sed -e 's%/\./%/%g' -e 's%//*%/%g'
}

#
##################################################################
#		C H E C K I N
#		-------------
# Description:
#	Copy and check in the file.
#
##################################################################
checkin()
{
    if [ $# != 1 ]; then
	return 1
    fi

    echo $1 | cpio -pudm $RCSBACKUPDIR > /dev/null 2>&1 || {
	echo "$prog: failed to copy $1" >&2
	return 1
    }
    ( cd `dirname $RCSBACKUPDIR/$1` || {
	echo "$prog: failed to cd to $RCSBACKUPDIR/$1" >&2
	exit 1
      }
      file=`basename $1`	
      ci -q ./$file,v < /dev/null || {
	rcs -M -u ./$file,v > /dev/null 2>&1
	rcs -l ./$file,v > /dev/null 2>&1
	      ci -q ./$file,v < /dev/null || {
		echo ci failed for $file
	      }
      }
      rcs -q -l ./$file,v || echo rcs failed to lock $file
    )
}

#
##################################################################
#		B A C K U P
#		-----------
# Description:
#	Read list of files and back them up.
#
##################################################################
backup()
{
    #
    # Read files and backup them.
    #
    while read file
    do
	#
	# New file ?.
	#
	if [ ! -f $file ]; then
	    echo "not found : $file" >&2
	elif [ ! -r $file ]; then
	    echo "unreadable: $file" >&2
	elif [ ! -f $RCSBACKUPDIR/$file,v ]; then
	    verbose "new       : $file"
	    checkin $file
	else
	    #
	    # Has file changed ?.
	    #
	    if [ ! -z "`find $file -newer $RCSBACKUPDIR/$file,v -print`" ]; then
		verbose "modified  : $file"
		checkin $file
	    else
		verbose "unchanged : $file"
	    fi
	fi
    done
}
    
#
##################################################################
#
#		M A I N
#		-------
# Description:
#	main routine of rcsbackup
#
##################################################################
main()
{
    unset inputfile

    #
    # Parse arguments.
    #
    while [ $# -ne 0 ]
    do
	case $1 in
	-d)
	    [ $# -gt 1 ] || usage
	    RCSBACKUPDIR=$2
	    shift;;
	-v)
	    verbose() {
		echo "$@"
	    };;
	-f)
	    [ $# -gt 1 ] || usage
	    inputfile=$2
	    shift;;
	-*)
	    usage;;
	*)
	    break;
	esac
	shift
    done

    #
    # Check that destination directory is known.
    #
    if [ x$RCSBACKUPDIR = x ]; then
	echo "$prog: the variable RCSBACKUPDIR must be set or the" >&2
	echo "option -d must be specified" >&2
	exit 1
    fi

    #
    # Check that it exists.
    #
    if [ ! -d $RCSBACKUPDIR ]; then
	echo "$prog: directory $RCSBACKUPDIR not found" >&2
	exit 1
    fi

    #
    # and writeable.
    #
    if [ ! -w $RCSBACKUPDIR ]; then
	echo "$prog: directory $RCSBACKUPDIR is not writeable" >&2
	exit 1
    fi

    #
    # Check if arguments or input file.
    #
    if [ $# -ne 0 ]; then
	echo "$@"
    else
	sed '/^#/d' $inputfile
    fi | expand | backup
}

#
##################################################################
#
#		M A I N   P R O G R A M
#		-----------------------
##################################################################
if [ x$NOEXEC = x ]; then
    main "$@"
fi
