#!/bin/sh
#
# vi wrapper.
#
# Features locking, file backup
# and version control, if desirable.
#
# requires vim and rcs or cvs.
#
# Copyright (c) 2002-2003  Thomas Linden, <tom@daemon.de>.
#
# $Id$
#



#
# default config, if nothing specified
VERSION_CONTROL="rcs"
FILE_BACKUP="yes"

#
# check for config
if test -e "/etc/viwl.conf"; then
    # use global config
    . /etc/viwl.conf
fi

if test -e "$HOME/.viwl"; then
    # use personal config
    . $HOME/.viwl
fi

#
# find out who we are
me=`basename $0`
editor=`bash -c "type -p ${me}.bin"`
if test "x$editor" = "x"; then
    echo "${me}.bin does not exist!" > /dev/stderr
    exit
fi




#
# function definitions
backup () {
    file=$1
    if test "x$FILE_BACKUP" = "xyes"; then
	if test ! -e "$file~"; then
	    # make backup copy
	    cp -p "$file" "$file~"
	fi
    fi
}

checkout () {
    file=$1
    if test "x$VERSION_CONTROL" = "xrcs"; then
	# RCS
	if test -e "RCS/$file,v"; then
	    # version controlled file
	    echo "Checking out $input" > /dev/stderr
	    chmod -w "$file"
	    co -l "$file"
	fi
    elif test "x$VERSION_CONTROL" = "xcvs"; then
	# CVS
	# nothing to do
	echo -n "" > /dev/stderr 
    fi
}

checkin () {
    file=$1
    if test "x$VERSION_CONTROL" = "xrcs"; then
	# RCS
	if test -e "RCS/$file,v"; then
	    # version controlled file
	    if test -w "$file"; then
		# need to check it in and out read only
		echo "Checking in $input" > /dev/stderr
                if test -n "$SSHUSER"; then
                  SSHUSER=`echo $SSHUSER | sed 's/@/-/'`
		  ci -w$SSHUSER "$file"
                else
                  ci "$file"
                fi
		co "$file"
	    fi
	fi
    elif test "x$VERSION_CONTROL" = "xcvs"; then
	# CVS
	dir=`dirname $file`
	file=`basename $file`
	if test "x$dir" = "x."; then
	    dir=""
	fi
	dir="`pwd`/$dir"
	dir=`echo $dir | sed 's/^\///'`
	dir=`echo $dir | sed 's/\/$//'`
	repository=`basename $WORK_DIR`
	if test -e "$CVS_ROOT/$repository/$dir/$file,v"; then
	    # version controlled file
	    cp -p "/$dir/$file" "$WORK_DIR/$dir/"
	    cvs -d $CVS_ROOT commit "$WORK_DIR/$dir/$file"
	    cp -p "$WORK_DIR/$dir/$file" "/$dir/"
	fi
    fi
}

lock () {
    if test -n "$LOCKING"; then
	file=$1
	os=`uname`
	inode=`ls -i "$file" | sed 's/^ //g' | cut -f 1 -d " "`
	lockfile="/tmp/.viwl.lock.${inode}"
    
	if test -r "${lockfile}"; then
	    echo "$file is locked by: `cat $lockfile` (LOCK: $lockfile) !" > /dev/stderr
	    exit
	else
	    if test -n "$SSHUSER"; then
		lockuser=$SSHUSER
	    else
		lockuser=`whoami`
	    fi
	    echo "$lockuser (PID: $$) (executing: $0 $@) (pwd: `pwd`)" > $lockfile
	    chmod 644 $lockfile
	fi
    fi
}

unlock () {
    if test -n "$LOCKING"; then
	file=$1
	os=`uname`
	inode=`ls -i "$file" | sed 's/^ //g' | cut -f 1 -d " "`
	lockfile="/tmp/.viwl.lock.${inode}"

	if test -w "$file"; then
	    rm -f $lockfile
	elif test -r "$file"; then
	    echo "lockfile $lockfile for $file exists but is not writable!" > /dev/stderr
	    exit
	fi
    fi
}

# work on every input file (if any)
for input in "$@"; do
    if test -e "$input"; then
	# edit file
	dir=`dirname $input | sed 's/^\.//'`
	if test -d "$dir"; then
	    # absolute filename
	    cd $dir
	    changedir="yes"
	    file=`basename "$input"`
	else
	    file="$input"
	fi

	lock "$file"
	backup "$file"
	checkout "$file"

	if test -n "$changedir"; then
	    cd -
	    changedir=""
	fi
    fi
done

$editor $@

for input in "$@"; do
    if test -e "$input"; then
	dir=`dirname $input | sed 's/^\.//'`
	if test -d "$dir"; then
	    # absolute filename
	    cd $dir
	    changedir="yes"
	    file=`basename "$input"`
	else
	    file="$input"
	fi

	checkin "$file"
	unlock "$file"

	if test -n "$changedir"; then
	    cd -
	    changedir=""
	fi
    fi
done



