#!/bin/bash
#
# ::do_not_edit::
# ::maintainer::
#
# __copy1__
# __copy2__
#
CMD=$(basename $0)
CMDVER="1.1"
CMDSTR="$CMD v$CMDVER (2019/04)"

set -e -u

usage()
{
	echo "
=== $CMDSTR == create/update a set of standard sieve filter for user ===

usage: $CMD [options] user email

options:
 -n|--dry-run)	no actions, only check
 -x		do actions
" >&2
	exit 1
}

cleanup()
{
	trap "" 1 2 3 ERR EXIT
	rm -f $tmp_old $tmp_new $tmp_req
	trap 1 2 3 ERR EXIT
}

create_auto_vacation()
{
	local domain=${email/*@/}
	local gecos=$(getent passwd $user | cut -d':' -f5) 

	echo '# rule:[VACATION]'
	echo 'if false # allof (not header :contains "from" "@'$domain'")'
	echo '{'
	echo '	vacation :days 2 :addresses "'$email'" :subject "Out of office" text:'
	echo "I'm out of office from XXXXX to XXXXX."
	echo ""
	echo "Will answer to your e-mail as soon as I come back."
	echo ""
	echo "Best Regards"
	echo ''
	echo '--'
	echo '  '$gecos
	echo '.'
	echo ';'
	echo '}'
	echo
}

create_auto_spamassassin()
{
	# note, backslashes are double escaped, due installer parsing
	echo '# rule:[auto-spamassassin]'
	echo 'if header :regex "subject" "^\\\\*\\\\*\\\\*SPAM\\\\*\\\\*\\\\*"'
	echo '{'
        echo '	fileinto "'$folder_spam'";'
	echo '	stop;'
	echo '}'
	echo
}

create_auto_banned()
{
	echo '# rule:[auto-banned]'
	echo 'if header :contains "X-Amavis-Alert" "BANNED"'
	echo '{'
        echo '	fileinto "'$folder_banned'";'
	echo '	stop;'
	echo '}'
	echo
}



compile_sieve()
{
	[ -L "$home/.dovecot.sieve" ] || {
		su - $user -c "pwd; ln -s sieve/roundcube.sieve .dovecot.sieve"
	}
	sievec "$file_sieve" "$file_compiled"
	chown -R --reference "$home" "$file_compiled"
	chown -R --reference "$home" "$home/sieve"
	return 0
}


# (MAIN)

f_exec=false
DEBUG=false

while [ $# != 0 ]
do
  case $1 in
    -n|--dry-run)	f_exec=false ;;
    -x)			f_exec=true ;;
    -D|--debug)		DEBUG=true ;;
    -*)			usage ;;
    *)			break ;;
  esac
  shift
done

[ $# != 2 ] && usage
user=$1
email=$2

home=$(getent passwd $user | cut -d':' -f6) || {
	echo "$CMD error: can't get infos for user '$user'" >&2
	exit 1
}

folder_spam="Junk"
folder_banned="Junk"

# custom settings
#
[ -f $home/.$CMD.conf ] && eval $(grep '^folder_[a-z]*=' $home/.$CMD.conf)

# mandatory files
#
file_sieve="$home/sieve/roundcube.sieve"
file_compiled="$home/.dovecot.svbin"

tmp_old=$(mktemp /tmp/$CMD-XXXXXXXXX)
tmp_new=$(mktemp /tmp/$CMD-XXXXXXXXX)
tmp_req=$(mktemp /tmp/$CMD-XXXXXXXXX)
require_min="body fileinto imap4flags regex vacation"

trap 'echo -e "\n*INTR*\n" >&2; exit 255' 1 2 3
trap 'echo -e "\nunexpected error $? at $LINENO\n" >&2' ERR
trap 'cleanup' EXIT

:>$tmp_old
:>$tmp_new

	###fgrep -q '/* empty file */' "$file_sieve" && {

# first, wipe out auto rules from actual sieve file
#
[ -f "$file_sieve" ] && {
	f_skip=false
	autotag="# rule:?auto-"

	# needs to preserve leading spaces (indent) and backslashes
	# note, backslashes are double escaped, due installer parsing
	sed -e 's/^/X/' -e 's/\\\\/X-bs-X/g' "$file_sieve" >$tmp_new

	exec 9<&0 <$tmp_new
	while read line
	do
		case $line in
		  Xrequire*)	echo "$line" | sed \
		  			-e 's/.*\[//' -e 's/\].*//' \
					-e 's/[,"]/ /g' -e 's/  */\n/g' \
					>$tmp_req
		  		continue
				;;
		  "X}")		$f_skip || echo "}"
		  		f_skip=false
				continue
				;;
		  X${autotag}*)	f_skip=true
		  		continue
				;;
		esac
		$f_skip && continue
		echo "$line"
	done | sed -e 's/^X//' -e 's/X-bs-X/\\\\/g' >$tmp_old
	exec 0<&9 9<&-
	:>$tmp_new

	$DEBUG && { echo "@D DUMP tmp_old=$tmp_old">&2; cat $tmp_old >&2; }
}

# sort out require keywords
#
$DEBUG && { echo "@D DUMP tmp_req=$tmp_req" >&2; cat $tmp_req >&2; }
echo $require_min | tr ' ' '\n' >>$tmp_req
sed -e '/^$/d' $tmp_req | sort -u -o $tmp_req
$DEBUG && { echo "@D DUMP tmp_req=$tmp_req" >&2; cat $tmp_req >&2; }


# create header
#
require='require: ["'
comma=
for req in $(cat $tmp_req)
do
	require="${require}${comma}${req}"
	comma='",'
done
require="${require}\"];"
echo "$require" >$tmp_new

$DEBUG && { echo "@D DUMP tmp_new=$tmp_new" >&2; cat $tmp_new >&2; }

create_auto_spamassassin	>>$tmp_new
create_auto_banned		>>$tmp_new
create_auto_vacation		>>$tmp_new

cat $tmp_old			>>$tmp_new

$DEBUG && { echo "@D DUMP tmp_new=$tmp_new" >&2; cat $tmp_new >&2; }

$DEBUG && {
	echo -e "\n=== $file_sieve < == > $tmp_new ===\n"
	diff "$file_sieve" $tmp_new || :
}

exit 0 #####


	if $f_exec
	then
		mkdir -p "$home/sieve" 2>/dev/null || :
		compile_sieve
	else
		echo "(dummy) create empty file: '$file_sieve'"
	fi
}

compile_sieve

exit 0
