#!/bin/sh # # ========================================================================= # Copyright 2004 Josh Glover # # LICENCE: # # This file is distributed under the terms of the BSD License (version # 2). See the COPYING file, which should have been distributed with this # file, for details. If you did not receive the COPYING file, see: # # http://www.jmglov.net/opensource/licenses/bsd.txt # # cvs-unlock # # DESCRIPTION: # # Recursively unlocks a directory and all below it in a CVS repository. # The directory must have previously been locked by cvs-lock. # # *A single run of unlock unlocks multiple runs of lock.* # # USAGE: # # See usage(), below # # EXAMPLES: # # *** # # TODO: # # - Why does unlock_dir() fail to detect that the lockfile exists? # - Implement unlocking a remote repository using CVS_RSH # - Nothing, this code is perfect # # DEPENDENCIES: # # Bourne shell # # MODIFICATIONS: # # Josh Glover (2004/05/28): Initial revision; # modified Jennifer Vesperman's cvs-unfreeze.sh script (from O'Reilly's # _Essential CVS_): http://examples.oreilly.com/cvs/unfreeze.sh # ========================================================================= # Constant: ME # # Basename of the script ME=`basename $0` # Variable: cvsroot # # Path to CVS repository (defaults to $CVSROOT environment variable) cvsroot="${CVSROOT}" # Variable: dir # # Top-level directory in CVS repository to lock dir="" # Variable: dryrun # # If non-zero, run in dryrun mode dryrun=0 # Variable: keymagic # # Unique key to append to lockfiles keymagic="" # Variable: quiet # # If non-zero, informational messages will be spewed to STDOUT quiet=0 # Variable: tmpfile # # Temporary file for recording lockfiles tmpfile="" # Variable: trace # # If non-zero, each command will be spewed to STDOUT before it is run trace=0 # Variable: unlock_read # # Unlock read locks? unlock_read="rfl" # Variable: unlock_write # # Unlock write locks? unlock_write="wfl" # Function: bail_out() # # Exit abruptly with an error code after displaying an error message. # # Parameters: # # 1 - error message to display bail_out () { echo "${ME}: $1" rm -f ${tmpfile} exit 1 } # bail_out() # Function: unlock_directory() # # Unlocks the specified directory. # # Parameters: # # 1 - directory to unlock # # Returns: # # 0 on success, 1 on failure unlock_directory () { if [ ${quiet} -eq 0 ]; then echo "${ME}: unlock: $1"; fi # Obtain the master lock if [ ${trace} -ne 0 ]; then echo mkdir "$1/#cvslock" fi # if (trace mode?) if [ ${dryrun} -eq 0 ]; then mkdir "$1/#cvslock" fi # if (dryrun mode?) # If we could not get the master lock, return failure if [ $? != 0 ]; then return 1; fi # Unlock read and or write locks? for i in ${unlock_read} ${unlock_write}; do # Check for a lockfile if [ ${trace} -ne 0 ]; then echo test -f "$1/#cvs.$i.${keymagic}" fi # if (trace mode?) if [ ${dryrun} -eq 0 ]; then test -f "$1/#cvs.$i.${keymagic}" fi # if (dryrun mode?) # If we did not find a lockfile, spew a warning. Otherwise, remove the # lockfile if [ $? -ne 0 ]; then echo "${ME}: unlock: expected to find a lockfile: $1/#cvs.$i.${keymagic}" else if [ ${trace} -ne 0 ]; then echo rm -f "$1/#cvs.$i.${keymagic}" fi # if (trace mode?) if [ ${dryrun} -eq 0 ]; then rm -f "$1/#cvs.$i.${keymagic}" fi # if (dryrun mode?) fi # if (did we find a lockfile?) if [ ${quiet} -eq 0 ]; then echo "${ME}: $1/#cvs.$i.${keymagic} unlocked" fi # if (spewing debuggery) done # for (unlocking read and/or write locks) # Release the master lock if [ ${trace} -ne 0 ]; then echo rmdir "$1/#cvslock" fi # if (trace mode?) if [ ${dryrun} -eq 0 ]; then rmdir "$1/#cvslock" fi # if (dryrun mode?) return 0 } # unlock_directory() # Function: unlock_all() # # Recursively calls to unlock a whole directory tree. # # Returns: # # 0 on success, 1 on failure unlock_all () { tmpfile=/tmp/lock.${keymagic} for i in `find ${cvsroot}/${dir} -type d ! -iname CVS ! -iname Attic ! -iname "#cvslock"`; do # If we cannot unlock this directory, return failure if ! unlock_directory $i; then return 1; fi done # for (unlocking all directories below ${dir} return 0 } # unlock_all() # Function: usage() # # Displays a usage message and exits with the specified code. # # Parameters: # # 1 - return code (defaults to 255) usage () { retval=$1 if [ -z "${retval}" ]; then retval=255; fi cat <} where valid