[comp.mail.uucp] Rewriting rules

mcvoy@uwvax.UUCP (02/24/87)

Hi-
    I've written some software that I'm about to farm out to a couple
of people that don't want to deal with sendmail/smail/uumail/whatever.
All it does is allow you to specify where domainified/unknown mail
should go for further rerouting, in other words it allows you to punt
mail to a smart site.

    Here's the problem and question:  the software has two forms

	route(addr) & rroute(addr)

Route understands !'s and @'s, rroute deals with those and %'s.  Rroute is
intended for use as help to rmail, route as help to mail[x].  The rules
I'm using are

    [R]route:
	1) If the address contains a bang(!), don't touch.
	2) If the address contains an @, try to rewrite.

    Rroute only:
	3) If 1 & 2 fail, and there is a %, change the rightmost % to an @.
    
Rroute is just a stub that applies rule three (if needed) and then passes 
the address to route.  The rule that is questionable is rule #3.  I need to
know if that is acceptable to most sites that pass mail.

The rewriting is done via a tempalte, so it's changeable on a per site basis,
but rule #3 is hard coded.

Please respond to the net.
-- 
Larry McVoy 	        mcvoy@rsch.wisc.edu, 
      		        {seismo, topaz, harvard, ihnp4, etc}!uwvax!mcvoy

"They're coming soon!  Quad-stated guru-gates!"

bbanerje@sju.UUCP (02/25/87)

mcvoy@rsch.WISC.EDU (Lawrence W. McVoy) writes in Article <3261@rsch.WISC.EDU>

>> 	[ Some stuff deleted ]
>>     Here's the problem and question:  the software has two forms
>> 	[ Here also ]
>> 
>>     [R]route:
>> 	1) If the address contains a bang(!), don't touch.
>> 	2) If the address contains an @, try to rewrite.
>> 
>>     Rroute only:
>> 	3) If 1 & 2 fail, and there is a %, change the rightmost % to an @.
>> Rroute is just a stub that applies rule three (if needed) and then
>> passes the address to route.  The rule that is questionable is rule
>> #3.  I need to know if that is acceptable to most sites that pass
>> mail.

This isn't entirely relevant to his question, but one of the
things that bugged me about smail is that it doesn't handle the
'%' stuff.  Eg. steve%gvlv1@burdvax where gvlv1 isn't in the
map becomes 'burdvax!steve%gvlv1'.  This looks a lot like an ugly
mixed mode address to me.  Because of this (and also route addresses
and the like), I wrote a little program which sits between sendmail
and smail, and does some preliminary rewriting of addresses first.

It's small enough to be included in it's entirety, so here it is:
================== This is not a shell script ============
/*
 * This routine will rewrite an address given in RFC822/976
 * into uucp format.  The rewriting is done in-situ.
 *
 *	Compile with:
 *		cc -DSTANDALONE uucppaddress.c -lstrings -ldbug
 *	in order to test.
 *	If you want to use the dbug library trace facilities,
 *	then you must undefine DBUG_OFF
 *
 * If NO_NAME_XLATE is defined, this entire file will compile to
 * nothing.
 *
 *	Binayak Banerjee
 *	St. Joseph's University
 *	bbanerje@sjuvax.uucp	UUCP
 *	bbanerje@sju.edu	CSNET
 *	August 19, 1986.
 */

# ifndef NO_NAME_XLATE

# define DBUG_OFF	/* No tracing overhead */

# define Nil(Typ)	((Typ *)0)
# ifdef DBUG_OFF
#	 define DBUG_ENTER(X)
#	 define DBUG_RETURN(X)	return(X)
#	 define DBUG_PRINT(X,Y)
#	 define DBUG_PUSH(X)
#	 define DBUG_PROCESS(X)
# else
# include <local/dbug.h>
# endif

# include <stdio.h>
# include <strings.h>

/*
 * Returns a pointer to the trailing null in a string.
 */

static char *
strend(s)
register char *s;
{
	DBUG_ENTER("strend");
	while (*s) s++;
	DBUG_RETURN(s);
}

/*
 * Like strcat, but returns trailing null on dest. string
 */

static char *
strmov(dest,src)
register char *dest;
register char *src;
{
	DBUG_ENTER("strmov");
	while (*dest++ = *src++)
		;
	DBUG_RETURN(--dest);
}

char *
do_address(s)
char *s;
{
	char *x_route(),*x_address();
	char *ret;

	DBUG_ENTER("do_address");

	DBUG_PRINT("do_address",("s - %s",s));
	if (index(s,':'))	/* Route Address */
		ret = x_route(s,s);
	else if (index(s,'!'))	/* Uucp */
	 {
		if ((ret = index(s,'@')) || (ret = index(s,'%')) )
		 {
			register char *temp;

			for (temp = ret; *temp != '!'; temp--)
				;
			temp++;
			DBUG_PRINT("uu_address",("temp - %s",temp));
			DBUG_PRINT("uu_address",("ret - %s",ret));
			ret = x_address(temp,temp);
		 }
		else
			ret = strend(ret);
	 }
	else if (index(s,'@'))	/* RFC 822 */
		ret = x_address(s,s);
	else
		ret = x_address(s,s);		/* local-part only */
	
	DBUG_PRINT("do_address",("ret - %s",s));
	DBUG_RETURN(ret);
}

/*
 * X_route(src,dest) - translate a route address in src to dest.
 * src and dest can overlap.
 *
 * A route address is an address of the form
 *	@domain1,@domain2,@domain3:user@domain
 * This is translated to an address of the form:
 *	domain1!domain2!domain3!domain!user
 *
 */

static char *
x_route(src,dest)
char *src,*dest;
{
	char buf[BUFSIZ];
	char *temp;
	register char *x,*y;
	register char *t = &buf[0];
	char *x_domain(),*x_address();

	DBUG_ENTER("x_route");
	DBUG_PRINT("x_route",("src - %s",src));

	temp = index(src,':'); *temp = '\0';
	for (x = src;(y = index(x,',')) != Nil(char);x = ++y)
	 {
		*y = '\0';
		t = x_domain(x,t);
	 }
	
	t = x_domain(x,t);
	x_address(++temp,t);
	t = strmov(dest,buf);
	DBUG_PRINT("x_route",("dest - %s",dest));
	DBUG_RETURN(t);
}

/*
 * X_address(src,dest) - translate an RFC address into uucp form.
 * An address is of the form
 *
 *	local-part@domain.  This is translated into -
 *	domain!local-part
 *
 *	In the event that there is only a local-part, this will 
 * 	still work.
 */

static char *
x_address(src,dest)
char *src,*dest;
{
	char buf[BUFSIZ];
	char *temp;
	register char *x,*y;
	register char *t = &buf[0];
	char *x_local(),*x_domain();

	DBUG_ENTER("x_address");
	DBUG_PRINT("x_address",("src - %s",src));

	if (temp = index(src,'@'))
	 {
		t = x_domain(temp,t); *temp = '\0';
		t = x_local(src,t);   *temp = '@';
	 }
	else
		t = x_local(src,t);

	t = strmov(dest,buf);
	DBUG_PRINT("x_address",("dest - %s",dest));
	DBUG_RETURN(t);
}

/*
 * X_domain(src,dest) - translates an @domain specification in
 * an RFC address to uucp format (domain!).
 */

static char *
x_domain(src,dest)
char *src,*dest;
{
	char buf[BUFSIZ];
	register char *t = src;
	register char *s;
  
	DBUG_ENTER("x_domain");
	DBUG_PRINT("x_domain",("src - %s",src));

	s = &buf[0];
	if (*t != '@')
  		DBUG_RETURN(Nil(char));
  
	for (s--;*++s = *++t;)
		;

	*s++ = '!'; *s = '\0';
	t = strmov(dest,buf);
	DBUG_PRINT("x_domain",("dest - %s",dest));
	DBUG_RETURN(t);
}

/*
 * X_local(src,dest) - translates the local part of an RFC address
 * to uucp format.
 *
 * The local part is either a user name (such as foo), or an
 * RFC format address of the form foo%domain.  In such a case,
 * foo might again be another such address.
 */

static char *
x_local(src,dest)
char *src,*dest;
{
	register char *t;
	register char *ret;

	DBUG_ENTER("x_local");
	DBUG_PRINT("x_local",("src - %s",src));

	if ((t = rindex(src,'%')) == Nil(char))
	 {
		ret = strmov(dest,src);
		DBUG_PRINT("x_local",("dest - %s",dest));
		DBUG_RETURN(ret);
	 }
	
	/*
	 * Recursive, so make the rightmost % into an @ and try again
	 */
	
	*t = '@';

	ret = x_address(src,dest);
	DBUG_PRINT("x_local",("dest - %s",dest));
	DBUG_RETURN(ret);
}

# if( defined(STANDALONE))

char *my_name;

# define usage() fprintf(stderr,"Usage: %s\n",my_name)

main(argc, argv, environ)
int argc;
char *argv[], *environ[];
{
	extern int optind, getopt();
	extern char *optarg;
	register int c;
	char inbuf[BUFSIZ];
	int 	badflg;

	while ((c = getopt(argc,argv,"#:")) != EOF)
	 {
		switch (c)
		 {
			case '#': /* Debugging Macro enable */
				DBUG_PUSH(optarg);
				break;
			default:
				badflg++;
				break;
		 }
	 }
	
	if (badflg)
	 {
		usage();
	 }

	printf("Address : ");
	while (gets(inbuf) != NULL)
	 {

		do_address(inbuf);
		printf("Uucp corresponding: %s\n\n",inbuf);
		printf("Address: ");
	 }
	
	exit(0);
}
# endif
# endif

avolio@decuac.UUCP (02/27/87)

In article <587@sjuvax.sju.UUCP>, bbanerje@sju.UUCP (B. Banerjee) writes:
> This isn't entirely relevant to his question, but one of the
> things that bugged me about smail is that it doesn't handle the
> '%' stuff.  Eg. steve%gvlv1@burdvax where gvlv1 isn't in the
> map becomes 'burdvax!steve%gvlv1'.  This looks a lot like an ugly
> mixed mode address to me.  Because of this (and also route addresses
> and the like), I wrote a little program which sits between sendmail
> and smail, and does some preliminary rewriting of addresses first.

But it *does* handle it.  Since it has no idea what '%' will mean to
burdvax, in your example, it passes it as is to burdvax.  There are
many systems that will choke if they get a "uucp" address for s system
that is not connected to them via UUCP.  In other words, they "know"
to change "local address" u%something to u@something before trying it,
but might not change something!user to user@soemthing.  In other
words, I believe that your transformation is incorrect.

Since in most cases % has a lower priority than ! or @ (and ! should
be lower than @, but that's another story), what smail does seems
correct to me and replaceing a % with a ! certainly seems wrong.  

Fred.