1#!/bin/sh 2# 3# Run this script as root on the machine that has the tape drive, to make a 4# level-1 dump containing all files changed since the last full dump. 5# 6# If you give `now' as an argument, the dump is done immediately. 7# Otherwise, it waits until 1am. 8# 9# You must edit the file `backup-specs' to set the parameters for your site. 10 11# Useful for backup-specs, in case things have to be done slightly 12# differently for different dump levels. 13DUMP_LEVEL=1 14 15# Insure `mail' is in PATH. 16PATH="/usr/ucb:${PATH}" 17export PATH 18 19# This is not the most reliable test in the world. The following might be 20# more predictable: 21# 22# whoami="`whoami`" 23# euid="`sed -ne '/^'\"${whoami}\"':/{s/^[^:]*:[^:]*://;s/:.*//p;q;}' /etc/passwd`" 24# if [ "${euid}" != 0 ]; then ... 25# 26if [ ! -w / ]; then 27 echo "The backup must be run as root or else some files will fail to be dumped." 28 exit 1 29fi 30 31# Get the values of BACKUP_DIRS, BACKUP_FILES, and other variables. 32. ./backup-specs 33 34# Maybe sleep until around specified or default hour. 35if [ "z${1}" != "znow" ]; then 36 if [ "${1}x" != "x" ]; then 37 spec="${1}" 38 else 39 spec="${BACKUP_HOUR}" 40 fi 41 42 pausetime="`date | awk ' 43 { 44 hr = substr($4, 1, 2); 45 mn = substr($4, 4, 2); 46 if((hr + 0) < (spec + 0)) 47 print 3600 * (spec - hr) - 60 * mn; 48 else 49 print 3600 * (spec + (24 - hr)) - 60 * mn; 50 }' spec=\"${spec}\"`" 51 52 clear 53 echo "${SLEEP_MESSAGE}" 54 sleep "${pausetime}" 55fi 56 57# start doing things 58 59# Put startdate in the subject line of mailed report, since if it happens 60# to run longer than 24 hours (as may be the case if someone forgets to put 61# in the next volume of the tape in adequate time), the backup date won't 62# appear too misleading. 63startdate="`date`" 64 65here="`pwd`" 66 67# Logfile name should be in the form ``log-1993-03-18-level-1'' 68# i.e. year-month-date. This format is useful for sorting by name, since 69# logfiles are intentionally kept online for future reference. 70LOGFILE="log-`date | sed -ne ' 71 s/[^ ]* *\([^ ]*\) *\([^ ]*\).* \([^ ]*\)$/\3-\1-\2/ 72 /-[0-9]$/s/\([0-9]\)$/0\1/ 73 /Jan/{s/Jan/01/p;q;} 74 /Feb/{s/Feb/02/p;q;} 75 /Mar/{s/Mar/03/p;q;} 76 /Apr/{s/Apr/04/p;q;} 77 /May/{s/May/05/p;q;} 78 /Jun/{s/Jun/06/p;q;} 79 /Jul/{s/Jul/07/p;q;} 80 /Aug/{s/Aug/08/p;q;} 81 /Sep/{s/Sep/09/p;q;} 82 /Oct/{s/Oct/10/p;q;} 83 /Nov/{s/Nov/11/p;q;} 84 /Dec/{s/Dec/12/p;q;}'`-level-${DUMP_LEVEL}" 85 86localhost="`hostname | sed -e 's/\..*//'`" 87 88TAR_PART1="${TAR} -c --multi-volume --one-file-system --block-size=${BLOCKING} --sparse --volno-file=${VOLNO_FILE}" 89 90# Only use --info-script if DUMP_REMIND_SCRIPT was defined in backup-specs 91if [ "x${DUMP_REMIND_SCRIPT}" != "x" ]; then 92 TAR_PART1="${TAR_PART1} --info-script='${DUMP_REMIND_SCRIPT}'" 93fi 94 95# Make sure the log file did not already exist. Create it. 96 97if [ -f "${LOGFILE}" ] ; then 98 echo "Log file ${LOGFILE} already exists." 1>&2 99 exit 1 100else 101 touch "${LOGFILE}" 102fi 103 104# Most everything below here is run in a subshell for which all output is 105# piped through `tee' to the logfile. Doing this, instead of having 106# multiple pipelines all over the place, is cleaner and allows access to 107# the exit value from various commands more easily. 108( 109 # Caveat: Some version of `mt' require `-t', not `-f'. 110 mt -f "${TAPE_FILE}" rewind 111 rm -f "${VOLNO_FILE}" 112 113 set - ${BACKUP_DIRS} 114 while [ $# -ne 0 ] ; do 115 date="`date`" 116 remotehost="`echo \"${1}\" | sed -e 's/:.*$//'`" 117 fs="`echo \"${1}\" | sed -e 's/^.*://'`" 118 fsname="`echo \"${1}\" | sed -e 's/\//:/g'`" 119 120 # This filename must be absolute; it is opened on the machine that runs tar. 121 TAR_PART2="--listed=/etc/tar-backup/temp.level-1" 122 TAR_PART3="--label='level 1 backup of ${fs} on ${remotehost} at ${date}' -C ${fs} ." 123 124 echo "Backing up ${1} at ${date}" 125 echo "Last full dump on this filesystem:" 126 127 if [ "z${remotehost}" != "z${localhost}" ] ; then 128 rsh "${remotehost}" "ls -l /etc/tar-backup/${fsname}.level-0; \ 129 cp /etc/tar-backup/${fsname}.level-0 /etc/tar-backup/temp.level-1" 130 else 131 ls -l "/etc/tar-backup/${fsname}.level-0" 132 cp "/etc/tar-backup/${fsname}.level-0" /etc/tar-backup/temp.level-1 133 fi 134 135 # Actually back things up. 136 137 if [ "z${remotehost}" != "z${localhost}" ] ; then 138 rsh "${remotehost}" ${TAR_PART1} -f "${localhost}:${TAPE_FILE}" ${TAR_PART2} ${TAR_PART3} 139 else 140 # Using `sh -c exec' causes nested quoting and shell substitution 141 # to be handled here in the same way rsh handles it. 142 sh -c "exec ${TAR_PART1} -f \"${TAPE_FILE}\" ${TAR_PART2} ${TAR_PART3}" 143 fi 144 145 # `rsh' doesn't exit with the exit status of the remote command. What 146 # stupid lossage. TODO: think of a reliable workaround. 147 if [ $? -ne 0 ] ; then 148 echo "Backup of ${1} failed." 149 # I'm assuming that the tar will have written an empty 150 # file to the tape, otherwise I should do a cat here. 151 else 152 if [ "z${localhost}" != "z${remotehost}" ] ; then 153 rsh "${remotehost}" mv -f /etc/tar-backup/temp.level-1 "/etc/tar-backup/${fsname}.level-1" 154 else 155 mv -f /etc/tar-backup/temp.level-1 "/etc/tar-backup/${fsname}.level-1" 156 fi 157 fi 158 ${TAPE_STATUS} 159 sleep 60 160 shift 161 done 162 163 # Dump any individual files requested. 164 165 if [ "x${BACKUP_FILES}" != "x" ] ; then 166 date="`date`" 167 TAR_PART2="--listed=/etc/tar-backup/temp.level-1" 168 TAR_PART3="--label='Incremental backup of miscellaneous files at ${date}'" 169 170 echo "Backing up miscellaneous files at ${date}" 171 echo "Last full dump of these files:" 172 ls -l /etc/tar-backup/misc.level-0 173 174 rm -f /etc/tar-backup/temp.level-1 175 cp /etc/tar-backup/misc.level-0 /etc/tar-backup/temp.level-1 176 177 # Using `sh -c exec' causes nested quoting and shell substitution 178 # to be handled here in the same way rsh handles it. 179 sh -c "exec ${TAR_PART1} -f \"${TAPE_FILE}\" ${TAR_PART2} ${TAR_PART3} ${BACKUP_FILES}" 180 181 if [ $? -ne 0 ] ; then 182 echo "Backup of miscellaneous files failed." 1>&2 183 # I'm assuming that the tar will have written an empty 184 # file to the tape, otherwise I should do a cat here. 185 else 186 mv -f /etc/tar-backup/temp.level-1 /etc/tar-backup/misc.level-1 187 fi 188 ${TAPE_STATUS} 189 else 190 echo "No miscellaneous files specified" 191 fi 192 193 # Caveat: some versions of `mt' use `-t' instead of `-f'. 194 mt -f "${TAPE_FILE}" rewind 195 mt -f "${TAPE_FILE}" offl 196 197) 2>&1 | tee -a "${LOGFILE}" 198 199echo "Sending the dump log to ${ADMINISTRATOR}" 200mail -s "Results of backup started ${startdate}" ${ADMINISTRATOR} < "${LOGFILE}" 201 202# eof 203