#!/bin/sh
# rautobak			Version 1.00
#
# Copyright  2012 RTK Media, Inc
# All Rights Reserved.
#
# Any unauthorized use, reproduction, transfer or disclosure is prohibited.
#
# name: rautobak
#
# function: remote backup script for cron
#
# Author: Richard P. Nolan - RTK Media, Inc.  (719) 522-0377  rich@rtkmedia.com
#
# inputs: 
#
# outputs: 
#
# history:                  	     	(spr#) 
# version  date      name		reason/description
# -------  --------  -----------------	--------------------------------------
# 1.00 	   09/25/12	 rpn	Original Version
# ----------------------------------------------------------------------------
#

# Variables for rautobak files
RABDIR="/versyss/rab"                 # Where the remote autobackup files are
RABOUT="${RABDIR}/rautobak.out"    # File for details of the last backup
RABLOG="${RABDIR}/rautobak.log"    # File for summary of start and stop of B/Us
TEMPLOG="${RABDIR}/temp.log$$"    # A work file to make rautobak.log smaller
RABSTAT="${RABDIR}/rautobak.stat"  # Summary (no tar stuff) of last backup
RABLOGS="${RABDIR}/rablogs"        # Directory of rautobak.stat history
AGE=30                            # How many days we will keep the logs
RABFTPPATH="${RABDIR}/ftppath"  # Save all none comment lines here for path
RABFTPFILES="${RABDIR}/ftpfiles" # Save all none comment lines for files
RABEXCLUDES="${RABDIR}/excludes"  # File of Filenames/Directories to exclude
RABTAR="/versyss/data/tmp"            # A place to do the tar file MAKE IT BIG!
RABTEMPDIR="${RABDIR}/tmp"         # Directory for Temporary files
RABSELF="$RABTEMPDIR/excludeself$$" #A file created that has the tar name in it
TEMPPATH="$RABTEMPDIR/temp.path$$" # Save all none comment lines here for path
TOTALSECONDS=0
TEMPFILES="$RABTEMPDIR/temp.files$$" # Save all none comment lines for files
#
# Programs to Call
#
RABNOTIFY="$RABDIR/RNotify" # Optional program used to notify users of complete
RABINSTALL="${RABDIR}/RABInstall"  # Program to modify crontab for rautobak
RAUTOBAK="${RABDIR}/rautobak"      # The program for running a manual backup

#
# Subroutine to change a file to rw-rw-rw and be owned and grouped to cadol
#

FixPermiss()
{
  chmod 666 $1
  chown root $1
  chgrp sys $1
}

#
# Subroutine to print the seconds our in hours minutes and seconds
#
convertsecs() {
    h=`expr $1 / 3600`
    m=`expr $1  % 3600 / 60`
    s=`expr $1 % 60`
    printf "%02d:%02d:%02d " $h $m $s | tee -a ${RABLOG} ${RABSTAT} ${RABOUT}
}

#
# Subroutine to end the logs, either at good end or on a bad exit
#

EndLog()
{
  printf "\n\nEnd backup in " | tee -a ${RABLOG} ${RABSTAT} ${RABOUT}
  h=`expr $TOTALSECONDS / 3600`
  m=`expr $TOTALSECONDS  % 3600 / 60`
  s=`expr $TOTALSECONDS % 60`
  printf "%02d:%02d:%02d " $h $m $s | tee -a ${RABLOG} ${RABSTAT} ${RABOUT}
  echo ": `date`" | tee -a ${RABLOG} ${RABSTAT} ${RABOUT}
# ensure log files are readable by all
  FixPermiss ${RABLOG} >/dev/null 2>&1   # Summary of start and stop times
  FixPermiss ${RABOUT} >/dev/null 2>&1   # Detail including the tar command
  FixPermiss ${RABSTAT} >/dev/null 2>&1  # Summary of what happened
}

#
# do the actual backup
#
# NOTE: FTP can take some time, if the FTP site is set to kill idle connections
# in (let's say) 15 mins, you will need to ensure you have put the following
# line in the area where the other no commands are in the /etc/rc.net file:
#    no -o tcp_keepidle=600
# this is 300 seconds or 5 minutes and then the system will send a null packet
# to the FTP site so that it knows something is still happening and to keep
# the connection live.  You should also change the idle timeout at the host FTP
# server to allow the connections to last long enough so you don't disconnect
#
# NOTE: modifying the rc.net file does not take affect
# until the next boot, but you can run the command from the command line if you
# want to test before a reboot happens.  NOTE: you can run no -a to see all the
# values that are set.  If you are having issues getting large files to
# transmit, just lookup what all the no values are and see what you might
# be able to change to help out.
#
# NOTE: For this area to work we need 2 files in the rab directory:
#  1) 'ftppath' is the list of IPs/URLs we are going to send the data to (you
#     can have multiple lines in this file to backup to multiple FTPs).
#     The format of this file is ipaddress<space>username<space>password<space>
#     backup directory.  Note: it
#     makes the directory with the date/timestamp appended to it, so this is
#     the relative path and the directory beginning name.  For example:
#     '192.168.0.20 un pw backup' would create a directory named
#     HOME/backup120925-131215 if you started the backup on 
#     09/25/12 at 13:12:15.
#     Like wise '192.168.0.20 un pw public/backups/backup' would create a
#     directory at the ftp site named HOME/public/backups/backup120925-131215
#  3) 'ftpfiles' is the list of files/directories to tar and then ftp to the
#     above servers. This is the tar filename (without the .tar) and then an
#     unlimited lists of directories and/or files to put in that tar (the new
#     line at the end of the line signifies the end of the list for that file.
#     The file created from this tar process will be named 
#     TARNAME-120925-131215.tar.  So you would have to have unique tarnames
#
# Hint: instead of doing FTP to two different servers here, you could FTP to
# a local hard disk on the network (I just used FileZilla to create an internal
# ftp server for the office (which is also accessible remotely to backup your
# client systems as a service.  They could then just have a cloud program like
# BackBlaze that would automatically get this new information and archive it.
#
# NOTE: This area is specific to the client and the FTP they will be sending to
# If space permits, you can tar to 1 file and just send that.  If disk space
# is limited, then individuals elements (like an entire directory) can be done
# separately.  You can then download from the FTP site any tar file and work
# with it on your PC in normal file structure (like expand it and pull one file
# out of the tar.  You can also take the entire tar file and extract it
# on the original or a new system (see tar guides on the internet)
#

# figure out the date/timestamp to put on directories/files
YEAR=`date +%y`
if [ "$YEAR" -le "18" ]; then #if the system date is way back, add 16 years
  (( YEAR = YEAR+16))
fi
MONTH=`date +%m`
DAY=`date +%d`
HOUR=`date +%H`
MINUTE=`date +%M`
SECOND=`date +%S`
d=$YEAR$MONTH$DAY-$HOUR$MINUTE$SECOND

#
# see if we have the place to do the tar file and switch to it
if [ ! -d ${RABTAR} ]  # See if we have the work directory for the tar files
then
  mkdir ${RABTAR} >/dev/null 2>&1
  FixPermiss ${RABTAR} >/dev/null 2>&1
fi
cd ${RABTAR}      # Get to the directory we do the autobackup tar work in

#
# show start time in log files
#

if [ -f ${RABLOG} ]   # Shorten the rautobak.log file if necessary
then
	tail -n 18 ${RABLOG} > ${TEMPLOG}
	rm ${RABLOG}
	mv ${TEMPLOG} ${RABLOG}
fi

echo "Start backup : `date`" >> ${RABLOG}   # Add to rautobak.log
# start the rautobak.out (detail) and rautobak.stat (summary) logs
echo "Start backup by user-$USER logstamp-$d : `date`" 2>/dev/null | tee $RABOUT $RABSTAT

#
# ensure the temporary directory is in the RABDIR directory
#
if [ ! -d ${RABTEMPDIR} ]  # See if we have the detail auto backup directory
then
  mkdir ${RABTEMPDIR} >/dev/null 2>&1
  FixPermiss ${RABTEMPDIR} >/dev/null 2>&1
fi

# 
# first process the ftppath and ftpfiles to get only non-comment lines in files
#
PathsExist=0  # Assume we don't have something to work with in the paths file
if [ -f $RABFTPPATH ]  # If we have the ftppath file
then
  cat ${RABFTPPATH} | grep -v "^#" > $TEMPPATH  # cat/grep to see if any lines
	if [ -f $TEMPPATH ]   # if we have some non-comment lines from ftppath
  then
		PathsExist=1
	fi
fi

if [ ! $PathsExist=1 ]  # if we didn't find anything good, let em know
then
	echo "Missing/bad file ftppath, fix and try again" | tee -a $RABOUT $RABSTAT
	EndLog
  exit 1
fi

FilesExist=0  # Assume we don't have something to work with in the files file
if [ -f $RABFTPFILES ]  # If we have the ftpfiles file
then
  cat ${RABFTPFILES} | grep -v "^#" > $TEMPFILES # cat/grep to see if any lines
	if [ -f $TEMPFILES ]   # if we have some non-comment lines from ftpfiles
  then
		FilesExist=1
	fi
fi

if [ ! $FilesExist=1 ]  # if we didn't find anything good, let em know
then
	echo "Missing/bad file ftpfiles, fix and try again" | tee -a $RABOUT $RABSTAT
	EndLog
  exit 1
fi

# read the tempftpfiles file in a loop taring the files as you go
while read TARNAME FILENAMES   #Read 1 line of Tarname and Filenames
do
  TARFILE=$TARNAME-$d.tar  # Format: Tarname-Date/Timstamp.tar
  echo "\\ncreating tar file for file $TARFILE : `date`" | tee -a $RABOUT $RABSTAT
	echo "files/directories to tar $FILENAMES" | tee -a $RABOUT $RABSTAT
#
# NOTE: There are two lines below to build the TAR file. Some versions of
# tar do not allow you to exclude files that are in a directory
# Use the line of tar based on what level of OS or tar version you have
# on the machine.  If you can't exclude file(s), then you must ensure
# where the tar file is being built is outside the directories being tarred
# as the tar command will tar itself.
#
# echo $TARFILE > RABSELF # Put our own name in the list of excludes
# if [ -f $RABEXCLUDES ] # If we have the file 'excludes'
# then # If we have an additional list of files to exclude
#  tar -cvf $TARFILE -X $RABSELF -X $RABEXCLUDES $FILENAMES >> $RABOUT
# else # We don't have an additional list, but don't backup ourselves
#  tar -cvf $TARFILE -X $RABSELF $FILENAMES >> $RABOUT
# fi

#
# before we do a new tar file, let's clean up any that didn't finish transfer
#
  OLDTARS=$TARNAME-*
  rm $OLDTARS
#
# Loop thru all the tar files to create and transfer them
#
  SECONDS=0
  tar -cvf $TARFILE $FILENAMES >> $RABOUT #Only write tar detail to .out
  echo "\\ntar file creation complete in $SECONDS seconds, starting tranfer : `date`" | tee -a $RABOUT $RABSTAT
  ((TOTALSECONDS=$TOTALSECONDS+$SECONDS))
#
# Loop thru each FTPSITE and send the TAR file there
  while read FTPSITE USERNAME PASSWORD FTPDIRECTORY #1 line of FTP/UN/PW/DIR
  do
    FTPD=$FTPDIRECTORY-$d
    echo "ftp to $FTPSITE directory $FTPD : `date`" | tee -a $RABOUT $RABSTAT
#
# allow for active and passive modes
#
    SECONDS=0
    if [ $FTPSITE == "ftp.livedrive.com" ] #livedrive.com requires passive
    then
      ftp -nv $FTPSITE <<ENDOFCOMMANDS >>$RABOUT #Only FTP stuff to .out
        user $USERNAME $PASSWORD
        prompt off
        binary
        passive
        mkdir $FTPD
        cd $FTPD
        mput $TARFILE
        quit
#Note: the line 'ENDOFCOMMANDS' can not have any spaces in front of it
ENDOFCOMMANDS
    else
      ftp -nv $FTPSITE <<ENDOFCOMMANDS >>$RABOUT #Only FTP stuff to .out
        user $USERNAME $PASSWORD
        prompt off
        binary
        mkdir $FTPD
        cd $FTPD
        mput $TARFILE
        quit
#Note: the line 'ENDOFCOMMANDS' can not have any spaces in front of it
ENDOFCOMMANDS
    fi
    printf "send of file $TARFILE is complete in " | tee -a $RABOUT $RABSTAT
    h=`expr $SECONDS / 3600`
    m=`expr $SECONDS  % 3600 / 60`
    s=`expr $SECONDS % 60`
    printf "%02d:%02d:%02d " $h $m $s | tee -a $RABSTAT $RABOUT
    echo ": `date`" | tee -a $RABOUT $RABSTAT
    ((TOTALSECONDS = $TOTALSECONDS+SECONDS))
  done < $TEMPPATH
  rm $TARFILE | tee -a $RABOUT $RABSTAT # We ftp'd all the FTP Sites, del tar
done < $TEMPFILES
#
#All TAR Files backed up to all locations, show a directory of each location
#
while read FTPSITE USERNAME PASSWORD FTPDIRECTORY #1 line of FTP/UN/PW/DIR
do
  FTPD=$FTPDIRECTORY-$d
  echo "\\nftp to $FTPSITE directory $FTPD : `date`" | tee -a $RABOUT $RABSTAT
  
  if [ $FTPSITE == "ftp.livedrive.com" ] #livedrive.com requires passive
  then
    ftp -nv $FTPSITE <<ENDOFCOMMANDS | tee -a $RABOUT $RABSTAT 
      user $USERNAME $PASSWORD
      prompt off
      binary
      passive
      cd $FTPD
      dir
      quit
#Note: the line 'ENDOFCOMMANDS' can not have any spaces in front of it
ENDOFCOMMANDS
  else
    ftp -nv $FTPSITE <<ENDOFCOMMANDS | tee -a $RABOUT $RABSTAT 
      user $USERNAME $PASSWORD
      prompt off
      binary
      cd $FTPD
      dir
      quit
#Note: the line 'ENDOFCOMMANDS' can not have any spaces in front of it
ENDOFCOMMANDS
  fi
  echo "********** END OF DIRECTORY LISTING *************" | tee -a $RABOUT $RABSTAT
done < $TEMPPATH
rm $TEMPPATH | tee -a $RABOUT $RABSTAT 
rm $TEMPFILES | tee -a $RABOUT $RABSTAT 

# show end time in log
EndLog

# if the RABNOTIFY is an executable, call it
if [ -x ${RABNOTIFY} ]   # If the optional program is here to run
then # Call the program RNotify and do whatever to tell the users
	$RABNOTIFY
fi

#
# Archive the latest summary log (RABSTAT) to the RABLOGS directory
#

if [ ! -d ${RABLOGS} ]  # See if we have the detail auto backup directory
then
  mkdir ${RABLOGS} >/dev/null 2>&1
  FixPermiss ${RABLOGS} >/dev/null 2>&1
fi
  
if [ -d ${RABLOGS} ]   # If we were actually able to create the directory
then
	NewName=${RABLOGS}/rautobak-$d.log
  cp ${RABSTAT} $NewName >/dev/null 2>&1
	FixPermiss ${NewName} >/dev/null 2>&1
# get rid of any logs older than AGE days old
  find ${RABLOGS} -name rautobak*.log -mtime +${AGE} -exec rm {} \;
fi
