#!/bin/csh -f # set echo verbose # There is absolutely no warranty of any type on this public-domain script. # Template backup script. This assumes you have a separate backup program # such as dar_static already installed. # This script is not intended for unsophisticated users with little # knowledge about writing scripts. It is intended for those who could # write their own script from scratch if they wanted to, to be a time saver, # by having the general lines already worked out and to some extent # tested. # This script will keep old backups at various super-exponentially spaced, # selectable, age-levels. It allows for a few additional incremental or # full backups as needs arise. It is designed to put notification files on # your desktop so that a visual check on backup status is maintained. # Copy this template to a suitably named file, e.g. "backup", then edit # it. In particular the variables below will need to be edited. # # The script should then be run once as # backup init # to create the "backup" directory for the backups. # # Subsequent backup instructions are given when running this script with no # arguments. # Start of variables to set: # The name given to this script (backup as above or whatever). # This will also be used as the name of the subdirectory to hold the # backups: set nam=backup # Existing root directory for the backup subdirectory. Cannot be # blank. This should normally be the mount point of the USB or other # external disk to hold the backups, maybe /media/... Directory # "$root/$nam" will be created during '$nam init' to hold the backups: set root="" if ($#argv == 2) then set root="$1" shift endif # Error-message-file directory with fully specified path. Cannot be blank. # Watch it: files with name templates "$nam_*" may be overwritten in this # directory without notice. Files that may be overwritten are $nam_running, # $nam_disabled, $nam_tmp, $nam_FAILED*, and $nam_nn-nn-nn, with n any # decimal digit: set errdir="$HOME/Desktop" # Username(s) to email about failure or blank for none. On Debian systems, # you do not get e-mail on root; to do so, you can create a symbolic link as # 'ln -s /var/mail/username /var/mail/root' with username from /etc/aliases. # Or use whatever name you do login as, if not root. # On Ubuntu, mail is not operational, so leave this blank. # To test, try the command # echo testing | mail -s test # and see whether it arrives. set email="" # Days after which to kill $nam_running lock files or empty for no killing. # For unattended systems, leaving this blank will cause an orphaned lock # file to abort backups indefinitely: set rmlock=2 # The number of lines to keep when truncating the log file: set maxlines=1000 # Backup file filetype and grep regular expression for it: set ext='.1.dar' # first slice generated set exta='.?.dar' # any slice of the backup set exts='\.1\.dar$' # Chmod executed on generated files: set chm='chmod go-rwx' # Find command to search $errdir. It depends on your system what works; # test it out using "find ~ -maxdepth 1 -name '.bashrc'"! alias fnd '/usr/bin/find "$errdir" -maxdepth 1' # Other possibilities to try, in order of decreasing desirability: # alias fnd '/usr/local/bin/find "$errdir" -maxdepth 1' # alias fnd 'find "$errdir" \! -name "$errdir:t" -prune' # alias fnd 'find "$errdir"' # command to return the date of a file alias fdate '/bin/date -r \!* +"%m-%d-%y"' # Other possibilities to try, in order of decreasing desirability: # alias fdate '/usr/local/bin/date -r \!* +"%m-%d-%y"' # alias fdate 'date +"%m-%d-%y" ; echo \!* > /dev/null' # Path to executable backupex creating new file names to use: set newfnm="$HOME/bin/backupex" # Highest directory to be backed up: set fsroot="/" # Whether to skip backup if 'find -newer' cannot find any files in $fsroot # that have a later modification time than the current backup set. Not # recommended unless it is a backup you can afford to lose: if something # changes the modification time of the backup set, you are out of luck. # And so you are if someone mis-touches an important file. Can still be # useful if all you are backing up is var/cache/apt/archives or similar. # Set to "inc" to skip incrementals or to "all" to also skip new backups: set skip= # Backup executable. set backexe='/usr/bin/dar_static' # Backup command. This will not work correctly as is and must be adapted # to your system. In particular the list of directories to prune will be # incorrect. Note that they are relative to the top directory fs-root to # back up. Note the need to avoid backing up the backup directory! # (Separate backup scripts can be created to backup massive, non-critical, # folders like apt/archives with less redundancy.) Name $backprog will be # replaced by $backexe above in operation; do not change it here, since # this alias will also be used to log the command parameters used in the # backup. Note the trailing backslashes and final blank line: alias backcmd \ '$backprog' \ '$backfils' \ --noconf \ -Q \ --fs-root "$fsroot" \ --empty-dir \ --no-mount-points \ --prune dev/pts --prune lost+found --prune media --prune proc \ --prune tmp \ --prune var/cache/apt/archives \ --prune c --prune d --prune f --prune h --prune j --prune sct \ --prune ".$root/$nam" \ --alter=atime \ --slice 2G \ --mincompr 256 --gzip=6 --alter=no-case \ -Z "'*.gz'" -Z "'*.bz2'" -Z "'*.zip'" \ -Z "'*.png'" -Z "'*.gif'" -Z "'*.jpg'" \ # How to set the backup file arguments. The following two commands are for # dar, but may have to be changed to their short form on some systems. $fnm # is the backup file name, without filetype, and $oldfnm the backup file # name of the previous backup: alias argnew 'set backfils="--create $fnm"' alias arginc 'set backfils="--create $fnm --ref $oldfnm"' # Backup program return status values to ignore, should normally include 0. set statign='0' # Backup program return status values for which an error notification is # send, but for which the backup is still accepted as valid. Anything not # listed in this string or statign above causes the backup set to be marked # as bad, to be deleted during the next backup. According to 'man # dar_static', exit status 5 indicates that a file could not be opened or # read, and 11 that a file changed while dar was reading it and may be # corrupt in the backup. If you decide that an acceptable backup was bad # after all or vice-versa, and want to fix it manually, note that if the # next backup that is performed is incremental, the old good backup *must* # be in $root/$nam/1, and its filename *must* be settable by sourcing file # $root/$nam/oldfnm.src: set statnoti='5 11' # List of files to copy to the backup directory, separated by spaces. The # idea is that you may want to put a copy of the backup program along with # your backups, and maybe its docs. Then you can recover the backups even # with a crashed system disk, by booting from some live CD like the Insert # one. But this only works for "statically linked" backup programs; others # would require libraries from the crashed disk to run. In Debian, you # need Lenny package dar-static, not dar, for it to work. I would think # dar-static would work fine on etch, it being statically linked. I know # it works with the Insert live CD. To not save any files, remove the # stuff behind the equals sign; to save more, add them between the quotes, # separated by spaces: set savefils="$backexe" # Lines to put in the readme file in the backup directory. Modify this to # the instructions needed to recover your own system. Note the trailing # backslashes and watch the quotes: if ("$*" != "init") goto endrme set readme=(\ '# To recover a crashed or messed-up system disk:'\ ''\ '# Boot from the Insert or other live CD.'\ '# Create the desired file system on the new disk and cd to it:'\ 'mkfs.ext3 /dev/sdaN'\ 'mkdir /recov'\ 'mount /dev/sdaN /recov'\ 'cd /recov'\ '# Recover the files using dar_static on the USB disk'\ '[USB disk]/[backup]/dar_static -h | more'\ '[USB disk]/[backup]/dar_static -x [USB disk]/[backup]/1/mmddyy_NNNNNN0'\ '[USB disk]/[backup]/dar_static -x [USB disk]/[backup]/1/mmddyy_NNNNNN1'\ '[USB disk]/[backup]/dar_static -x [USB disk]/[backup]/1/mmddyy_NNNNNN2'\ '...'\ '# Recreate subdirectories in skipped folder /var/cache/apt/archives:'\ 'mkdir var/cache/apt/archives/partial'\ ''\ '# To recover a single file (-g does not take wild cards):'\ 'cd [USB disk]/[backup]/1/'\ 'mkdir tmp'\ 'cd tmp'\ 'dar_static -x ../mmddyy_nnnnnn0 -g [path relative to fs-root] -v -e | more'\ 'dar_static -x ../mmddyy_nnnnnn0 -g [path relative to fs-root]'\ ''\ ) endrme: # The final variables to be set select how often the backups at various age # levels are refreshed. Each variable that is not blank represents a backup # that is kept, n1 being the latest and greatest one, saved in directory # $root/$nam/1/, n2 a relatively recent but older one in $root/$nam/2/, n3 a # still older one in $root/$nam/3/, and so on until a variable is blank. # Depending on the precise values of the variables a backup corresponding to # n7 could be very old. # # The values must be hexadecimal-style, upper-case, single digits in base 36, # i.e. in the range 0, 1, ..., 9, A, B, ..., Z. The final values can be left # blank for less than nine backup age levels: # Maximum number of incremental backups to do for each nonincremental one. # (To override this in usage, use the explicit '$nam new' or '$nam inc'. # To do a weekly full backup on Sundays and daily incremental ones, but # maybe a few more incrementals as circumstances dictate, set this to Z and # do daily '$nam 7' backups using [ana]cron.) set n1=6 # How many finished (full plus incrementals) backup sets not to save # to the 2nd age level for each that is. (Set this to zero, or you # may end up with no latest-and-greatest backup if a new backup # crashes.) set n2=0 # From now on use at least 1 for the parameter values so that you spread the # dates of the older backups out over time. # How many 2nd level backups not to save to the 3th age level for each that is. set n3=1 # How many 3th level backups not to save to the 4th age level for each that is. set n4=1 # How many 4th level backups not to save to the 5th age level for each that is. set n5=2 # How many 5th level backups not to save to the 6th age level for each that is: set n6=2 # How many 6th level backups not to save to the 7th age level for each that is: set n7=3 # How many 7th level backups not to save to the 8th age level for each that is: set n8= # How many 8th level backups not to save to the 9th age level for each that is: set n9= # End of variables to set. # Initial checks and actions # see whether we just want help if ("$*" == "") goto proarg if ("$*" == '-h' || "$*" == '-?') goto proarg if ("$*" == '-help' || "$*" == '--help') goto proarg # see whether root is set, otherwise assume no serious attempt to run is made if ("$root" != "") goto hvroot echo "This script performs backups. It should be copied into an appropriately" echo "named executable file and then edited to set the backup properties." goto end hvroot: # set the command being executed set dat=`date +'%m-%d-%y'` set cmd="$nam" if ("$*" != "") set cmd="$nam $*" set cmd="$cmd on `date +'%a %D %H:%M%P'`" # error folder not yet secured unset haverr # no lock file yet unset lckfil # no log file yet unset logfil # goto error processing on an interrupt onintr erri # try to secure the error directory set msg="Error-file directory $errdir is not specified" if ("$errdir" == "") goto err set msg="Error-file directory $errdir does not exist" if !(-d "$errdir") goto err set msg="Incomplete access to error-file directory $errdir" if !(-rwx "$errdir") goto err set haverr # no processing if there is a $nam_disabled file if (-e "$errdir/$nam""_disabled") then if ("$*" != "enable") goto proarg endif # try to secure the lock file if !(-f "$errdir/$nam""_running") goto endrml if ("$rmlock" == "") goto endrml set msg="Test if the lock file is older than $rmlock days using fnd failed" set i=`fnd -name "$nam""_running" -mtime +"$rmlock" | wc -l` if ($status) goto err set msg="Unable to remove expired lock file $errdir/$nam""_running" if ($i > 0) rm "$errdir/$nam""_running" if ($status) goto err endrml: set msg="$nam is already running according to $errdir/$nam""_running" if (-f "$errdir/$nam""_running") goto err set msg="Lock file $errdir/$nam""_running exists and is not a proper file" if (-e "$errdir/$nam""_running") goto err set msg="Unable to initialize lock file $errdir/$nam""_running" echo "Running $cmd" > "$errdir/$nam""_running" if ($status) goto err if !(-f "$errdir/$nam""_running") goto err set lckfil="$errdir/$nam""_running" # enable the program if ("$*" != "enable") goto noena set msg="The $errdir/$nam""_disabled file does not exist" if !(-e "$errdir/$nam""_disabled") goto err set msg="The $errdir/$nam""_disabled file is not a proper file" if !(-f "$errdir/$nam""_disabled") goto err set msg="Unable to get file date of $errdir/$nam""_disabled using fdate" set olddat=`fdate "$errdir/$nam""_disabled"` if ($status) goto err set msg="File $nam""_$olddat already exists, remove it first" if (-f "$errdir/$nam""_$olddat") goto err set msg="Unable to rename $errdir/$nam""_disabled to $nam""_$olddat" mv "$errdir/$nam""_disabled" "$errdir/$nam""_$olddat" if ($status) goto err if !(-f "$errdir/$nam""_$olddat") goto err goto finish noena: # find old log file set msg="Unable to search for old log files with fnd" set oldlog=`fnd -name "$nam""_[0-9][0-9]-[0-9][0-9]-[0-9][0-9]" | tail -1` if ($status) goto err if (-e "$errdir/$nam""_$dat") set oldlog="$errdir/$nam""_$dat" if ("$oldlog" != "") then set msg="Old log $oldlog is not a proper file." if !(-f "$oldlog") goto err endif # disable the program if ("$*" != "disable") goto nodis if ("$oldlog" != "") then set msg="Unable to rename $oldlog to $errdir/$nam""_disabled" mv "$oldlog" "$errdir/$nam""_disabled" if ($status) goto err if !(-e "$errdir/$nam""_disabled") goto err else set msg="Unable to create $errdir/$nam""_disabled" set oldlog > "$errdir/$nam""_disabled" if ($status) goto err if !(-f "$errdir/$nam""_disabled") goto err endif goto finish nodis: # try to secure the log file if ("$oldlog" != "") then set msg="Unable to rename old log file $oldlog" if ("$oldlog" != "$errdir/$nam""_$dat") mv "$oldlog" "$errdir/$nam""_$dat" if ($status) goto err if !(-f "$errdir/$nam""_$dat") goto err # truncate old log size, maintaining its icon position set msg="Unable to check log file size" set i=`cat "$errdir/$nam""_$dat" | wc -l` if ($status) goto err set msg="Invalid number of lines to keep in the log" @ imax = $maxlines + $maxlines if ($status) goto err if ($i > $imax) then set msg="Unable to remove $errdir/$nam""_tmp" if (-e "$errdir/$nam""_tmp") rm "$errdir/$nam""_tmp" if (-e "$errdir/$nam""_tmp") goto err set msg="Unable to truncate $errdir/$nam""_$dat to $errdir/$nam""_tmp" tail -$maxlines "$errdir/$nam""_$dat" > "$errdir/$nam""_tmp" if ($status) goto err if !(-f "$errdir/$nam""_tmp") goto err if (`cat "$errdir/$nam""_tmp" | wc -l` < $maxlines) goto err set msg="Unable to create truncated file $errdir/$nam""_$dat" cp "$errdir/$nam""_tmp" "$errdir/$nam""_$dat" if ($status) goto err rm "$errdir/$nam""_tmp" endif set msg="Unable to write to the log file $nam""_$dat" echo "" >> "$errdir/$nam""_$dat" if ($status) goto err else set msg="Unable to create log file $nam""_$dat" set i > "$errdir/$nam""_$dat" if ($status) goto err if !(-f "$errdir/$nam""_$dat") goto err endif set logfil="$errdir/$nam""_$dat" set msg="Unable to write to the log file $logfil" echo "Running $cmd" >> "$logfil" if ($status) goto err # check that only the final digits are blank set msg="Frequency n1 cannot be blank" if ($n1 == ) goto err set msg= if ($n9 == ) set msg="$n9" if ($n8 == ) set msg="$n8$n9" if ($n7 == ) set msg="$n7$n8$n9" if ($n6 == ) set msg="$n6$n7$n8$n9" if ($n5 == ) set msg="$n5$n6$n7$n8$n9" if ($n4 == ) set msg="$n4$n5$n6$n7$n8$n9" if ($n3 == ) set msg="$n3$n4$n5$n6$n7$n8$n9" if ($n2 == ) set msg="$n2$n3$n4$n5$n6$n7$n8$n9" if ("$msg" != "") then set msg="Blank fields inside the backup frequency list" goto err endif set msg=$n1$n2$n3$n4$n5$n6$n7$n8$n9 if ($status || "$n1$n2$n3$n4$n5$n6$n7$n8$n9" != "$msg") then set msg="Invalid fields inside the backup frequency list" goto err endif # check skip set msg="Invalid skip: $skip" if ("$skip" != "" && "$skip" != "inc" && "$skip" != "all") goto err # check the root directory set msg="Root directory $root does not exist" if !(-d "$root") goto err # set the extended base name set base="$root/$nam" # process arguments proarg: # go to run (or terminate quietly if there is a disable file) if ("$*" == "auto") goto run if ("$*" == "inc") goto run if ("$*" == "max") goto run if ("$*" == "new") goto run if ("$*" == "1") goto run if ("$*" == "2") goto run if ("$*" == "3") goto run if ("$*" == "4") goto run if ("$*" == "5") goto run if ("$*" == "6") goto run if ("$*" == "7") goto run # initialize if ("$*" == "init") goto init # disable is not possible set msg="Cannot disable $nam; $errdir/$nam""_disabled already exists" if ("$*" == "disable") goto err # print usage instructions set f="$nam [root]" echo "Usage: $f init Creates the backup directory. Edit $nam first." echo " $f auto Does a backup" echo " $f inc Forces an incremental backup" echo " $f new Forces a new backup" echo " $f max Forces a new backup to be kept for the maximum time" echo " $f n Forces a new backup on day n of the week (7=Sunday)" echo " $f disable Disables all backups" echo " $f enable Enables backups again" echo "where root is the path to backup directory $nam (default: $root)." echo " No more than 36 successive incremental backups can be done without" echo "doing a full one." echo " When manually deleting an incremental backup from folder $nam/1," echo "be sure to also adjust file ../oldfnm.src. Do not delete full backups" echo "without doing a replacemant full backup with '$nam new' afterwards." echo "In general, if the next backup that is performed is incremental, the" echo "previous good backup *must* be in $root/$nam/1, and its filename *must*" echo "be settable by sourcing file $root/$nam/oldfnm.src." echo " Be sure you regularly get desktop log files notifying you of" echo "successful backups or investigate." echo " See also: man cron, man crontab, man -S 5 crontab, man anacron" if ("$*" == "") exit 1 if ("$*" == "-h" || "$*" == "-?") exit 1 if ("$*" == "-help" || "$*" == "--help") exit 1 set msg="Invalid arguments: $*" goto err # initialize and exit if called with init init: # fail if disabled set msg="Cannot initialize $nam; there is already a $nam""_disabled file" if (-e "$errdir/$nam""_disabled") goto err # check permissions for the root directory set msg="Insufficient permissions for directory $root" if !(-rwx "$root") goto err # check $savefils set msg="Variable savefils is not set" if !($?savefils) goto err foreach i ($savefils) set msg="File to save not found: $i" if !(-f "$i") goto err end # create the backup directory set msg="Unable to create directory $base, it exists" if (-d "$base") goto err set msg="Unable to create directory $base" mkdir "$base" if ($status) goto err if !(-d "$base") goto err $chm "$base" if ($status) goto err # cd to it set msg="Unable to cd to directory $base" cd "$base" if ($status) goto err if (`pwd | grep -c "/$nam"'$'` != 1) goto err # create the backup age-level subdirectories set msg="Unable to create directory $base/1" mkdir 1 if !(-d 1) goto err if ($n2 != ) mkdir 2 if ($n3 != ) mkdir 3 if ($n4 != ) mkdir 4 if ($n5 != ) mkdir 5 if ($n6 != ) mkdir 6 if ($n7 != ) mkdir 7 if ($n8 != ) mkdir 8 if ($n9 != ) mkdir 9 $chm `find . -type d` # create the starting file name set msg="Unable to create oldfnm.src in $base" echo "set oldfnm='000000_$n9$n8$n7$n6$n5$n4$n3$n2$n1'" > oldfnm.src if ($status) goto err if !(-f oldfnm.src) goto err chmod a-x oldfnm.src $chm oldfnm.src # copy in the requested files foreach i ($savefils) set msg="Error saving file $i to the backup folder" cp "$i" . if ($status) goto err end # create the readme file if !($?readme) goto endwrm set msg="Error creating readme.txt file in the backup folder" echo "" > readme.txt if ($status) goto err if !(-f readme.txt) goto err set i=0 lpwrm: @ i = $i + 1 if ($i > $#readme) goto endwrm echo "$readme[$i]" >> readme.txt if ($status) goto err goto lpwrm endwrm: # notify of success: echo "Directory $base successfully initialized." >> "$logfil" echo "Directory $base successfully initialized." # finish up goto finish # run run: # done if disabled if (-e "$errdir/$nam""_disabled") goto end # cd to the backup directory set msg="Directory $base does not exist" if !(-d "$base") goto err set msg="Insufficient permissions for directory $base" if !(-rwx "$base") goto err set msg="Unable to cd to directory $base" cd "$base" if ($status) goto err # check that we can delete any oldfnm.old backup if (-e oldfnm.old) then set msg="Invalid file: $base/oldfnm.old" if !(-f oldfnm.old) goto err set msg="No privileges to delete $base/oldfnm.old" if !(-rw oldfnm.old) goto err endif # get the old backup file name set msg="File $base/oldfnm.src not found" if !(-f oldfnm.src) goto err set msg="No permisions for file $base/oldfnm.src" if !(-rw oldfnm.src) goto err set oldfnm= set msg="File $base/oldfnm.src is corrupt" source oldfnm.src if ($status) goto err if ("$oldfnm" == "") goto err if ("$*" == "inc") then set msg="Too many incremental backups" if (`echo "$oldfnm$ext" | grep -c "Z$exts"` != 0) goto err set n1=Z endif # get the new file name set fnm="$oldfnm" if ("$*" == "max") set fnm="000000_$n9$n8$n7$n6$n5$n4$n3$n2$n1" @ iter = 0 gennam: set msg="Unable to remove fnm.tmp" if (-e fnm.tmp) rm fnm.tmp if (-e fnm.tmp) goto err set msg="Failure while running $newfnm" "$newfnm" "$fnm" "$n9$n8$n7$n6$n5$n4$n3$n2$n1" >> "$logfil" if ($status) goto err if !(-f fnm.tmp) goto err set msg="File fnm.tmp is corrupt" set fnm= source fnm.tmp if ($status) goto err if ("$fnm" == ) goto err rm fnm.tmp @ iter = $iter + 1 if ($iter > 35) then set msg="Stuck in a file name loop" goto err endif if ("$*" == "new" || "$*" == `date +'%u'`)then if (`echo "$fnm$ext" | grep -c "0$exts"` == 0) goto gennam endif # cd to the backup directory set msg="Insufficient permissions for directory $base/1" if !(-rwx "$base/1") goto err set msg="Unable to cd to directory $base/1" cd 1 if ($status) goto err if (`pwd | grep -c "/$nam/1"'$'` != 1) goto err # delete any junked backups if (`find . -name "*$exta.bad" | wc -l` != 0) then set msg="Unable to get rid of the bad old backups" rm *$exta.bad if ($status) goto err if (`find . -name "*$exta.bad" | wc -l` != 0) goto err endif if (`find . -name "*.log.bad" | wc -l` != 0) rm *.log.bad # decide whether to do an incremental or new backup if (`echo "$fnm$ext" | grep -c "0$exts"` != 0) goto donew # process incremental backups doinc: # set arguments for an incremental backup arginc # see whether the previous backup exists set msg="Previous backup $oldfnm$ext not in $root/$nam/1" if !(-f $oldfnm"$ext") goto err # remove any existing failed backups foreach f (`find . -name "$fnm$exta"`) set msg="Unable to remove orphaned backup $f" echo "** removing orphaned backup $f" >> "$logfil" echo "** removing orphaned backup $f" rm $f if ($status) goto err if (-e $f) goto err end # skip if $skip is set to inc or all and there are no newly modified files if ("$skip" != "inc" && "$skip" != "all") goto noiskp set msg="Unable to figure out newly modified files" set i=`find "$fsroot" -newer $oldfnm"$ext" | wc -l` if ($status) goto err if ("$i" != 0) goto noiskp echo "No modified files found. Terminating" >> "$logfil" if ("$oldlog" != "") then if ("$logfil" != "$oldlog") mv "$logfil" "$oldlog" endif unset logfil goto finish noiskp: # go do it goto doback # process a new backup donew: # set arguments for a new backup argnew # skip if $skip is set to all and there are no newly modified files if ("$skip" != "all") goto nonskp if !(-f $oldfnm"$ext") then echo "** No current backup. Ignoring skip." >> "$logfil" goto nonskp endif set msg="Unable to figure out newly modified files" set i=`find "$fsroot" -newer $oldfnm"$ext" | wc -l` if ($status) goto err if ("$i" != 0) goto nonskp echo "No modified files found. Terminating" >> "$logfil" if ("$oldlog" != "") then if ("$logfil" != "$oldlog") mv "$logfil" "$oldlog" endif unset logfil goto finish nonskp: # clear the first directory that can be set msg="Insufficient privileges for the backup directories" if (`ls -1 | wc -l` == 0) goto mov1 if ($status) goto err if (-d ../2 && `ls -1 | grep -c "00$exts"` != 0) goto clr2 rm * if ($status) goto err goto mov1 clr2: cd ../2 if (`ls -1 | wc -l` == 0) goto mov2 if ($status) goto err if (-d ../3 && `ls -1 | grep -c "000$exts"` != 0) goto clr3 rm * if ($status) goto err goto mov2 clr3: cd ../3 if (`ls -1 | wc -l` == 0) goto mov3 if ($status) goto err if (-d ../4 && `ls -1 | grep -c "0000$exts"` != 0) goto clr4 rm * if ($status) goto err goto mov3 clr4: cd ../4 if (`ls -1 | wc -l` == 0) goto mov4 if ($status) goto err if (-d ../5 && `ls -1 | grep -c "00000$exts"` != 0) goto clr5 rm * if ($status) goto err goto mov4 clr5: cd ../5 if (`ls -1 | wc -l` == 0) goto mov5 if ($status) goto err if (-d ../6 && `ls -1 | grep -c "000000$exts"` != 0) goto clr6 rm * if ($status) goto err goto mov5 clr6: cd ../6 if (`ls -1 | wc -l` == 0) goto mov6 if ($status) goto err if (-d ../7 && `ls -1 | grep -c "0000000$exts"` != 0) goto clr7 rm * if ($status) goto err goto mov6 clr7: cd ../7 if (`ls -1 | wc -l` == 0) goto mov7 if ($status) goto err if (-d ../8 && `ls -1 | grep -c "00000000$exts"` != 0) goto clr8 rm * if ($status) goto err goto mov7 clr8: cd ../8 if (`ls -1 | wc -l` == 0) goto mov8 if ($status) goto err if (-d ../9 && `ls -1 | grep -c "000000000$exts"` != 0) goto clr9 rm * if ($status) goto err goto mov8 clr9: cd ../9 if (`ls -1 | wc -l` != 0) rm * if ($status) goto err # move the files to be kept out of the way mv ../8/* . if ($status) goto err cd ../8 mov8: mv ../7/* . if ($status) goto err cd ../7 mov7: mv ../6/* . if ($status) goto err cd ../6 mov6: mv ../5/* . if ($status) goto err cd ../5 mov5: mv ../4/* . if ($status) goto err cd ../4 mov4: mv ../3/* . if ($status) goto err cd ../3 mov3: mv ../2/* . if ($status) goto err cd ../2 mov2: mv ../1/* . if ($status) goto err cd ../1 mov1: # go do it goto doback # do it doback: # log the backup command to an accompanying log file set backprog="echo $backexe" set msg="Unable to write backup parameters to $base/1/$fnm.log" backcmd > $fnm.log if ($status) goto err # back up set backprog="$backexe" backcmd >> $fnm.log set bckstat="$status" echo "$backexe command returned status $bckstat" >> $fnm.log cat $fnm.log >> "$logfil" if (`echo "$statnoti" | grep -w -c $bckstat` == 1) goto noabo if (`echo "$statign" | grep -w -c $bckstat` == 1) then unset bckstat goto noabo endif mv $fnm.log $fnm.log.bad foreach f (`find . -name "$fnm$exta"`) set msg="$backexe failed, $bckstat, and cannot get rid of the junk" mv $f $f.bad if ($status) goto err end set msg="Backup command $backexe failed; status: $bckstat" goto err noabo: set msg="Missing reference backup $root/$nam/1/$fnm" if !(-f $fnm"$ext") goto err foreach f (`find . -name "$fnm$exta"`) chmod a-x $f $chm $f end chmod a-x $fnm.log $chm $fnm.log # set the backup as the old filename set msg="Unable to move $base/oldfnm.src to oldfnm.old" if (-e ../oldfnm.src) mv ../oldfnm.src ../oldfnm.old if (-e ../oldfnm.src) goto err set msg="Unable to create $root/$nam/oldfnm.src" echo "set oldfnm='$fnm'" > ../oldfnm.src if !(-f ../oldfnm.src) goto err chmod a-x ../oldfnm.src $chm ../oldfnm.src # notify of error if ($?bckstat) then set msg="Backup command $backexe had problems; status: $bckstat" goto err endif # finish up goto finish # finish finish: # mark as done if ($?logfil) then echo "Done: $cmd" >> "$logfil" endif # remove the lock file set msg="Unable to remove lock file $lckfil" rm "$lckfil" if (-e "$lckfil") goto err # all done goto end # error processing erri: # no more jumping to erri onintr # interrupted set msg="Interrupted" err: # put a failure message in $errdir if !($?haverr) goto enderr if (-e "$errdir/$nam""_FAILED") then echo "FAILED: $cmd" >> "$errdir/$nam""_FAILED" else echo "FAILED: $cmd" > "$errdir/$nam""_FAILED" endif echo "*** $msg\!" >> "$errdir/$nam""_FAILED" if ($status) then echo "*** $cmd $msg\!" > "$errdir/$nam""_FAILED_AGAIN" endif if ($?logfil) then echo "*** $msg\!" >> "$logfil" endif enderr: # remove the lock file if ($?lckfil) then rm "$lckfil" endif # echo the message to stdout, wherever that goes echo "*** $msg\!" # send a mail message if ("$email" == "") goto endemail echo "$msg" | mail -s "FAILED: $cmd" $email endemail: # exit in disgrace exit 1 end: # end of script