Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watnot!watmath!clyde!rutgers!cbmvax!bpa!sju!bbanerje From: bbanerje@sju.UUCP Newsgroups: comp.mail.uucp Subject: Re: Rewriting rules (folklore) Message-ID: <587@sjuvax.sju.UUCP> Date: Wed, 25-Feb-87 12:45:14 EST Article-I.D.: sjuvax.587 Posted: Wed Feb 25 12:45:14 1987 Date-Received: Sat, 28-Feb-87 06:24:15 EST References: <3261@rsch.WISC.EDU> Reply-To: bbanerje@sjuvax.UUCP (B. Banerjee) Distribution: comp Organization: St. Joseph's Univ., Phila. PA Lines: 318 Keywords: uucp, rewriting-rules Summary: Here's something 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 # endif # include # include /* * 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