#! /bin/sh # This file is part of BEAM # Copyright (C) 2012-2014 Sergey Poznyakoff # # BEAM is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # BEAM is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with BEAM. If not, see . # Force C locale LC_ALL=C export LC_ALL openlog_hook= prologue_hook= epilogue_hook= # User configuration variables backup_tar_options= backup_suffix= backup_archive_dir= backup_snapshot_dir= backup_verbose= backup_logfile="/var/log/backup" backup_pidfile="/var/run/beam.pid" backup_tmp_dir=/tmp error() { echo >&2 $0: $* } logit() { echo `date`: $* } abend() { ec=$1 shift error $@ exit $ec } beam_lock() { if [ -r $backup_pidfile ]; then pid=$(head -n 1 $backup_pidfile) if [ -z "$pid" ]; then abend 1 "pidfile $backup_pidfile exists but is unreadable or empty" fi abend 1 "another beam process (pid $pid) is still running; exiting" fi echo $$ > $backup_pidfile || exit 1 epilogue_hook="$epilogue_hook beam_unlock" } beam_unlock() { rm -f $backup_pidfile } tarcode() { case $1 in 0) logit "success";; 1) logit "some files changed while being archived";; 2) logit "fatal error occurred, but trying to continue anyway" tarerror=$((tarerror + 1));; *) logit "unexpected error code $1" tarerror=$((tarerror + 1)); esac } load_config() { local delayed_exit remote test -z "$BEAM_CONFIG" && BEAM_CONFIG=@SYSCONFDIR@/beam.conf if [ -r $BEAM_CONFIG ]; then . $BEAM_CONFIG else abend 1 "configuration file $BEAM_CONFIG does not exist or is unreadable" fi if [ -z "$backup_items" ]; then abend 1 "backup_items not specified" fi if [ -z "$backup_archive_dir" ]; then if [ -n "$backup_bucket_name" ]; then backup_archive_dir=$backup_mp_s3 else abend 1 "backup_archive_dir not set" fi fi delayed_exit= loaded_types= for item in $backup_items do eval type=\$${item}_type if [ -z "$type" ]; then error "${item}_type not set" delayed_exit=1 continue fi if echo "$loaded_types" | grep -wq $type; then : elif [ -x $libdir/${type}.sh ]; then . $libdir/${type}.sh || delayed_exit=1 loaded_types="$loaded_files $type" else error "$libdir/${type}.sh not found" delayed_exit=1 fi ${type}_check $item || delayed_exit=1 done test -n "$delayed_exit" && abend 1 "aborting" tar_suffix=${backup_suffix:-.tar} if [ -n "$backup_bucket_name" ]; then . @LIBDIR@/beam/s3.sh prologue_hook="s3_mount $prologue_hook" fi remote=${backup_archive_dir%%:*} if [ "$remote" != "$backup_archive_dir" ]; then beam_rsh="${backup_rsh:-ssh} $remote" backup_local_archive_dir=${backup_archive_dir#*:} else beam_rsh= backup_local_archive_dir=$backup_archive_dir fi } beam_exec() { if [ -z "$beam_rsh" ]; then set -- $(echo "$@" | sed 's/\\\\\([bcfnrtv0]\)/\\\1/g') "$@" else set -- $(echo "$@" | sed 's/\\\\\([bcfnrtv0]\)/\\\1/g;s/[]\[\\\*]/\\&/g') $beam_rsh "$@" fi } runhook() { local hook_list eval hook_list=\$$1 for hook in $hook_list do $hook done } print_version() { name=$(basename $0) cat < This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. EOF exit 0 } wtf() { l=$(echo "${1#beam-}"|sed "s|.|.|g") s=$(echo " " | sed "s|$l|${1#beam-}|") shift echo " $s $@" } dry_mail() { echo "=============================================================" cat - echo "=============================================================" } # mail_report FILE mail_report() { : ${backup_mailer_program:=/usr/sbin/sendmail -oi -t -F $backup_sender_email} if [ -n "$dry_run" ]; then echo "Sending mail using $backup_mailer_program" backup_mailer_program=dry_mail fi if [ -z "$backup_sender_email" ]; then backup_sender_email=root@$(hostname) fi case $backup_sender_email in "<"*) ;; *) backup_sender_email="<$backup_sender_email>" esac if [ -n "$backup_sender_personal" ]; then case $backup_sender_personal in \"*) ;; *) backup_sender_personal="\"$backup_sender_personal\"" esac backup_sender_personal="$backup_sender_personal " fi if [ -z "$backup_report_subject" ]; then backup_report_subject="Backup of $(hostname) on $(date)" fi test -n "$backup_report_signature" && echo "$backup_report_signature" >> $report (cat - < $conf <