[alt.sources] Rerouting spooled UUCP mail

gam@netcom.UUCP (Gordon Moffett) (11/27/90)

My query for a shell script to respool UUCP mail for a site gone dead
had gotten a few responses, but all refering to Lenny Tropiano's
"uureroute.c" posted recently, which expected *you* to provide the new
path names, *you* to provide the UUCP job names, etc ....  A computer
should be expected to do better than that :-)!

I had sent a copy of this shell script I was speaking of to our
neighbor, amdahl, when I had originally gotten it, and got it back from
them -- here it is.  You just recalculate your pathalias database, run
this shell script for a given site, and see the mail get rerouted to
new paths.  The usage is quite simple:  "reroute <sitename>", like
"reroute claris" or whatever.  It expects to be run by 'root', and uses
the id(1) program to determine that.

I call it "reroute" the author called it "nukeq", you can name it
whatever you like.

Here is the author's original message.  Note the caveats!  But I have used it
several times and it works beautifully.  (There was a bug in the reference
to the $user environment variable which is fixed here).

When he talks about "smail" he is refering to smail 2.5.  But I have
used it with smail 3.1 without any problems.  Smail 3.1 appears to ignore
the -R flag, perhaps it should be taken out if you're running 3.1

Subject: Re: Rerouting spooled UUCP mail?
Date: 11 Jan 90 20:18:08 EST (Thu)
From: uunet!wang.COM!fitz (Tom Fitzgerald)

> I need a tool to take UUCP jobs queued up for one site (which is dead)
> and move them to another site's UUCP queue.

Here's what I use.  It makes some assumptions:

- You're using HDB.  If not, you'll have to screw with the filename
  pattern matching and directories.

- You're using SMAIL.  If not, you'll have to have some other mailer that
  accepts header lines in the message without modifying them, and you'll
  have to find some way of simulating SMAIL's -R (aggressive-rerouting)
  option.

- You've already rebuilt the 'paths' file so that the dead node is missing
  from all paths.

- You're logged in as root (needless to say).

It's also got these flaky aspects:

- It's dangerous as hell.  I wrote it, and it scares me.  Save a copy
  of all mail, and make sure the result is what you wanted before you
  let a uucico start up.

- If any mail is queued for a user on the dead system (or for a user
  that can _only_ be reached via the dead system) it will not be rerouted.

- Results in a doubled "Recieved:" line in the header.

- More flakinesses are mentioned in the script itself.

If you haven't given up yet, here it is.  Good luck.

-----------------------------------------------------------------------------
# Remail all of the mail queued for a particular system.  Run as
#
# nukeq <sysname>
#
# Does nothing unless the paths files have been rebuilt so that all
# final destinations in the mail messages are now reached through a
# different neighbor.  Otherwise mail will just be requeued for the
# same system again.
#
# Doesn't fix the requestor field in the new X file, so errors in mailing
# further along the line will probably be returned to the person who ran
# nukeq rather then the person who originally sent the mail.
#
# The destinations are aggressively rerouted on the assumption that the
# old path is irrelevant to the new first-hop.  This may result in mail
# sent to an incorrect system with the same name as the correct system.
#
# If uucico starts up while this thing is running, the world will come
# to an end.


if [ `id|sed 's/^uid=\([0-9]*\).*$/\1/'` -ne 0 ]
then
	echo Not superuser, no can do.
	exit
fi

if [ $# -ne 1 ]
then
	echo Need a system name
	exit
fi

sysname=$1

cd /usr/spool/uucp/$sysname

for cfile in C.*
do
	(
		echo Doing C-file $cfile

		# For each C-file
		# Grab the line describing the D file

		read type source dest sender opts data mode notify || {
			echo $cfile is empty, skipping...
			continue
		}

		if [ "$type" != "S" -o "$source" != "$data" \
		  -o "$sender" != "$notify" -o "$opts" != "-" ]
		then
			echo $cfile has invalid line 1, skipping...
			continue
		fi

		case $dest in
			D.*)	;;
			*)	echo $cfile line 1 isn\'t a Dfile, skipping...
				continue
				;;
		esac

		dfile=$source
		echo D-file is $dfile

		# Grab the line describing the X file
		read type source dest sender opts data mode notify || {
			echo $cfile missing line 2, skipping...
			continue
		}

		if [ "$type" != "S" -o "$source" != "$data" \
		  -o "$sender" != "$notify" -o "$opts" != "-" ]
		then
			echo $cfile has invalid line 2, skipping...
			continue
		fi

		case $dest in
			X.*)	;;
			*)	echo $cfile line 2 isn\'t an Xfile, skipping...
				continue
				;;
		esac

		xfile=$source
		echo X-file is $xfile

		# Make sure the X-file was the last line in the C-file
		read type
		if [ -n "$type" ]
		then
			echo $cfile has more than 2 lines, skipping...
			continue
		fi

		# Read the xfile looking for the destinations
		dests=`egrep '^C rmail ' < $xfile | sed 's/^C rmail //'`

		if [ `echo $dests | wc -w` -eq 0 ]
		then
			echo $cfile isn\'t an rmail job, skipping...
			continue
		fi

		# Build newdests, which is the same as dests for users on
		# machines other than the one being nuked, and is $sysname!user
		# for users on the same system (this will result in mail being
		# queued back onto the same system again).

		newdests=''
		for user in $dests
		do
			if [ -n "`echo $user | grep !`" ]
			then
				newdests="$newdests $user"
			else
				newdests="$newdests $sysname!$user"
			fi
		done

#		echo Rerouting to $newdests

		# Re-send the mail, using aggressive rerouting
		smail -R -v $newdests < $dfile

		# And kill off the old message
		rm $cfile $dfile $xfile
		echo Done
	) < $cfile
done
exit