+++ /dev/null
-#!/bin/bash\r
-# Author: Hari Krishna Dara ( hari_vim at yahoo dot com ) \r
-# Last Change: 17-Mar-2004 @ 18:47\r
-# Requires:\r
-# - bash or ksh (tested on cygwin and MKS respectively).\r
-# - Info Zip for the -z option to work (comes with linux/cygwin). Download for\r
-# free from:\r
-# http://www.info-zip.org/\r
-# - GNU tar for the -a option to work (comes with linux/cygwin).\r
-# Version: 1.4.2\r
-# Licence: This program is free software; you can redistribute it and/or\r
-# modify it under the terms of the GNU General Public License.\r
-# See http://www.gnu.org/copyleft/gpl.txt \r
-# Description:\r
-# Shell script to take backup of all the open files in perforce SCM.\r
-#\r
-#TODO:\r
-# - Zip comment option -zz is no longer working?\r
-# - To create cpio archives, I can use "cpio -o -H | gzip" command.\r
-# - Option to generate a diff at the end.\r
-# - Option to restrict by type (useful to avoid huge binary files).\r
-# - Support to run zip from a different directory (to avoid certain path\r
-# component from getting into zipfile).\r
-\r
-usage()\r
-{\r
-cat <<END\r
-$0 [<backup dir>] [<source dir>] ...\r
-$0 -h -n -q -v -z -zz [-c <change number>] [-t <backup dir>] [-r <backup root>] [[-s <source dir>] ...]\r
- -t specify full path name to the target directory. If -z is specified this\r
- becomes the path to the zip file name.\r
- -r set the root for creating the default backup dir/zip file. Not used if\r
- "backup dir" is specified. You can also set BAKUP_ROOT environmental\r
- variable. Defaults to p: (p drive), because that is what it is on my\r
- system :).\r
- -i incremental backup, which makes the program use the previous backup\r
- directory/archive for that day (if it exists) instead of creating a new\r
- one. For tar (with "-a" option), you will have to provide one of the\r
- relevant options to force reuse an existing archive ("-ar" e.g.) or the\r
- existing archive will simply get overwritten. However this will not work\r
- with compressed tar archives. You can also specify any existing backup\r
- directory/archive path explicitly by using the "-t" option.\r
- -a create a tar file instead of copying the files. You can specify the\r
- tar file name using -t option.\r
- -a[-|--]<taropt>\r
- Pass -taropt to tar command.\r
- Ex:\r
- - Pass "-aC <dir>" or "-adirectory=<dir>" to cd to a directory before\r
- creating the tar file (thus dropping file component).\r
- - Pass "-az" to gzip the created tar file.\r
- -z create a zip file instead of copying the files. You can specify the\r
- zip file name using -t option.\r
- -z[-]<zipopt>\r
- Pass -zipopt to zip command.\r
- Ex: Pass -zz for a prompt from zip to enter a comment.\r
- -s limit to open files matching the given wildcard (local or depot). This\r
- can be repeated multiple times to specify multiple source directories.\r
- You can pass in anything that the 'p4 opened' command itself accepts.\r
- -c limit the files to those specified in the change number, in addition to\r
- the -s option. This can't be repeated multiple times though.\r
- -n don't execute any commands, just show what is going to be done. Does not\r
- currently work with -z option.\r
- -q quite mode, no messages\r
- -v verbose mode, print messages (the default).\r
- -h print help message (this message) and exit\r
- The first unspecified directory is treated as target directory, and the\r
- remaining directories are treated as source directories. The '-n' option can\r
- be used to generate a batch script that can be run later. The source\r
- directory can be in depot or local format (NO BACKSLASHES PLEASE). Do not\r
- combine multiple options into one argument.\r
-Examples:\r
- bakup.sh\r
- - Backup all the open files into a default generated backup dir. in p:\r
- drive (p: driver is the default backup directory).\r
- bakup.sh mybak c:/dev/branch/src\r
- - Backup open files only under 'c:/dev/branch/src' into 'mybak'\r
- directory.\r
- bakup.sh -s //depot/branch/src -s //depot/branch/cfg\r
- - Backup open files only under 'src' and 'cfg' into the default bakup\r
- dir.\r
-\r
- You could add -z option to all the above usages to create a zip file\r
- instead of creating a directory. You need to have Info-Zip installed in the\r
- path for this to work.\r
-\r
- bakup.sh -n > mybackup.bat\r
- - Generates a 'mybackup.bat' batch file that can be run at a later\r
- time to take a backup. The files to be backed up are based on the\r
- time the script was generated, so it should be regenerated if the\r
- list has changed since then.\r
-END\r
-exit 1\r
-}\r
-\r
-generateTargetDirName()\r
-{\r
- today=`date +"%d-%b-%Y"`\r
- inc=1\r
- #echo "---first time"\r
- tDir="$targetRoot/bakup-$today"\r
- prevDir=$tDir\r
- while [ -d $tDir -o -f $tDir.* ]; do\r
- inc=$[inc + 1]\r
- prevDir=$tDir\r
- tDir="$targetRoot/bakup-${today}_$inc"\r
- #echo "---subsequent time inc=$inc tDir=$tDir"\r
- done\r
- if [ $incrementalMode -ne 0 ]; then\r
- tDir=$prevDir # Backup one level to use an existing db.\r
- fi\r
- echo "$tDir"\r
-}\r
-\r
-getExtOpt()\r
-{\r
- archiveOpt=${1/[-+]$2/}\r
- case $archiveOpt in\r
- --*)\r
- ;;\r
- -??*) # Mistyped long option\r
- archiveOpt="-$archiveOpt"\r
- ;;\r
- -*)\r
- ;;\r
- ??*) # Long option.\r
- archiveOpt="--$archiveOpt"\r
- ;;\r
- *)\r
- archiveOpt="-$archiveOpt"\r
- ;;\r
- esac\r
- echo $archiveOpt\r
-}\r
-\r
-#getExtOpt '-a--directory' 'a'\r
-#getExtOpt '-a-directory' 'a'\r
-#getExtOpt '-adirectory' 'a'\r
-#getExtOpt '-aC' 'a'\r
-#getExtOpt '-a-C' 'a'\r
-#exit\r
-\r
-checkOptArg='\r
- shift;\r
- if [ $# -eq 0 ]; then\r
- usage;\r
- fi\r
-'\r
-\r
-testMode=0\r
-archiveOpts=''\r
-chDirectory='' # If set, the listing is generated relative to this dir.\r
-archiveMode=0\r
-verboseMode=1\r
-targetDir=""\r
-targetRoot=""\r
-sourceDirs=""\r
-changeNumber=""\r
-compressedTar=0\r
-incrementalMode=0\r
-until [ $# -eq 0 ]; do\r
- case $1 in\r
- -h|-help|--help)\r
- usage\r
- ;;\r
- -v)\r
- verboseMode=1\r
- ;;\r
- -q)\r
- verboseMode=0\r
- ;;\r
- -i)\r
- incrementalMode=1\r
- ;;\r
- -a)\r
- archiveMode=2 # Tar.\r
- verboseMode=0 # Turn on quite mode, as zip will anyway show the files.\r
- testMode=1 # Turn on test mode, so we won't copy files.\r
- ;;\r
- -a*)\r
- # Need to take care of options with optional args.\r
- extOpt=`getExtOpt $1 a`\r
- if [ $extOpt = -z -o $extOpt = -Z -o $extOpt = -j ]; then\r
- compressedTar=1\r
- tarExt=`echo $extOpt | awk 'BEGIN{ext["-j"]="bz2";ext["-z"]="gz";ext["-Z"]="Z";}{print ext[$0];}'`\r
- fi\r
- archiveOpts="${archiveOpts} $extOpt"\r
- case $extOpt in\r
- --directory)\r
- chDirectory=${extOpt/*=}\r
- ;;\r
- -C)\r
- eval $checkOptArg\r
- chDirectory=$1\r
- #echo "---setting chDirectory=$chDirectory"\r
- archiveOpts="${archiveOpts} $chDirectory"\r
- ;;\r
- esac\r
- ;;\r
- -z)\r
- archiveMode=1 # Zip.\r
- verboseMode=0 # Turn on quite mode, as zip will anyway show the files.\r
- testMode=1 # Turn on test mode, so we won't copy files.\r
- ;;\r
- -z*)\r
- # Need to take care of options with optional args.\r
- archiveOpts="${archiveOpts} `getExtOpt $1 z`"\r
- ;;\r
- -n)\r
- testMode=1\r
- verboseMode=0\r
- ;;\r
- -c)\r
- eval $checkOptArg\r
- changeNumber=$1\r
- ;;\r
- -t)\r
- eval $checkOptArg\r
- targetDir=$1\r
- ;;\r
- -r)\r
- eval $checkOptArg\r
- targetRoot=$1\r
- ;;\r
- -s)\r
- eval $checkOptArg\r
- sourceDirs="$sourceDirs $1"\r
- #echo "---setting sourceDirs=$sourceDirs"\r
- ;;\r
- -?)\r
- usage\r
- ;;\r
- *)\r
- if [ "$targetDir" = "" ]; then\r
- #echo "---setting targetDir=$targetDir"\r
- targetDir=$1\r
- else\r
- #echo "---appending sourceDirs=$1"\r
- sourceDirs="$sourceDirs $1"\r
- fi\r
- ;;\r
- esac\r
- shift\r
-done\r
-\r
-# For tar, we can add -a option only if no other equivalent option is specified.\r
-if [ $archiveMode -eq 2 ]; then\r
- case $archiveOpts in\r
- *-[Acdtrux]*)\r
- ;;\r
- *)\r
- archiveOpts="$archiveOpts -c"\r
- ;;\r
- esac\r
-fi\r
-\r
-if [ x${targetDir}x = xx -a x${targetRoot}x = xx ]; then\r
- targetRoot=$BAKUP_ROOT\r
- if [ "$targetRoot" = "" ]; then\r
- targetRoot="p:"\r
- fi\r
-fi\r
-\r
-if [ "$targetDir" = "" ]; then\r
- targetDir=`generateTargetDirName`\r
-fi\r
-\r
-if [ "$sourceDirs" = "" ]; then\r
- # By default backup all the open files.\r
- sourceDirs="//..."\r
-fi\r
-\r
-\r
-# Create a dir if it doesn't exist, exit on error.\r
-createDir()\r
-{\r
- if ! [ -d "$1" ]; then\r
-\r
- if [ $testMode -eq 1 -o $verboseMode -eq 1 ]; then\r
- echo "mkdir -p $1" 1>&4\r
- fi\r
-\r
- if [ $testMode -eq 0 ]; then\r
- mkdir -p "$1"\r
- if [ $? -ne 0 ]; then\r
- echo "Error creating $1" 1>&2\r
- exit 1\r
- fi\r
- fi\r
- fi\r
-}\r
-\r
-\r
-#if [ $testMode -eq 1 ]; then\r
-# echo "Running in test mode"\r
-#fi\r
-\r
-if [ $archiveMode -eq 0 ]; then\r
- createDir $targetDir 4>&1\r
-fi\r
-\r
-if [ $verboseMode -eq 1 ]; then\r
- echo "Copying to target directory: $targetDir"\r
-fi\r
-\r
-# Testing for $BASH will not work, if you happen to use the cygwin sh instead of\r
-# bash.\r
-unset PWD\r
-codelineRoot=`p4 info | sed -n -e 's;\\\\;/;g' -e 's/Client root: //p'`\r
-#echo "---codelineRoot=$codelineRoot"\r
-rootDirLength=${#codelineRoot}\r
-\r
-if [ $archiveMode -eq 1 ]; then\r
- fileExt=''\r
- if [ ${targetDir%.zip} = $targetDir ]; then\r
- fileExt='.zip'\r
- fi\r
- pipeCmd="zip ${archiveOpts} -@ ${targetDir}${fileExt}"\r
- echo "Using: '${pipeCmd}' to create zip archive"\r
-elif [ $archiveMode -eq 2 ]; then\r
- fileExt=''\r
- if [ $compressedTar -eq 1 -a ${targetDir%.tar.$tarExt} = $targetDir ]; then\r
- fileExt=".tar.$tarExt"\r
- elif [ $compressedTar -ne 1 -a ${targetDir%.tar} = $targetDir ]; then\r
- fileExt='.tar'\r
- fi\r
- pipeCmd="tar -vf ${targetDir}${fileExt} ${archiveOpts} -T -"\r
- echo "Using: '${pipeCmd}' to create tar archive"\r
-else\r
- pipeCmd="cat"\r
-fi\r
-\r
-exec 4>&1; {\r
- for sourceDir in $sourceDirs; do\r
- if [ ! -f $sourceDir ]; then\r
- case $sourceDir in\r
- *...)\r
- ;;\r
- */)\r
- sourceDir="${sourceDir}..."\r
- ;;\r
- *)\r
- sourceDir="${sourceDir}/..."\r
- ;;\r
- esac\r
- fi\r
- if [ "$changeNumber" = "" ]; then\r
- openedCmd="p4 opened $sourceDir"\r
- else\r
- openedCmd="p4 opened -c $changeNumber $sourceDir"\r
- fi\r
- if [ $verboseMode -eq 1 ]; then\r
- echo "Collecing list of open files using: $openedCmd" 1>&4\r
- fi\r
-\r
- # FIXME: I couldn't get it working with the following IFS, don't know\r
- # why. So as a temp. work-around, I am temporarily substituting spaces\r
- # with '|' in sed and converting them back to spaces in the start of the\r
- # loop.\r
- #IFS="\n\r"\r
- openedFiles=`$openedCmd | \\r
- sed -e '/ - delete \(default \)\?change /d' \\r
- -e 's/#.*//' |\r
- p4 -x - where | \\r
- sed -e 's;.\+/[^/]\+/\([^ /]\+\) //.*\1 \(.*\1\);\2;' \\r
- -e "s;^${chDirectory}/*;;" \\r
- -e 's/ /|/g' \\r
- -e 's;\\\\;/;g'`\r
- for file in `echo $openedFiles`; do\r
- file=${file//\|/ }\r
- #echo "---file = $file" 1>&4\r
- dir=`dirname "$file"`\r
- # Relative to the codeline root.\r
- tgtDir="${targetDir}/${dir:$rootDirLength}"\r
- #echo "---tgtDir = $tgtDir" 1>&4\r
-\r
- if [ $archiveMode -eq 0 ]; then\r
- createDir "$tgtDir"\r
- fi\r
-\r
- if [ $archiveMode -ne 0 ]; then\r
- echo $file 1>&3\r
- elif [ $testMode -eq 1 -o $verboseMode -eq 1 ]; then\r
- echo "cp \"$file\" \"$tgtDir\"" 1>&4\r
- fi\r
- if [ $testMode -eq 0 ]; then\r
- cp "$file" "$tgtDir"\r
- if [ $? -ne 0 ]; then\r
- echo "Error copying $1" 1>&2\r
- exit 1\r
- fi\r
- fi\r
- done\r
- done\r
-} 3>&1 | $pipeCmd\r
-\r
-# vim6: et sw=4\r