#! /bin/sh
:
#ident	"@(#)contrib:RELEASE-3_2_0_115:unfreezemail.sh,v 1.11 2003/01/08 21:32:06 woods Exp"
#
#	unfreeze.sh - move a message back out of the error queue for resend
# 
# clears any "Xfail" entries from the msglog file so that the resend
# might actually work....
#
# Note: there's nothing magic in here -- people have been manually clearing
# their error queues with "rm" or "mv" and the text editor of their choice
# for over a decade now.  This script just helps mechanise the process.
#
# Written by Greg A. Woods <woods@planix.com>
# Contributed to the public domain.
#

umask 022

PATH="/usr/lib/smail:/usr/sbin:/bin:/usr/bin"; export PATH

UTIL_BIN_DIR=/usr/lib/smail

SMAIL_NAME="/usr/sbin/smail"
SPOOL_DIRS="`${SMAIL_NAME} -bP spool_dirs`"

GETOPT=${UTIL_BIN_DIR}/getopt

# TMPFILES="$TMPDIR/tc$$ $TMPDIR/et$$ $TMPDIR/qu$$"
# trap 'rc=$?; rm -f $TMPFILES; exit $rc' 0 1 2 3 13 15

argv0=`basename $0`

USAGE="Usage: $argv0 [-D [-f]] [-i] [-m] [n] [-v debug_level] message_queue_id [...]"

delete=false
confirm=false
interactive="-i"
domailq=false
dorunq=true
verbose=""

TMPDIR="/var/mail/tmp"
if [ ! -d $TMPDIR ] ; then
	if ! mkdir $TMPDIR ; then
		echo "$argv0: $TMPDIR exists as a file!" 1>&2
		exit 1
	else
		chmod 700 $TMPDIR
	fi
fi

set -- `${GETOPT} -n ${argv0} -q Dfimnv: ${1+"$@"}`
if [ "$?" -ne 0 ]; then
	echo $USAGE 1>&2
	exit 2
fi
for i in ${1+"$@"} ; do
	case "$i" in
	-D)
		delete=true
		shift
		;;
	-f)
		force="-f"
		shift
		;;
	-i)
		confirm=true
		shift
		;;
	-m)
		domailq=true
		shift
		;;
	-n)
		dorunq=false
		shift
		;;
	-v)
		if [ "$2" -ne 0 -a $# -gt 2 ] ; then
			verbose="-v$2"
		else
			echo $USAGE 1>&2
			exit 2
		fi
		shift 2
		;;
	--)
		shift
		break
		;;
	-?)
		echo $USAGE 1>&2
		exit 2
		;;
	esac
done

if [ $# -lt 1 ] ; then
	echo $USAGE 1>&2
	exit 2
fi

if expr "`id`" : '^uid=0(root)' >/dev/null ; then
	:
else
	echo "$argv0:  ERROR:  you must be root to do this!" 1>&2
	exit 1
fi

# first clean out the msglog file of any Xfail errors and then move
# the queue file back out from the error queue to the primary input
# queue, and run the queue processor for it
#
for argid in ${1+"$@"} ; do
	curqueue=`expr "${argid}" : '[m]*\(.*\)'`
	for spool_dir in ${SPOOL_DIRS} ; do
		if [ -f ${spool_dir}/error/${curqueue} -a ! -f ${spool_dir}/input/${curqueue} ] ; then
			if [ -n "${verbose}" ] ; then
				echo "$argv0: working on ${curqueue}"
			fi
			if $delete ; then
				if [ -n "${verbose}" ] ; then
					echo "$argv0: deleting all remnants of ${curqueue}"
				fi
				rm $interactive ${spool_dir}/error/${curqueue} ${spool_dir}/msglog/${curqueue}
			else
				if [ -f ${spool_dir}/msglog/${curqueue} ] ; then
					if $domailq; then
						mailq -E -v ${curqueue}
					fi
					if $confirm; then
						echo "$argv0: shall we attempt re-delivery of ${curqueue}?"
						read answer junk
						case $answer in
						[Yy]*|[Tt]*|1)
							# OK, we will....
							;;
						*)
							continue
							;;
						esac
					fi
					msglogfn=${spool_dir}/msglog/${curqueue}
					# 
					# Pretend the previous failures had
					# never happened and that the addresses
					# associated with them have not yet
					# been processed by throwing away the
					# existing "fail" entries from the
					# msglog file.
					#
					# msglog entries are "Xtype txtmsg...",
					# optionally followed by an SMTP error
					# message (which can be multi-line)....
					# 
					# There is a theory that says we
					# should keep these messages and just
					# change them into Xdefer's (and tack
					# on a note about this change), which
					# would mean keeping all the SMTP
					# error messages too, which would mean
					# we could more or less just use sed
					# instead.
					#
					awk '
						BEGIN {
							sawxfail=0;
						}
						/^Xfail: / {
							sawxfail=1;
							next;
						}
						/^[0-9][0-9][0-9]\-/ {
							if (!sawxfail)
								print $0;
							next;
						}
						/^[0-9][0-9][0-9] / {
							if (!sawxfail)
								print $0;
							sawxfail=0;
							next;
						}
						{
							sawxfail=0;
							print $0;
						}
					' ${msglogfn} > ${msglogfn}.nofail
					mv ${msglogfn}.nofail ${msglogfn}
				fi
				mv ${spool_dir}/error/${curqueue} ${spool_dir}/input
				if $dorunq; then
					${SMAIL_NAME} ${verbose} -q ${curqueue}
				fi
			fi
			unset curqueue
			break
		elif [ -f ${spool_dir}/input/${curqueue} ] ; then
			echo "$argv0:  ERROR:  ${curqueue} is an active message!" 1>&2
		fi
	done
	if [ -n "${curqueue}" ] ; then
		echo "$argv0:  ERROR:  ${curqueue} was not found!" 1>&2
	fi
done

exit $?
