#!/bin/bash
#< Create a tar file of specified input files - for backing up configuration files

BASENAME="/usr/bin/basename"
CHMOD="/bin/chmod"
DATE="/usr/bin/date"
ECHO="/bin/echo"
HOSTNAME=${HOSTNAME:=$( /bin/hostname )}
TAR="/usr/bin/tar"

THISPROG=$( ${BASENAME} $0 )

COMPRESS=0
FORCE=0
DEREFERENCE=0
VERBOSE=0

function print_error {
   ${ECHO} "Error: $@" >&2
}

function printv {
   (( VERBOSE )) && {
      ${ECHO} "--> $@"
   }
}

function print_usage {
   {
      ${ECHO} "Usage: ${THISPROG} [-cdFhv] -f <input_file> -o <output_dir>"
      ${ECHO} "       -c   Compress using bzip2 compression"
      ${ECHO} "       -d   Dereference links"
      ${ECHO} "       -f   Input file"
      ${ECHO} "       -F   Force, even if output file exists"
      ${ECHO} "       -o   Output directory"
      ${ECHO} "       -h   Display this usage message"
      ${ECHO} "       -v   Verbose mode"
   } >&2
}

function check_arguments {
   ERROR_COUNT=0
   if [ -z "${INPUT_FILE}" ]; then
      (( ERROR_COUNT = ERROR_COUNT + 1 )) 
      print_error "Input file (-f) mandatory"
   fi 
   if [ -z "${OUTPUT_DIR}" ]; then
      (( ERROR_COUNT = ERROR_COUNT + 1 )) 
      print_error "Output directory (-o) mandatory"
   fi 
   if [ "${ERROR_COUNT}" -gt "0" ]; then
      exit 1
   fi
}

function validate_arguments {
   if [ ! -e "${INPUT_FILE}" ]; then
      print_error "Input file does not exist" && exit 1
   fi
   if [ ! -f "${INPUT_FILE}" ]; then
      print_error "Input file is not a regular file" && exit 1
   fi
   # perform some basic sanity checking on our input file
   ERROR_COUNT=0
   while read LINE_FROM_FILE; do
      if [ ! -r "${LINE_FROM_FILE}" ]; then
         print_error "Cannot read ${LINE_FROM_FILE}"
         (( ERROR_COUNT = ERROR_COUNT + 1 ))
      fi
   done < ${INPUT_FILE}
   if [ "${ERROR_COUNT}" -gt "0" ]; then
      exit 1
   fi
   if [ ! -w "${OUTPUT_DIR}" ]; then
      print_error "Cannot write to output directory" && exit 1
   fi
}

function generate_output_filename {
   OUTPUT_FILE="${OUTPUT_DIR}/${HOSTNAME}_$( ${DATE} +%Y%m%d_%H%M ).tar"
   if [ "${COMPRESS}" -gt "0" ]; then
      OUTPUT_FILE="${OUTPUT_FILE}.bz2"
   fi 
   if [ -e "${OUTPUT_FILE}" -a "${FORCE}" -eq "0" ]; then
      print_error "Output file exists - use (-F) to force overwrite" && exit 1
   fi
}

function perform_tar {
   if [ "${COMPRESS}" -gt "0" ]; then
      COMPRESS_FLAG="j"
   fi
   if [ "${DEREFERENCE}" -gt "0" ]; then
      DEREF_FLAG="h"
   fi
   TAR_OPTIONS="c${COMPRESS_FLAG}${DEREF_FLAG}f ${OUTPUT_FILE} -T ${INPUT_FILE}"
   printv "Tar command: ${TAR} ${TAR_OPTIONS}"
   ${TAR} ${TAR_OPTIONS} 2>/dev/null
   ${CHMOD} 644 ${OUTPUT_FILE}
}

#
# main()
#
while getopts ":cdFhf:o:v" OPTION; do
  case ${OPTION} in
     "c")  COMPRESS=1              ;;
     "d")  DEREFERENCE=1           ;;
     "f")  INPUT_FILE="${OPTARG}"  ;;
     "F")  FORCE=1                 ;;
     "h")  print_usage && exit 0   ;;
     "o")  OUTPUT_DIR="${OPTARG}"  ;;
     "v")  VERBOSE=1               ;;
     *  )  print_usage && exit 1   ;;
  esac
done

shift $(( ${OPTIND} - 1 ))

if [ "$#" -ne "0" ]; then
   print_usage && exit 1
fi

check_arguments
validate_arguments
generate_output_filename
perform_tar

exit 0