#! /bin/sh
:
#ident	"@(#)contrib:RELEASE-3_2_0_114:unfreezemail.sh,v 1.4 2001/08/03 13:33:11 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/local/libexec/smail:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"; export PATH

UTIL_BIN_DIR=/usr/local/libexec/smail

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

SMAIL_NAME="/usr/local/sbin/sendmail"
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 [-i]] [-v[NNN]] message_queue_id [...]"

delete=false
interactive="-f"
verbose=""

set -- `$GETOPT -n $argv0 -q Di:v: ${1+"$@"}`
if [ "$?" -ne 0 ]; then
	echo $USAGE 2>&1
	exit 2
fi
for i in ${1+"$@"} ; do
	case "$i" in
	-D)
		delete=true
		shift
		;;
	-i)
		interactive="-i"
		shift
		;;
	-v)
		if [ "$2" -ne 0 ] ; then
			verbose="-v$2"
		else
			echo $USAGE
			exit 2
		fi
		shift 2
		;;
	--)
		shift
		break
		;;
	esac
done

if [ $# -lt 1 ] ; then
	echo $USAGE
	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 "${curqueue}" : '[m]*\(.*\)')
	for spool_dir in ${SPOOL_DIRS} ; do
		if [ -f ${spool_dir}/error/${curque} -a ! -f ${spool_dir}/input/${curque} ] ; then
			if [ -n "${verbose}" ] ; then
				echo "$argv0: working on ${curque}"
			fi
			if $delete ; then
				rm $interactive ${spool_dir}/error/${curque} ${spool_dir}/msglog/${curque}
			else
				if [ -f ${spool_dir}/msglog/${curque} ] ; then
					msglogfn=${spool_dir}/msglog/${curque}
					# 
					# 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/${curque} ${spool_dir}/input
				${SMAIL_NAME} ${verbose} -q ${curque}
			fi
			unset curque
			break
		elif [ -f ${spool_dir}/input/${curque} ] ; then
			echo "$argv0:  ERROR:  ${curque} is an active message!" 1>&2
		fi
	done
	if [ -n "${curque}" ] ; then
		echo "$argv0:  ERROR:  ${curque} was not found!" 1>&2
	fi
done

exit $?
