#! /bin/sh
:
#ident	"@(#)smail/util:RELEASE-3_2_0_120:mkcyrusoqlist.sh,v 1.6 2004/07/24 15:49:53 woods Exp"
#
#	mkcyrusoqlist - update the Cyrus Over-Quota list
#
# This script should be run periodically as root from cron (as often
# as you can afford to run it).

umask 022
PATH="X_UTIL_PATH_X:X_SECURE_PATH_X"; export PATH

argv0=$(basename $0)

TMPDIR="X_TMP_DIR_X"
if [ ! -d ${TMPDIR} ] ; then
	if mkdir ${TMPDIR} ; then
		chmod 700 ${TMPDIR}
	else
		echo "$argv0: ${TMPDIR} may exist as a file!" 1>&2
		exit 1
	fi
fi

: ${SMAIL_PROGRAM:="X_SMAIL_NAME_X"}

SMAIL_LIB_DIR=$(${SMAIL_PROGRAM} -bP smail_lib_dir)

cd ${SMAIL_LIB_DIR} || exit 1

CYRUS_USER=$(${SMAIL_PROGRAM} -bP cyrus_user)
CYRUS_DELIVER_PATH=$(${SMAIL_PROGRAM} -bP cyrus_deliver_path)

if [ -z "${CYRUS_BIN}" ]; then
	CYRUS_BIN=$(dirname ${CYRUS_DELIVER_PATH})
fi

# WARNING:  this script could fail to interlock properly if it can be
# invoked simultaneously with more than one name!  Don't do that!
# 
LOCKDIR=${TMPDIR}/${argv0}.lock
PIDFILE=${LOCKDIR}/${argv0}.pid

if [ -s ${PIDFILE} ] ; then
	if kill -0 `cat ${PIDFILE}` > /dev/null 2>&1 ; then
		: # still running... error reported below...
	else
		# system probably rebooted while checkerr was running...
		rm ${PIDFILE}
		rmdir ${LOCKDIR}
	fi
fi

if [ -e ${LOCKDIR} ] ; then
	echo "It appears there's already an instance of ${argv0} running..." 1>&2
	exit 1
fi

if mkdir ${LOCKDIR} ; then
	: #got it!
else
	echo "Oops, just missed grabbing ${LOCKDIR}!" 1>&2
	exit 1
fi

echo $$ > ${PIDFILE}

rm -f cyrus_over_quota.tmp
cat <<__EOF__ > cyrus_over_quota.tmp
#
#    #     #                                                   ###
#    #  #  #    ##    #####   #    #     #    #    #   ####    ###
#    #  #  #   #  #   #    #  ##   #     #    ##   #  #    #   ###
#    #  #  #  #    #  #    #  # #  #     #    # #  #  #         #
#    #  #  #  ######  #####   #  # #     #    #  # #  #  ###
#    #  #  #  #    #  #   #   #   ##     #    #   ##  #    #   ###
#     ## ##   #    #  #    #  #    #     #    #    #   ####    ###
# 
# This file is automatcialy maintained by '$argv0'
#
# Last updated: $(date)
#
__EOF__

# the current implementation only selects mailboxes over 99%
# utilization, generates regular expressions that should match every
# sub-mailbox of the over-quota mailbox root, and aliases them to
# ":fail:"  so that they are permanently rejected (i.e. it is assumed
# the default user_with_mbox director is being used).
#
# It might be wise to use >98% instead of >99%.
#
# It might sometimes be desirable to use :defer: for temporary
# rejection, especially if you do not set lmtp_overquota_perm_failure
# to "yes" in your Cyrus imapd.conf, though you really should always
# trigger an immediate and permanent reject for over-quota failures so
# that the sender will know right away what's going on.
#
su -m "${CYRUS_USER}" -c ${CYRUS_BIN}/quota | awk '
	$2 > 99 {
		# unixhierarchysep: no
		sub(/^user\./, "", $4);
		# unixhierarchysep: yes
		sub(/^user\//, "", $4);
		printf("\"%s([-+].*)?\": :fail:\"This mailbox has exceeded its allotted storage quota.\"\n", $4);
	}' >> cyrus_over_quota.tmp

exitvalue=$?

if [ $exitvalue -ne 0 ]; then
	echo "$argv0:  ERROR:  Problems creating ${SMAIL_LIB_DIR}/cyrus_over_quota.tmp" 1>&2
fi

mv cyrus_over_quota.tmp cyrus_over_quota.list

if [ ! -d ${LOCKDIR} ] ; then
	echo "$argv0: OOPS!!!!  ${LOCKDIR} went missing!!!!" 1>&2
	exit 1
fi
rm -f ${PIDFILE}
rmdir ${LOCKDIR}

exit $exitvalue
