#!/bin/sh # cpdir --- copy directories preserving time, symlinks, etc. # Copyright (C) 1991, 1995 Noah S. Friedman # Author: Noah Friedman # 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