1*b30d1939SAndy Fiddaman######################################################################## 2*b30d1939SAndy Fiddaman# # 3*b30d1939SAndy Fiddaman# This software is part of the ast package # 4*b30d1939SAndy Fiddaman# Copyright (c) 1994-2011 AT&T Intellectual Property # 5*b30d1939SAndy Fiddaman# and is licensed under the # 6*b30d1939SAndy Fiddaman# Eclipse Public License, Version 1.0 # 7*b30d1939SAndy Fiddaman# by AT&T Intellectual Property # 8*b30d1939SAndy Fiddaman# # 9*b30d1939SAndy Fiddaman# A copy of the License is available at # 10*b30d1939SAndy Fiddaman# http://www.eclipse.org/org/documents/epl-v10.html # 11*b30d1939SAndy Fiddaman# (with md5 checksum b35adb5213ca9657e911e9befb180842) # 12*b30d1939SAndy Fiddaman# # 13*b30d1939SAndy Fiddaman# Information and Software Systems Research # 14*b30d1939SAndy Fiddaman# AT&T Research # 15*b30d1939SAndy Fiddaman# Florham Park NJ # 16*b30d1939SAndy Fiddaman# # 17*b30d1939SAndy Fiddaman# Glenn Fowler <gsf@research.att.com> # 18*b30d1939SAndy Fiddaman# # 19*b30d1939SAndy Fiddaman######################################################################## 20*b30d1939SAndy Fiddaman: replicate directory hierarchies 21*b30d1939SAndy Fiddaman 22*b30d1939SAndy FiddamanCOMMAND=ditto 23*b30d1939SAndy Fiddamancase `(getopts '[-][123:xyz]' opt --xyz; echo 0$opt) 2>/dev/null` in 24*b30d1939SAndy Fiddaman0123) ARGV0="-a $COMMAND" 25*b30d1939SAndy Fiddaman USAGE=$' 26*b30d1939SAndy Fiddaman[-? 27*b30d1939SAndy Fiddaman@(#)$Id: ditto (AT&T Labs Research) 2010-11-22 $ 28*b30d1939SAndy Fiddaman] 29*b30d1939SAndy Fiddaman'$USAGE_LICENSE$' 30*b30d1939SAndy Fiddaman[+NAME?ditto - replicate directory hierarchies] 31*b30d1939SAndy Fiddaman[+DESCRIPTION?\bditto\b replicates the \asource\a directory hierarchy 32*b30d1939SAndy Fiddaman to the \adestination\a directory hierarchy. Both \asource\a and 33*b30d1939SAndy Fiddaman \adestination\a may be of the form 34*b30d1939SAndy Fiddaman [\auser\a@]][\ahost\a:]][\adirectory\a]]. At least one of 35*b30d1939SAndy Fiddaman \ahost\a: or \adirectory\a must be specified. The current user is used 36*b30d1939SAndy Fiddaman if \auser@\a is omitted, the local host is used if \ahost\a: is 37*b30d1939SAndy Fiddaman omitted, and the user home directory is used if \adirectory\a is 38*b30d1939SAndy Fiddaman omitted.] 39*b30d1939SAndy Fiddaman[+?Remote hosts and files are accessed via \bssh\b(1) or \brsh\b(1). \bksh\b(1), 40*b30d1939SAndy Fiddaman \bpax\b(1), and \btw\b(1) must be installed on the local and remote hosts.] 41*b30d1939SAndy Fiddaman[+?For each source file \bditto\b does one of these actions:]{ 42*b30d1939SAndy Fiddaman [+chmod|chown?change the mode and/or ownership of the destination 43*b30d1939SAndy Fiddaman file to match the source] 44*b30d1939SAndy Fiddaman [+copy?copy the source file to the destination] 45*b30d1939SAndy Fiddaman [+delete?delete the destination file] 46*b30d1939SAndy Fiddaman [+skip?the destination file is not changed] 47*b30d1939SAndy Fiddaman} 48*b30d1939SAndy Fiddaman[+?The source and destination hierarchies are generated by \btw\b(1) with 49*b30d1939SAndy Fiddaman the \b--logical\b option. An \b--expr\b option may 50*b30d1939SAndy Fiddaman be specified to prune the search. The \btw\b searches are relative to 51*b30d1939SAndy Fiddaman the \asource\a and \adestination\a directories.] 52*b30d1939SAndy Fiddaman[c:checksum?Copy if the \btw\b(1) 32x4 checksum mismatches.] 53*b30d1939SAndy Fiddaman[d:delete?Delete \adestination\a files that are not in the \asource\a.] 54*b30d1939SAndy Fiddaman[e:expr?\btw\b(1) select expression.]:[tw-expression] 55*b30d1939SAndy Fiddaman[m!:mode?Preserve file mode.] 56*b30d1939SAndy Fiddaman[n:show?Show the operations but do not exectute.] 57*b30d1939SAndy Fiddaman[o:owner?Preserve file user and group ownership.] 58*b30d1939SAndy Fiddaman[p:physical?Generate source and destination hierarchies by \btw\b(1) with 59*b30d1939SAndy Fiddaman the \b--physical\b option.] 60*b30d1939SAndy Fiddaman[r:remote?The remote access protocol; either \bssh\b or 61*b30d1939SAndy Fiddaman \brsh\b.]:[protocol:=ssh] 62*b30d1939SAndy Fiddaman[u:update?Copy only if the \asource\a file is newer than the 63*b30d1939SAndy Fiddaman \adestination\a file.] 64*b30d1939SAndy Fiddaman[v:verbose?Trace the operations as they are executed.] 65*b30d1939SAndy Fiddaman[D:debug?Enable the debug trace.] 66*b30d1939SAndy Fiddaman 67*b30d1939SAndy Fiddamansource destination 68*b30d1939SAndy Fiddaman 69*b30d1939SAndy Fiddaman[+SEE ALSO?\brdist\b(1), \brsync\b(1), \brsh\b(1), \bssh\b(1), \btw\b(1)] 70*b30d1939SAndy Fiddaman' 71*b30d1939SAndy Fiddaman ;; 72*b30d1939SAndy Fiddaman*) ARGV0="" 73*b30d1939SAndy Fiddaman USAGE="de:[tw-expression]mnouvD source destination" 74*b30d1939SAndy Fiddaman ;; 75*b30d1939SAndy Fiddamanesac 76*b30d1939SAndy Fiddaman 77*b30d1939SAndy Fiddamanusage() 78*b30d1939SAndy Fiddaman{ 79*b30d1939SAndy Fiddaman OPTIND=0 80*b30d1939SAndy Fiddaman getopts $ARGV0 "$USAGE" OPT '-?' 81*b30d1939SAndy Fiddaman exit 2 82*b30d1939SAndy Fiddaman} 83*b30d1939SAndy Fiddaman 84*b30d1939SAndy Fiddamanparse() # id user@host:dir 85*b30d1939SAndy Fiddaman{ 86*b30d1939SAndy Fiddaman typeset id dir user host 87*b30d1939SAndy Fiddaman id=$1 88*b30d1939SAndy Fiddaman dir=$2 89*b30d1939SAndy Fiddaman (( debug || ! exec )) && print -r $id $dir 90*b30d1939SAndy Fiddaman if [[ $dir == *@* ]] 91*b30d1939SAndy Fiddaman then 92*b30d1939SAndy Fiddaman user=${dir%%@*} 93*b30d1939SAndy Fiddaman dir=${dir#${user}@} 94*b30d1939SAndy Fiddaman else 95*b30d1939SAndy Fiddaman user= 96*b30d1939SAndy Fiddaman fi 97*b30d1939SAndy Fiddaman if [[ $dir == *:* ]] 98*b30d1939SAndy Fiddaman then 99*b30d1939SAndy Fiddaman host=${dir%%:*} 100*b30d1939SAndy Fiddaman dir=${dir#${host}:} 101*b30d1939SAndy Fiddaman else 102*b30d1939SAndy Fiddaman host= 103*b30d1939SAndy Fiddaman fi 104*b30d1939SAndy Fiddaman if [[ $user ]] 105*b30d1939SAndy Fiddaman then 106*b30d1939SAndy Fiddaman user="-l $user" 107*b30d1939SAndy Fiddaman if [[ ! $host ]] 108*b30d1939SAndy Fiddaman then 109*b30d1939SAndy Fiddaman host=$(hostname) 110*b30d1939SAndy Fiddaman fi 111*b30d1939SAndy Fiddaman fi 112*b30d1939SAndy Fiddaman eval ${id}_user='$user' 113*b30d1939SAndy Fiddaman eval ${id}_host='$host' 114*b30d1939SAndy Fiddaman eval ${id}_dir='$dir' 115*b30d1939SAndy Fiddaman} 116*b30d1939SAndy Fiddaman 117*b30d1939SAndy Fiddaman# initialize 118*b30d1939SAndy Fiddaman 119*b30d1939SAndy Fiddamantypeset -A chown chmod 120*b30d1939SAndy Fiddamantypeset tw cp rm link 121*b30d1939SAndy Fiddamaninteger ntw=0 ncp=0 nrm=0 nlink=0 n 122*b30d1939SAndy Fiddaman 123*b30d1939SAndy Fiddamantypeset src_user src_host src_path src_type src_uid src_gid src_perm src_sum 124*b30d1939SAndy Fiddamantypeset dst_user dst_host dst_path dst_type dst_uid dst_gid dst_perm dst_sum 125*b30d1939SAndy Fiddamaninteger src_size src_mtime src_eof 126*b30d1939SAndy Fiddamaninteger dst_size dst_mtime dst_eof 127*b30d1939SAndy Fiddaman 128*b30d1939SAndy Fiddamaninteger debug=0 delete=0 exec=1 mode=1 owner=0 update=0 verbose=0 logical 129*b30d1939SAndy Fiddaman 130*b30d1939SAndy Fiddamantypeset remote=ssh trace 131*b30d1939SAndy Fiddamantypeset checksum='"-"' pax="pax" 132*b30d1939SAndy Fiddamantypeset paxreadflags="" paxwriteflags="--write --format=tgz --nosummary" 133*b30d1939SAndy Fiddaman 134*b30d1939SAndy Fiddamantw[ntw++]=tw 135*b30d1939SAndy Fiddaman(( logical=ntw )) 136*b30d1939SAndy Fiddamantw[ntw++]=--logical 137*b30d1939SAndy Fiddamantw[ntw++]=--chop 138*b30d1939SAndy Fiddamantw[ntw++]=--ignore-errors 139*b30d1939SAndy Fiddamantw[ntw++]=--expr=sort:name 140*b30d1939SAndy Fiddaman 141*b30d1939SAndy Fiddaman# grab the options 142*b30d1939SAndy Fiddaman 143*b30d1939SAndy Fiddamanwhile getopts $ARGV0 "$USAGE" OPT 144*b30d1939SAndy Fiddamando case $OPT in 145*b30d1939SAndy Fiddaman c) checksum=checksum ;; 146*b30d1939SAndy Fiddaman d) delete=1 ;; 147*b30d1939SAndy Fiddaman e) tw[ntw++]=--expr=\"$OPTARG\" ;; 148*b30d1939SAndy Fiddaman m) mode=0 ;; 149*b30d1939SAndy Fiddaman n) exec=0 verbose=1 ;; 150*b30d1939SAndy Fiddaman o) owner=1 ;; 151*b30d1939SAndy Fiddaman p) tw[logical]=--physical ;; 152*b30d1939SAndy Fiddaman r) remote=$OPTARG ;; 153*b30d1939SAndy Fiddaman u) update=1 ;; 154*b30d1939SAndy Fiddaman v) verbose=1 ;; 155*b30d1939SAndy Fiddaman D) debug=1 ;; 156*b30d1939SAndy Fiddaman *) usage ;; 157*b30d1939SAndy Fiddaman esac 158*b30d1939SAndy Fiddamandone 159*b30d1939SAndy Fiddamanshift $OPTIND-1 160*b30d1939SAndy Fiddamanif (( $# != 2 )) 161*b30d1939SAndy Fiddamanthen usage 162*b30d1939SAndy Fiddamanfi 163*b30d1939SAndy Fiddamantw[ntw++]=--expr=\''action:printf("%d\t%d\t%s\t%s\t%s\t%-.1s\t%o\t%s\t%s\n", size, mtime, '$checksum', uid, gid, mode, perm, path, symlink);'\' 164*b30d1939SAndy Fiddamanif (( exec )) 165*b30d1939SAndy Fiddamanthen 166*b30d1939SAndy Fiddaman paxreadflags="$paxreadflags --read" 167*b30d1939SAndy Fiddamanfi 168*b30d1939SAndy Fiddamanif (( verbose )) 169*b30d1939SAndy Fiddamanthen 170*b30d1939SAndy Fiddaman paxreadflags="$paxreadflags --verbose" 171*b30d1939SAndy Fiddamanfi 172*b30d1939SAndy Fiddaman 173*b30d1939SAndy Fiddaman# start the source and destination path list generators 174*b30d1939SAndy Fiddaman 175*b30d1939SAndy Fiddamanparse src "$1" 176*b30d1939SAndy Fiddamanparse dst "$2" 177*b30d1939SAndy Fiddaman 178*b30d1939SAndy Fiddaman# the |& command may exit before the exec &p 179*b30d1939SAndy Fiddaman# the print sync + read delays the |& until the exec &p finishes 180*b30d1939SAndy Fiddaman 181*b30d1939SAndy Fiddamanif [[ $src_host ]] 182*b30d1939SAndy Fiddamanthen ($remote $src_user $src_host "{ test ! -f .profile || . ./.profile ;} && cd $src_dir && read && ${tw[*]}") 2>&1 |& 183*b30d1939SAndy Fiddamanelse (cd $src_dir && read && eval "${tw[@]}") 2>&1 |& 184*b30d1939SAndy Fiddamanfi 185*b30d1939SAndy Fiddamanexec 5<&p 7>&p 186*b30d1939SAndy Fiddamanprint -u7 sync 187*b30d1939SAndy Fiddamanexec 7>&- 188*b30d1939SAndy Fiddaman 189*b30d1939SAndy Fiddamanif [[ $dst_host ]] 190*b30d1939SAndy Fiddamanthen ($remote $dst_user $dst_host "{ test ! -f .profile || . ./.profile ;} && cd $dst_dir && read && ${tw[*]}") 2>&1 |& 191*b30d1939SAndy Fiddamanelse (cd $dst_dir && read && eval "${tw[@]}") 2>&1 |& 192*b30d1939SAndy Fiddamanfi 193*b30d1939SAndy Fiddamanexec 6<&p 7>&p 194*b30d1939SAndy Fiddamanprint -u7 sync 195*b30d1939SAndy Fiddamanexec 7>&- 196*b30d1939SAndy Fiddaman 197*b30d1939SAndy Fiddaman# scan through the sorted path lists 198*b30d1939SAndy Fiddaman 199*b30d1939SAndy Fiddamanif (( exec )) 200*b30d1939SAndy Fiddamanthen 201*b30d1939SAndy Fiddaman src_skip=* 202*b30d1939SAndy Fiddaman dst_skip=* 203*b30d1939SAndy Fiddamanelse 204*b30d1939SAndy Fiddaman src_skip= 205*b30d1939SAndy Fiddaman dst_skip= 206*b30d1939SAndy Fiddamanfi 207*b30d1939SAndy Fiddamansrc_path='' src_eof=0 208*b30d1939SAndy Fiddamandst_path='' dst_eof=0 209*b30d1939SAndy Fiddamanifs=${IFS-$' \t\n'} 210*b30d1939SAndy FiddamanIFS=$'\t' 211*b30d1939SAndy Fiddamanwhile : 212*b30d1939SAndy Fiddamando 213*b30d1939SAndy Fiddaman # get the next source path 214*b30d1939SAndy Fiddaman 215*b30d1939SAndy Fiddaman if [[ ! $src_path ]] && (( ! src_eof )) 216*b30d1939SAndy Fiddaman then 217*b30d1939SAndy Fiddaman if read -r -u5 text src_mtime src_sum src_uid src_gid src_type src_perm src_path src_link 218*b30d1939SAndy Fiddaman then 219*b30d1939SAndy Fiddaman if [[ $text != +([[:digit:]]) ]] 220*b30d1939SAndy Fiddaman then 221*b30d1939SAndy Fiddaman print -u2 $COMMAND: source: "'$text'" 222*b30d1939SAndy Fiddaman src_path= 223*b30d1939SAndy Fiddaman continue 224*b30d1939SAndy Fiddaman fi 225*b30d1939SAndy Fiddaman src_size=$text 226*b30d1939SAndy Fiddaman elif (( dst_eof )) 227*b30d1939SAndy Fiddaman then 228*b30d1939SAndy Fiddaman break 229*b30d1939SAndy Fiddaman elif (( src_size==0 )) 230*b30d1939SAndy Fiddaman then 231*b30d1939SAndy Fiddaman exit 1 232*b30d1939SAndy Fiddaman else 233*b30d1939SAndy Fiddaman src_path= 234*b30d1939SAndy Fiddaman src_eof=1 235*b30d1939SAndy Fiddaman fi 236*b30d1939SAndy Fiddaman fi 237*b30d1939SAndy Fiddaman 238*b30d1939SAndy Fiddaman # get the next destination path 239*b30d1939SAndy Fiddaman 240*b30d1939SAndy Fiddaman if [[ ! $dst_path ]] && (( ! dst_eof )) 241*b30d1939SAndy Fiddaman then 242*b30d1939SAndy Fiddaman if read -r -u6 text dst_mtime dst_sum dst_uid dst_gid dst_type dst_perm dst_path dst_link 243*b30d1939SAndy Fiddaman then 244*b30d1939SAndy Fiddaman if [[ $text != +([[:digit:]]) ]] 245*b30d1939SAndy Fiddaman then 246*b30d1939SAndy Fiddaman print -u2 $COMMAND: destination: $text 247*b30d1939SAndy Fiddaman dst_path= 248*b30d1939SAndy Fiddaman continue 249*b30d1939SAndy Fiddaman fi 250*b30d1939SAndy Fiddaman dst_size=$text 251*b30d1939SAndy Fiddaman elif (( src_eof )) 252*b30d1939SAndy Fiddaman then 253*b30d1939SAndy Fiddaman break 254*b30d1939SAndy Fiddaman elif (( dst_size==0 )) 255*b30d1939SAndy Fiddaman then 256*b30d1939SAndy Fiddaman exit 1 257*b30d1939SAndy Fiddaman else 258*b30d1939SAndy Fiddaman dst_path= 259*b30d1939SAndy Fiddaman dst_eof=1 260*b30d1939SAndy Fiddaman fi 261*b30d1939SAndy Fiddaman fi 262*b30d1939SAndy Fiddaman 263*b30d1939SAndy Fiddaman # determine the { cp rm chmod chown } ops 264*b30d1939SAndy Fiddaman 265*b30d1939SAndy Fiddaman if (( debug )) 266*b30d1939SAndy Fiddaman then 267*b30d1939SAndy Fiddaman [[ $src_path ]] && print -r -u2 -f $': src %8s %10s %s %s %s %s %3s %s\n' $src_size $src_mtime $src_sum $src_uid $src_gid $src_type $src_perm "$src_path" 268*b30d1939SAndy Fiddaman [[ $dst_path ]] && print -r -u2 -f $': dst %8s %10s %s %s %s %s %3s %s\n' $dst_size $dst_mtime $dst_sum $dst_uid $dst_gid $dst_type $dst_perm "$dst_path" 269*b30d1939SAndy Fiddaman fi 270*b30d1939SAndy Fiddaman if [[ $src_path == $dst_path ]] 271*b30d1939SAndy Fiddaman then 272*b30d1939SAndy Fiddaman if [[ $src_type != $dst_type ]] 273*b30d1939SAndy Fiddaman then 274*b30d1939SAndy Fiddaman rm[nrm++]=$dst_path 275*b30d1939SAndy Fiddaman if [[ $dst_path != $dst_skip ]] 276*b30d1939SAndy Fiddaman then 277*b30d1939SAndy Fiddaman if [[ $dst_type == d ]] 278*b30d1939SAndy Fiddaman then 279*b30d1939SAndy Fiddaman dst_skip="$dst_path/*" 280*b30d1939SAndy Fiddaman print -r rm -r "'$dst_path'" 281*b30d1939SAndy Fiddaman else 282*b30d1939SAndy Fiddaman dst_skip= 283*b30d1939SAndy Fiddaman print -r rm "'$dst_path'" 284*b30d1939SAndy Fiddaman fi 285*b30d1939SAndy Fiddaman fi 286*b30d1939SAndy Fiddaman fi 287*b30d1939SAndy Fiddaman if [[ $src_type == l ]] 288*b30d1939SAndy Fiddaman then if [[ $src_link != $dst_link ]] 289*b30d1939SAndy Fiddaman then 290*b30d1939SAndy Fiddaman cp[ncp++]=$src_path 291*b30d1939SAndy Fiddaman if [[ $src_path != $src_skip ]] 292*b30d1939SAndy Fiddaman then 293*b30d1939SAndy Fiddaman src_skip= 294*b30d1939SAndy Fiddaman print -r cp "'$src_path'" 295*b30d1939SAndy Fiddaman fi 296*b30d1939SAndy Fiddaman fi 297*b30d1939SAndy Fiddaman elif [[ $src_type != d ]] && { (( update && src_mtime > dst_mtime )) || (( ! update )) && { (( src_size != dst_size )) || [[ $src_sum != $dst_sum ]] ;} ;} 298*b30d1939SAndy Fiddaman then 299*b30d1939SAndy Fiddaman if [[ $src_path != . ]] 300*b30d1939SAndy Fiddaman then 301*b30d1939SAndy Fiddaman cp[ncp++]=$src_path 302*b30d1939SAndy Fiddaman if [[ $src_path != $src_skip ]] 303*b30d1939SAndy Fiddaman then 304*b30d1939SAndy Fiddaman src_skip= 305*b30d1939SAndy Fiddaman print -r cp "'$src_path'" 306*b30d1939SAndy Fiddaman fi 307*b30d1939SAndy Fiddaman fi 308*b30d1939SAndy Fiddaman else 309*b30d1939SAndy Fiddaman if (( owner )) && [[ $src_uid != $dst_uid || $src_gid != $dst_gid ]] 310*b30d1939SAndy Fiddaman then 311*b30d1939SAndy Fiddaman chown[$src_uid.$src_gid]="${chown[$src_uid.$src_gid]} '$src_path'" 312*b30d1939SAndy Fiddaman if [[ $src_path != $src_skip ]] 313*b30d1939SAndy Fiddaman then 314*b30d1939SAndy Fiddaman src_skip= 315*b30d1939SAndy Fiddaman print -r chown $src_uid.$src_gid "'$src_path'" 316*b30d1939SAndy Fiddaman fi 317*b30d1939SAndy Fiddaman if (( (src_perm & 07000) || mode && src_perm != dst_perm )) 318*b30d1939SAndy Fiddaman then 319*b30d1939SAndy Fiddaman chmod[$src_perm]="${chmod[$src_perm]} '$src_path'" 320*b30d1939SAndy Fiddaman if [[ $src_path != $src_skip ]] 321*b30d1939SAndy Fiddaman then 322*b30d1939SAndy Fiddaman src_skip= 323*b30d1939SAndy Fiddaman print -r chmod $src_perm "'$src_path'" 324*b30d1939SAndy Fiddaman fi 325*b30d1939SAndy Fiddaman fi 326*b30d1939SAndy Fiddaman elif (( mode && src_perm != dst_perm )) 327*b30d1939SAndy Fiddaman then 328*b30d1939SAndy Fiddaman chmod[$src_perm]="${chmod[$src_perm]} '$src_path'" 329*b30d1939SAndy Fiddaman if [[ $src_path != $src_skip ]] 330*b30d1939SAndy Fiddaman then 331*b30d1939SAndy Fiddaman src_skip= 332*b30d1939SAndy Fiddaman print -r chmod $src_perm "'$src_path'" 333*b30d1939SAndy Fiddaman fi 334*b30d1939SAndy Fiddaman fi 335*b30d1939SAndy Fiddaman fi 336*b30d1939SAndy Fiddaman src_path= 337*b30d1939SAndy Fiddaman dst_path= 338*b30d1939SAndy Fiddaman elif [[ ! $dst_path || $src_path && $src_path < $dst_path ]] 339*b30d1939SAndy Fiddaman then 340*b30d1939SAndy Fiddaman if [[ $src_path != . ]] 341*b30d1939SAndy Fiddaman then 342*b30d1939SAndy Fiddaman cp[ncp++]=$src_path 343*b30d1939SAndy Fiddaman if [[ $src_path != $src_skip ]] 344*b30d1939SAndy Fiddaman then 345*b30d1939SAndy Fiddaman if [[ $src_type == d ]] 346*b30d1939SAndy Fiddaman then 347*b30d1939SAndy Fiddaman src_skip="$src_path/*" 348*b30d1939SAndy Fiddaman print -r cp -r "'$src_path'" 349*b30d1939SAndy Fiddaman else 350*b30d1939SAndy Fiddaman src_skip= 351*b30d1939SAndy Fiddaman print -r cp "'$src_path'" 352*b30d1939SAndy Fiddaman fi 353*b30d1939SAndy Fiddaman fi 354*b30d1939SAndy Fiddaman fi 355*b30d1939SAndy Fiddaman src_path= 356*b30d1939SAndy Fiddaman elif [[ $dst_path ]] 357*b30d1939SAndy Fiddaman then 358*b30d1939SAndy Fiddaman if (( delete )) 359*b30d1939SAndy Fiddaman then 360*b30d1939SAndy Fiddaman rm[nrm++]=$dst_path 361*b30d1939SAndy Fiddaman if [[ $dst_path != $dst_skip ]] 362*b30d1939SAndy Fiddaman then 363*b30d1939SAndy Fiddaman if [[ $dst_type == d ]] 364*b30d1939SAndy Fiddaman then 365*b30d1939SAndy Fiddaman dst_skip="$dst_path/*" 366*b30d1939SAndy Fiddaman print -r rm -r "'$dst_path'" 367*b30d1939SAndy Fiddaman else 368*b30d1939SAndy Fiddaman dst_skip= 369*b30d1939SAndy Fiddaman print -r rm "'$dst_path'" 370*b30d1939SAndy Fiddaman fi 371*b30d1939SAndy Fiddaman fi 372*b30d1939SAndy Fiddaman fi 373*b30d1939SAndy Fiddaman dst_path= 374*b30d1939SAndy Fiddaman fi 375*b30d1939SAndy Fiddamandone 376*b30d1939SAndy FiddamanIFS=$ifs 377*b30d1939SAndy Fiddaman 378*b30d1939SAndy Fiddaman(( exec )) || exit 0 379*b30d1939SAndy Fiddaman 380*b30d1939SAndy Fiddaman# generate, transfer and execute the { rm chown chmod } script 381*b30d1939SAndy Fiddaman 382*b30d1939SAndy Fiddamanif (( ${#rm[@]} || ${#chmod[@]} || ${#chown[@]} )) 383*b30d1939SAndy Fiddamanthen 384*b30d1939SAndy Fiddaman { 385*b30d1939SAndy Fiddaman if (( verbose )) 386*b30d1939SAndy Fiddaman then 387*b30d1939SAndy Fiddaman print -r -- set -x 388*b30d1939SAndy Fiddaman fi 389*b30d1939SAndy Fiddaman print -nr -- cd "'$dst_dir'" 390*b30d1939SAndy Fiddaman n=0 391*b30d1939SAndy Fiddaman for i in ${rm[@]} 392*b30d1939SAndy Fiddaman do 393*b30d1939SAndy Fiddaman if (( --n <= 0 )) 394*b30d1939SAndy Fiddaman then 395*b30d1939SAndy Fiddaman n=32 396*b30d1939SAndy Fiddaman print 397*b30d1939SAndy Fiddaman print -nr -- rm -rf 398*b30d1939SAndy Fiddaman fi 399*b30d1939SAndy Fiddaman print -nr -- " '$i'" 400*b30d1939SAndy Fiddaman done 401*b30d1939SAndy Fiddaman for i in ${!chown[@]} 402*b30d1939SAndy Fiddaman do 403*b30d1939SAndy Fiddaman n=0 404*b30d1939SAndy Fiddaman for j in ${chown[$i]} 405*b30d1939SAndy Fiddaman do 406*b30d1939SAndy Fiddaman if (( --n <= 0 )) 407*b30d1939SAndy Fiddaman then 408*b30d1939SAndy Fiddaman n=32 409*b30d1939SAndy Fiddaman print 410*b30d1939SAndy Fiddaman print -nr -- chown $i 411*b30d1939SAndy Fiddaman fi 412*b30d1939SAndy Fiddaman print -nr -- " $j" 413*b30d1939SAndy Fiddaman done 414*b30d1939SAndy Fiddaman done 415*b30d1939SAndy Fiddaman for i in ${!chmod[@]} 416*b30d1939SAndy Fiddaman do 417*b30d1939SAndy Fiddaman n=0 418*b30d1939SAndy Fiddaman for j in ${chmod[$i]} 419*b30d1939SAndy Fiddaman do 420*b30d1939SAndy Fiddaman if (( --n <= 0 )) 421*b30d1939SAndy Fiddaman then 422*b30d1939SAndy Fiddaman n=32 423*b30d1939SAndy Fiddaman print 424*b30d1939SAndy Fiddaman print -nr -- chmod $i 425*b30d1939SAndy Fiddaman fi 426*b30d1939SAndy Fiddaman print -nr -- " $j" 427*b30d1939SAndy Fiddaman done 428*b30d1939SAndy Fiddaman done 429*b30d1939SAndy Fiddaman print 430*b30d1939SAndy Fiddaman } | { 431*b30d1939SAndy Fiddaman if (( ! exec )) 432*b30d1939SAndy Fiddaman then 433*b30d1939SAndy Fiddaman cat 434*b30d1939SAndy Fiddaman elif [[ $dst_host ]] 435*b30d1939SAndy Fiddaman then 436*b30d1939SAndy Fiddaman $remote $dst_user $dst_host sh 437*b30d1939SAndy Fiddaman else 438*b30d1939SAndy Fiddaman $SHELL 439*b30d1939SAndy Fiddaman fi 440*b30d1939SAndy Fiddaman } 441*b30d1939SAndy Fiddamanfi 442*b30d1939SAndy Fiddaman 443*b30d1939SAndy Fiddaman# generate, transfer and read back the { cp } tarball 444*b30d1939SAndy Fiddaman 445*b30d1939SAndy Fiddamanif (( ${#cp[@]} )) 446*b30d1939SAndy Fiddamanthen 447*b30d1939SAndy Fiddaman { 448*b30d1939SAndy Fiddaman cd $src_dir && 449*b30d1939SAndy Fiddaman print -r -f $'%s\n' "${cp[@]}" | 450*b30d1939SAndy Fiddaman $pax $paxwriteflags 451*b30d1939SAndy Fiddaman } | { 452*b30d1939SAndy Fiddaman if [[ $dst_host ]] 453*b30d1939SAndy Fiddaman then 454*b30d1939SAndy Fiddaman $remote $dst_user $dst_host "{ test ! -f .profile || . ./.profile ;} && { test -d \"$dst_dir\" || mkdir -p \"$dst_dir\" ;} && cd \"$dst_dir\" && gunzip | $pax $paxreadflags" 455*b30d1939SAndy Fiddaman else 456*b30d1939SAndy Fiddaman ( { test -d "$dst_dir" || mkdir -p "$dst_dir" ;} && cd "$dst_dir" && gunzip | $pax $paxreadflags ) 457*b30d1939SAndy Fiddaman fi 458*b30d1939SAndy Fiddaman } 459*b30d1939SAndy Fiddaman wait 460*b30d1939SAndy Fiddamanfi 461