From: utzoo!watmath!watcgl!dmmartindale
Newsgroups: net.unix-wizards
Title: Re: Bugs in 4.1bsd mailers
Article-I.D.: watcgl.95
Posted: Tue Jan  4 13:58:15 1983
Received: Wed Jan  5 00:28:37 1983
References: uw-beave.273

Several comments about uw-beaver!jim's suggestions on how to handle
errors in /bin/mail:
Do NOT change /bin/mail to do "exit(pclose(rmf) >> 8);"
If uux dies from any sort of signal, this fact is indicated by the lower
8 bits of the return status and the upper 8 bits are zero, and you DON'T
want to indicate normal exit in this case.  The switch statement he
suggested is much better.  Unfortunately, it still won't return the proper
exit code to delivermail, since this exit is from a forked child of /bin/mail,
and is waited for by the parent who only checks the status against zero
(look at the wait() not far above the exit()).  Considerably more work would
be required to have the parent pass back the child's exit status.  Part of
the problem is that /bin/mail is written to handle multiple recipients so it
can't pass back a return code indicating what happened for each of them,
but delivermail makes one call of the deliverer for each recipient and wants
a meaningful code back.  Anyway, I'm currently running code which does:

	exit(pclose(rmf) != 0);

This at least causes delivermail to save a copy of the letter or mail
it back, whichever is appropriate.
While you're attacking /bin/mail, you should also wrap a "#ifndef DELIVERMAIL"
around the code which saves mail in dead.letter, as:

#ifndef DELIVERMAIL
	if (error) {
		setuid(getuid());
		malf = fopen(dead, "w");
		if (malf == NULL) {
			fprintf(stdout, "mail: cannot open %s\n", dead);
			fclose(tmpf);
			return;
		}
		copylet(0, malf, ZAP);
		fclose(malf);
		fprintf(stdout, "Mail saved in %s\n", dead);
	}
#endif

This allows delivermail to handle undeliverable mail, since it's cleverer
about what to do with it.  Once you've fixed mail to return the result
of pclose() properly you will sometimes get two copies of a letter saved in
dead.letter (for local mail) because both /bin/mail and delivermail save it.
Also, /bin/mail has always tried to save a copy of the letter in
/usr/spool/uucp, or somewhere similar, when incoming remote mail fails - this
is silly.  Much better to just return an exit status and let delivermail
worry about what to do with the error - it knows how to mail it back.

I suspect /bin/mail is sloppy because Eric didn't write it - it looks
like standard v7 mail hacked up a bit.

	Dave Martindale