[alt.sources] Anonymous Contact Service software v1.1, Part06/08

csu@alembic.acs.com (Dave Mack) (07/16/90)

This is the second distribution of the Anonymous Contact Service
software. The distribution consists of 8 shar files. This will
(hopefully) be the last full distribution of the system - all
future versions will be distributed as patches. The patchlevel of
this version is 1.

The ACS software provides a mechanism for posting anonymous articles,
for receiving replies to those articles which are also anonymous, and
permits prolonged anonymous conversations in which neither writer knows
the other's actual e-mail address.

This software is currently being used to provide an anonymous personals
service in alt.personals.

Dave Mack
csu@alembic.ACS.COM

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 6 (of 8)."
# Contents:  mailer/alias.c mailer/defs.h mailer/smail.8
# Wrapped by csu@alembic on Sun Jul 15 12:46:52 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'mailer/alias.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mailer/alias.c'\"
else
echo shar: Extracting \"'mailer/alias.c'\" \(11011 characters\)
sed "s/^X//" >'mailer/alias.c' <<'END_OF_FILE'
X#ifndef lint
Xstatic char *sccsid = "@(#)alias.c	2.5 (smail) 9/15/87";
X#endif
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <pwd.h>
X#include "defs.h"
X#include <ctype.h>
X
Xextern enum edebug debug;	/* verbose and debug modes		*/
Xextern char hostdomain[];
Xextern char hostname[];
Xextern char *aliasfile;
X
X/*
X**
X** Picture of the alias graph structure
X**
X**	head
X**       |
X**       v
X**	maps -> mark -> gjm -> mel -> NNULL
X**       |
X**       v
X**	sys ->  root -> ron -> NNULL
X**       |
X**       v
X**	root -> mark -> chris -> lda -> NNULL
X**       |
X**       v
X**      NNULL
X*/
X
Xtypedef struct alias_node node;
X
Xstatic struct alias_node {
X	char *string;
X	node *horz;
X	node *vert;
X};
X
X#ifndef SENDMAIL
Xstatic node aliases = {"", 0, 0}; /* this is the 'dummy header' */
X#endif /* not SENDMAIL */
X
X/*
X** lint free forms of NULL
X*/
X
X#define NNULL	((node   *) 0)
X#define CNULL	('\0')
X
X/*
X** string parsing macros
X*/
X#define SKIPWORD(Z)  while(*Z!=' ' && *Z!='\t' && *Z!='\n' && *Z!=',') Z++;
X#define SKIPSPACE(Z) while(*Z==' ' || *Z=='\t' || *Z=='\n' || *Z==',') Z++;
X
Xstatic int nargc = 0;
Xstatic char *nargv[MAXARGS];
X
Xvoid	add_horz();
Xvoid	load_alias(), strip_comments();
Xint	recipients();
Xnode	*pop();
X#ifndef SENDMAIL
Xnode	*v_search(), *h_search();
Xchar	*tilde();
X#endif	/* not SENDMAIL */
X
X/* our horizontal linked list looks like a stack */
X#define push		add_horz
X
X#define escape(s)	((*s != '\\') ? (s) : (s+1))
X
Xchar **
Xalias(pargc, argv)
Xint *pargc;
Xchar **argv;
X{
X/*
X**  alias the addresses
X*/
X	int	i;
X	char	domain[SMLBUF], ubuf[SMLBUF], *user;
X	node	*addr, addrstk;
X	node	*flist,  fliststk, *u;
X
X#ifndef SENDMAIL
X	FILE	*fp;
X	node	*a;
X	char	*home, buf[SMLBUF];
X	int	aliased;
X	struct	stat st;
X#endif /* not SENDMAIL */
X
X#ifdef FULLNAME
X	char *res_fname();	/* Does fullname processing */
X#endif
X
X	addr  = &addrstk;
X	flist = &fliststk;
X	user  = ubuf;
X
X	addr->horz = NNULL;
X	flist->horz  = NNULL;
X
X	/*
X	** push all of the addresses onto a stack
X	*/
X	for(i=0; i < *pargc; i++) {
X		push(addr, argv[i]);
X	}
X
X	/*
X	** for each adress, check for included files, aliases,
X	** full name mapping, and .forward files
X	*/
X
X	while((nargc < MAXARGS) && ((u = pop(addr)) != NNULL)) {
X#ifndef SENDMAIL
X		if(strncmpic(u->string, ":include:", 9) == 0) {
X			/*
X			** make sure it's a full path name
X			** don't allow multiple sourcing
X			** of a given include file
X			*/
X			char *p = u->string + 9;
X
X			if((*p == '/')
X			&& (h_search(flist, p) == NULL)) {
X				push(flist, p);
X				if((stat(p, &st) >= 0)
X				&&((st.st_mode & S_IFMT) == S_IFREG)
X				&&((fp = fopen(p, "r")) != NULL)) {
X					while(fgets(buf, sizeof buf, fp)) {
X						(void) recipients(addr, buf);
X					}
X					(void) fclose(fp);
X				}
X			}
X			continue;
X		}
X#endif /* not SENDMAIL */
X		/*
X		** parse the arg to see if it's to be aliased
X		*/
X
X		if(islocal(u->string, domain, ubuf) == 0) {
X			goto aliasing_complete;
X		}
X
X		/*
X		** local form - try to alias user
X		** aliases file takes precedence over ~user/.forward
X		** since that's the way that sendmail does it.
X		*/
X
X#ifdef LOWERLOGNAME
X		/* squish 'user' into lower case */
X		for(user = ubuf; *user ; user++) {
X			*user = lower(*user);
X		}
X#endif
X		user = escape(ubuf);
X
X		(void) strcpy(u->string, user);	/* local => elide domain */
X#ifndef SENDMAIL
X		/*
X		** check for alias - all this complication is necessary
X		** to handle perverted aliases like these:
X		** # mail to 's' resolves to 't' 'm' and 'rmt!j'
X		** s	t,g,j,m
X		** g	j,m
X		** j	rmt!j
X		** # mail to 'a' resolves to 'rmt!d'
X		** a	b c
X		** b	c
X		** c	rmt!d
X		** # mail to x resolves to 'x'
X		** x	local!x
X		** # mail to 'y' resolves to 'y' and 'z'
X		** y	\y z
X		*/
X		if(((a = v_search(user)) != NNULL)) {
X			char dtmpb[SMLBUF], utmpb[SMLBUF], *ut;
X			int user_inalias = 0;
X			node *t = a;
X
X			for(a = a->horz; a != NNULL; a=a->horz) {
X				if(islocal(a->string, dtmpb, utmpb)) {
X#ifdef LOWERLOGNAME
X					/* squish 'utmpb' into lower case */
X					for(ut = utmpb; *ut ; ut++) {
X						*ut = lower(*ut);
X					}
X#endif
X
X					ut = escape(utmpb);
X#ifdef CASEALIAS
X					if(strcmp(ut, user) == 0)
X#else
X					if(strcmpic(ut, user) == 0)
X#endif
X					{
X						user_inalias = 1;
X					} else {
X						push(addr, a->string);
X					}
X				} else {
X					push(addr, a->string);
X				}
X			}
X			t->horz = NNULL; /* truncate horz list of aliases */
X			if(user_inalias == 0) {
X				continue;
X			}
X		}
X
X		if((home = tilde(user)) != NULL) {
X			/* don't allow multiple sourcing
X			** of a given .forward file
X			*/
X
X			if((h_search(flist, home) != NULL)) {
X				continue;
X			}
X			push(flist, home);
X
X			/*
X			** check for ~user/.forward file
X			** must be a regular, readable file
X			*/
X
X			(void) sprintf(buf, "%s/%s", home, ".forward");
X			if((stat(buf, &st) >= 0)
X			&&((st.st_mode & S_IFMT) == S_IFREG)
X			&&((st.st_mode & 0444)   == 0444)
X			&&((fp = fopen(buf, "r")) != NULL)) {
X				aliased = 0;
X				while(fgets(buf, sizeof buf, fp)) {
X					aliased |= recipients(addr, buf);
X				}
X				(void) fclose(fp);
X				if(aliased) {
X					continue;
X				}
X			}
X		}
X#endif /* not SENDMAIL */
X
X#ifdef FULLNAME
X		/*
X		** Do possible fullname substitution.
X		*/
X#ifdef DOT_REQD
X		if (index(user, '.') != NULL)
X#endif
X		{
X			static char t_dom[SMLBUF], t_unam[SMLBUF];
X			char *t_user = res_fname(user);
X			if (t_user != NULL) {
X				if(islocal(t_user, t_dom, t_unam) == 0) {
X					/* aliased to non-local address */
X					push(addr, t_user);
X					continue;
X				}
X				if(strcmp(t_unam, user) != 0) {
X					/* aliased to different local address */
X					push(addr, t_unam);
X					continue;
X				}
X			}
X		}
X#endif
X
Xaliasing_complete:
X		user = escape(u->string);
X		for(i=0; i < nargc; i++) {
X			if(strcmpic(nargv[i], user) == 0) {
X				break;
X			}
X		}
X
X		if(i == nargc) {
X			nargv[nargc++] = user;
X		}
X	}
X	*pargc     = nargc;
X	return(nargv);
X}
X
X#ifndef SENDMAIL
X/*
X** v_search
X**	given an string, look for its alias in
X**	the 'vertical' linked list of aliases.
X*/
Xnode *
Xv_search(user)
Xchar *user;
X{
X	node *head;
X	node *a;
X	static int loaded = 0;
X
X	head = &aliases;
X	if(loaded == 0) {
X		load_alias(head, aliasfile);
X		loaded = 1;
X	}
X
X	for(a = head->vert; a != NNULL; a = a->vert) {
X#ifdef CASEALIAS
X		if(strcmp(a->string, user) == 0)
X#else
X		if(strcmpic(a->string, user) == 0)
X#endif
X		{
X			break;
X		}
X	}
X	if(a == NNULL) {		/* not in graph */
X		return(NNULL);
X	}
X	return(a);
X}
X
X/*
X** h_search
X**	given an string, look for it in
X**	a 'horizontal' linked list of strings.
X*/
Xnode *
Xh_search(head, str)
Xnode *head;
Xchar *str;
X{
X	node *a;
X	for(a = head->horz; a != NNULL; a = a->horz) {
X#ifdef CASEALIAS
X		if(strcmp(a->string, str) == 0)
X#else
X		if(strcmpic(a->string, str) == 0)
X#endif
X		{
X			break;
X		}
X	}
X	return(a);
X}
X#endif /* not SENDMAIL */
X
X/*
X** load_alias
X**	parse an 'aliases' file and add the aliases to the alias graph.
X**	Handle inclusion of other 'aliases' files.
X*/
X
Xvoid
Xload_alias(head, filename)
Xnode *head;
Xchar *filename;
X{
X	FILE *fp;
X	node *v, *h, *add_vert();
X	char domain[SMLBUF], user[SMLBUF];
X	char *p, *b, buf[SMLBUF];
X
X	if((fp = fopen(filename,"r")) == NULL) {
XDEBUG("load_alias open('%s') failed\n", filename);
X		return;
X	}
X
X	while(fgets(buf, sizeof buf, fp) != NULL) {
X		p = buf;
X		if((*p == '#') || (*p == '\n')) {
X			continue;
X		}
X
X		/*
X		** include another file of aliases
X		*/
X
X		if(strncmp(p, ":include:", 9) == 0) {
X			char *nl;
X			p += 9;
X			if((nl = index(p, '\n')) != NULL) {
X				*nl = CNULL;
X			}
XDEBUG("load_alias '%s' includes file '%s'\n", filename, p);
X			load_alias(head, p);
X			continue;
X		}
X
X		/*
X		**  if the first char on the line is a space or tab
X		**  then it's a continuation line.  Otherwise,
X		**  we start a new alias.
X		*/
X		if(*p != ' ' && *p != '\t') {
X			b = p;
X			SKIPWORD(p);
X			*p++ = CNULL;
X			/*
X			** be sure that the alias is in local form
X			*/
X			if(islocal(b, domain, user) == 0) {
X				/*
X				** non-local alias format - skip it
X				*/
X				continue;
X			}
X			/*
X			** add the alias to the (vertical) list of aliases
X			*/
X			if((h = add_vert(head, user)) == NNULL) {
XDEBUG("load_alias for '%s' failed\n", b);
X				return;
X			}
X		}
X		/*
X		**  Next on the line is the list of recipents.
X		**  Strip out each word and add it to the
X		**  horizontal linked list.
X		*/
X		(void) recipients(h, p);
X	}
X	(void) fclose(fp);
X	/*
X	** strip out aliases which have no members
X	*/
X	for(v = head; v->vert != NNULL; ) {
X		if(v->vert->horz == NNULL) {
X			v->vert = v->vert->vert;
X		} else {
X			v = v->vert;
X		}
X	}
X}
X
X/*
X** add each word in a string (*p) of recipients
X** to the (horizontal) linked list associated with 'h'
X*/
X
Xrecipients(h, p)
Xnode *h;
Xchar *p;
X{
X
X	char *b, d[SMLBUF], u[SMLBUF];
X	int ret = 0;
X
X	strip_comments(p);	/* strip out stuff in ()'s */
X
X	SKIPSPACE(p);		/* skip leading whitespace on line */
X
X	while((*p != NULL) && (*p != '#')) {
X		b = p;
X		if(*b == '"') {
X			if((p = index(++b, '"')) == NULL) {
X				/* syntax error - no matching quote */
X				/* skip the rest of the line */
X				return(ret);
X			}
X		} else {
X			SKIPWORD(p);
X		}
X
X		if(*p != CNULL) {
X			*p++ = CNULL;
X		}
X
X		/* don't allow aliases of the form
X		** a	a
X		*/
X		if((islocal(b, d, u) == 0)
X		|| (strcmpic(h->string, u) != 0)) {
X			add_horz(h, b);
X			ret = 1;
X		}
X		SKIPSPACE(p);
X	}
X	return(ret);
X}
X
X/*
X** some aliases may have comments on the line like:
X**
X** moderators	moderator@somehost.domain	(Moderator's Name)
X**		moderator@anotherhost.domain	(Another Moderator's Name)
X**
X** strip out the stuff in ()'s
X**
X*/
X
Xvoid
Xstrip_comments(p)
Xchar *p;
X{
X	char *b;
X	while((p = index(p, '(')) != NULL) {
X		b = p++;	/*
X				** save pointer to open parenthesis
X				*/
X		if((p = index(p, ')')) != NULL) {/* look for close paren */
X			(void) strcpy(b, ++p);	 /* slide string left    */
X		} else {
X			*b = CNULL;	/* no paren, skip rest of line  */
X			break;
X		}
X	}
X}
X
X/*
X** add_vert - add a (vertical) link to the chain of aliases.
X*/
X
Xnode *
Xadd_vert(head, str)
Xnode *head;
Xchar *str;
X{
X	char *p, *malloc();
X	void free();
X	node *new;
X
X	/*
X	** strip colons off the end of alias names
X	*/
X	if((p = index(str, ':')) != NULL) {
X		*p = CNULL;
X	}
X	if((new = (node *) malloc(sizeof(node))) != NNULL) {
X		if((new->string = malloc((unsigned) strlen(str)+1)) == NULL) {
X			free(new);
X			new = NNULL;
X		} else {
X			(void) strcpy(new->string, str);
X			new->vert   = head->vert;
X			new->horz   = NNULL;
X			head->vert  = new;
X/*DEBUG("add_vert %s->%s\n", head->string, new->string);/* */
X		}
X	}
X	return(new);
X}
X
X/*
X** add_horz - add a (horizontal) link to the chain of recipients.
X*/
X
Xvoid
Xadd_horz(head, str)
Xnode *head;
Xchar *str;
X{
X	char *malloc();
X	node *new;
X
X	if((new = (node *) malloc(sizeof(node))) != NNULL) {
X		if((new->string = malloc((unsigned) strlen(str)+1)) == NULL) {
X			free(new);
X			new = NNULL;
X		} else {
X			(void) strcpy(new->string, str);
X			new->horz  = head->horz;
X			new->vert  = NNULL;
X			head->horz = new;
X		}
X/*DEBUG("add_horz %s->%s\n", head->string, new->string);/* */
X	}
X}
X
Xnode *
Xpop(head)
Xnode *head;
X{
X	node *ret = NNULL;
X
X
X	if(head != NNULL) {
X		ret = head->horz;
X		if(ret != NNULL) {
X			head->horz = ret->horz;
X		}
X	}
X	return(ret);
X}
END_OF_FILE
if test 11011 -ne `wc -c <'mailer/alias.c'`; then
    echo shar: \"'mailer/alias.c'\" unpacked with wrong size!
fi
# end of 'mailer/alias.c'
fi
if test -f 'mailer/defs.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mailer/defs.h'\"
else
echo shar: Extracting \"'mailer/defs.h'\" \(9866 characters\)
sed "s/^X//" >'mailer/defs.h' <<'END_OF_FILE'
X/*
X**
X**  Defs.h:  header file for rmail/smail.
X**
X**  Configuration options for rmail/smail.
X**	default configuration is:
X**	full domain name is 'hostname.uucp' (get registered!)
X**	path file is /usr/lib/uucp/paths.
X**	no log, no record, use sendmail.
X** 
X**  You can change these in the next few blocks.
X**
X*/
X
X/*
X**	@(#)defs.h	2.5 (smail) 9/15/87
X*/
X
X#ifndef VERSION
X#define	VERSION	"smail2.5"
X#endif
X
X#define BSD				/* if system is a Berkeley system */
X
X#define SENDMAIL "/usr/lib/sendmail"	/* Turn off to use /bin/(l)mail only */
X
X#ifdef BSD
X#define GETHOSTNAME			/* use gethostname() */
X#else
X#define UNAME 				/* use uname() */
X#endif
X
X/* if defined, HOSTNAME overrides UNAME and GETHOSTNAME */
X/*#define HOSTNAME	"host"		/* literal name */
X
X/*#define HOSTDOMAIN	"host.dom"	/* overrides default HOSTNAME.MYDOM */
X
X/*
X * .UUCP here is just for testing, GET REGISTERED in COM, EDU, etc.
X * See INFO.REGISTRY for details.
X */
X
X#define MYDOM		".ACS.COM"		/* literal domain suffix */
X
X/*
X * WARNING: DOMGATE is only for qualified gateways - use caution.
X * If you don't fully understand it - don't use it!
X * If you are not completely sure you need it - don't use it!
X * If you are not prepared to handle all addresses to MYDOM - don't use it!
X *
X * if defined, DOMGATE (DOMain GATEway) will cause addresses of the form
X *
X *	user@MYDOM or MYDOM!user
X *
X * (with and without the leading '.' on MYDOM)
X * to be seen treated simply 'user' - a purely local address.
X * Then, it is left to the aliasing code to map it back to a
X * non-local address if necessary.
X */
X
X#define DOMGATE		/* Act as Domain Gateway */
X
X/*
X * HIDDENHOSTS allows hosts that serve as domain gateways to hide
X * the subdomains beneath them.  Mail that originates at any of
X * the hosts in the subdomain will appear to come from the gateway host.
X * Hence, mail from
X *
X * 		anything.hostdomain!user
X *
X * will appear to come from 
X *
X * 		hostdomain!user
X *
X * A consequence is that return mail to hostdomain!user would need to
X * be forwarded to the proper subdomain via aliases or other forwarding
X * facilities.
X *
X * If you're using sendmail, then if defined here,
X * it should be used in ruleset 4 of the sendmail.cf, too.
X */
X
X/*#define HIDDENHOSTS			/* hide subdomains of hostdomain */
X
X/*
X * Mail that would otherwise be undeliverable will be passed to the
X * aliased SMARTHOST for potential delivery.
X *
X * Be sure that the host you specify in your pathalias input knows that you're
X * using it as a relay, or you might upset somebody when they find out some
X * other way.  If you're using 'foovax' as your relay, and below you have
X * #define SMARTHOST "smart-host", then the pathalias alias would be:
X *
X *	smart-host = foovax
X */
X
X#define SMARTHOST  "uunet"	/* pathalias alias for relay host */
X
X/*
X**  ALIAS and CASEALIAS are used only if SENDMAIL is NOT defined.
X**  Sites using sendmail have to let sendmail do the aliasing.
X**  LOWERLOGNAME maps all local login names into lower case.  This
X**  helps sites who have only upper case send mail to mixed case sites.
X*/
X
X/*#define ALIAS	"/usr/lib/aliases"	/* location of mail aliases       */
X/*#define CASEALIAS			/* make aliases case sensitive    */
X/*#define LOWERLOGNAME			/* map local logins to lower case */
X
X/*
X * defining FULLNAME means that Full Name resolution
X * will be attempted when necessary.
X *
X * the Full Name information will be taken from a
X * list of {Full Name, address} pairs.
X * The names in the list must be sorted
X * without regard to upper/lower case.
X *
X * defining DOT_REQD says that the user name must contain a '.' for
X * the Full Name search to be done.
X *
X * All full name searches are case insensitive.
X *
X */
X
X/*#define FULLNAME	"/usr/lib/fullnames"
X					/* list of Full Name, address pairs */
X
X/*#define DOT_REQD			/* Must be George.P.Burdell@gatech.EDU
X					** not just  Burdell@gatech.EDU
X					*/
X
X/*
X**	PATHS is name of pathalias file.  This is mandatory.
X**	Define LOG if you want a log of mail.  This can be handy for
X**	debugging and traffic analysis.
X**	Define RECORD for a copy of all mail.  This uses much time and
X**	space and is only used for extreme debugging cases.
X*/
X
X#ifndef PATHS
X#define PATHS	"/usr/lib/uucp/paths"	/* location of the path database */
X#endif
X
X#define LOG	"/usr/spool/uucp/mail.log"	/* log of uucp mail */
X/*#define RECORD	"/tmp/mail.log"		/* record of uucp mail */
X
X/*
X**  Mailer options:
X**	RMAIL is the command to invoke rmail on machine sys.
X**	RARG is how to insulate metacharacters from RMAIL. 
X**	LMAIL is the command to invoke the local mail transfer agent.
X**	LARG is how to insulate metacharacters from LMAIL. 
X**	RLARG is LARG with host! on the front - to pass a uux addr to sendmail.
X**	SENDMAIL selects one of two sets of defines below for either
X**	using sendmail or /bin/lmail.
X*/	
X
X#ifndef UUX
X#define UUX		"/usr/bin/uux"	/* location of uux command   */
X#endif
X
X#ifndef SMAIL
X#define SMAIL		"/bin/smail"	/* location of smail command */
X#endif
X
X/*
X** command used to retry failed mail, flag is used to set the routing level.
X*/
X#define VFLAG		((debug == VERBOSE)?"-v":"")
X#define RETRY(flag)	"%s %s %s -f %s ", SMAIL, VFLAG, flag, spoolfile
X
X/*
X** use the -a if you have it.  This sometimes helps failed mail and warning
X** messages get back to where the mail originated.
X**
X** some versions of uux can't do '-a' - pick one of the next two definitions
X*/
X
X/*#define RMAIL(flags,from,sys) "%s -a%s %s - %s!rmail",UUX,from,flags,sys /* */
X#define RMAIL(flags,from,sys) "%s %s - %s!rmail",UUX,flags,sys /* */
X
X#define RARG(user)		" '(%s)'",user
X/*
X#ifdef ACSMAIL
X#define RFROM(frm,now,host) 	"From anonymous  %.24s remote from %s\n",now,host
X#else
X#define RFROM(frm,now,host) 	"From %s  %.24s remote from %s\n",frm,now,host
X#endif
X*/
X#define RFROM(frm,now,host) 	"From %s  %.24s remote from %s\n",frm,now,host
X#ifdef SENDMAIL
X
X#define HANDLE	JUSTUUCP	/* see HANDLE definition below */
X#define ROUTING JUSTDOMAIN	/* see ROUTING definition below */
X
X#define LMAIL(frm,sys) 	"%s -em -f%s",SENDMAIL,frm
X#define LARG(user)		" '%s'",postmaster(user)
X#define RLARG(sys,frm)		" '%s!%s'",sys,frm
X#define LFROM(frm,now,host)	"From %s %.24s\n",frm,now
X
X#else
X
X#define HANDLE	ALL
X#define ROUTING JUSTDOMAIN
X
X#ifdef BSD
X#define LMAIL(frm,sys)		"/bin/mail"	/* BSD local delivery agent */
X#else
X#define LMAIL(frm,sys)		"/bin/lmail"	/* SV  local delivery agent */
X#endif
X
X#define LARG(user)		" '%s'",postmaster(user)
X#define RLARG(sys,frm)		" '%s!%s'",sys,frm
X#define LFROM(frm,now,host)	"From %s %.24s\n",frm,now
X
X#endif
X
X/*
X**	The following definitions affect the queueing algorithm for uux.
X**
X**	DEFQUEUE	if defined the default is to queue uux mail
X**
X**	QUEUECOST	remote mail with a cost of less than QUEUECOST
X**			will be handed to uux for immediate delivery.
X**
X**	MAXNOQUEUE	don't allow more than 'n' immediate delivery
X**			jobs to be started on a single invocation of smail.
X**	
X**	GETCOST		if defined, the paths file will be searched for
X**			each address to discover the cost of the route.
X**			this allows informed decisions about whether to
X**			use the queue flags when calling uux.  The price
X**			is in the overhead of a paths file search for
X**			addresses that are not going to be routed.
X*/
X
X#define DEFQUEUE			/* default is to queue uux jobs */
X
X#define QUEUECOST		100	/* deliver immediately if the cost
X					/* is DEDICATED+LOW or better */
X
X#define MAXNOQUEUE		2	/* max UUX_NOQUEUE jobs         */
X
X#define GETCOST				/* search for cost		*/
X
X#define UUX_QUEUE		"-r"	/* uux flag for queueing	*/
X#define UUX_NOQUEUE		""	/* uux with immediate delivery	*/
X
X/*
X** Normally, all mail destined for the local host is delivered with a single
X** call to the local mailer, and all remote mail is delivered with one call
X** to the remote mailer for each remote host.  This kind of 'batching' saves
X** on the cpu overhead.
X**
X** MAXCLEN is used to limit the length of commands that are exec'd by smail.
X** This is done to keep other program's buffers from overflowing, or to
X** allow for less intelligent commands which can take only one argument
X** at a time (e.g., 4.1 /bin/mail).  To disable the batching, set MAXCLEN
X** a small value (like 0).
X*/
X
X#define MAXCLEN			128	/* longest command allowed (approx.)
X					/* this is to keep other's buffers
X					** from overflowing
X					*/
X
X/*
X** PLEASE DON'T TOUCH THE REST
X*/
X
X#define SMLBUF	512	/* small buffer (handle one item) */
X#define BIGBUF	4096	/* handle lots of items */
X 
X#define MAXPATH	32	/* number of elements in ! path */
X#define MAXDOMS	16	/* number of subdomains in . domain */
X#define MAXARGS	500	/* number of arguments */
X#ifndef NULL
X#define NULL	0
X#endif
X
X#define DEBUG 		if (debug==YES) (void) printf
X#define ADVISE 		if (debug!=NO) (void) printf
X#define error(stat,msg,a)	{ (void) fprintf(stderr, msg, a); exit(stat); }
X#define lower(c) 		( isupper(c) ? c-'A'+'a' : c )
X
X
Xenum eform {	/* format of addresses */
X	ERROR, 		/* bad or invalidated format */
X	LOCAL, 		/* just a local name */
X	DOMAIN, 	/* user@domain or domain!user */
X	UUCP,		/* host!address */
X	ROUTE,		/* intermediate form - to be routed */
X	SENT		/* sent to a mailer on a previous pass */
X};
X
Xenum ehandle { 	/* what addresses can we handle? (don't kick to LMAIL) */
X	ALL,		/* UUCP and DOMAIN addresses */
X	JUSTUUCP,	/* UUCP only; set by -l  */
X	NONE		/* all mail is LOCAL; set by -L */
X};
X
Xenum erouting {	/* when to route A!B!C!D */
X	JUSTDOMAIN,	/* route A if A is a domain */
X	ALWAYS,		/* route A always; set by -r */
X	REROUTE		/* route C, B, or A (whichever works); set by -R */
X};
X
Xenum edebug {	/* debug modes */
X	NO,		/* normal deliver */
X	VERBOSE,	/* talk alot */
X	YES		/* talk and don't deliver */
X};
X
X#ifdef BSD
X
X#include <strings.h>
X#include <sysexits.h>
X
X#else
X
X#include <string.h>
X#include "sysexits.h"
X#define	index	strchr
X#define	rindex	strrchr
X
X#endif
Xextern void exit(), perror();
Xextern unsigned sleep();
END_OF_FILE
if test 9866 -ne `wc -c <'mailer/defs.h'`; then
    echo shar: \"'mailer/defs.h'\" unpacked with wrong size!
fi
# end of 'mailer/defs.h'
fi
if test -f 'mailer/smail.8' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mailer/smail.8'\"
else
echo shar: Extracting \"'mailer/smail.8'\" \(10111 characters\)
sed "s/^X//" >'mailer/smail.8' <<'END_OF_FILE'
X.TH SMAIL 8
X.SH NAME
Xsmail, rmail \- UUCP mailer with routing
X.SH SYNOPSIS
X.B smail
X[ options ] address ...
X.br
X.B rmail
X[ options ] address ...
X.SH DESCRIPTION
XThe
X.I smail/rmail
Xprogram replaces
X.IR /bin/rmail (1)
Xto become the UUCP mail transport mechanism.
XThey are links to the same executable.
X.I rmail
Xreceives mail from UUCP,
X.I smail
Xintroduces mail into UUCP.
X.PP
X.I smail/rmail
Xcan work with or without
X.IR sendmail (8),
Xor another intelligent mail system.
XFor hosts with just
X.IR /bin/mail (1),
X.I smail/rmail
Xsubsumes some of the functions of
X.I sendmail,
Xand hands only local mail to
X.I /bin/mail.
XFor hosts with
X.I sendmail,
X.I smail/rmail
Xcan act as UUCP front and back ends to
X.I sendmail,
Xallowing
X.I sendmail
Xto process all mail through the host.
XAs distributed, 'bang' mail that is not bound for a local
Xrecipient will be passed directly to
X.I uux
Xwithout calling
X.I sendmail.
X.PP
XTo varying degrees,
X.I smail/rmail
Xautomatically routes the addresses it processes.
X.I smail/rmail
Xmost often routes domain style addresses (i.e. user@domain), producing
Xa UUCP path (i.e. host!address) or a local address (i.e. user), but it can
Xalso reroute explicit UUCP paths.
X.SH OPTIONS
X.TP
X.B \-A
XPrint the resolved addresses.  Don't collect a message or invoke a mailer.
X.TP
X.B \-d
XBe verbose and don't invoke other mailers.
X.TP
X.B \-v
XBe verbose, but still invoke other mailers.
X.TP
X.BI \-h " hostname"
XSet hostname.  The default is configuration dependent, but usually provided
Xby a system call such as
X.IR gethostname (2)
Xor
X.IR uname (2).
X.TP
X.BI \-H " hostdomain"
Xset hostdomain.  The default is configuration dependent.
X.TP
X.BI \-F " address"
Xuse
X.I address
Xon the From: line in locally generated mail.
X.TP
X.BI \-p " pathfile"
XSet path database file name if not /usr/lib/uucp/paths.
X.TP
X.BI \-a " aliasfile"
XFor sites without sendmail, set alias database file name if not in
Xthe place defined at compile time (see ALIASES in defs.h).
XThis is usually
X.I /usr/lib/aliases
X.TP
X.BI \-n " namelist"
X.I smail
Xsupports another type of aliasing intended for full name resolution
Xusing a sorted file,
X.I namelist,
Xof name/address pairs.
XThis allows mail to George.P.Burdell@gatech.edu to be delivered
Xappropriately.  These aliases are by their nature very simple
Xsince they are not composed of long lists of recipients for each alias.
XThey are also numerous, since mail to George.P.Burdell may be addressed
Xto Burdell, G.Burdell, George.Burdell, P.Burdell, G.P.Burdell, or
XGeorge.P.Burdell.  This simpler form of aliasing uses the same
Xfast searching algorithm that is used for the paths file, so
Xit keeps resolution time manageable.
X.TP
X.BI \-q " number"
XTake
X.I number
Xas the queueing threshold.
XWhen routing mail (
X.I -r, -R,
Xor domain addressed mail
X) to a given host, if the cost listed in the
X.I paths
Xfile is less than the queueing threshold, then the mail
Xwill be sent immediately.  This overrides the default threshold
X(see QUEUECOST in defs.h) of DEDICATED+LOW.
X.TP
X.BI \-m " number"
XAt most 
X.I number
Xjobs will be handed to uux for immediate delivery
Xby a single invocation of
X.I smail
X(see MAXNOQUEUE in defs.h).
X.TP
X.BI \-u " uuxflags"
XUse
X.I uuxflags
Xas the flags passed to uux for remote mail.
XThis overrides any of the default values and other queueing strategies.
X.TP
X.B -c
XConsult the paths file for the cost of the path even when not routing
Xthe mail.  This makes it possible to use the cost information when
Xsending pure UUCP path mail without rerouting it.
X.TP
X.B \-r
XRoute the first component of a UUCP path (host!address) in addition to routing
Xdomain addresses (user@domain).
X.TP
X.B \-R
XReroute UUCP paths, trying successively larger righthand substrings
Xof a path until a component is recognized.
X.TP
X.B \-l
XInstead of routing a domain address, send it to the local mailer for
Xprocessing.  Normally, only local addresses go to the local mailer.
X.TP
X.B \-L
XSend all addresses to the local mailer for processing, including UUCP paths.
X.PP
XMost of the flags are also compile time options, since
X.I uux
Xdoes not normally invoke
X.I rmail
Xwith the desired flags.
X.I smail
Xresets any preset
X.B -l
Xor
X.B -L
Xflags.
X.B -l
Xflag causes 
X.B rmail
Xto send all domain addresses through the local mailer,
Xto process addresses for non UUCP domains.
XThe
X.B -L
Xflag causes
X.B rmail
Xto send even explicit UUCP paths through the local mailer,
Xpresumably to make use of other transport mechanisms.
XIn both cases, rmail defers any routing until smail gets hold it.
X.SH ADDRESSES
X.I smail/rmail
Xunderstands "user@domain" to be a domain address, "host!address" to be a
XUUCP path, and anything else to be a local address.
X.PP
XBecause hostile
X.I rmail's
Xunpredictably interpret mixed UUCP/domain addresses,
X.I smail/rmail
Xunderstands "domain!user" to be a domain address, and generates
X"path!domain!user" when mailing to a cognate
X.I smail/rmail
Xhost.
XTo distinguish domain "domain!user" from UUCP "host!address", "domain"
Xcontains at least one (1) period.
XUnlike the old
X.I /bin/rmail,
X.I smail/rmail
Xgives precedence to @ over ! when parsing mixed addresses,
Xthus a!b@c is parsed as (a!b)@c, rather than a!(b@c).
X.SH ROUTING
XBecause
X.I smail/rmail
Xis the UUCP transport mechanism, it can only effect delivery on UUCP paths 
Xand local addresses; domain addresses require resolution into UUCP paths or
Xlocal addresses.  
XTo resolve a domain address,
X.I smail/rmail
Xfinds a route to the most specific part of the domain specification listed
Xin the routing table.
XTwo degrees of resolution can occur:
X.RS
X.PP
XFull resolution:
X.I smail/rmail
Xfinds a route for the entire domain specification, and tacks the user
Xspecification onto the end of the UUCP path.
XThe address can also fully resolve to a local address (the UUCP path is null).
X.PP
XPartial resolution:
X.I smail/rmail
Xfinds a route for only righthand part of the domain specification, so it 
Xtacks the complete address (in the form domain!user) onto the end of the 
XUUCP path.
XSince this syntax is not widely understood, UUCP gateways listed in
Xthe path database must install new UUCP software, either
X.I smail/rmail
Xor new
X.I sendmail
Xconfiguration files (or both).
X.RE
X.PP
XIt is an error if a partially resolved address routes to the local host 
X(a null UUCP path), since according to the routing table, the local
Xhost is responsible for resolving the address more fully.
X.PP
XThe
X.B -r
Xflag causes
X.I smail/rmail
Xto attempt to route the first component of a UUCP path, probably so it
Xcan impress people with how many UUCP hosts it knows.
XIf this fails, it passes the unrouted address to
X.I uux,
Xin case the path database is not complete.
XThe 
X.B -R
Xflag causes
X.I smail/rmail
Xto take a UUCP path and route the rightmost component of the path (save
Xthe user name) possible.
XThis is mostly for hosts that have very up-to-date routing tables.
X.PP
XIf a route cannot be discerned from the available routing database,
Xthen one more attempt to route the mail is made by searching for an
Xentry in the database for a route to a
X.I smart-host.
XIf this entry exists, then the mail will be forwarded along that route
Xto be delivered.  This allows a host to depend on another, presumably
Xbetter informed, host for delivering its mail.
XThis kind of arrangement should be worked out,
X.I in advance,
Xwith the
X.IR smart-host 's
Xadministrator.
X.PP
XAfter
X.I smail/rmail
Xresolves an address, it reparses it to see if it is now a UUCP path or
Xlocal address.  If the new address turns out to be another
Xdomain address, smail complains because we don't like to resolve more than once.
XThis error occurs when an address partially resolves the local host.
X.PP
XBy default,
X.I smail
Xwill not alter the explicit bang path routing of any mail message.
XIf the stated path is unuseable, (i.e., the next hop host is unknown)
Xthen smail will apply ALWAYS routing, and attempt to deliver the mail
Xto the potentially new address.  If this fails too, then REROUTE routing
Xwill be applied to the address, and another attempt to deliver is made.
XLastly, an attempt to find a path to a better informed host
X.I smart-host
Xwill be made and the mail passed to that host.
X.SH FROMMING
X.I smail/rmail
Xcollapses From_ and >From_ lines to generate a simple from argument, which
Xit can pass to
X.I sendmail
Xor use to create its own "From" line.
XThe rule for fromming is: concatenate each "remote from" host (separating 
Xthem by !'s), and tack on the address on the last From_ line; if that address 
Xis in user@domain format, rewrite it as domain!user; ignore host or
Xdomain if either is simply the local hostname.  It also removes redundant
Xinformation from the From_ line.  For instance:
X.sp
X.ce
X ...!myhost!myhost.mydomain!...
X.sp
Xbecomes
X.sp
X.ce
X ...!myhost!...
X.sp
XLeading occurrences of the local host name are elided as well.
X.PP
X.I smail/rmail
Xgenerates it own From_ line, unless it is feeding
X.I sendmail,
Xwhich is happy with the
X.BI -f from
Xargument.
XFor UUCP bound mail,
X.I smail/rmail
Xgenerates a "remote from hostname", where hostname is the UUCP hostname
X(not the domain name), so that From_ can indicate a valid UUCP path, leaving
Xthe sender's domain address in From:.
X.SH HEADERS
XCertain headers, To:, From:, Date, etc., are required by RFC822.
XIf these headers are absent in locally generated mail, they will
Xbe inserted by smail.  Also, a line of trace information, called
Xa Received: line, will be inserted at the top of each message.
X.SH UNDELIVERABLE MAIL"
XAlthough nobody likes to have a mail message fail to reach its
Xintended destination, it somtimes happens that way.
XMail that is found to be undeliverable
X(i.e., unknown user or unknown host)
Xwill be returned to the sender.
X.SH FILES
X/usr/lib/uucp/paths		ascii path database
X.br
X/usr/lib/aliases		ascii alias database
X.br
X/usr/spool/uucp/mail.log		log of mail
X.br
X/tmp/mail.log			record of mail
X.SH SUPPORT
XEnhancements, enhancement requests, trouble reports, etc.,
Xshould be sent to
X.sp
X.ce
Xuucp-problem@Stargate.COM.
X.sp
X.SH "SEE ALSO"
X.IR uux (1),
X.IR paths (8),
X.IR aliases (8)
X.br
X.IR sendmail (8)
X.br
X.IR binmail (1)
Xon BSD systems only
X.br
X.IR mail (1)
Xon System V systems
X.SH VERSION
X@(#)smail.8	2.5 (smail) 9/15/87
END_OF_FILE
if test 10111 -ne `wc -c <'mailer/smail.8'`; then
    echo shar: \"'mailer/smail.8'\" unpacked with wrong size!
fi
# end of 'mailer/smail.8'
fi
echo shar: End of archive 6 \(of 8\).
cp /dev/null ark6isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 8 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0