[net.unix-wizards] Losing less mail down the black hole of uucp

rick@seismo.UUCP (Rick Adams) (08/18/84)

As you probably are aware, much of the uucp mail that fails to
reach its destination is never seen again. Most of this
goes to whoever started the uucico on the machine previous to the
one one which it failed.

For example, if someone at "cvl" sent mail to "ut-sally", they would
use the path "umcp-cs!seismo!ut-sally!whoever". In most cases,
if whoever did not exist on ut-sally, an error message would
be returned to "seismo!uucp", which is not exactly what you would
want to happen.

sendmail partly solves this problem, by returning the failed message
to the originator of the message instead of who handed it to sendmail.

Honey DanBer attacks this problem at the uux/uuxqt level where it is
screwing up in the first place. The method is fairly simple. It just
specifies a return address to be used for error messages.

By a few simple modifications to uux.c, uuxqt.c and whatever program
your rmail command hands mail to, you can help these poor orphaned
error messages return to their rightful masters.


Basically, when you exec "uux" to run the rmail you give it the
return address for errors in addition to the destination.

If you were running sendmail, you would change the uux invocation
in /usr/lib/sendmail.cf from:
	Muucp, P=/usr/bin/uux, F=sDFMhuU, S=13, R=23, M=100000,
		A=uux - -r $h!rmail ($u)
to
	Muucp, P=/usr/bin/uux, F=sDFMhuU, S=13, R=23, M=100000,
		A=uux - -r -a$f $h!rmail ($u)

The -a flag to uux says to use this as the return address for errors.
It causes uux to put an extra line in the X. file that uuxqt
interprets as a return address. The "$f" is sendmail's idea
of who originated the mail.

The changes for whatever other mail delivery system would be similar.

This has drastically reduced the amount of mail that seismo!uucp gets
since we put it in.

So, if you're not running Honey DanBer, you'd do the uucp world a
big favor by installing the folowing modifications. (Even if
you don't generate the return address for your outgoing traffic,
at least make the mods to uuxqt so that it uses the
return address that someone else provided.).

To the file uucp.h, add the following line:

#define X_RETURNTO	'R'

Following is a diff -c of uux.c:

*** uux.c.old	Fri Aug 17 14:36:05 1984
--- uux.c	Fri Aug 17 14:36:07 1984
***************
*** 61,66
  	char redir = '\0';
  	int nonoti = 0;
  	int nonzero = 0;
  	extern int LocalOnly;
  
  	strcpy(Progname, "uux");

--- 61,67 -----
  	char redir = '\0';
  	int nonoti = 0;
  	int nonzero = 0;
+ 	char *ReturnTo = NULL;
  	extern int LocalOnly;
  
  	strcpy(Progname, "uux");
***************
*** 99,104
  		case 'L':
  			LocalOnly++;
  			break;
  		default:
  			fprintf(stderr, "unknown flag %s\n", argv[1]);
  				break;

--- 100,108 -----
  		case 'L':
  			LocalOnly++;
  			break;
+ 		case 'a':
+ 			ReturnTo = &argv[1][2];
+ 			break;
  		default:
  			fprintf(stderr, "unknown flag %s\n", argv[1]);
  				break;
***************
*** 139,144
  		fprintf(fprx, "%c\n", X_NONOTI);
  	if (nonzero)
  		fprintf(fprx, "%c\n", X_NONZERO);
  
  	/* find remote system name */
  	ap = inargs;

--- 143,151 -----
  		fprintf(fprx, "%c\n", X_NONOTI);
  	if (nonzero)
  		fprintf(fprx, "%c\n", X_NONZERO);
+ 	if (ReturnTo == NULL || *ReturnTo == '\0')
+ 		ReturnTo = User;
+ 	fprintf(fprx, "%c %s\n", X_RETURNTO, ReturnTo);
  
  	/* find remote system name */
  	ap = inargs;

Following is a diff -c of uuxqt.c. The changes aren't really
as big as they look. Most of then are just changing "notify(user,"
to "notify(ReturnTo,".

*** uuxqt.c.old	Fri Aug 17 14:33:43 1984
--- uuxqt.c.	Fri Aug 17 14:33:46 1984
***************
*** 35,40
  int nonzero = 0;
  
  char PATH[MAXFULLNAME] = "PATH=/bin:/usr/bin";
  /*  to remove restrictions from uuxqt
   *  define ALLOK 1
   *

--- 35,41 -----
  int nonzero = 0;
  
  char PATH[MAXFULLNAME] = "PATH=/bin:/usr/bin";
+ char ReturnTo[MAXFULLNAME];
  /*  to remove restrictions from uuxqt
   *  define ALLOK 1
   *
***************
*** 156,162
  		while (fgets(buf, BUFSIZ, xfp) != NULL) {
  			switch (buf[0]) {
  			case X_USER:
! 				sscanf(&buf[1], "%s%s", user, Rmtname);
  				break;
  			case X_STDIN:
  				sscanf(&buf[1], "%s", fin);

--- 157,165 -----
  		while (fgets(buf, BUFSIZ, xfp) != NULL) {
  			switch (buf[0]) {
  			case X_USER:
! 				sscanf(&buf[1], "%s %s", user, Rmtname);
! 				if (ReturnTo[0] == '\0')
! 					strcpy(ReturnTo, user);
  				break;
  			case X_RETURNTO:
  				sscanf(&buf[1], "%s", ReturnTo);
***************
*** 158,163
  			case X_USER:
  				sscanf(&buf[1], "%s%s", user, Rmtname);
  				break;
  			case X_STDIN:
  				sscanf(&buf[1], "%s", fin);
  				i = expfile(fin);

--- 161,169 -----
  				if (ReturnTo[0] == '\0')
  					strcpy(ReturnTo, user);
  				break;
+ 			case X_RETURNTO:
+ 				sscanf(&buf[1], "%s", ReturnTo);
+ 				break;
  			case X_STDIN:
  				sscanf(&buf[1], "%s", fin);
  				i = expfile(fin);
***************
*** 238,244
  			sprintf(lbuf, "%s XQT DENIED", user);
  			logent(cmd, lbuf);
  			DEBUG(4, "bad command %s\n", prm);
! 			notify(user, Rmtname, cmd, "DENIED");
  			goto rmfiles;
  		}
  		sprintf(lbuf, "%s XQT", user);

--- 244,250 -----
  			sprintf(lbuf, "%s XQT DENIED", user);
  			logent(cmd, lbuf);
  			DEBUG(4, "bad command %s\n", prm);
! 			notify(ReturnTo, Rmtname, cmd, "DENIED");
  			goto rmfiles;
  		}
  		sprintf(lbuf, "%s XQT", user);
***************
*** 259,265
  		notiflg = chknotify(xcmd);
  		if (notiok && notiflg != NT_NO &&
  		   (ret != 0 || (!nonzero && notiflg == NT_YES)))
! 			notify(user, Rmtname, cmd, retstat);
  		else if (ret != 0 && strcmp(xcmd, "rmail") == SAME) {
  			/* mail failed - return letter to sender  */
  			if (!nonzero)

--- 265,271 -----
  		notiflg = chknotify(xcmd);
  		if (notiok && notiflg != NT_NO &&
  		   (ret != 0 || (!nonzero && notiflg == NT_YES)))
! 			notify(ReturnTo, Rmtname, cmd, retstat);
  		else if (ret != 0 && strcmp(xcmd, "rmail") == SAME) {
  			/* mail failed - return letter to sender  */
  			if (!nonzero)
***************
*** 263,270
  		else if (ret != 0 && strcmp(xcmd, "rmail") == SAME) {
  			/* mail failed - return letter to sender  */
  			if (!nonzero)
! 				retosndr(user, Rmtname, fin);
! 			sprintf(buf, "ret (%o) from %s!%s", ret, Rmtname, user);
  			logent("MAIL FAIL", buf);
  		}
  		DEBUG(4, "exit cmd - %d\n", ret);

--- 269,276 -----
  		else if (ret != 0 && strcmp(xcmd, "rmail") == SAME) {
  			/* mail failed - return letter to sender  */
  			if (!nonzero)
! 				retosndr(ReturnTo, Rmtname, fin);
! 			sprintf(buf, "ret (%o) from %s!%s", ret, Rmtname, ReturnTo);
  			logent("MAIL FAIL", buf);
  		}
  		DEBUG(4, "exit cmd - %d\n", ret);

---rick