#! /bin/sh

# baak copyright by kkumer@phy.hr 
#   Backup script. Uses dump(8) and saves volumes on (possibly remote)
#   hard disk. Volumes can then be burned to CDs.
#   $Id: baak,v 1.2 2003/04/29 18:29:22 kkumer Exp $
#   Version: $Name:  $


# Capacity of media in MB
CAP=700

usage () {
    cat <<EOF
Usage: baak [-h] -l level -d targetdir filesystem
 -h  this help message
 -l  dump level
 -d  target directory where backup volumes go (e.g. /tmp or nfshost:/backup)
EOF
}

abort () {
    if [ $remote = "yes" ]; then
        cd $HOME
        umount $LOCDIR
        rmdir $LOCDIR
    fi
    echo "Aborted!"
    exit 1
}

# Is there enough command-line arguments?
if [ $# -lt 3 ]; then
    usage; exit 1
fi

# Parsing arguments
while getopts hl:d: opt
do
    case "$opt" in
      h)  usage; exit 0;;
      l)  LEVEL="$OPTARG";;
      d)  targetdir="$OPTARG";;
      \?) usage; exit 1;;               # unknown flag
    esac
done
shift `expr $OPTIND - 1`
FS=$@     # Filesystem we want backuped

# Checking that filesystem is regular and mounted
mount | grep $FS > /dev/null
if [ $? = 0 ]; then
    echo "$FS OK and mounted."
else 
    echo "$FS is either not filesystem or is not mounted"; exit 1
fi

# Creating basename for backup files
base=`hostname -s``echo ${FS} | tr \/  _`
baselev=${base}_l${LEVEL}

# If the target directory is NFS-remote, we may need to mount it
remote="no"
echo $targetdir | grep ":" > /dev/null
if [ $? = 0 ]; then        # if there is ":" in $targetdir it's NFS
     remote="yes"
     NFSHOST=`echo $targetdir | cut -d: -f1`
     EXTDIR=`echo $targetdir | cut -d: -f2`
     LOCDIR="/tmp/baakmnt$$"  # name of temporary local mount directory
     mkdir -p  $LOCDIR
fi

# Mounting NFS directory
if [ $remote = "yes" ]; then
    # Checking whether network connection exists
    ping -q -c 3 $NFSHOST > /dev/null
    if  [ ! $? = 0 ]; then
        echo "NFSHOST $NFSHOST unreachable"; exit 1
    fi
    # Checking whether we can mount the NFS directory
    showmount -e $NFSHOST | grep `hostname -s` | grep -q $EXTDIR
    if [ ! $? = 0 ]; then
        echo "NFSHOST $NFSHOST is not exporting $EXTDIR to us"; exit 1
    fi
    # Mount it and point $targetdir to the right place
    echo "mounting $NFSHOST:$EXTDIR on $LOCDIR"
    mount -t nfs $NFSHOST:$EXTDIR  $LOCDIR 
    if [ ! $? = 0 ]; then
        echo "Unable to mount $NFSHOST:$EXTDIR"; exit 1
    fi
    targetdir=$LOCDIR
fi

# Is target directory reachable?
cd ${targetdir}
if [ ! $? = 0 ]; then
    echo "Cannot cd to ${targetdir}!"; abort
fi

# Delete all dumps of the current and larger levels
echo "Deleting obsolete dumps ..."
lev=9
while [ $lev -ge $LEVEL ]
    do
        rm ${base}_l${lev}* > /dev/null 2>&1
        lev=`expr $lev - 1`
    done

# If doing level 0 decide how many volumes do we need
if [ $LEVEL -eq 0 ]; then
    # How many megabytes we have to backup
    mbs=`df -P -m ${FS} | grep ${FS} | sed 's/  */ /g' | cut -d" " -f3`
    echo "There is $mbs MB of data for level 0 backup on $FS,"

    # How many volumes do we need
    nvols=`expr \( $mbs / $CAP \) + 1`
    echo -n "$nvols files will be used as backup volumes. Their names are: "

    # Creating volume names
    target=${baselev}_$nvols.1
    i=2
    while [ $i -le $nvols ]
    do
        target=$target,${baselev}_$nvols.$i
        i=`expr $i + 1`
    done
    echo $target
else  # Else there is a single volume
    target=${baselev}
    echo "Backup volume is file ${target}"
fi

# Do the dump
cd ${targetdir} || abort
dump ${LEVEL}u -B `expr $CAP \* 1024` -f ${target} -h 0 ${FS}
cd ${HOME}

# Info about space left
avmbs=`df -P -m ${targetdir} | tail -n 1 |\
                        sed 's/  */ /g' | cut -d" " -f4`
echo "There is $avmbs MB of available space left on ${targetdir}."

# Unmounting NFS dirs
if [ $remote = "yes" ]; then
    sleep 3
    umount $LOCDIR; rmdir $LOCDIR
fi

echo " --  baak done --"
