#!/bin/sh # cpv file dest # could extend with -r or copying multiple files ln_or_cp () { f=$(df $(dirname $1) | tail -1 | awk '{ print $1 }') d=$(df $(dirname $2) | tail -1 | awk '{ print $1 }') if [ "$f" != "$d" ]; then cmd="cp -p"; else cmd="ln"; fi echo $cmd } file="$1" dest="$2" if [ ! -f "$file" ]; then echo "Error: no such file "$file". Exiting." exit 1 fi # if dest is a directory, add the source file name if [ -d "$dest" ]; then dest=$dest/`basename $file` fi # if (the new) $dest is a directory, then just bail if [ -d "$dest" ]; then echo "Error: destination file ($dest) is a directory. Exiting." exit 1 fi # if no such file $dest then just copy if [ ! -f "$dest" ]; then $(ln_or_cp $file $dest) $file $dest echo "Added $(basename $dest) to $(dirname $dest)" exit 0 fi # find maximum version of dest max=0 for vf in "$dest".~[1-9]*~ do vn=`echo $vf | sed -e 's/^.*\.~\([1-9][0-9]*\)~$/\1/'` if [ -f $dest.~$vn~ ]; then if [ $max -lt $vn ]; then max=$vn fi fi done if [ $max -eq 0 ]; then # no current versions mv $dest $dest.~1~ # change version to version 1 new=2 else if cmp -q $dest $dest.~$max~ >/dev/null 2>&1 then # they're different max=`expr $max + 1` # make newer version mv $dest $dest.~$max~ new=`expr $max + 1` else # dest and dest.~nn~ are equal so rm $dest # delete dest leave old version behind new=`expr $max + 1` fi fi # make new version and link it $(ln_or_cp $file $dest.~new~) $file $dest.~$new~ echo "Added $(basename $dest.~$new~) to $(dirname $dest.~$new~)" rm -f $dest ln $dest.~$new~ $dest echo "Linked $(basename $dest) to $(basename $dest.~$new~) in $(dirname $dest)"