    #!/bin/bash
    ##################################################################
    # sqlbackup.sh:
    #   rolling sqlbackups using mysqldump
    #
    #
    #   This script will dump mysql databases to a specified directory
    #   with optional encrytion.
    #
    #
    ###################################################################

    # program options
    backup_dir=/backup
    backup_age=28
    use_encryption=0
    use_bzip=0
    nice_level=19
    mysql_user=root
    mysql_passfile=/etc/keys/.mysqlpass
    openssl_passfile=/etc/keys/.opensslpass
    date=`date +%Y%m%d`
    exten=".sql"
    logfile=/var/log/mysqlbackup.log
    mysqldump_options=" --all-databases --single-transaction --quote-names "

    # program paths
    mysqldump=/usr/bin/mysqldump
    openssl=/usr/bin/openssl
    bzip2=/usr/bin/bzip2


    # usage summary
    function usage {
    echo "
    sqlbackup.sh:
        creates backups of sql databases using the mysqldump command,
        including optional encryption, bzip2 compression, and 
        variable backup aging

    Usage: sqlbackup.sh [OPTIONS]

        Options:

        -h              : display this help

        -b <dir>        : select directory to store backups. This directory 
                        will not be created.

        -e              : enable encryption using openssl's des3 encryption. 

        -k <file>       : specify file containing password to be used for encryption
                        This defaults to /etc/keys/.opensslpass
                
        -u <user>       : username to use for connecting to MySQL

        -p <file>       : specifies a file containing a password to be used for
                        connecting to MySQL
    
        -z              : enable bzip2 compression of backups

        -a <days>       : backup age in days. Backups older than this will be deleted

        -n <level>      : Specifies a nice level. This level will apply to all operations of the 
                        backup. Defaults to 19 (very nice)
                
        -l <file>       : logfile path. Alternate path to a file for logging. Defaults
                        to '/var/log/mysqlbackup.log'
                
    "
    }      

    # echo a string to screen and log
    function echo_and_log {
        logstring="[ `date` ] : $*"
        echo $logstring
        echo $logstring >> $logfile
    }


    # print error to screen and exit
    function exit_with_error {
        echo_and_log "Error: $*"
        echo_and_log "Exiting with code 1"
        exit 1
    }

    # funtion to delete old backups
    function clean_backups {
    find $backup_dir -type f -mtime +${backup_age} -exec rm -f {} \;
    [ "$?" == "0" ] || echo_and_log "Error encountered when cleaning old backups from $backup_dir"
    }


    # process command line options
    while getopts ":hb:ek:u:p:za:n:l:" opt 
    do
        case $opt in
            b) backup_dir=$OPTARG ;;
            e) use_encryption=1 ;;
            k) openssl_passfile=$OPTARG ;;
            u) mysql_user=$OPTARG ;;
            p) mysql_passfile=$OPTARG ;;
            z) use_bzip=1 ;;
            a) backup_age=$OPTARG ;;
            n) nice_level=$OPTARG ;;
            l) logfile=$OPTARG ;;
            h) usage 
                exit 0 ;;
            \?) echo "unknown option"
                usage 
                exit 1 ;;
            *)  usage
                exit 1 ;;
        esac
    done

    # set umask
    umask 0077

    # start processing
    echo_and_log "Starting MySQL backup: encryption = $use_encryption, bzip = $use_bzip, backup directory = $backup_dir"
    
    # error checking and validation
    [ -d $backup_dir ] || exit_with_error "Backup directory '$backup_dir' does not exist"
    [ -n "$logfile" ] || exit_with_error "No log file specified."
    [ -f $mysql_passfile ] || exit_with_error "MySQL password file '$mysql_passfile' does not exist"
    [ -x $mysqldump ] || exit_with_error "MySQLDump program at '$mysqldump' does not exist or is not executable"
    # validate compression options
    if [ "$use_bzip" == "1" ]
    then
        [ -x $bzip2 ] || exit_with_error "Bzip2 program at '$bzip2' does not exist or is not executable"
        bzip2_command=" | nice -n $nice_level $bzip2 "
        exten="${exten}.bz2"
    fi

    # validate encryption options
    if [ "$use_encryption" == "1" ]
    then 
        [ -x $openssl ] || exit_with_error "OpenSSL program at '$openssl' does not exist or is not executable"
        [ -f $openssl_passfile ] || exit_with_error "OpenSSL password file '$openssl_passfile' does not exist"
        openssl_command=" | nice -n $nice_level $openssl des3 -salt -pass file:${openssl_passfile} "
        exten="${exten}.cryp"
    fi

    # call funtion to clean backup directory
    clean_backups

    # execute dump command
    command="$mysqldump $mysqldump_options --user=${mysql_user} --password=$(<$mysql_passfile) $bzip2_command $openssl_command > $backup_dir/mysqlbackup_${date}${exten}"
    eval $command
    [ "$?" == "0" ] || exit_with_error "MySQLDump command returned non-zero error code. Backup not completed successfully"

    # finish
    echo_and_log "Backup complete"
    exit 0

