#!/bin/sh
#=========================================================================
# name:         checkbu
# description:  check current state of system backups
# author:       G.R.Keech
# date:         1998-07-17
# peer review:  pending
# $Id: checkbu,v 1.3 2001/09/19 10:21:18 rkeech Exp $
#=========================================================================
# Note: pre-requisite programs checkbu-run, secs-to-date
# are required.

BASEDIR=/usr/  # The base directory for location of scripts and configs.
LOGDIR=/var/log/backup/ # The location for log files.
SECS_TO_DATE=/usr/bin/secs-to-date
CHECK_RUN=${BASEDIR}sbin/checkbu-run
PROGNAME=`basename $0`
CONFIG_FILE=/etc/rkbackup/backup.conf # sets default.
CONFIG=default  # sets default.
repair=false  # set default
verbose=false # set default
showlog=false # set default
showsummary=false # set default
showsf=false # set defaut  sf= success or failure
line=1  # set default;  if -d is not specified, the last backup is assumed.
history_only=false  # set default; over-ridden with -d is set.
count=1 # set default; over-ridden when -m is set.
#--------------------------------------------------------------------------
# Handle an error.  
# Note: this should only be called before the main logging starts
# since the main logging goes to a file in /var/tmp initially.
error () {
  echo ${PROGNAME}: error: $* 1>&2
  exit 1
}
#---------------------------------------------------------------------------
# Show program usage.
usage () {
  echo usage:
  echo "  $PROGNAME [-l|-s|-S] [-r] [-v] [-m count] [-d countback] [-c configuration]"
  echo "  eg:  $PROGNAME -c test"
  echo " -s    show log file summary."
  echo " -S    show short summary, success or fail only"
  echo " -l    show complete log file."
  echo " -r    repair state by removing redundant files if found."
  echo " -v    show verbose output."
  echo " -d    look at backup \"countback\" runs ago."
  echo " -m    show multiple instances."
  echo " Without arguments this shows the state of the default configuration."
  exit 1
}
#--------------------------------------------------------------------------
version () {
  ver='$Revision: 1.3 $'
  echo $ver|sed 's/\$//g; s/Revision://g'|awk '{print $1}'
}
#--------------------------------------------------------------------------
#  yesterday returns the date for yesterday
yesterday () {
  SECS_IN_DAY=86400
  yesterday_secs=`echo "$(date +%s) - $SECS_IN_DAY" | bc `
  $SECS_TO_DATE -i $yesterday_secs|cut -dT -f1
}
#--------------------------------------------------------------------------
# Conditionally remove the pid file if it is extraneous.
conditional_repair () {
  if [ $repair = true ]
  then
    if [ $verbose = true ]
    then
      echo pid file removed.
    fi
    rm -f $pid_file
  else
    if [ $verbose = true ]
    then
      echo Use -r flag to remove the redundant pid file.
    fi
  fi
}
#---------------------------------------------------------------------------
# Test that command is available.
available () {
  cmd=`type $1 2>/dev/null`
  if [ $? -ne 0 ]
  then
    echo "$PROGNAME command $1 does not seem to be available"
    exit 1
  fi
}
#============================================================================
#                 Start of main block of script.
#----------------------------------------------------------------------------
available $SECS_TO_DATE
available $CHECK_RUN

while [ $# -ne 0 ]
do
  case $1 in
    "-v")  # verbose
          verbose=true
          shift
          echo backup check.
          echo $PROGNAME Version `version`.
          echo Written by G.Richard Keech, 1998.
          exit
          ;;
    "-r") # repair
          repair=true
          shift
          ;;
    "-c") # configuration
         shift
          # Manage the configuration name.
          if [ $# -ge 1 ]
          then
            CONFIG=$1
            shift
            # In this case we need to derive a config file name 
            # from the name of the config.
            if [ ${CONFIG} = default ]
            then
              CONFIG_FILE=/etc/rkbackup/backup.conf
            else
              CONFIG_FILE=/etc/rkbackup/backup-${CONFIG}.conf
            fi
          
            if [ ! -f $CONFIG_FILE -o ! -r $CONFIG_FILE ]
            then
              error Config name ${CONFIG} does not correspond to a config file.
            fi
          fi
          ;;
    "-d") # days ago; ie check on a backup other than the last one performed.
         shift
         history_only=true
          # Manage the configuration name.
          if [ $# -ge 1 ]
          then
            # check that the item following -d is a number >= 1
            line=`echo $1 | grep "^[1-9][0-9]*$"`
            shift
            if [ ${line}x = x ]
            then
              error Item following -d is not a number greater than zero.
            fi
          else
            error The -d flag should be followed by a number greater than zero.
          fi
          ;;
    "-m") # multiple instances; when this is set the program checks multiple log files.
         shift
         history_only=true
          # Manage the configuration name.
          if [ $# -ge 1 ]
          then
            # check that the item following -d is a number >= 1
            count=`echo $1 | grep "^[1-9][0-9]*$"`
            shift
            if [ ${count}x = x ]
            then
              error Item following -m is not a number greater than zero.
            fi
          else
            error The -m flag should be followed by a number greater than zero.
          fi
          ;;
    "-l") # show log
          shift
          if [ $showsummary = true -o $showsf = true ]
          then
            error The -l, -s and -S flags are mutually exclusive.
          fi
          showlog=true;;  # In this case the whole log file is shown when the
                          # backup is not running.
    "-s") # show summary
          shift
          if [ $showlog = true -o $showsf = true ]
          then
            error The -l, -s and -S flags are mutually exclusive.
          fi
          showsummary=true;;  # In this case the log file summary is shown 
                              # when the backup is not running.
    "-S") # show short summary
          shift
          if [ $showlog = true -o $showsummary = true ]
          then
            error The -l, -s and -S flags are mutually exclusive.
          fi
          history_only=true
          showsf=true;;  # In this case the log file summary is shown 
                              # when the backup is not running.
    "--version") 
          echo $PROGNAME Version `version`.;
          echo Written by G.Richard Keech, 1998.
          exit;;
    *) usage;;
  esac
done # processing command-line arguments

pid_file=/var/tmp/backup-${CONFIG}.pid
DISABLE_FILE="/etc/rkbackup/backup-${CONFIG}.disable"
#----------------------------------------------------------------------------
if [ $history_only = false ]
then
  pid=`$CHECK_RUN -c $CONFIG`
  state=$?   # if this gets set to zero then the backup is currently running.
else
  # Don't worry whether or not the backups are currently running,
  # only interested in the history of the backups.
  state=1
fi

hdr="For configuration \"${CONFIG}\" "
case $state in
  0) # Backup is currently running.
    echo $hdr backup is currently running.
    start_secs=`grep "start_secs:" $pid_file |awk '{print $2}'`
    echo Started at `$SECS_TO_DATE -i $start_secs`.
    last_line="`tail -1 $pid_file`"
    current_token=`echo $last_line|awk '{print $1}'`
    case $current_token in
      pid:) echo Backup has just started and is configuring.;;
      rewind:) echo Currently rewinding the tape before backup.;;
      rewinding_offline:) echo Currently rewinding the tape after backup.;;
      pre_actions:) echo Currently performing pre-backup actions.;;
      post_actions:) echo Currently performing post-backup actions.;;
      total_gb:|total_files:) echo Currently writing header.;;
      started_first_file:) echo Currently writing first file system to tape.;;
      header:) echo Creating tape header.;;
      completed_file:)
        total_files=`grep "total_files:" $pid_file |awk '{print $2}'`
        tape_file=`echo $last_line|awk '{print $2}'`
        tape_file=`expr $tape_file + 1`
        echo Currently writing tape file number $tape_file of $total_files;;
      aborting:) echo Currently aborting the backup;;
      *) echo Unable to determine details of backup currently in progress.;;
    esac
    ;;
  1) # Backup is not currently running.
    if [ $history_only = false ]
    then
      echo $hdr backup NOT currently running.
      if [ -f $DISABLE_FILE ]
      then
	echo This configuration is currently DISABLED, ie cannot be started from cron.
      else
	echo This configuration is currently enabled, ie can be started from cron.
      fi
    fi
    #yd=`yesterday`
    #LOGF="backup-${CONFIG}.${yd}"
    #MAINLOG="${LOGDIR}${LOGF}"

    while [ $count -ge 1 ]
    do
      count=`expr $count - 1`
      lc=`expr $count + $line`
      MAINLOG=`ls -t ${LOGDIR}backup-${CONFIG}.* 2>/dev/null | sed -n "${lc}p"`

      if [ ${MAINLOG}x != x ]
      then
        if [ $showlog = true ]
        then
        echo The log file for this configuration is:
        echo "     $MAINLOG"
          echo '#======================================================================'
          echo '# Contents of log file follows'
          echo '#======================================================================'
          awk '{print ">> " $0}' $MAINLOG
          echo '#======================================================================'
        fi
    
        if [ $showsf = true ]
        then
          # Show short summary; success or failure only.
    
          fn=`basename $MAINLOG`
	  # extract the date from the filename.
          date="`echo $fn|sed -n  's/^backup-.*\([0-9]\{4\}\)\([0-9]\{2\}\)\([0-9]\{2\}\).*/\1-\2-\3/p'`"
    
          # Success or failure.
          sf="`sed -n '/^Summary:/,//p' $MAINLOG|grep 'Backup was successful.'`"
    
          if [ "${sf}x" = x ]
          then
	    sf="`sed -n '/^Summary:/,//p' $MAINLOG|grep 'Backup aborted.'`"
	    if [ "${sf}x" = x ]
	    then
	      echo ${lc}:${date}: failure
	    else
	      echo ${lc}:${date}: aborted
	    fi
          else
            echo ${lc}:${date}: success
          fi
        fi
    
        if [ $showsummary = true ]
        then
          # Print the LOGFILE from the "Summary:" to the end of the file.
          echo Log file: `basename $MAINLOG`.
          echo
          # Print the lines following the Summary: line.
          sed -n '/^Summary:/,//p' $MAINLOG
        echo
        fi
      fi
    done
    ;;
  2) echo $hdr PID corresponds to an active process that is not backup.
    conditional_repair
    ;;
  3) echo $hdr PID does not correspond to an active process.
    conditional_repair
    ;;
  *) error Unknown return code $state from checkbu-run.
    ;;
esac
