#!/bin/sh PROGNAME=`basename $0` VERSION=`echo '$Id: bu,v 1.17 1996/10/03 21:50:42 alexis Exp $' | cut -f3 -d' '` LIST_DIR=/usr/local/adm/$PROGNAME CFG_DIR=/usr/local/lib/$PROGNAME DFLT_DEVICE=/dev/rmt0 DFLT_DESC="Unknown" DFLT_DEBUG_LEVEL=2 LSPIPE_CMD=/usr/local/bin/lspipe TIMESTAMP=`date '+%y%m%d%H%M'` FINDOUT=/tmp/$PROGNAME.$$.findraw CPIOOUT=/tmp/$PROGNAME.$$.cpioraw FINDRAT=/tmp/$PROGNAME.$$.findrat CPIORAT=/tmp/$PROGNAME.$$.cpiorat debug() { [ $1 -le $DEBUG_LEVEL ] && echo "$PROGNAME: DEBUG[$1] $2" } error() { echo "$PROGNAME: ERROR: $1" exit 1 } warning() { echo "$PROGNAME: WARNING: $1" } usage() { echo "Usage: $PROGNAME [ -v | -d level ] backup-id media-id" echo " $PROGNAME -l" echo " $PROGNAME -V" exit 1 } clean_exit() { exit 2 } list_last_backups() { cd $CFG_DIR for BUSTEM in *; do DATE=`ls -lt $LIST_DIR/filelist-$BUSTEM-*-* 2>/dev/null | \ head -1 | \ sed -n "s/.*filelist-$BUSTEM-\([0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]\)-.*$/\3\/\2\/\1 \4:\5/p"` [ "X$DATE" = X ] && DATE="no backup on record" printf "%-10s %s\n" "$BUSTEM:" "$DATE" done exit 0 } # Process options while [ "X$1" != X ]; do case "$1" in -V) echo "$PROGNAME version $VERSION" exit 0 ;; -v) DEBUG_LEVEL=3 ;; -d) [ "X$2" = X ] && usage DEBUG_LEVEL=$2 shift ;; -l) list_last_backups ;; -*) usage ;; *) break ;; esac shift done [ $DEBUG_LEVEL ] || DEBUG_LEVEL=$DFLT_DEBUG_LEVEL # Process required parameters [ "X$2" = X -o "X$3" != X ] && usage [ -d $LIST_DIR -a -w $LIST_DIR ] || error "can't access backup listings directory '$LIST_DIR'" BUSTEM=$1 MEDIA=$2 CONFIG_FILE=$CFG_DIR/$BUSTEM/config SRCDIRS_FILE=$CFG_DIR/$BUSTEM/roots EXCLUSIONS_FILE=$CFG_DIR/$BUSTEM/exclusions ORDER_SCRIPT=$CFG_DIR/$BUSTEM/order SIZE_SCRIPT=$CFG_DIR/$BUSTEM/size GENLIST_SCRIPT=$CFG_DIR/$BUSTEM/genlist if [ -f $SRCDIRS_FILE -a ! -f $GENLIST_SCRIPT ]; then MODE=roots [ -r $SRCDIRS_FILE ] || error "can't access roots file '$SRCDIRS_FILE'" while read SRCDIR; do if [ "X$SRCDIRS" = X ]; then SRCDIRS="$SRCDIR" else SRCDIRS="$SRCDIRS $SRCDIR" fi done < $SRCDIRS_FILE [ "X$SRCDIRS" = X ] && error "$SRCDIRS_FILE: empty!" elif [ ! -f $SRCDIRS_FILE -a -f $GENLIST_SCRIPT ]; then MODE=genlist else error "one and only one a 'roots' file and a 'genlist' script must be supplied" fi # Load config data and verify [ -f $CONFIG_FILE -a -r $CONFIG_FILE ] || error "can't access config file '$CONFIG_FILE'" . $CONFIG_FILE if [ "X$DEVICE" = X ]; then warning "no destination device specified, defaulting to $DFLT_DEVICE" DEVICE=$DFLT_DEVICE fi if [ "X$DESC" = X ]; then warning "no description specified, defaulting to $DFLT_DESC" DEVICE=$DFLT_DESC fi [ -f $EXCLUSIONS_FILE -a -r $EXCLUSIONS_FILE ] || error "can't access exclusions file '$EXCLUSIONS_FILE'" if read EXCLUSION; then EXCLUSION_LIST="$EXCLUSION" while read EXCLUSION; do EXCLUSION_LIST="$EXCLUSION_LIST|$EXCLUSION" done fi < $EXCLUSIONS_FILE debug 5 "exlusions pattern: [$EXCLUSION_LIST]" FILELIST=$LIST_DIR/filelist-$BUSTEM-$TIMESTAMP-$MEDIA # Tell the user what's we're doing. echo echo "Backup: $DESC" if [ $MODE = roots ]; then echo "Roots: $SRCDIRS" else echo "Genlist: $GENLIST_SCRIPT" fi echo "Device: $DEVICE" echo "Media: $MEDIA" echo "Listfile: $FILELIST" if [ -x $ORDER_SCRIPT ]; then echo "Order: $ORDER_SCRIPT" else echo "Order: as they come" fi if [ -x $SIZE_SCRIPT ]; then echo "Size: `$SIZE_SCRIPT`" else echo "Size: unknown" fi echo echo "Log entry: $TIMESTAMP $MEDIA cpio $BUSTEM" echo echo -en "Ready?: " trap 'clean_exit' 2 15 read DUMMY trap 2 15 case "$DUMMY" in [Yy]*) ;; *) echo "Backup abandoned" exit 2 ;; esac echo "Backing up ..." sleep 2 rm -f $LIST_DIR/filelist-*-*-$MEDIA.gz { [ $MODE = roots ] && find $SRCDIRS -depth || $GENLIST_SCRIPT; } | \ { [ "X$EXCLUSION_LIST" = X ] && cat || egrep -v "$EXCLUSION_LIST"; } | \ { [ ! -x $ORDER_SCRIPT ] && cat || $ORDER_SCRIPT; } | \ $LSPIPE_CMD -a $FINDOUT | cpio -ovB -F $DEVICE 2>&1 | \ tee $CPIOOUT echo "Generating list file ..." cat $CPIOOUT | \ egrep -v '^[0-9][0-9]* blocks$|^cpio: .*: truncating inode number$|cpio:.*No such file or directory$' | \ sort > $CPIORAT cat $FINDOUT | \ sed -e 's/[ ][ ]*/ /g' -e 's/^[ ][ ]*//g' | \ sort +8 > $FINDRAT # Do some calculations for showing at the end FINDTOT=`wc -l < $FINDRAT` CPIOTOT=`wc -l < $CPIORAT` rm $CPIOOUT $FINDOUT # Merge the list of files whose names were fed to cpio and the list of names # of files that cpio actually backed up to generate a informative listing of # what was actually backed up join -1 1 -2 9 $CPIORAT $FINDRAT | \ awk '{ printf "%s %3d %-8s %-8s %8d %s %2d %5s %s\n", $2, $3, $4, $5, $6, $7, $8, $9, $1 }' > $FILELIST rm $CPIORAT $FINDRAT echo "Compressing file list ..." gzip $FILELIST # A little summary echo "Number of files that should have been backup up: $FINDTOT" echo "Number of files that were actually backed up: $CPIOTOT"