#!/bin/bash
#
# Backup script by Ole-Henrik Jakobsen
#	Last updated: 2017-05-10
#
# This script requires basic linux tools, awk, taraball and bzip2
#
# The script will save a compressed file in the folder specified (BACKUP_STORE_DIR)
# containing the listed files and directories (recursive) (BACKUP_FILESDIR)
# and keep X (BACKUP_KEEP) days of backup files before deleting them. NB! Number of days, not files.
# You can also update existing archive.
#
# For help and information, run:
#   sh backup-script.sh --help
#

# Backup directory to store backup
BACKUP_STORE_DIR="/mnt/backup"

# Backup filename. Do not include extensions.
BACKUP_FILENAME="server01"

# How many days to keep the old backup files before they get permanently deleted (new file not counted). Enter 0 to disable.
BACKUP_KEEP="5"

# List files and directories to backup, separate with new line.
BACKUP_FILESDIR=(
  /etc
  /var
  /home/*/.bash*
  /home/*/public_www
  /home/*/Maildir
  /home/*/.courier*
  /home/*/.mailfilter
  /root/package.list
  /root/backup-script.sh
)

# Enter commands you want to run before you make a backup here.
apt-get clean							# clean APT cache from /var
dpkg --get-selections > /root/package.list			# backup a list of installed programs

# ************************* DO NOT TOUCH UNLESS YOU KNOW WHAT YOU ARE DOING *************************
echo -e "\e[1;97m\e[44m"
echo -e "Backup script by Ole-Henrik Jakobsen\e[0m"
echo -e ""

BS_TIME_START="$(date +%s)"

usage() {
    echo -e "Commands: (./backup-script.sh [OPTION ...])"
    echo -e "    -c, --create              Create a new archive every time the script is running."
    echo -e "                              The file will be created with an additional timestamp as a prefix."
    echo -e "                              This method is the safest. It will be compressed with bzip2."
    echo -e ""
    echo -e "    -u, --update              Update the current archive instead of creating a new file."
    echo -e "                              A backup copy of the archive is done before updating."
    echo -e "                              Prefix of the copied file will be \"old.$BACKUP_FILENAME.tar\""
    echo -e "                              This archive will be also be uncompressed."
    echo -e ""
    echo -e "    -v, --verbose             Verbosely list files processed."
    echo -e ""
    echo -e "    -h, --help                You are reading it."
    exit 0
}

unset BS_TARFLAG
unset BS_VERBOSE

if [ $# -lt 1 ]; then
    echo -e "\e[0;91mError: There are not enough arguments in command line.\e[0m" > /dev/stderr
    echo -e ""
    usage
    exit 1
fi

while test -n "$1"; do
  case "$1" in
  -c|--create)
    if [ "$BS_TARFLAG" = "-u" ];
    then
      echo -e "\e[0;91mError: You must choose either --create or --update.\e[0m" > /dev/stderr
      echo -e ""
      usage
      exit 1
    else
      BS_TARFLAG="-c"
      shift
    fi
    ;;
  -u|--update)
    if [ "$BS_TARFLAG" = "-c" ];
    then
      echo -e "\e[0;91mError: You must choose either --create or --update.\e[0m" > /dev/stderr
      echo -e ""
      usage
      exit 1
    else
      BS_TARFLAG="-u"
      shift
    fi
    ;;
  -v|--verbose)
    BS_VERBOSE="-v"
    shift
    ;;
  -h|--help|*)
    usage
    exit 0
    ;;
  esac
done

if test -z "$BS_TARFLAG";
then
  echo -e "\e[0;91mError: You must choose either --create or --update.\e[0m" > /dev/stderr
  echo -e ""
  usage
  exit 1
fi

BS_FILENAME_DATE="$(date +%Y%m%d%H%M)"

if [ "$BS_TARFLAG" = "-c" ];
then
  echo -e "Creating backup..."
  tar -c -j -p $BS_VERBOSE -f $BACKUP_STORE_DIR/$BACKUP_FILENAME.$BS_FILENAME_DATE.tar.bz2 ${BACKUP_FILESDIR[*]}
  if test -f "$BACKUP_STORE_DIR/$BACKUP_FILENAME.$BS_FILENAME_DATE.tar.bz2";
  then
    echo -e "Backup created: $BACKUP_STORE_DIR/$BACKUP_FILENAME.$BS_FILENAME_DATE.tar.bz2"
  else
    echo -e "\e[0;91m Error: Backup failed. Try to run the script in verbose mode.\e[0m" > /dev/stderr
    exit 1
  fi
else if [ "$BS_TARFLAG" = "-u" ];
then
  if test -f "$BACKUP_STORE_DIR/$BACKUP_FILENAME.tar";
  then
    echo -e "Updating backup..."
    cp -P $BS_VERBOSE $BACKUP_STORE_DIR/$BACKUP_FILENAME.tar $BACKUP_STORE_DIR/old.$BACKUP_FILENAME.tar
    tar -u -p $BS_VERBOSE -f $BACKUP_STORE_DIR/$BACKUP_FILENAME.tar ${BACKUP_FILESDIR[*]}
    echo -e "Backup updated: $BACKUP_STORE_DIR/$BACKUP_FILENAME.tar"
  else
    echo -e "Creating backup..."
    tar -c -p $BS_VERBOSE -f $BACKUP_STORE_DIR/$BACKUP_FILENAME.tar ${BACKUP_FILESDIR[*]}
    echo -e "Backup created: $BACKUP_STORE_DIR/$BACKUP_FILENAME.tar"
  fi
fi
fi

FIND_OLD_FILES="$(find $BACKUP_STORE_DIR/$BACKUP_FILENAME.* -type f -mtime +$BACKUP_KEEP)"
if [ $BACKUP_KEEP -lt 1 ]; then
  echo -e "\e[0;93mWarning: Backup deletion has been disabled, make sure you always have enough space on your backup device.\e[0m"
  else if test -n "$FIND_OLD_FILES";
  then
    echo -e "Deleting old backup files..."
    find $BACKUP_STORE_DIR/$BACKUP_FILENAME.* -type f -mtime +$BACKUP_KEEP | xargs rm $BS_VERBOSE
    echo -e "Old backup files deleted."
  else
    echo -e "No old backup files has been found or deleted."
  fi
fi


BS_TIME_STOP="$(date +%s)"

echo -e "\e[1;97m\e[42m"
echo -e "Backup done in $(awk "BEGIN { print $BS_TIME_STOP - $BS_TIME_START ; }") seconds.\e[0m"

exit 0