# Compare and update a backup directory. # Copyright (c) 2001-2012 by Hamilton Laboratories. All rights reserved. # Usage: update [-acd] frompath topath # # Compare the frompath and topath directories looking for differences, # updating the topath directory as needed to make it an up-to-date # copy. # # Comparison is done based on timestamps, not contents for speed. By # default, only files that already exist in the 'topath' are updated. # Files that exist only in the 'frompath' are not copied. (This is # done on the assumption that the 'topath' is intended only to contain # a snapshot of the important files.) # # By default, an extra files in the 'topath' are not deleted. # # Options: # # -a All files. If a file or subdirectory exists only in the # frompath, copy it to the topath. # -c Compare only and report. # -d Delete any extra files in the topath. # -v Verbose. proc update(args) local j, frompath, topath, allfiles, compareonly, deleteextra, Verbose if ($#args < 2) then echo "Usage: update [-acdv] frompath topath" @ status = 1 return end while ($#args >= 3) if (substr(args[0], 1, 1) != '-') then echo "Usage: update [-acd] frompath topath" @ status = 1 return end for j = 2 to strlen(args[0]) do switch (substr(args[0], j, 1)) case 'a': @ allfiles = 1 break case 'c': @ compareonly = 1 break case 'd': @ deleteextra = 1 break case 'v': @ Verbose = 1 break case '-': break default: echo "Usage: update [-acd] frompath topath" @ status = 1 return end end shift args end @ frompath = fullpath(args[0]) @ topath = fullpath(args[1]) if (frompath =~ "*\") @ frompath = substr(frompath, 1, strlen(frompath) - 1) if (topath =~ "*\") @ topath = substr(topath, 1, strlen(topath) - 1) if (Verbose) echo Comparing "$frompath" and "$topath" if (-e "$frompath" && -e "$topath" && $#frompath == 1 && $#topath == 1) then if (Verbose) echo Paths exist, now comparing if (-D "$frompath") then if (! -D "$topath") then echo "$topath" must be a directory @ status = 1 return end if (!allfiles) then foreach j (``ls -1rD "$frompath"``:q) if (-e "$topath\$j" && `newer "$frompath\$j" "$topath\$j"`) then if (compareonly) then echo -- "$topath\$j" is out of date else if (Verbose) echo Updating "$topath\$j" cp -- "$frompath\$j" "$topath\$j" end end end else foreach j (``ls -1ra +D -. "$frompath"``:q) if (! -e "$topath\$j") then if (compareonly) then echo -- "$topath\$j" does not exist else if (Verbose) echo Creating "$topath\$j" mkdir -- "$topath\$j" end end end foreach j (``ls -1rD "$frompath"``:q) if (-e "$topath\$j") then if (`newer "$frompath\$j" "$topath\$j"`) then if (compareonly) then echo -- "$topath\$j" is out of date else if (Verbose) echo Updating "$topath\$j" cp -- "$frompath\$j" "$topath\$j" end end else if (compareonly) then echo -- "$topath\$j" does not exist else if (Verbose) echo Creating "$topath\$j" cp -- "$frompath\$j" "$topath\$j" end end end end if (deleteextra) then if (compareonly) then foreach j (``ls -1rD "$topath"``:q) if (! -e "$frompath\$j") then echo -- "$frompath\$j" does not exist end end else foreach j (``ls -1rD "$topath"``:q) if (! -e "$frompath\$j") then if (Verbose) echo Deleting "$topath\$j" rm -- "$topath\$j" end end end end else if (-D "$topath") then echo -- "$topath" must be an ordinary file @ status = 1 return end if (compareonly) then echo -- "$topath" is out of date else if (Verbose) echo Updating "$topath" cp -- "$frompath" "$topath" end end else echo Either "$frompath" or "$topath" is not a valid pathname end end update $argv |