home *** CD-ROM | disk | FTP | other *** search
- #!/bin/sh
- #
- # xcopy
- #
- # Recursively copy a directory tree
- #
- # Requires cpio, find, tty, basename, and any reasonable /bin/sh
- #
- # 1994/01/15 DCN Created
- # 1994/12/01 DCN Cleanup and minor improvements
- #
- # Copyright (C) 1994 David C. Niemi (niemidc@erols.com)
- # The author requires that any copies or derived works include this
- # copyright notice; no other restrictions are placed on its use.
- #
-
- set -e
- set -u
-
- ## Exit and complain about improper usage
- usage_exit ()
- { echo ''
- if [ -n "${INTERACTIVE-}" ]; then
- echo \
- "Usage: $NAME [-s | -S] [ <source dir> [ <destination dir> ] ]" >&2
- exit 2
- else
- echo \
- "Non-interactive usage: $NAME [-s|-S] <source dir> [<destination dir>]" >&2
- exit 3
- fi
- }
-
- ## Clean up path name $1
- fix_dir_name ()
- {
- ## Remove leading "./" from path
- _DIR=`echo "$1" | sed -e 's,^\./,,' -e 's,/./,,'`
- _WD=${WD-}
-
- ## Parse away leading ../'s
- while echo "$_DIR" | grep -s '^\.\./'; do
- _DIR=`echo $_DIR | sed 's,^\.\./,,'`
- _WD=`dirname "$_WD"`
- done
-
- ## Clean up and return resulting path
- case $_DIR in
- '' | .)
- ## Use current working directory
- _DIR=$_WD
- ;;
-
- /*)
- ## Absolute path; no change needed
- ;;
-
- ..)
- _DIR=`dirname "$_WD"`
- ;;
-
- *)
- ## Path relative to "."
- _DIR=$_WD/$_DIR
- ;;
- esac
- echo $_DIR
- }
-
- ## Determine if we are using a real tty or not
- if tty -s; then
- INTERACTIVE=yes
- fi
-
- ## Ensure these variables get set
- FROMDIR=${FROMDIR-}
- TODIR=${TODIR-}
- NAME=`basename $0`
-
- ## Make sure that the current directory is really the same as $PWD
- if [ -z "${PWD-}" ]; then
- ## PWD variable is null or not set
- WD=`pwd`
- elif [ ! -d "$PWD" ]; then
- ## $PWD does not exist or is not a directory
- WD=`pwd`
- elif [ X"`ls -id`" != X"`cd $PWD; ls -id`" ]; then
- ## PWD variable is not up to date, so ignore it
- WD=`pwd`
- else
- ## Use $PWD, as it is likely to be "cleaner" that `pwd`
- WD=$PWD
- fi
-
- ## Check usage
- case $# in
- 0)
- if [ -z "$INTERACTIVE" ]; then
- usage_exit
- fi
- ;;
- 1)
- FROMDIR=`fix_dir_name $1`
- TODIR="${WD}/`basename ${WD}/$FROMDIR`"
- ;;
- 2)
- FROMDIR=`fix_dir_name $1`
- TODIR=`fix_dir_name $2`
- ;;
- *)
- usage_exit
- ;;
- esac
-
- #### Ask for missing information
- while [ -z "$FROMDIR" -o -z "$TODIR" ]; do
- if [ -z "$FROMDIR" ]; then
- echo "Your current directory is \"$WD\"."
- echo -n 'What directory do you want to copy (default is "'$WD'")? '
- if read answer; then
- if [ ! -d "$answer" ]; then
- echo ''
- echo "Source directory \"$answer\" does not exist!"
- echo
- else
- FROMDIR=`fix_dir_name $answer`
- fi
- else
- INTERACTIVE=no
- usage_exit
- fi
- fi
- if [ -z "$TODIR" ]; then
- DEFAULT_TODIR=`basename \`cd $FROMDIR; pwd\``
- echo 'Destination directory? (<Return> for "'$DEFAULT_TODIR'"): '
- if read answer; then
- if [ -z "$answer" ]; then
- TODIR=`fix_dir_name $DEFAULT_TODIR`
- else
- TODIR=`fix_dir_name $answer`
- fi
- if [ "$TODIR" = "$FROMDIR" ]; then
- echo ''
- echo "Cannot copy directory onto itself!"
- echo
- TODIR=
- fi
- else
- INTERACTIVE=
- usage_exit
- fi
- fi
- done
-
- if [ ! -d "$FROMDIR" ]; then
- echo ''
- echo "Source directory \"$FROMDIR\" does not exist!" >&2
- exit 4
- elif [ "$TODIR" = "$FROMDIR" ]; then
- echo "Cannot copy directory onto itself!" >&2
- exit 5
- elif [ ! -d "$TODIR" ]; then
- if [ 'X-S' != "X${MODE-}" ]; then
- echo "Creating destination directory \"$TODIR\"."
- fi
- mkdir -p "$TODIR"
- fi
-
- if [ 'X-S' != "X${MODE-}" ]; then
- echo "Copying directory \"$FROMDIR\" to \"$TODIR\"."
- fi
- cd $FROMDIR
-
- OPTIONS='-pmdu'
- if [ -w "$FROMDIR" ]; then
- ## Reset access times if permissions available
- OPTIONS=${OPTIONS}a
- fi
-
- if [ -z "${SILENT-}" ]; then
- OPTIONS=${OPTIONS}v
- fi
-
- exec find . -xdev -depth -print | sed 's,^./,,' | cpio "$OPTIONS" "$TODIR"
-
- ## Notreached
-