#! /usr/bin/ksh ########################################################################## # Title : update.ksh - update files based on the modification time # Author : Heiner Steven # Date : 1996-05-24 # Requires : ksh # Category : File Utilities # SCCS-Id. : @(#) update 2.2 18/05/17 ########################################################################## # Description # ########################################################################## PN=${0##*/} # Program name VER='2.2' CpFlags=p function Usage { print -u2 "$PN - update files based on the modification time, $VER usage: $PN [-efv] file [file ...] directory or $PN [-efv] file file or $PN [-efrv] {file|directory} [...] directory -e: only update already existing files -f: force overwriting read-only files -r: copy recursively -v: verbose operation" exit 1 } function msg { print -u2 -- "$PN:" "$@"; } function fatal { msg "$@"; exit 1; } set -u # DEBUG Recurse=false Verbose=false AddFiles=true while getopts :efhrv Opt do case "$Opt" in (e) AddFiles=false;; (f) CpFlags=${CpFlags}f;; (r) Recurse=true;; (v) Verbose=true;; (h) Usage;; (*) Usage;; esac done shift OPTIND-1 (( $# < 2 )) && Usage eval dst=\${$#} # There is one special case where # (1) exactly two arguments are specified, and # (2) both are files FileCopy=false [[ -f $dst ]] && (($# == 2)) && FileCopy=true if [[ -d $dst ]] || $FileCopy then # Copy files to a directory integer newcnt=0 oldcnt=0 while [ $# -gt 1 ] do srcpath=$1; shift [[ $srcpath == $dst ]] && continue [[ $srcpath -ef $dst ]] && continue if [[ -d $srcpath ]] then if ! $Recurse then msg "omitting directory \"$srcpath\"" continue fi # Recurse into the subdirectory, using the positional argument # list as a stack: set -- "$srcpath"/* "$@" #echo >&2 "DEBUG: recurse into $srcpath ($# stack elements)" continue fi # We will only process ordinary files. No devices, no pipes. [[ -f $srcpath ]] || continue # Process a file. Note that the source file name may have a # directory part, which we will re-create in the destination # directory. srcfile=$srcpath srcbase=${srcfile##*/} # Remove directory part if $FileCopy then dstdir=$dst dstfile=$dst else if [[ $srcfile == */* ]] then dir=${srcfile%/*} dstdir=$dst/$dir [[ -e $dstdir ]] || mkdir -p "$dstdir" || exit else dstdir=$dst fi dstfile=$dstdir/$srcbase fi # Compare "srcfile" with "dstfile" if [[ -e $dstfile ]] then if [[ $srcfile -nt $dstfile ]] then copy=true else copy=false $Verbose && msg "existing \"$dstfile\" is same age or newer" ((oldcnt=$oldcnt+1)) fi else if $AddFiles || $FileCopy then copy=true else copy=false $Verbose && msg "does not exist in target directory: \"$srcfile\"" fi fi $copy || continue $Verbose && echo "$dstfile" cp -$CpFlags "$srcfile" "$dstdir" && ((newcnt=$newcnt+1)) done msg "$newcnt file(s) updated, $oldcnt kept" else fatal "no directory: $dst" fi