#!/bin/bash # # mirror-recursive : mirror the contents of a directory recursively # (only copies updated files) # # Copyright (C) 1998 Alexander V. Konstantinou (akonstan@acm.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, # MA 02111-1307, USA. # # $Id: mirror-recursive,v 1.7 1998/03/08 22:49:05 akonstan Exp $ USAGE="Usage : $0 SRC DST -verbose" if [ -z "$1" -o -z "$2" ]; then echo $USAGE exit 1 fi if [ "$3" = "-verbose" ]; then DEV=`tty` elif [ -z "$3" ]; then DEV="/dev/null" else echo $USAGE exit 1 fi LS="/bin/ls -aw1" CP="/bin/cp -a" if [ ! -d "$1" ]; then if [ -f "$1" ]; then # File copy SRCFILE=$1 DSTFILE=$2 if [ -e "$2" -a ! -f "$2" ]; then echo "Destination $2 is not a regular file" exit 1 fi echo "# $0 $SRCFILE (file) -> $DSTFILE ..." > $DEV if [ "$DSTFILE" -nt "$SRCFILE" ]; then echo "*** Destination file $SRCFILE is newer in destination file $DSTFILE!" diff $DSTFILE $SRCFILE exit 1 fi if [ -f "$2" ]; then if [ "$SRCFILE" -nt "$DSTFILE" ]; then chmod u+w $DSTFILE echo "Copying UPDATED $SRCFILE" $CP $SRCFILE $DSTFILE fi else echo "Copying NEWFILE $SRCFILE" $CP $SRCFILE $DSTFILE fi exit 0 else # First argument is neither a file nor a directory echo "Source file/directory $1 not found" exit 1 fi else # Directory copy SRCDIR=$1 DSTDIR=$2 FILTERNAMES=". .." if [ ! -d "$DSTDIR" ]; then echo "Destination directory $DSTDIR not found" exit 1 fi echo "# $0 $SRCDIR -> $DSTDIR" > $DEV SRCFILES=`$LS $SRCDIR` SUBDIRS="" fi echo "# Checking for updated files (please wait) ..." > $DEV for FNAME in $SRCFILES; do FILTERITEM="" for NAME in $FILTERNAMES; do if [ "$NAME" = "$FNAME" ]; then FILTERITEM="Yes" fi done if [ -n "$FILTERITEM" ]; then true # null op elif [ -L "$SRCDIR/$FNAME" ]; then if [ ! -e "$DSTDIR/$FNAME" ]; then echo "Copying LINK $DSTDIR/$FNAME" $CP $SRCDIR/$FNAME $DSTDIR/$FNAME elif [ -L "$DSTDIR/$FNAME" ]; then if [ "$SRCDIR/$FNAME" -nt "$DSTDIR/$FNAME" ]; then echo "Removing LINK $DSTDIR/$FNAME" /bin/rm -f $DSTDIR/$FNAME $CP $SRCDIR/$FNAME $DSTDIR/$FNAME fi else echo "Destination $FNAME is not a link!" exit 1 fi elif [ -d "$SRCDIR/$FNAME" ]; then SUBDIRS=$FNAME" "$SUBDIRS if [ ! -d "$DSTDIR/$FNAME" ]; then /bin/rm -f $DSTDIR/$FNAME echo "Creating NEWDIRECTORY $DSTDIR/$FNAME" mkdir $DSTDIR/$FNAME fi elif [ -f "$SRCDIR/$FNAME" ]; then if [ -f "$DSTDIR/$FNAME" ]; then if [ "$SRCDIR/$FNAME" -nt "$DSTDIR/$FNAME" ]; then echo "Copying UPDATED $FNAME" chmod u+w $DSTDIR/$FNAME /bin/rm $DSTDIR/$FNAME $CP $SRCDIR/$FNAME $DSTDIR/$FNAME elif [ "$DSTDIR/$FNAME" -nt "$SRCDIR/$FNAME" ]; then echo "*** Destination file $FNAME is newer in destination directory!" diff $DSTDIR/$FNAME $SRCDIR/$FNAME exit 1 fi elif [ -d "$DSTDIR/$FNAME" ]; then echo "Removing directory $DSTDIR/$FNAME" /bin/rm -r $DSTDIR/$FNAME echo "Copying NEWFILE $FNAME" $CP $SRCDIR/$FNAME $DSTDIR/$FNAME else echo "Copying NEWFILE $FNAME" $CP $SRCDIR/$FNAME $DSTDIR/$FNAME fi elif [ -b "$SRCDIR/$FNAME" ]; then echo "Block special type mirroring not supported ! ($FNAME)" elif [ -c "$SRCDIR/$FNAME" ]; then echo "Character special type mirroring not supported ! ($FNAME)" elif [ -p "$SRCDIR/$FNAME" ]; then echo "Pipe type mirroring not supported ! ($FNAME)" elif [ -S "$SRCDIR/$FNAME" ]; then echo "Socket type mirroring not supported ! ($FNAME)" else echo "Unknown file type $SRCDIR/$FNAME" exit 1 fi done echo "# Checking for removed files (please wait) ..." > $DEV DSTFILES=`$LS $DSTDIR` for FNAME in $DSTFILES; do if [ ! -e "$SRCDIR/$FNAME" ]; then if [ -d "$DSTDIR/$FNAME" ]; then echo "Directory $FNAME no longer exists (delete recursively?)" /bin/rm -ri $DSTDIR/$FNAME else echo "File $FNAME no longer exists." /bin/rm -i $DSTDIR/$FNAME fi echo "" fi done if [ -n "$SUBDIRS" ]; then echo "# Recursing into subdirectories $SUBDIRS :" > $DEV for NAME in $SUBDIRS; do mirror-recursive "$SRCDIR/$NAME" "$DSTDIR/$NAME" $3 done fi