#!/bin/sh
# cpdir --- copy directories preserving time, symlinks, etc.

# Copyright (C) 1991, 1995 Noah S. Friedman

# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1991-08-14

# $Id: cpdir,v 1.8 1997/01/09 07:14:52 friedman Exp $

# 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, 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, you can either send email to this
# program's maintainer or write to: The Free Software Foundation,
# Inc.; 59 Temple Place, Suite 330; Boston, MA 02111-1307, USA.

# Commentary:
# Code:

# Name by which this script was invoked.
progname=`echo "$0" | sed -e 's/[^\/]*\///g'`

# To prevent hairy quoting and escaping later.
bq='`'
eq="'"

usage="Usage: $progname {options} srcdir {srcdir2 ...} dstdir

Options are:
-D, --debug                  Turn on shell debugging ($bq${bq}set -x$eq$eq).
-d, --dereference            Dereference symlinks when copying.
-f, --full-path              Copy entire src directory component.
-h, --help                   You're looking at it.
-q, --quiet                  Do not print filenames as they're copied.
-v, --verbose                Print filenames as they're copied (default).

Example: ${progname} /home/fsf/friedman /home/gp
         => /home/fsf/friedman -> /home/gp/friedman

         ${progname} --full-path /home/fsf/friedman /home/gp
         => /home/fsf/friedman -> /home/gp/home/fsf/friedman

"

# Initialize variables.
# Don't use `unset' since old bourne shells don't have this command.
# Instead, assign them an empty value.
debug=
deref=
verbose=v
fullpath=

# Parse command line arguments.
# Make sure that all wildcarded options are long enough to be unambiguous.
# It's a good idea to document the full long option name in each case.
# Long options which take arguments will need a `*' appended to the
# canonical name to match the value appended after the `=' character.
while test $# != 0; do
  case "$1" in
    -D | --debug | --d* )
      debug=t
      shift
     ;;
    -d | --dereference | --der* )
      deref=h
      shift
     ;;
    -f | --full-path | --f* )
      fullpath=t
      shift
     ;;
    -h | --help | --h )
      echo "$usage" 1>&2
      exit 1
     ;;
    -q | --quiet | --q* )
      verbose=
      shift
     ;;
    -v | --verbose | --v* )
      verbose=v
      shift
     ;;
    -- )     # Stop option processing
      shift
      break
     ;;
    -? | --* )
      case "$1" in
        --*=* ) arg=`echo "$1" | sed -e 's/=.*//'` ;;
        * )     arg="$1" ;;
      esac
      exec 1>&2
      echo "$progname: unknown or ambiguous option $bq$arg$eq"
      echo "$progname: Use $bq--help$eq for a list of options."
      exit 1
     ;;
    -??* )
      # Split grouped single options into separate args and try again
      optarg="$1"
      shift
      set fnord `echo "x$optarg" | sed -e 's/^x-//;s/\(.\)/-\1 /g'` ${1+"$@"}
      shift
     ;;
    * )
      break
     ;;
  esac
done

case "$debug" in t ) set -x ;; esac

_saved_args=
while : ; do
  case $# in 0 | 1 ) break ;; esac
  eval _saved_args$#=\$1
  _saved_args="$_saved_args \"\$_saved_args$#\""
  shift
done

dst=$1
eval '{ eval set fnord $_saved_args; }'
shift

for src in ${1+"$@"} ; do
  case "$fullpath" in
    t )
      srcdir=.
      case "$src" in
        /* )
          srcdir=/
          src=`echo "$src" | sed -e 's/^\/*//'`
         ;;
      esac
     ;;
    * )
      # sed is more portable than `dirname'
      srcdir=`echo "$src" \
              | sed -e 's/\/*$//
                        s/\/[^\/]*$//'`

      case "$srcdir" in "$src" )
        srcdir=. ;;
      esac

      # same as `basename'
      src=`echo "$src" \
           | sed -e 's/\/*$//
                     s/.*\///'`
     ;;
  esac

  if test -d "$dst" ; then
    ( cd "$srcdir" && tar c${deref}f - "$src" ) \
     | ( cd "$dst" && tar xp${verbose}f - )
  else
    mkdir "$dst"
    ( cd "$srcdir/$src" && tar c${deref}f - . ) \
     | ( cd "$dst" && tar xp${verbose}f - )
  fi
done

# cpdir ends here
