bstempleton (12/15/82)
At watmath, I, along with Dave Martindale have produced code to allow people who run delivermail to get uucp aliasing and internet addressing with minimal changes to the delivermail source. The following is an explanation of how to add internet mailing and uucp aliasing simply to your delivermail based mail system. There is also source to the required mail handler and an explanation for users. The source to a "uua" program that lets people query the database themselves is included. The code is not complete, but provides a quick and dirty implementation of the new mailing standard. It is meant to serve for the few months before 4.2bsd comes out. This system is simpler because it doesn not involve changing anything in delivermail except for the file "conf.c" which you are supposed to changed. What follows is the source to a program called "netmail" which you should compile and place somewhere. The place we keep it is /usr/lib/mailers/netmail but it may go wherever you like. To run this system you need to have a uucp alias database in DBM format as generated by Steve Bellovin's alias generating program. This program is around in a lot of places and can be found in decvax!~uucp/pathalias.tar among others. To install this system you must: 1) Create an alias database and place it somewhere. The suggested place is /usr/lib/uucp. There is a #define in the source to the internet mailer that gives the location of this database. To get internet addressing to work, you should put in aliases for various domain control sites. For example, to handle the arpa domain you should have an alias for your nearest arpa gateway. I have a line of the form: ucbvax = arpa in mine. You may also wish lines of the form: udel-relay = csnet watmath = wat to define the "csnet" and "wat" domains, the only others I know to exist. If you connect to only one machine, and it already has a database, it is wise (to avoid the hassle of maintaining several databases) to just alias that machine to domain "uucp" and thus any messages for that domain go there for routing. If not we assume you have a map for the whole uucp domain in your own filesystem. 2) Change the appropriate #defines in the netmail.c source and compile it somewhere. Also change the "wat" domain listed there to any local domain you may have. Don't forget to use -ldbm when compiling. Also try -DDEBUG to begin with if you aren't sure your conf.c is right. 3) [The hard part] Go to your delivermail source and change the conf.c file. You must make the following changes. You must be careful that you change the appropriate entries for your sites as conf.c is full of ifdefs for all kins of Berkeley sites. You may want to run cc -E on the file to see which ones are yours, or follow it through. If you actually have an arpanet connection, the process will be somewhat different from what I describe, which is for the typical isolated uucp site. a) Change the entry for the uucp mailer. Currently this will call /bin/mail for you. After the comment that says: "Cheat & use Bell's V7 mail", change the struct entry to: { "/usr/lib/mailers/netmail", M_FOPT|M_STRIPQ, EX_UNAVAILABLE, UucpLocal, { "...net%mail", "-s", "$h", "-u", "$u", NULL } }, And add another mailer immediately after it with /* internet mailer takes user@host.domain syntax */ { "/usr/lib/mailers/netmail", M_FOPT|M_STRIPQ, EX_UNAVAILABLE, UucpLocal, { "...net%mail", "-i", "-s", "$h", "-u", "$u", NULL } }, =========================================== You may wish to change the UucpLocal in the second instance to something else if you have other names in other domains. b) After the line saying "#define M_UUCP 4" add a line with "#define M_INTERNET 5" c) Change your configure table, after the "# else BERKELEY" probably. Since several people and sites will stick the the old "!" syntax, you will want to give it highest priority for the time being. Thus your table order should be something like: "!", "^", '.', "@", "\0" You should note that the internet mailing is keyed on "." while "@" keys uucp mailing (with aliasing) through a different syntax. This is because delivermail will not allow a host name to have a dot in it, and thus you can't have user@host.uucp keyed off of the at-sign. Plain old user@host with no dots is assumed to be uucp mail now. You can of course change that to arpanet mail if you prefer by a simple alteration to the conf.c. Our table looks like this, with #ifdefs to take away the internet code: =========================================== # else BERKELEY struct parsetab ParseTab[] = { # ifdef HASUUCP '^', -1, P_MAP, "!", '!', M_UUCP, P_USR_UPPER, NULL, # endif HASUUCP #ifdef INTERNET '.' M_INTERNET, P_HLAST|P_USR_UPPER, NULL, '@' M_UUCP, P_HLAST|P_USR_UPPER, NULL, #else INTERNET # ifdef HASARPA '@', M_ARPA, P_HLAST|P_USR_UPPER, NULL, # else HASARPA '@', M_UUCP, P_HLAST|P_USR_UPPER|P_MOVE, "decvax!ucbvax", # endif HASARPA #endif INTERNET '\0', M_LOCAL, P_MOVE, "", }; # endif BERKELEY ================================================== d) Compile Delivermail with the new conf.c You are now ready to go! ================================================= Here is a description of the changes for posting as was done at our site. You will need to change local refeences. ==================================================== A new version of delivermail(8) has been installed to aid in the sending of mail to remote computers. There are several new features: .sp An automatic uucp site aliaser allows mail to be sent to other sites that we are not directly connected to as though we had a direct connection. The result of this is that you no longer have to type long uucp path strings for most sites on the net. In a string of the form site!site2!...!user, the new mailer will look "site1" up in a special database to find the way to mail to it. Thus "ucbvax!eric" gets mapped to "decvax!ucbvax!eric". .sp Longer strings work as well, as "uw-beaver!user" becomes "decvax!cornell!uw-beaver!user". The database generally knows the best way to mail to a certain site. You can even mail to other nets. "sri-unix!knutsen" becomes "decvax!ucbvax!knutsen@sri-unix". Not all sites and paths are in the database, so if you know of any special ones you would like put in it, mail to bstempleton with the connection you know of. The current database is built from files found in /usr/lib/uucp/paths. Currently an ascii version of the database can be found in the file /usr/pub/uucpaliases, if you wish to query what path is being used to your site. In certain cases, where there is a rare direct connection to a site that the database doesn't know about, you can force the aliasing to be stopped by using the path "math!yoursite!...". (ie. stick "math!" in front of your path. Normally, however, if you wish to give explicit uucp paths, things should work as they did before. .sp 2 In addition, the new delivermail crudely supports the new proposed internet addressing standard. A description of this standard can be found the the report in /usr/pub/rfc819. Addresses of the from "user@host.domain" are recognized. We are in the "uucp" domain, and you are "yourname@watmath.uucp". You can mail to an arpanet user fbaggins on arpanet site shire with "fbaggins@shire.arpa" You can mail any uucp users with "user@site.uucp". The uucp is not needed if you are mailing a message entirely within the uucp domain. If it goes outside this domain, for example to the arpa domain, then you must put the ".uucp" on the end. Otherwise addresses of the form "mark@cbosgd" and "peterr@utcsrgv" work fine. Currently the domains "uucp", "arpa" and "csnet" are recognized. The same aliaser as the one described above is used. .sp The "net mailing" characters have a priority arranged. That priority is (high to low) "!", '.' and "@". This means that if an "!" is found anywhere in an address it will be sent to the uucp mailer directly without any internet interpretation. This means that if you want what the arpanet sees as "csin!cjh@cca-unix.arpa" you can not type it like this. The "!" will be interpreted first and the "cjh@cca-unix.arpa" will be shipped off to csin by the correct path. To get such a path, try the address: "arpa!csin!cjh@cca-unix" for now. .sp .ce IMPORTANT NOTE .sp This new aliaser may cause problems with replies from other sites. The network is slowly moving over to this new syntax, but not all sites are switched. Many major sites like "cbosg" and "ucbvax" and friends are switched, but others may not be. Due to this, they may have trouble in using the "r" command to reply to your mail. There will never be any problems in the reply to you, just in the replies to additional recipients of your mail. At worst, such replies may be routed through our machine. If you are sending to large lists of people you may wish to worry about this and use explicit routing. Also, the "rmail" program that handles incoming mail has not yet been changed to handle this, so there may be minor problems with incoming mail from the arpanet. These problems will be limited to an inability to reply with the "r" command. This should not bother anybody since this never worked before. If you reply with "r", it will only work if the arpanet site is in our uucp database. Most sites are already in that database, and if you wish to mail to one that is not, send mail and it will be added. To properly reply to user@site, just mail to user@site.arpa and things will be fine. .sp If you don't want your replies to other people running this system to include you, you will need the latest ucb mail and will need to put a command of the form: .ce alternate yourname@yoursite.uucp in the file. Another find undocumented command! ================================================================= Here is the source to the netmail program. ================================================================= /* * Net mailer that handles all uucp and "internet" mail. * With ALIASFILE defined, it tries looking up the destination * machine in a path database, expanding the alias if found. * There is a special kludge to check for the local GCOS site, * which doesn't run uucp but has a special mailer to handle * the mail anyway. */ #include <stdio.h> /* outsiders comment out gcos stuff #define GCOS_SITE "watbun" #define GCOS_LEN sizeof( GCOS_SITE ) #define GCOS_MAILER "/usr/lib/mailers/hmail" */ #define ALIASFILE "/usr/lib/uucp/alpath" #define CALL_NAME "...net%mail" typedef struct { char *dptr; int dsize; } datum; datum fetch(); char *rindex(); char *sprintf(); char *domains[] = { "uucp", "wat", 0 }; main(argc, argv) int argc; char **argv; { char *from = NULL; char *site = NULL; char *user = NULL; char *mailargs[10], **argp, *mailer; char flag; char internet = 0; char *recip, *malloc(); datum newsite; /* dbm entry with new site */ datum key; /* key to look for */ char **dom, *p, *q; int stat, i; #ifndef DEBUG if (strcmp(argv[0], CALL_NAME)) error("Net mailer not called from delivermail\n"); #endif while (--argc > 0) if (**++argv == '-') { if (strcmp(*argv, "-i")==0) { ++internet; } else { flag = argv[0][1]; if (--argc <= 0) error("Missing arg for -%c\n", flag); ++argv; switch (flag) { case 'f': from = *argv; break; case 's': site = *argv; break; case 'u': user = *argv; break; default: error("Bad option %c\n", flag); break; } } } else error("Unflagged string %s\n", *argv); if (site == NULL || user == NULL) error("Missing site or user\n"); argp = &mailargs[1]; if (from != NULL) { *argp++ = "-r"; *argp++ = from; } if (internet) { for (dom = domains; *dom; dom++) if (strcmp(*dom, site)==0) { p = rindex(user, '.'); if ((q=rindex(user, '@')) > p) p = q; if( p ) { *p = 0; /* shorten user */ site = p+1; } else /* No @ or dot, we will thus leave the site at the examined domain and quit */ break; } } #ifdef ALIASFILE /* now do uucp aliasing */ dbminit(ALIASFILE); key.dptr = site; key.dsize = strlen(site) + 1; newsite = fetch(key); if (newsite.dptr) { /* we got an alias */ recip = malloc(newsite.dsize + strlen(user) + 1); sprintf(recip, newsite.dptr, user); } else #endif ALIASFILE { recip = malloc(strlen(site) + strlen(user) + 2); sprintf(recip, "%s!%s", site, user); } /* At this point it would be nice to add code that checked the first character of the recip string to see if it is an or bar, and if so, pass the rest of the string on to the shell. This allows adding new mailers for individual sites without changing any code and gets rid of this GCOS special case below. The problem is that this is a terrible security hole so we leave it out for now. */ #ifdef GCOS_SITE if( strncmp( recip, GCOS_SITE, GCOS_LEN -1 ) == 0 ) { mailer = GCOS_MAILER; mailargs[0] = "...gcos%mail"; *argp++ = recip + GCOS_LEN; } else #endif GCOS_SITE { mailer = "/bin/mail"; mailargs[0] = "...uucp%mail"; *argp++ = "-d"; *argp++ = recip; } switch (fork()) { case -1: error("Could not fork!\n"); case 0: setuid(getuid()); *argp = NULL; #ifdef DEBUG printf( "%s", mailer ); { int i; for( i = 0; mailargs[i]; i++ ) printf( " %s", mailargs[i] ); } exit(0); break; #else DEBUG execv(mailer, mailargs); error("execl of %s failed\n", mailer); #endif DEBUG default: if (wait(&stat) == -1) stat = 1; exit((stat>>8)|stat); } } error(x) char *x; { printf("Net Mailer: %r", &x); exit(1); } ================================================== Here is an database query program ================================================== /* uucp datbase checker */ #define ALIASES "/usr/lib/uucp/alpath" typedef struct { char *dptr; int dsize; } datum; datum fetch(); main(argc, argv) int argc; char **argv; { datum findit, result; int i; dbminit( ALIASES ); for( i = 1; i < argc; i++ ) { findit.dptr = argv[i]; findit.dsize = strlen( argv[i] ) + 1; result = fetch( findit ); if( result.dptr ) printf( result.dptr, "User" ); else printf( "%s : Not found", argv[i] ); putchar( '\n' ); } } ===================================================