#!/bin/bash dir1=$1 dir2=$2 work_dir=$3 mail_to=$4 mail_from=$5 hour_to_mail_regardless=$6 cache_results=$7 #hour_to_mail_regardless="" start_date=$(date) [ "$mail_from" == "" ] && mail_from="root@moparisthebest.com" [ "$hour_to_mail_regardless" == "" ] && hour_to_mail_regardless="$(date +%k)" ( [ "$cache_results" != "0" ] && [ "$cache_results" != "1" ] ) && cache_results="0" #( [ "$cache_results" != false ] && [ "$cache_results" != true ] ) && cache_results=false mkdir -p $work_dir list_files(){ find -L . -not -type d -not -type l | egrep -v "^./rdiff-backup-data" | egrep -v '.bash_history$' | egrep -v 'logs/lighttpd/.*\.log$' | egrep -v 'cache/(data|lang)_.*\.php$' | egrep -v "worldmap/.*\.png$" | egrep -v "(crc_file|log)$" | egrep -v "moparscape\.org/timestamp$" | egrep -v "moparisthebest\.com/downloads/current_simba/.*(\.7z|\.exe|-linux)$" | egrep -v "moparisthebest\.com/rs/gamepack.*\.(jar|properties)$" | egrep -v "moparisthebest\.com/smf/attachments/([0-9]+_[0-9a-f]{40}|post_tmp_[0-9]+_[0-9])$" } print_report(){ [ -s "$2" ] && (echo -e "$1"; cat "$2"; echo; echo -en "$3") >> $work_dir/report } # copy over cached files if requested, and they exist if [ "$cache_results" == "1" ] then [ -f "$dir1/dir1.files" ] && cp "$dir1/dir1.files" "$work_dir/dir1.files" [ -f "$dir1/dir1.md5" ] && cp "$dir1/dir1.md5" "$work_dir/dir1.md5" # [ -f "$dir1/files_to_checksum" ] && cp "$dir1/files_to_checksum" "$work_dir/files_to_checksum" fi cd $dir1 # list files if cache_results is false or dir1.files doesn't exist ( [ "$cache_results" == "0" ] || [ ! -f "$work_dir/dir1.files" ] ) && list_files > $work_dir/dir1.files # if cache_results is true, and a cached file list doesn't exist, copy it ( [ "$cache_results" == "1" ] && [ ! -f "$dir1/dir1.files" ] ) && cp "$work_dir/dir1.files" "$dir1/dir1.files" cd $dir2 list_files > $work_dir/dir2.files diff -Naurw $work_dir/dir1.files $work_dir/dir2.files > $work_dir/files.diff egrep "^\+" $work_dir/files.diff | tail -n+2 | sed "s/^\+//" > $work_dir/files_added egrep "^-" $work_dir/files.diff | tail -n+2 | sed "s/^-//" > $work_dir/files_removed cat $work_dir/dir1.files $work_dir/dir2.files | sort | uniq -d > $work_dir/files_to_checksum cat $work_dir/dir1.files $work_dir/dir2.files | sort | uniq -u > $work_dir/files_added_or_removed # if cache is enabled, and files_to_checksum is different, refresh dir1.md5sum #( [ "$cache_results" == "1" ] && [ "$(md5sum "$dir1/files_to_checksum" | cut -f1 -d ' ')" != "$(md5sum "$work_dir/files_to_checksum" | cut -f1 -d ' ')" ] ) && ( rm "$work_dir/dir1.md5" "$dir1/dir1.md5"; cp "$work_dir/files_to_checksum" "$dir1/files_to_checksum" ) temp_ifs=$IFS IFS=" " if ( [ "$cache_results" == "0" ] || [ ! -f "$work_dir/dir1.md5" ] ) then rm -f $work_dir/dir1.md5 cd $dir1 for f in $(cat $work_dir/files_to_checksum) do md5sum "$f" >> $work_dir/dir1.md5 done fi ( [ "$cache_results" == "1" ] && [ ! -f "$dir1/dir1.md5" ] ) && cp "$work_dir/dir1.md5" "$dir1/dir1.md5" cd $dir2 cat $work_dir/dir1.md5 | md5sum -c | egrep -v ": OK$" | sed "s/: FAILED$//" | sed "/: FAILED open or read$/d" > $work_dir/files_changed rm -f $work_dir/files_changed.diff dir1_sed=$(echo $dir1 | sed -e 's/\(\.\|\/\|\*\|\[\|\]\|\\\)/\\&/g') dir2_sed=$(echo $dir2 | sed -e 's/\(\.\|\/\|\*\|\[\|\]\|\\\)/\\&/g') for f in $(cat $work_dir/files_changed | sed "s/\.\///") do tmp=$(diff -Naurw "$dir1/$f" "$dir2/$f") # just use sed on the first 2 lines, so we know we won't mess up anything else echo "$tmp" | head -n2 | sed "s/^--- $dir1_sed/--- a/" | sed "s/^+++ $dir2_sed/+++ b/" >> $work_dir/files_changed.diff # copy from lines 3 on down echo "$tmp" | tail -n+3 >> $work_dir/files_changed.diff done IFS=$temp_ifs rm -f $work_dir/report print_report "Files added:\n" "$work_dir/files_added" print_report "Files removed:\n" "$work_dir/files_removed" print_report "Files changed:\n" "$work_dir/files_changed" "Diff file: $work_dir/files_changed.diff\n\n" [ ! -s "$work_dir/report" ] && attach="no" && echo -e "No changes!\n" >> $work_dir/report (echo "Started:"; echo $start_date; echo "Finished:"; date; uptime; echo; echo ) >> $work_dir/report [ "$mail_to" != "" ] && ( [ "$attach" != "no" ] || [ "$(date +%k)" == "$hour_to_mail_regardless" ] ) && ( echo -e "To: $mail_to\nFrom: $mail_from\nSubject: Diff Report\n"; cat $work_dir/report $work_dir/files_changed.diff; echo; [ "$attach" != "no" ] && uuencode $work_dir/report report.txt; [ -s "$work_dir/files_changed.diff" ] && uuencode $work_dir/files_changed.diff files_changed.diff.txt ) | sendmail -f $mail_from $mail_to if [ $? != 0 ] then # if the last command (sendmail) failed (maybe diff file too big?), send a shorter email saying so, without the diff file or attachment [ "$mail_to" != "" ] && ( [ "$attach" != "no" ] || [ "$(date +%k)" == "$hour_to_mail_regardless" ] ) && ( echo -e "To: $mail_to\nFrom: $mail_from\nSubject: Diff Report\n"; cat $work_dir/report; echo "Diff file too big!"; echo; ) | sendmail -f $mail_from $mail_to # if the last command (sendmail) failed (maybe report too big?), send a short-and-sweet email saying so, without anything else [ $? != 0 ] && [ "$mail_to" != "" ] && ( [ "$attach" != "no" ] || [ "$(date +%k)" == "$hour_to_mail_regardless" ] ) && ( echo -e "To: $mail_to\nFrom: $mail_from\nSubject: Diff Report\n"; echo "Changes too large to mail!"; echo; ) | sendmail -f $mail_from $mail_to fi exit 0;