[mod.sources] v07i010: Domain mailer and rmail replacement, Part02/02

sources-request@mirror.UUCP (08/28/86)

Submitted by: Mark Horton <mark@cbosgd.ATT.COM>
Mod.sources: Volume 7, Issue 10
Archive-name: smail/Part02


# To unpack the enclosed files, please use this file as input to the
# Bourne (sh) shell.  This can be most easily done by the command;
#     sh < thisfilename

# This archive contains;
#  Makefile         binmail.c           defs.h              deliver.c           
#  getopt.c         main.c              resolve.c           sendmail.att
#  sendmail.leaf    smail.cf.fix        smail.cf.form       smail.cf.sh
#  smail.prompt     sysexits.h          u.Path.local        u.Path.top.1
#  u.Path.uucp.1


# ---------- file Makefile ----------

filename="Makefile"

if [ -f $filename ]
then
  echo File \"$filename\" already exists\!  Skipping...
  filename=/dev/null		# throw it away
else
  echo extracting file Makefile...
fi

cat << 'END-OF-FILE' > $filename
# Makefile for smail (not a installation makefile)

# @(#)Makefile	1.6   (UUCP-Project/CS)   6/27/86

# If you have compressed files in this dir, uncompress them
# and point UUMAP at the directory with uncompressed files,
# or fiddle with zcat.
UUMAP=/usr/spool/news/maps/mod.map

PATHS	=	/usr/lib/uucp/paths

CFLAGS	=	-O -DPATHS=\"$(PATHS)\"

OBJECTS =	main.o resolve.o deliver.o getopt.o

all: smail binmail

smail:		${OBJECTS}
		cc ${CFLAGS} ${OBJECTS} -o smail

${OBJECTS}:	defs.h

binmail:

install: all
	@echo read INFO.INSTALL

paths:
	pathalias u.Path.* $(UUMAP)/u.* | sort -f > path.out
	cp path.out $(PATHS)

clean:
	rm -f *.o a.out core

clobber: clean
	rm -f smail rmail binmail
END-OF-FILE

if [ "$filename" != "/dev/null" ]
then
  size=`wc -c < $filename`

  if [ $size != 691 ]
  then
    echo $filename changed - should be 691 bytes, not $size bytes
  fi

  chmod 644 $filename
fi

# ---------- file binmail.c ----------

filename="binmail.c"

if [ -f $filename ]
then
  echo File \"$filename\" already exists\!  Skipping...
  filename=/dev/null		# throw it away
else
  echo extracting file binmail.c...
fi

cat << 'END-OF-FILE' > $filename
/* */
/* This program will be used in place of /bin/mail on SVR2 sites.
/* It looks at the arguments and decides whether to call
/* SENDER for sending mail, or READER for reading mail.
/*
/* before installing as /bin/mail, move the stock /bin/mail to /bin/lmail
/*
/*  */

#include <stdio.h>
#include "defs.h"

#ifdef SENDMAIL
#define	SENDER	"/usr/lib/sendmail"
#else
#define	SENDER	"/bin/rmail"
#endif

#define	READER	"/bin/lmail"

#define TRUE 1
#define FALSE 0

char prog[128];

void	perror(), exit(), usage();
char	*strcpy();

main(argc, argv)
int argc;
char *argv[];
{
	extern int optind;
	extern char *optarg;

	int i, j, c;
	int reading, sending;

	reading = sending = FALSE;

	(void) strcpy(prog, argv[0]);

	if(argc == 1) {
		reading = TRUE;
	} else {
		while((c = getopt(argc, argv, "epqrtf:")) != EOF) {
			switch(c) {
			case 'e':
			case 'p':
			case 'q':
			case 'r':
			case 'f':
				reading = TRUE;
				break;
			case 't':
				sending = TRUE;
				break;
			default:
				usage();
				return(1);
			}
		}
	}

	/* any arguments left over -> sending */
	if(argc > optind) {
		sending = TRUE;
	}

	if((reading == TRUE) && (sending == TRUE)) {
		usage();
		return(1);
	}

	if(sending == TRUE) {
		argv[0] = SENDER;
		for(i = 1, j = optind; i < argc; i++, j++) {
			argv[i] = argv[j];
		}
		argv[i] = NULL;
	} else {
		argv[0] = READER;
	}

	(void) execvp(argv[0], argv);
	(void) fprintf(stderr, "%s: execvp(\"%s\", argv) failed: ",
		prog, argv[0]);
	perror("");
	return(1);
}

void
usage()
{
	(void) fprintf(stderr, "usage:\t%s [ -epqr ] [ -f file ]\n", prog);
	(void) fprintf(stderr, "\t%s [ -t ] persons\n", prog);
}
END-OF-FILE

if [ "$filename" != "/dev/null" ]
then
  size=`wc -c < $filename`

  if [ $size != 1630 ]
  then
    echo $filename changed - should be 1630 bytes, not $size bytes
  fi

  chmod 644 $filename
fi

# ---------- file defs.h ----------

filename="defs.h"

if [ -f $filename ]
then
  echo File \"$filename\" already exists\!  Skipping...
  filename=/dev/null		# throw it away
else
  echo extracting file defs.h...
fi

cat << 'END-OF-FILE' > $filename
/*
**
**  Defs.h:  header file for rmail/smail.
**
**  Configuration options for rmail/smail.  As distributed, these are
**  your options:
** 	use gethostname() to determine hostname.
**	full domain name is 'hostname.uucp'.
**	path file is /usr/lib/uucp/paths.
**	no log, no record, no dbm, use sendmail.
** 
**  You can change these in the next few blocks.
**
*/

/*
**	@(#)defs.h	1.12   (UUCP-Project/CS)   6/29/86
*/

/*
**  If you select SENDMAIL below, you needn't worry about hostdomain here,
**  as rmail does no domain routing with a SNOOPY sendmail, and sendmail
**  itself sets hostdomain for smail.
**
**  Determining hostname:
**	To use gethostname(), define GETHOSTNAME.
**	To use uname(), define UNAME.
**	To use a literal string, define HOSTNAME "host"
**
**  Determining hostdomain:
**	To use hostname.mydomain, define MYDOM "mydomain"
**	To use a literal string, define HOSTDOMAIN "host.domain"
**	Otherwise, it will be "hostname" (not advised).
**
**  THE TOP LEVEL OF YOUR DOMAIN NAME IS IMPLICIT IN THE PATHALIAS DATABASE
*/

# define BSD				/* if system is a Berkeley system */
# define SENDMAIL 1			/* Turn off to use /bin/(l)mail only */

# ifdef BSD
# define GETHOSTNAME			/* use gethostname() */
# else
# define UNAME 				/* use uname() */
# endif
/* # define HOSTNAME   "host"		/* literal name */

/*
 * .UUCP here is just for testing, GET REGISTERED in COM, EDU, etc.
 * See INFO.REGISTRY for details.
 */
# define MYDOM	    ".UUCP"		/* literal domain suffix */

/* # define HOSTDOMAIN "host.dom"	/* replacement for HOSTNAME.MYDOM */

/*
**  Locations of files:
**	PATHS is where the pathalias output is.  This is mandatory.
**	Define LOG if you want a log of mail.  This can be handy for
**	debugging and traffic analysis.
**	Define RECORD for a copy of all mail.  This uses much time and
**	space and is only used for extreme debugging cases.
*/

#ifndef PATHS
# define PATHS	"/usr/lib/uucp/paths"	/* where the path database is */
#endif

/*# define LOG 	"/usr/spool/uucp/mail.log"	/* log of uucp mail */
/*# define RECORD	"/tmp/mail.log"		/* record of uucp mail */

/*
**  Mailer options:
**	RMAIL is the command to invoke rmail on machine sys.
**	RARG is how to insulate metacharacters from RMAIL. 
**	LMAIL is the command to invoke the local mail transfer agent.
**	LARG is how to insulate metacharacters from LMAIL. 
**	RLARG is LARG with host! on the front - to pass a uux addr to sendmail.
**	SENDMAIL selects one of two sets of defines below for either
**	using sendmail or /bin/lmail.
*/	

				/* add -r for queueing */
# define RMAIL(from,sys)	"/usr/bin/uux - -r %s!rmail",sys
# define RARG(user)		" '(%s)'",user
# define RFROM(frm,now,host) 	"From %s  %.24s remote from %s\n",frm,now,host

#ifdef SENDMAIL
# define HANDLE	JUSTUUCP	/* see HANDLE definition below */
# define ROUTING JUSTDOMAIN	/* see ROUTING definition below */
/* # define ROUTING REROUTE	/* reroute everything (sets -R flag) */
# define LMAIL(frm,sys) 	"/usr/lib/sendmail -em -f%s",frm
# define LARG(user)		" '%s'",user
# define RLARG(sys,frm) " '%s!%s'",sys,frm
# define LFROM(frm,now,host) 	""
#else
# define HANDLE	ALL
# define ROUTING JUSTDOMAIN	/* */
/* # define ROUTING REROUTE	/* reroute everything (sets -R flag) */
#ifdef BSD
# define LMAIL(frm,sys)		"/bin/mail"	/* BSD local delivery agent */
#else
# define LMAIL(frm,sys)		"/bin/lmail"	/* SV  local delivery agent */
#endif
# define LARG(user)		" '%s'",user
# define RLARG(sys,frm) " '%s!%s'",sys,frm
# define LFROM(frm,now,host)	"From %s %.24s\n",frm,now
#endif SENDMAIL

/*
** DON'T TOUCH THE REST
*/

# define SMLBUF		512	/* small buffer (handle one item) */
# define BIGBUF		4096	/* handle lots of items */
 
# define MAXPATH	32	/* number of elements in ! path */
# define MAXDOMS	16	/* number of subdomains in . domain */
# define MAXARGS	32	/* number of arguments */

#ifndef NULL
# define NULL	0
#endif

# define DEBUG 			if (debug==YES) (void) printf
# define ADVISE 		if (debug!=NO) (void) printf
# define error(stat,msg,a)	{ (void) fprintf(stderr, msg, a); exit(stat); }
# define lower(c) 		( isupper(c) ? c-'A'+'a' : c )


enum eform {	/* format of addresses */
	ERROR, 		/* bad or invalidated format */
	LOCAL, 		/* just a local name */
	DOMAIN, 	/* user@domain */
	UUCP,		/* host!address */
	ROUTE };	/* intermediate form - to be routed */

enum ehandle { 	/* what addresses can we handle? (don't kick to LMAIL) */
	ALL,		/* UUCP and DOMAIN addresses */
	JUSTUUCP,	/* UUCP only; set by -l  */
	NONE };		/* all mail is LOCAL; set by -L */

enum erouting {	/* when to route A!B!C!D */
	JUSTDOMAIN,	/* route A if A is a domain */
	ALWAYS,		/* route A always; set by -r */
	REROUTE };	/* route C, B, or A (whichever works); set by -R */

enum edebug {	/* debug modes */
	NO,		/* normal deliver */
	VERBOSE,	/* talk alot */
	YES };		/* talk and don't deliver */

# ifdef BSD

# include	<sysexits.h>
# include	<strings.h>

# else

# include	"sysexits.h"
# include	<string.h>
# define	index	strchr
# define	rindex	strrchr

# endif
extern void exit(), perror();
extern unsigned sleep();
END-OF-FILE

if [ "$filename" != "/dev/null" ]
then
  size=`wc -c < $filename`

  if [ $size != 5060 ]
  then
    echo $filename changed - should be 5060 bytes, not $size bytes
  fi

  chmod 444 $filename
fi

# ---------- file deliver.c ----------

filename="deliver.c"

if [ -f $filename ]
then
  echo File \"$filename\" already exists\!  Skipping...
  filename=/dev/null		# throw it away
else
  echo extracting file deliver.c...
fi

cat << 'END-OF-FILE' > $filename
/*
**  Deliver.c
**
**  Routines to effect delivery of mail for rmail/smail. 
**
*/

#ifndef lint
static char 	*sccsid="@(#)deliver.c	1.13   (UUCP-Project/CS)   7/6/86";
#endif

# include	<sys/types.h>
# include	<stdio.h>
# include	<pwd.h>
# include	"defs.h"

extern int exitstat;		/* set if a forked mailer fails */
extern enum edebug debug;	/* how verbose we are 		*/ 
extern char hostname[];		/* our uucp hostname 		*/
extern enum ehandle handle;	/* what we handle		*/


/*
**
**  deliver():  hand the letter to the proper mail programs.
**
**  Copies stdin to a temp file, if more than one mailer 
**  will be invoked.  Issues one command for each different 
**  host of <hostv>, constructing the proper command for
**  LOCAL or UUCP mail.  Note that LOCAL mail has blank
**  host names.  The <userv> names for each host are arguments 
**  to the command.  Reads the "From_" and ">From_" lines 
**  of the letter to build a <from> argument.  Finally, 
**  prepends a "From" line to the letter just before going 
**  out, with a "remote from <hostname>" if it is a UUCP letter.
**
*/

deliver( argc, hostv, userv, formv )
int argc;				/* number of addresses		*/
char *hostv[];				/* host names			*/
char *userv[];				/* user names			*/
enum eform formv[];			/* form for each address	*/
{
	FILE *file;			/* source (stdin or temp file)	*/
	FILE *out;			/* pipe to mailer		*/
	FILE *popen();			/* to fork a mailer 		*/
#ifdef RECORD
	FILE *record();			/* snoopy mailer		*/
#endif
	char *tmpf = "/tmp/rmXXXXXX";	/* temp file name		*/
	char lcommand[SMLBUF];		/* local command issued 	*/
	char rcommand[SMLBUF];		/* remote command issued	*/
	char *command;			/* actual command		*/
	char from[SMLBUF];		/* accumulated from argument 	*/
	char line[SMLBUF];		/* one line of the letter 	*/
	int plural = 0;			/* more than one mailer? 	*/
	enum eform form;		/* holds form[i] for speed 	*/
	long size;			/* number of bytes of message 	*/
	time_t now, time();		/* the time 			*/
	char *nows;			/* the time in a string		*/
	int i, j, stat;
	char *c, *ctime();
	int failcount = 0;

	(void) strcpy( from, "" );
	(void) time( &now );		/* set the time */
	nows = ctime( &now );

/*
**  Decide if we should copy the letter to a temp file.  We do this if we
**  are sending to more than one mailer or if we are making a record.  We
**  check to see if there is more than one different host in hostv.
*/

# ifdef RECORD
	plural++;
# else
	for( i = 1; i < argc; i++ )
		if( strcmp( hostv[0], hostv[i] ) && ++plural )
			break;		/* shouldn't be case sensitive */
# endif

/*
**  If plural (more than one copy), copy stdin to a file.  Otherwise, just
**  set file pointer to stdin.  This way, we avoid an extra copy of the
**  file for the 99% of the cases with only one destination.  We also assume
**  that if we must return a failure to the sender, that stdin is a file
**  we can rewind and seek on, which is true of uuxqt.
*/
	if( plural ) 
	{
		char *mktemp();

		( void ) mktemp( tmpf );
		if( ( file = fopen( tmpf, "w+" ) ) == NULL )
			error( EX_CANTCREAT, "can't create %s.\n", tmpf );
		while( fgets( line, SMLBUF, stdin ) != NULL )
			(void) fputs( line, file );
	} else {
		file = stdin;
	} 
/*
**  We pass through the list of addresses.
*/
	for( i = 0; i < argc; i++ )
	{
/*
**  If form == ERROR, either the address was bad or it has been sent on a
**  previous pass.  So we break out.
*/
		form = formv[i];
		if ( form == ERROR )
			continue;
/*
**  Rewind the input file for multiple copies (won't be stdin).  Call
**  rline() to read the first few lines to collapse a From argument
**  from the From_ and >From_ lines.  Rline() leaves the first unused
**  line in line.
*/
		if ( plural )
			rewind( file );
		rline( file, line, from );
/*
**  Build the command name based on whether this is local mail or
**  uucp mail.  Someday, this will use a form->mailer table.
*/
		(void) sprintf( lcommand, LMAIL( from, hostv[i] ) );
		(void) sprintf( rcommand, RMAIL( from, hostv[i] ) );
/*
**  For each address with the same host name and form, append the user
**  name to the command line, and set form = ERROR so we skip this address
**  on later passes. 
*/
		for ( j = argc - 1; j >= i; j-- ) {
			if ( formv[j] != form || strcmp( hostv[i], hostv[j] ) )
				continue;
			c = lcommand + strlen( lcommand );
			if (form == LOCAL)
				(void) sprintf( c, LARG( userv[j] ) );
			else
				(void) sprintf( c, RLARG(hostv[i], userv[j]) );
			c = rcommand + strlen( rcommand );
			(void) sprintf( c, RARG( userv[j] ) );
			formv[j] = ERROR;
		}
retry:
		if (form == LOCAL)
			command = lcommand;
		else
			command = rcommand;
		ADVISE( "COMMAND: %s\n", command );
/*
** Fork the mailer and set it up for writing so we can send the mail to it,
** or for debugging divert the output to stdout.
*/
		if ( debug == YES )
			out = stdout;
		else {
			failcount = 0;
			do {
				out = popen( command, "w" );
				if (out) break;
				/*
				 * Fork failed.  System probably overloaded.
				 * Wait awhile and try again 10 times.
				 * If it keeps failing, probably some
				 * other problem, like no uux or sendmail.
				 */
				(void) sleep(60);
			} while (++failcount < 10);
		}
		if( out == NULL )
		{
			exitstat = EX_UNAVAILABLE;
			(void) printf( "couldn't execute %s.\n", command );
			continue;
		}
/*
**  Output our From_ line.
*/
	if ( form == LOCAL ) {
#ifdef SENDMAIL
		(void) fprintf( out, LFROM( from, nows, hostname ) );
#else
		char *p;
		if((p=index(from, '!')) == NULL) {
			(void) fprintf( out, LFROM( from, nows, hostname ) );
		} else {
			*p = NULL;
			(void) fprintf(out, RFROM( p+1, nows, from));
			*p = '!';
		}
#endif
	} else {
		(void) fprintf( out, RFROM( from, nows, hostname ) );
	}
/*
**  Copy input.  Remember that line from rline().
*/
		size = 0;
		do {
			(void) fputs( line, out );
			size += strlen( line );
		} while( fgets( line, SMLBUF, file ) != NULL );

/*
**  Get exit status and if non-zero, set global exitstat so when we exit
**  we can indicate an error.
*/
		if ( debug != YES ) {
			if ( stat = pclose( out ) )
				exitstat = stat >> 8;
			/*
			 * handle==ALL means we're smail, else we're rmail.
			 * The check here prevents a smail<=>sendmail loop.
			 * The form check prevents an internal smail loop.
			 */
			if (handle != ALL && form != LOCAL && exitstat != 0) {
				/*
				 * RMAIL failed, probably because the host
				 * being uux'ed isn't in L.sys.  Try again
				 * using sendmail.  If there is no sendmail,
				 * we should include code ala the old rmail
				 * which mails it back to the sender.
				 */
				rewind(file);	/* assume uuxqt file */
				rline( file, line, from );
				form = LOCAL;
				exitstat = 0;	/* don't bother uuxqt */
				ADVISE("uux failed %d, trying sendmail\n", exitstat);
				goto retry;
			}
		}
	}
/*
**  Update logs and records.  Blech.
*/

# ifdef LOG
	log( command, from, size ); /* */
# endif
# ifdef RECORD
	rewind( file );
	out = record( command, from, size );
	if(out != NULL) {
		while( fgets( line, SMLBUF, file ) != NULL ) {
			(void) fputs( line, out );
		}
		(void) fclose( out );
	}
# endif

/*
**  Close and unlink temp file if we made one.
*/
	if ( plural )
	{
		(void) fclose( file );
		(void) unlink( tmpf );
	}
}


/*
**
**  rline(): collapse From_ and >From_ lines.
**
**  Same idea as the old rmail, but also turns user@domain to domain!user. 
**  Leaves the first line of the letter in "line".
**
*/

rline( file, line, from )
FILE *file;				/* source file			*/
char *line;				/* return first unused line	*/
char *from;				/* return accumulated from arg 	*/
{
	int parts;			/* for cracking From_ lines ... */
	char *partv[16];		/* ... apart using ssplit() 	*/
	char user[SMLBUF];		/* for rewriting user@host	*/
	char domain[SMLBUF];		/* "   "         "          	*/
	char addr[SMLBUF];		/* "   "         "          	*/
	enum eform form, parse();	/* "   "         "          	*/
	extern build();			/* "   "         "          	*/
	struct passwd *pwent, *getpwuid();		/* to get default user		*/
	char *c;

	(void) strcpy( from, "" );
	(void) strcpy( addr, "" );
	(void) strcpy( line, "" );
/*
**  Read each line until we hit EOF or a line not beginning with "From "
**  or ">From " (called From_ lines), accumulating the new path in from
**  and stuffing the actual sending user (the user name on the last From_ 
**  line) in addr.
*/
	for( ;; )
	{
		if ( fgets( line, SMLBUF, file )==NULL )
			break;
		if ( strncmp( "From ", line, 5 ) 
		    && strncmp( ">From ", line, 6 ) )
			break;
/*
**  Crack the line apart using ssplit.
*/
		if( c = index( line, '\n' ) );
			*c = '\0';
		parts = ssplit( line, ' ', partv );
/*
**  Tack host! onto the from argument if "remote from host" is present.
*/

		if ( parts > 3 
		    && !strncmp( "remote from ", partv[parts-3], 12 ) )
		{
			(void) strcat( from, partv[parts-1] );
			(void) strcat( from, "!" );
		} 
/*
**  Stuff user name into addr, overwriting the user name from previous 
**  From_ lines, since only the last one counts.  Then rewrite user@host 
**  into host!user, since @'s don't belong in the From_ argument.
*/
		(void) strncpy( addr, partv[1], partv[2]-partv[1]-1 ); 
		addr[partv[2]-partv[1]-1] = '\0';	/* ugh */

		(void) parse( addr, domain, user );
		if(*domain == '\0') {
			form = LOCAL;
		} else {
			form = UUCP;
		}

		build( domain, user, form, addr );
	}
/*
**  Now tack the user name onto the from argument.
*/
	(void) strcat( from, addr );
/*
**  If we still have no from argument, we have junk headers, but we try
**  to get the user's name using /etc/passwd.
*/
	if ( !*from )
		if ( ( pwent = getpwuid( getuid() ) ) == NULL )
			(void) strcpy( from, "nowhere" );	/* bad news */
		else
			(void) strcpy( from, pwent->pw_name );
}


# ifdef LOG
log(command, from, size)
char *command, *from;
long size;
{
	FILE *fd;
	char *logtime, *ctime();
	time_t t;
	int cmask;

	( void ) time( &t );
	logtime = ctime( &t );
	logtime[16] = 0;
	logtime += 4;

	cmask = umask(0);
	fd = fopen( LOG, "a" );
	(void) umask(cmask);

	if ( fd != NULL ) {
		(void) fprintf( fd, "%s: %s, from %s, %ld bytes\n", 
			logtime, command, from, size);
		(void) fclose( fd );
	}
}
# endif

# ifdef RECORD
FILE *
record( command, from, size)
char *command, *from;
long size;
{
	FILE *fd;
	char *logtime, *ctime();
	long t;
	int cmask;

	( void ) time( &t );
	logtime = ctime( &t );
	logtime[16] = 0;
	logtime += 4;

	cmask = umask(0);
	fd = fopen( RECORD, "a" );
	(void) umask(cmask);

	if ( fd != NULL ) {
		(void) fprintf( fd, "%s: %s, from %s, %ld bytes\n", 
			logtime, command, from, size);
	}
	return(fd);
}
# endif
END-OF-FILE

if [ "$filename" != "/dev/null" ]
then
  size=`wc -c < $filename`

  if [ $size != 10558 ]
  then
    echo $filename changed - should be 10558 bytes, not $size bytes
  fi

  chmod 644 $filename
fi

# ---------- file getopt.c ----------

filename="getopt.c"

if [ -f $filename ]
then
  echo File \"$filename\" already exists\!  Skipping...
  filename=/dev/null		# throw it away
else
  echo extracting file getopt.c...
fi

cat << 'END-OF-FILE' > $filename
/*
 * Here's something you've all been waiting for:  the AT&T public domain
 * source for getopt(3).  It is the code which was given out at the 1985
 * UNIFORUM conference in Dallas.  I obtained it by electronic mail
 * directly from AT&T.  The people there assure me that it is indeed
 * in the public domain.
 * 
 * There is no manual page.  That is because the one they gave out at
 * UNIFORUM was slightly different from the current System V Release 2
 * manual page.  The difference apparently involved a note about the
 * famous rules 5 and 6, recommending using white space between an option
 * and its first argument, and not grouping options that have arguments.
 * Getopt itself is currently lenient about both of these things White
 * space is allowed, but not mandatory, and the last option in a group can
 * have an argument.  That particular version of the man page evidently
 * has no official existence, and my source at AT&T did not send a copy.
 * The current SVR2 man page reflects the actual behavor of this getopt.
 * However, I am not about to post a copy of anything licensed by AT&T.
 */

/* This include is needed only to get "index" defined as "strchr" on Sys V. */
#include "defs.h"

/*LINTLIBRARY*/
#define NULL	0
#define EOF	(-1)
#define ERR(s, c)	if(opterr){\
	extern int strlen(), write();\
	char errbuf[2];\
	errbuf[0] = c; errbuf[1] = '\n';\
	(void) write(2, argv[0], (unsigned)strlen(argv[0]));\
	(void) write(2, s, (unsigned)strlen(s));\
	(void) write(2, errbuf, 2);}

extern int strcmp();
extern char *index();

int	opterr = 1;
int	optind = 1;
int	optopt;
char	*optarg;

int
getopt(argc, argv, opts)
int	argc;
char	**argv, *opts;
{
	static int sp = 1;
	register int c;
	register char *cp;

	if(sp == 1)
		if(optind >= argc ||
		   argv[optind][0] != '-' || argv[optind][1] == '\0')
			return(EOF);
		else if(strcmp(argv[optind], "--") == NULL) {
			optind++;
			return(EOF);
		}
	optopt = c = argv[optind][sp];
	if(c == ':' || (cp=index(opts, c)) == NULL) {
		ERR(": illegal option -- ", c);
		if(argv[optind][++sp] == '\0') {
			optind++;
			sp = 1;
		}
		return('?');
	}
	if(*++cp == ':') {
		if(argv[optind][sp+1] != '\0')
			optarg = &argv[optind++][sp+1];
		else if(++optind >= argc) {
			ERR(": option requires an argument -- ", c);
			sp = 1;
			return('?');
		} else
			optarg = argv[optind++];
		sp = 1;
	} else {
		if(argv[optind][++sp] == '\0') {
			sp = 1;
			optind++;
		}
		optarg = NULL;
	}
	return(c);
}
END-OF-FILE

if [ "$filename" != "/dev/null" ]
then
  size=`wc -c < $filename`

  if [ $size != 2456 ]
  then
    echo $filename changed - should be 2456 bytes, not $size bytes
  fi

  chmod 644 $filename
fi

# ---------- file main.c ----------

filename="main.c"

if [ -f $filename ]
then
  echo File \"$filename\" already exists\!  Skipping...
  filename=/dev/null		# throw it away
else
  echo extracting file main.c...
fi

cat << 'END-OF-FILE' > $filename
/*
**
**  Rmail/Smail - UUCP mailer with automatic routing.
**
**  Christopher Seiwald		/+\
**  cbosgd!chris		+\
**  January, 1985		\+/
**
*/

#ifndef lint
static char 	*sccsid="@(#)main.c	1.5  (UUCP-Project/CS)  6/9/86";
#endif

/*
**
**  usage:  	rmail [options] address...
**		smail [options] address...
**  options:
**		-d 	debug - verbose and don't invoke mailers.
**		-v	verbose - just verbose.
**		-h hostname	set hostname (default GETHOSTNAME,
**				UNAME, or HOSTNAME)
**		-H hostdomain	set hostdomain (default hostname.MYDOM)
**		-p pathfile	path database filename
**		(without both -r and -R, only user@domain gets routed)
**		-r	force routing of host!address
**		-R	reroute even explicit path!user
**		(without both -l and -L, only local mail goes local)
**		-l	user@domain goes to local mailer
**		-L	all mail goes local
**
**  -r, -R, -l, and -L can be preset in defs.h  Smail clears -l and -L.
**
*/

#include	<stdio.h>
#include	<ctype.h>
#include	"defs.h"

#ifdef UNAME
#include	<sys/utsname.h>
#endif


int exitstat = 0;		/* exit status, set by resolve, deliver	*/
enum edebug debug = NO;		/* set by -d or -v option		*/
enum ehandle handle = HANDLE;	/* which mail we can handle, see defs.h	*/
enum erouting routing = ROUTING;/* to route or not to route, see defs.h */
char hostname[SMLBUF] = "";	/* set by -h, defaults in defs.h 	*/
char hostdomain[SMLBUF] = "";	/* set by -H, defaults in defs.h 	*/
char *pathfile = PATHS;		/* or set by -p 			*/


/*
**
**  Rmail/Smail: mail stdin letter to argv addresses.
**
**  After processing command line options and finding our host and domain 
**  names, we map addresses into <host,user,form> triples.  Then we deliver.
**
*/

main( argc, argv )
int argc;
char **argv;
{
	char *hostv[MAXARGS];		/* UUCP neighbor 		*/
	char *userv[MAXARGS];		/* address given to host 	*/
	enum eform formv[MAXARGS];	/* invalid, local, or uucp 	*/
	char *p;
	int c;

	char *optstr = "dvrRlLH:h:p:";
	extern char *optarg;
	extern int optind;

/*
**  see if we aren't invoked as rmail
*/
	if((p = rindex(argv[0], '/')) == NULL) {
		p = argv[0];
	} else {
		p++;
	}

	if(*p != 'r' ) {
		handle = ALL;
	}

/*
**  Process command line arguments ( maybe getopt()? ).
*/
	while ((c = getopt(argc, argv, optstr)) != EOF) {
		switch ( c ) {
		case 'd': debug = YES; 			break;
		case 'v': debug = VERBOSE; 		break; 
		case 'r': routing = ALWAYS;		break;
		case 'R': routing = REROUTE;		break;
		case 'l': handle = JUSTUUCP;		break;
		case 'L': handle = NONE;		break;
		case 'H': (void) strcpy( hostdomain, optarg );	break;
		case 'h': (void) strcpy( hostname, optarg ); 	break;
		case 'p': pathfile = optarg; 		break;
		default:
			error( EX_USAGE, "valid flags are %s\n", optstr);
		}
	}
	if ( argc <= optind ) {
		error( EX_USAGE, "usage: %s [flags] address...\n", argv[0] );
	}

/*
**  Get our default hostname and hostdomain.
*/
	getmynames();
/*
**  Map argv addresses to <host, user, form>.
*/
	map( (argc - optind), &argv[optind], hostv, userv, formv );
/*
**  Deliver.
*/
	deliver( (argc - optind), hostv, userv, formv );
/*
**  Exitstat was set if any resolve or deliver failed, otherwise 0.
*/
	exit( exitstat );
}


/*
**
**  map(): map addresses into <host, user, form> triples.
**
**  Calls resolve() for each address of argv.  The result is hostv and 
**  userv arrays (pointing into buffers userz and hostz), and formv array.
**
*/

map( argc, argv, hostv, userv, formv )
int argc;				/* address count 		*/
char **argv;				/* address vector 		*/
char *hostv[];				/* remote host vector 		*/
char *userv[];				/* user name vector 		*/
enum eform formv[];			/* address format vector 	*/
{
	int i;
	enum eform resolve();
	char *c, *malloc();
	char *userz = malloc( BIGBUF );
	char *hostz = malloc( BIGBUF );

	for( i=0; i<argc; i++ )
	{
		userv[i] = userz;		/* put results here */
		hostv[i] = hostz;
		if ( **argv == '(' )		/* strip () */
		{
			++*argv;
			c = index( *argv, ')' );
			if (c)
				*c = '\0';
		}
						/* here it comes! */
		formv[i] = resolve( *argv++, hostz, userz );
		userz += strlen( userz ) + 1;	/* skip past \0 */
		hostz += strlen( hostz ) + 1;
	}
}


/*
**
**  getmynames(): what is my host name and host domain?
**
**  Hostname set by -h, failing that by #define HOSTNAME, failing
**  that by gethostname() or uname().
**  
**  Hostdomain set by -h, failing that by #define HOSTDOMAIN,
**  failing that as hostname.MYDOM, or as just hostname.
**
**  See defs.h for the inside story.
**
*/

getmynames()
{
#ifdef HOSTNAME
	if ( !*hostname )
		(void) strcpy( hostname, HOSTNAME );
#endif
#ifdef GETHOSTNAME
	if ( !*hostname )
		gethostname( hostname, sizeof( hostname ) - 1 );
#endif
#ifdef UNAME
	if ( !*hostname ) {
		struct utsname site;

		if ( uname( &site ) < 0 )
			error( EX_SOFTWARE, "uname() call failed", 0 );
		(void) strcpy( hostname, site.nodename );
	}
#endif
	if ( !*hostname )
		error( EX_SOFTWARE, "can't determine hostname.\n", 0 );
#ifdef HOSTDOMAIN
	if ( !*hostdomain )
		(void) strcpy( hostdomain, HOSTDOMAIN );
#endif
#ifdef MYDOM
	if ( !*hostdomain )
		(void) strcat( strcpy( hostdomain, hostname ), MYDOM );
#endif
	if ( !*hostdomain )
		(void) strcpy( hostdomain, hostname );

}


/*
**  ssplit(): split a line into array pointers.
**
**  Each pointer wordv[i] points to the first character after the i'th 
**  occurence of c in buf.  Note that each wordv[i] includes wordv[i+1].
**
*/

ssplit( buf, c, ptr )
register char *buf;		/* line to split up 		*/
char c;				/* character to split on	*/
char **ptr;			/* the resultant vector		*/
{
        int count = 0;
        int wasword = 0;

        for( ; *buf; buf++ )
        {
		if ( !wasword )
			count++, *ptr++ = buf;
		wasword = ( c != *buf );
        }
	if ( !wasword )
		count++, *ptr++ = buf;
        *ptr = NULL;
        return( count );
}
END-OF-FILE

if [ "$filename" != "/dev/null" ]
then
  size=`wc -c < $filename`

  if [ $size != 5792 ]
  then
    echo $filename changed - should be 5792 bytes, not $size bytes
  fi

  chmod 644 $filename
fi

# ---------- file resolve.c ----------

filename="resolve.c"

if [ -f $filename ]
then
  echo File \"$filename\" already exists\!  Skipping...
  filename=/dev/null		# throw it away
else
  echo extracting file resolve.c...
fi

cat << 'END-OF-FILE' > $filename
/*
**
**  Resolve.c
**
**  Routes then resolves addresses into UUCP or LOCAL.
**
*/
#ifndef lint
static char 	*sccsid="@(#)resolve.c	1.9   (UUCP-Project/CS)   6/27/86";
#endif

#include	<ctype.h>
#include	<stdio.h>
#include	"defs.h"

extern int exitstat;		/* set if address doesn't resolve 	*/
extern enum ehandle handle;	/* what mail we can handle		*/
extern enum edebug debug;	/* verbose and debug modes		*/
extern enum erouting routing;	/* when to route addresses		*/
extern char hostdomain[];	/* for qualifying abbreviated addr's	*/
extern char *pathfile;		/* location of path database		*/


/*
**
**  rsvp(): how to resolve addresses.
**
**  After parsing an address into <form>, the resolved form will be
**  rsvp( form ).  If == ROUTE, we route the parsed address and parse again.
**
*/

# define rsvp(a) table[(int)a][(int)handle]

enum eform table[5][3] = {
/*	all		uucponly	none */
{	ERROR, 		ERROR, 		ERROR }, 	/* error */
{	LOCAL, 		LOCAL,	 	LOCAL }, 	/* local */
{	ROUTE, 		LOCAL, 		LOCAL }, 	/* domain */
{	UUCP, 		UUCP, 		LOCAL }, 	/* uucp */
{	ERROR, 		ERROR, 		ERROR }};	/* route */


/*
**  NOTE: in this module <domainv> replaces <hostv>. <domainv> contains 
**  the domain part of each address, though by the time it leaves here it 
**  can only be a host name.
*/


/*
**
**  resolve(): resolve addresses to <host, user, form>.
**
**  This is a gnarly piece of code, but it does it all.  Each section 
**  is documented.
**
*/

enum eform resolve( address, domain, user )
char *address;				/* the input address 	*/
char *domain;				/* the returned domain 	*/
char *user;				/* the returned user 	*/
{
	enum eform form;		/* the returned form	*/ 
	enum eform parse();		/* to crack addresses	*/
	int parts;			/* to ssplit addresses	*/
	char *partv[MAXPATH];		/* "  "      "		*/
	char temp[SMLBUF];		/* "  "      "		*/
	int i;
		

/*
**  If we set REROUTE and are prepared to deliver UUCP mail, we split the 
**  address apart at !'s and try to resolve successively larger righthand 
**  substrings until we succeed.  Regularly, we just resolve the whole thing 
**  once.
*/
	if ( routing == REROUTE && rsvp( UUCP ) == UUCP )
		parts = ssplit( address, '!', partv );
	else
		parts = 1, partv[0] = address;
/*
**  This for( i ) loop selects successively larger righthand substrings 
**  for BULLYing, see above. 
*/
	for( i = parts - 1; i >= 0; i-- )
	{
/*
**  Parse the address.  If we are BULLYing and our substring parses to 
**  the LOCAL address, we skip to the next larger.
*/
		(void) strcpy( temp, partv[i] );
		form = parse( temp, domain, user );
	DEBUG("parse address '%s' = %s @ %s (%d)\n",temp,user,domain,form);
		if ( i && form==LOCAL )
			continue;
/*
**  Routing is next step, so we break out if we don't have a UUCP form (if 
**  we are set to route ALWAYS or REROUTE) or a ROUTE form.
*/
		if ( rsvp( form ) != ROUTE && 
		    ( rsvp( form ) != UUCP || routing == JUSTDOMAIN ) )
			break;
/*
**  Apply router.  If BULLYing and routing failed, try next larger substring.
*/
		if ( route( form, domain, user, temp ) )
			continue;
/*
**  After routing, reparse and resolve.
*/
		form = parse( temp, domain, user );
	DEBUG("parse route '%s' = %s @ %s (%d)\n",temp,user,domain,form);
		break;
	}
/*
**  For LOCAL mail in non-local format, we rewrite the full address into 
**  <user> and leave <domain> blank.
*/
	if ( rsvp( form ) == LOCAL && form != LOCAL )
	{
		build( domain, user, form, temp );
		(void) strcpy( user, temp );
		(void) strcpy( domain, "" );
		form = LOCAL;
	}
/*
**  If we were supposed to route and address but failed (form == ERROR), 
**  or after routing once we are left with an address that still needs to
**  be routed (rsvp( form ) == ROUTE), complain.  It is possible that we 
**  may want to resolve this address more than once (if the routing tables
**  return a domain-style address), but most likely this address partially 
**  resolved to this host.
*/
	if ( form == ERROR || rsvp( form ) == ROUTE )
	{
		exitstat = EX_NOHOST;
		(void) printf( "%s...couldn't resolve %s.\n", address, domain );
		form = ERROR;
	}
	ADVISE("resolve '%s' = %s @ %s (%d)\n",address,user,domain,form);
	return ( form );
}


/*
**
** parse(): parse <address> into <domain, user, form>.
**
** 	input		form
**	-----		----
**	user		LOCAL
**	domain!user	DOMAIN
**	user@domain	DOMAIN
**	@domain,address	LOCAL	(just for sendmail)
**	host!address	UUCP
**
*/

enum eform parse( address, domain, user )
char *address;		/* input address 	*/
char *domain;		/* output domain 	*/
char *user;		/* output user 		*/
{
	int parts;
	char *partv[MAXPATH];				/* to crack address */

/*
**  If this is route address form @hosta,@hostb:user@hostd, break for
**  LOCAL since only sendmail would want to eat it.
*/
	if ( *address == '@' )
		goto local;
/*
**  Try splitting at !. If it works, see if the piece before the ! has
**  a . in it (domain!user, form DOMAIN) or not (host!user, form UUCP).
*/
	if ( ssplit( address, '!', partv ) > 1 )
	{
		(void) strcpy( user, partv[1] );
		(void) strncpy( domain, partv[0], partv[1]-partv[0]-1 );
		domain[partv[1]-partv[0]-1] = '\0';
		if( ( parts = ssplit( domain, '.', partv ) ) < 2 )
			return( UUCP );
		if( partv[parts-1][0] == '\0' )	
			partv[parts-1][-1] = '\0'; /* strip trailing . */
		return ( DOMAIN );
	}
/*
**  Try splitting at @.  If it work, this is user@domain, form DOMAIN.
**  Prefer the righthand @ in a@b@c.
*/
	if ( ( parts = ssplit( address, '@', partv ) ) >= 2 )
	{
		(void) strcpy( domain, partv[parts-1] );
		(void) strncpy( user, partv[0], partv[parts-1]-partv[0]-1 );
		user[partv[parts-1]-partv[0]-1] = '\0';
		return ( DOMAIN );
	} 
/* 
**  Done trying.  This must be just a user name, form LOCAL.
*/
local:
	(void) strcpy( user, address );
	(void) strcpy( domain, "" );
	return( LOCAL );				/* user */
}


/*
**
**  route(): route domain, plug in user.
**
**  Less complicated than it looks.  Each section is documented.
**
*/

route( form, domain, user, result )
enum eform form;		/* domain is UUCP host? */
char *domain;			/* domain or host name 	*/
char *user;			/* user name 		*/
char *result;			/* output route 	*/
{
	int	domains, step;			/* to split domain	*/
	char	*domainv[MAXDOMS];		/* "  "     "		*/
	char	temp[SMLBUF], path[SMLBUF];

/*
**  Fully qualify the domain, and then strip the last (top level domain) 
**  component off, so that we look it up separately.
*/
	(void) strcpy( temp, ".");
	(void) strcat( temp, domain );

	domains = ssplit( temp+1, '.', domainv );
	/* If the domain ends in .UUCP, trim that off. */
	if ( domains && isuucp(domainv[domains-1]))
		domainv[domains-1][-1] = '\0';
/*
**  Try to get the path for successive components of the domain.  
**  Example for osgd.cb.att.uucp:
**	osgd.cb.att
**	cb.att
**	att
**	uucp ( remember stripping top level? )
**  Returns with error if we find no path.
*/
	step = 0;
	while ( step<domains && getpath( domainv[step]-1, path )  /* w/dot */
			     && getpath( domainv[step]  , path ) )/* no dot */
		step++;
	if ( step == domains )
	{
		DEBUG( "getpath '%s' failed\n", domain );
		return( EX_NOHOST );
	}
	DEBUG("getpath '%s' (%s) = %s\n",domain,domainv[step],path);

/*
**  If we matched on the entire domain name, this address is fully resolved, 
**  and we plug <user> into it.  If we matched on only part of the domain 
**  name, we plug <domain>!<user> in.  
*/
	build( domain, user, step ? UUCP:LOCAL, temp+1 );
	(void) sprintf( result, path, temp+1 );
	return( EX_OK );
}

/*
 * Return 1 iff the string is "UUCP" (ignore case).
 */
isuucp(str)
char *str;
{
	if (lower(*str) != 'u') return 0;
	++str;
	if (lower(*str) != 'u') return 0;
	++str;
	if (lower(*str) != 'c') return 0;
	++str;
	if (lower(*str) != 'p') return 0;
	++str;
	if (*str != '\0') return 0;
	return 1;
}

/*
**
** qualifydomain(): turn domain into full domain name.
**
** Best explained by examples, if hostdomain = a.b.c.UUCP
**	host.domain.UUCP -> host.domain.UUCP
**	host.b -> host.b.c.UUCP
**	host.x -> host.x.UUCP
**
*/

/* qualifydomain():
 * Taken out 3/21/86 by MRH - if hostdomain is, say. a.b.c.COM,
 * and domain is x.UUCP, it turns it into x.UUCP.COM and then
 * barfs on it.  I don't see a way to handle PQN's this easily.
 */

build( domain, user, form, result )
char *domain;
char *user;
enum eform form;
char *result;
{
	switch( form )
	{
	case LOCAL:
		(void) sprintf( result, "%s", user ); 
		break;
	case UUCP:
		(void) sprintf( result, "%s!%s", domain, user );
		break;
	case DOMAIN:
		(void) sprintf( result, "%s@%s", user, domain );
		break;
	}
}



/*
**
** getpath(): look up key in ascii sorted path database.
**
** Binary searches a la look(1).  Sort -f to fold cases.
**
*/

getpath( key, path )
char *key;		/* what we are looking for */
char *path;		/* where the results go */
{
	long pos, middle, hi, lo;
	static long pathlength = 0;
	register char *s;
	int c;
	static FILE *file;
	int flag;

	if( !pathlength )	/* open file on first use */
	{
		if( ( file=fopen( pathfile, "r" ) ) == NULL )
		{
			(void) printf( "can't access %s.\n", pathfile );
			pathlength = -1;
		} else {
			(void) fseek( file, 0L, 2 );		/* find length */
			pathlength = ftell( file );
		}
	}
	if( pathlength == -1 )
		return( EX_OSFILE );

	lo = 0;
	hi = pathlength;
	(void) strcpy( path, key );
	(void) strcat( path, "\t" );
/*
** "Binary search routines are never written right the first time around."
** - Robert G. Sheldon.
*/
	for( ;; ) 
	{
		pos = middle = ( hi+lo+1 )/2;
		(void) fseek( file, pos, 0 );	/* find midpoint */
		if ( pos )		/* to beginning of next line */
			while( ( c=getc( file ) ) != EOF && c != '\n' );
		for( flag = 0, s = path; !flag; s++ ) /* match??? */
		{
			if ( *s == '\0' )
				goto solved;
			c = getc( file );
			flag = lower( c ) - lower( *s );
		} 
		if ( lo>=middle )		/* failure? */
			return( EX_NOHOST );
		if ( c != EOF && flag < 0 )	/* close window */
			lo = middle;
		else 
			hi = middle - 1;
	} 
/* 
** Now just copy the result.
*/
solved:
	while( ( c=getc( file ) ) != EOF && c != '\n' )
		*path++ = c;
	*path = '\0';
	return ( EX_OK );
}
END-OF-FILE

if [ "$filename" != "/dev/null" ]
then
  size=`wc -c < $filename`

  if [ $size != 10038 ]
  then
    echo $filename changed - should be 10038 bytes, not $size bytes
  fi

  chmod 644 $filename
fi

# ---------- file sendmail.att ----------

filename="sendmail.att"

if [ -f $filename ]
then
  echo File \"$filename\" already exists\!  Skipping...
  filename=/dev/null		# throw it away
else
  echo extracting file sendmail.att...
fi

cat << 'END-OF-FILE' > $filename
This is a diff between the distributed sendmail.cf file in this
directory and the actual sendmail.cf run on cbosgd.  The only
changes are filling in ATT.COM in place of orgname.COM, and
our local convention for CEM.  Other AT&T sites may wish to
support the CEM syntax by handing off to ihnp4 (as this does)
or otherwise.  This doesn't apply to non-AT&T sites, which should
only fill in orgname.

The sendmail.cf file here makes the host a gateway into and out of
the organization.  This is probably appropriate for the first machine
to bring up smail, but for less well-known machines you may prefer
the sendmail.leaf file or a simpler locally developed sendmail.cf.

*** sendmail.cf	Mon Jun  9 16:14:53 1986
--- /usr/lib/sendmail.cf	Mon Jun  9 16:16:50 1986
***************
*** 29,37
  # Until you register you can use orgname.UUCP for testing.
  
  #Dwhost
! DDorgname.COM
! DAorgname.UUCP
! CDUUCP orgname
  
  # Preemptive ether and UUCP connections.  We prefer these connections 
  # over both designated transport mechanisms and the general depository.

--- 29,37 -----
  # Until you register you can use orgname.UUCP for testing.
  
  #Dwhost
! DDATT.COM
! DAATT.UUCP
! CDUUCP ATT
  
  # Preemptive ether and UUCP connections.  We prefer these connections 
  # over both designated transport mechanisms and the general depository.
***************
*** 280,285
  #R$*<@$*>$*		$#uux$@$R$:$1@$2$3		hand to uucp relay
  #R$*<@$*>$*		$#ether$@$R$:$1@$2$3		hand to ether relay
  #R$*<$*>$*		$#error$:unkown address $1$2$3	don't hand anywhere
  
  # local delivery
  R$+			$#local$:$1			user

--- 280,288 -----
  #R$*<@$*>$*		$#uux$@$R$:$1@$2$3		hand to uucp relay
  #R$*<@$*>$*		$#ether$@$R$:$1@$2$3		hand to ether relay
  #R$*<$*>$*		$#error$:unkown address $1$2$3	don't hand anywhere
+ 
+ # AT&T CEM f.m.last /CBOSGD
+ R$-.$+			$#uux$@ihnp4$:$1.$2		AT&T CEM f.m.last
  
  # local delivery
  R$+			$#local$:$1			user
END-OF-FILE

if [ "$filename" != "/dev/null" ]
then
  size=`wc -c < $filename`

  if [ $size != 1919 ]
  then
    echo $filename changed - should be 1919 bytes, not $size bytes
  fi

  chmod 644 $filename
fi

# ---------- file sendmail.leaf ----------

filename="sendmail.leaf"

if [ -f $filename ]
then
  echo File \"$filename\" already exists\!  Skipping...
  filename=/dev/null		# throw it away
else
  echo extracting file sendmail.leaf...
fi

sed 's/^X//' << 'END-OF-FILE' > $filename
XDate: Thu, 29 May 86 14:28:47 edt
XFrom: avolio@decuac.DEC.COM (Frederick M. Avolio)
X
XThese changes are useful for a simple UUCP site with only one neighbor,
Xwhich does not run smail but does run sendmail.  It passes all mail to
Xthe neighbor, which must run smail.
X
X----------
X*** ORIGsendmail.cf	Sat Feb 15 23:27:33 1986
X--- sendmail.cf	Thu May 29 14:20:06 1986
X  ###############################
X  ###   Message precedences   ###
X***************
X*** 304,309
X  # if you just want general disposition.
X  
X  #R$+<@$-.UUX>		$#smail$@$:$2!$1		any uucp via smail
X  R$*<@$+.ETHER>$*	$#ether$@$2$:$1$3		etherhost
X  
X  # Send all foreign mail to general disposition now, and everything else
X
X--- 304,311 -----
X  # if you just want general disposition.
X  
X  #R$+<@$-.UUX>		$#smail$@$:$2!$1		any uucp via smail
X+ R$+<@$=U.UUX>	$#uux$@$2$:$1			any uucp via uux
X+ R$+<@$-.UUX>		$#uux$@$R$:$2!$1
X  R$*<@$+.ETHER>$*	$#ether$@$2$:$1$3		etherhost
X  
X  # Send all foreign mail to general disposition now, and everything else
X***************
X*** 322,327
X  
X  R$+			$#smail$@$:$1			hand to smail
X  #R$+			$#smail$@$:$R!$1		hand to uucp relay
X  #R$+			$#ether$@$R$:$1			hand to ether relay
X  #R$+			$#error$:unknown address $1	don't hand anywhere
X  
X
X--- 324,331 -----
X  
X  R$+			$#smail$@$:$1			hand to smail
X  #R$+			$#smail$@$:$R!$1		hand to uucp relay
X+ R$*@$*		$#uux$@$R$:$2!$1
X+ R$+			$#uux$@$R$:$1			hand to uucp relay
X  #R$+			$#ether$@$R$:$1			hand to ether relay
X  #R$+			$#error$:unknown address $1	don't hand anywhere
END-OF-FILE

if [ "$filename" != "/dev/null" ]
then
  size=`wc -c < $filename`

  if [ $size != 1509 ]
  then
    echo $filename changed - should be 1509 bytes, not $size bytes
  fi

  chmod 644 $filename
fi

# ---------- file smail.cf.fix ----------

filename="smail.cf.fix"

if [ -f $filename ]
then
  echo File \"$filename\" already exists\!  Skipping...
  filename=/dev/null		# throw it away
else
  echo extracting file smail.cf.fix...
fi

cat << 'END-OF-FILE' > $filename
Here is a note regarding the changes made at randvax to help handle
822 domain issues.  I don't claim this is a 100% solution, but it should
be worth some study.  This is supposed to be a fix to the problem that
vanilla 4.2 and 4.3BSD sendmails add their name and a ! to a legal RFC822
address, turning it into an illegal 822 address.

-----
-----

[terry%owl]

Here's the change I made:

S13
R$+			$:$>5$1				convert to old style
R$+<@$=w>		$:$1				strip @localhost (trw)
R$+@$=w			$:$1				strip @localhost (trw)
R$+@$=w.arpa		$:$1				strip @localhost (trw)
# trw: don't append our hostname to addresses with @s,
#  or to uucp addresses we don't talk to--class X
#  contains a list of sites we talk to.
R$+@$+			$@$1@$2				stop evaluation
R$=U!$+			$2				strip local name
R$=X!$+			$@$U!$1!$2			stick on our host name
R$+!$+			$@$1!$2				don't prepend our host
R$+			$:$U!$1				stick on our host name
END-OF-FILE

if [ "$filename" != "/dev/null" ]
then
  size=`wc -c < $filename`

  if [ $size != 902 ]
  then
    echo $filename changed - should be 902 bytes, not $size bytes
  fi

  chmod 644 $filename
fi

# ---------- file smail.cf.form ----------

filename="smail.cf.form"

if [ -f $filename ]
then
  echo File \"$filename\" already exists\!  Skipping...
  filename=/dev/null		# throw it away
else
  echo extracting file smail.cf.form...
fi

cat << 'END-OF-FILE' > $filename
############################################################
############################################################
#####
#####		SENDMAIL CONFIGURATION FILE
#####
#####	UUCP project prototype: supports domain style 
#####   addressing over UUCP and ethernet links.
#####
#####   A product of the UUCP Project.
#####
#####		@(#)smail.cf.form	1.11   (UUCP-Project/CS)   7/13/86
#####
############################################################
############################################################


############################################################
###
###  Local configuration options - HINTS
###

# Host name and domain name macros.  Dw set $w, DD sets $D, and
# CD sets $=D.  Most sendmails set $w to `hostname`, so you can 
# probably leave out Dw.  $D and $=D lists all domains in which this 
# host sits, and $D goes into outbound addresses, i.e. "user@$w.$D".
# $A is another domain for which this host is authoratative, which
# will be turned into $D.

CF_HOST
CF_DOMAIN
CF_AUTHORITY
CF_DCLASS

# Preemptive ether and UUCP connections.  We prefer these connections 
# over both designated transport mechanisms and the general depository.
# You can add more classes (here and in S0).

# /etc/hosts.smtp might be a link to /etc/hosts
CF_SMTP
FU/dev/null %s

# Mock top-level domain names.  These name designate a transport mechanism
# and appear internally only, set in S3, used in S0, and removed in S4 and
# (possibly) the ruleset for the particular mailer.  

CTETHER UUX

# Relay host.  Used at the end of S0 as the general depository for 
# addresses which didn't resolve locally.  

DRrelay

###
###  End Local configuration options
###
############################################################

############################################################
#
#	General configuration information
#
#	This information is basically just "boiler-plate"; it must be
#	there, but is essentially constant.
#
#	Information in this file should be independent of location --
#	i.e., although there are some policy decisions made, they are
#	not specific to Berkeley per se.
#
#		@(#)base.m4	4.3		8/30/83
#
############################################################

DVUUCP-Project/rel-1.0/CF_DATE

##########################
###   Special macros   ###
##########################

# official hostname
Dj$w.$D
# my name
DnMAILER-DAEMON
# UNIX header format
DlFrom $g  $d
# delimiter (operator) characters
Do.:%@!^=/[]
# format of a total name
Dq$g$?x ($x)$.
# SMTP login message
De$j Sendmail $v/$V ready at $b


###################
###   Options   ###
###################

# location of alias file
OA/usr/lib/aliases
# default delivery mode (deliver in background)
Odbackground
# (don't) connect to "expensive" mailers
#Oc
# temporary file mode
OF0644
# default GID
Og1
# location of help file
OH/usr/lib/sendmail.hf
# log level
OL9
# default messages to old style
Oo
# queue directory
OQ/usr/spool/mqueue
# read timeout -- violates protocols
Or2h
# status file
OS/usr/lib/sendmail.st
# queue up everything before starting transmission
Os
# default timeout interval
OT3d
# time zone names (V6 only)
OtPST,PDT
# default UID
Ou1
# wizard's password
OWtZWoIRijHq0EQ

###############################
###   Message precedences   ###
###############################

Pfirst-class=0
Pspecial-delivery=100
Pjunk=-100

#########################
###   Trusted users   ###
#########################

Troot
Tdaemon
Tuucp
Tnetwork

#############################
###   Format of headers   ###
#############################

#H?P?Return-Path: <$g>
HReceived: $?sfrom $s 
	$.by $j ($v/$V)
	id $i; $b
H?D?Resent-Date: $a
H?D?Date: $a
H?F?Resent-From: $q
H?F?From: $q
H?x?Full-Name: $x
HSubject:
# HPosted-Date: $a
# H?l?Received-Date: $b
H?M?Resent-Message-Id: <$t.$i@$j>
H?M?Message-Id: <$t.$i@$j>

############################################################
############################################################
#####
#####		REWRITING RULES
#####


###########################
#  Name Canonicalization  #
###########################
S3

# basic textual canonicalization
R<>			$@@				turn into magic token
R$*<$+>$*		$2				basic RFC821/822 parsing
R$+ at $+		$1@$2				"at" -> "@" for RFC 822
R$*<$*>$*		$1$2$3				in case recursive

# handle route-addr <@a,@b,@c:user@d> 
R@$+,$+			@$1:$2				change all "," to ":"
R@$+:$+			$@<@$1>:$2			handle <route-addr>
R$+:$*;@$+		$@$1:$2;@$3			list syntax

# Rewrite address into a domain-based address.  Any special mock domain names 
# (like UUX) should be defined on the CT line and removed (if necessary) 
# in S4.  You can use them in S0 for designated transport mechanisms.

# Delimiters with precendence over @.  Add yours here.

# The @ delimiter.  Leave this alone.
R$+@$+			$:$1<@$2>			focus on domain
R$+<$+@$+>		$1$2<@$3>			move gaze right
R$+<@$+>		$@$1<@$2>			already canonical

# Delimiters with precendece below @.  Add yours here.
R$+^$+			$1!$2				convert ^ to !
R$+!$-.$+!$+		$:$2.$3!$4			prefer domain /CBOSGD
R$-!$+			$@$2<@$1.UUX>			resolve uucp names
R$+.!$+			$@$2<@$1>			domain.!host
R$+!$+			$@$2<@$1>			domain!host

# % is a low precedence @.
R$*%$*			$@$>3$1@$2			%->@ and retry

############################################################
############################################################
#####
#####		RULESET ZERO PREAMBLE
#####
#####		UUCP Project 11/01/85
#####
############################################################
############################################################

S0

# first make canonical
R$*<$*>$*		$1$2$3				defocus
R$+			$:$>3$1				make canonical

# handle special cases.....
R@			$#local$:MAILER-DAEMON		handle <> form
R$*<@[$+]>$*		$#tcp$@[$2]$:$1@[$2]$3		numeric internet spec

# strip local stuff
R$*<$*$w.$D>$*		$1<$2>$3			thishost.mydom
CF_GATEWAYR$*<$*$D>$*		$1<$2>$3			mydom
R$*<$*$w.$=D>$*		$1<$2>$4			thishost.anydom
R$*<$*$w.$A>$*		$1<$2>$3			thishost.anotherdom
R$*<$*$A>$*		$1<$2>$3			anotherdom
R$*<$*$w.$=T>$*		$1<$2>$4			thishost.mockdom
CF_GATEWAYR$*<$*$w>$*		$1<$2>$3			thishost
R$*<$*.>$*		$1<$2>$3			drop trailing dot
R<@>:$+			$@$>0$1				strip null route, retry
R$+<@>			$@$>0$1				strip null addr, retry


###############################################
###  Machine dependent part of rulset zero  ###
###############################################

# Preemption: for a host on a known link turn the domain spec into a
# mock domain indicating the link.  One set of these rules for each of 
# the F classes listed in the local configuration options.

R$*<$*$=U.$D>$*			$:$1<$2$3.UUX>$4	uuxhost.mydomain
R$*<$*$=U.$=D>$*		$:$1<$2$3.UUX>$5	uuxhost.anydomain
R$*<$*$=U.$A>$*			$:$1<$2$3.UUX>$4	uuxhost.anotherdomain
R$*<$*$=U.$=T>$*		$:$1<$2$3.UUX>$5	uuxhost.mock-domain
R$*<$*$=U>$*			$:$1<$2$3.UUX>$4	uuxhost

R$*<$*$=E.$D>$*			$:$1<$2$3.ETHER>$4	etherhost.mydomain
R$*<$*$=E.$=D>$*		$:$1<$2$3.ETHER>$5	etherhost.anydomain
R$*<$*$=E.$A>$*			$:$1<$2$3.ETHER>$4	etherhost.anotherdomain
R$*<$*$=E.$=T>$*		$:$1<$2$3.ETHER>$5	etherhost.mock-domain
R$*<$*$=E>$*			$:$1<$2$3.ETHER>$4	etherhost

# Designated delivery: use the indicated transport mechanism.  One of
# these rules for each of the mock domains defined in $=T.  You can
# remove these if you just want general disposition.  HINTS.

# Designated delivery:
R$*<@$=U.UUX>$*		$#uux$@$2$:$1$3			known uucphost
R$*<@$+.ETHER>$*	$#ether$@$2$:$1@$2$3		etherhost

# throw out mock domain name now
R$*<$*.$=T>$*		$1<$2>$4

# General disposition of remote mail (comment out all but one).  You
# might add to this list, if you have other "smarter" mailers.  HINTS.

R$*<@$*>$*		$#uux$@$2$:$1$3			hand to uucp
#R$*<@$*>$*		$#uux$@$R$:$1@$2$3		hand to uucp relay
#R$*<@$*>$*		$#ether$@$R$:$1@$2$3		hand to ether relay
#R$*<$*>$*		$#error$:unkown address $1$2$3	don't hand anywhere

# local delivery
R$+			$#local$:$1			user

############################################################
############################################################
#####
#####		Local and Program Mailer specification
#####
#####		@(#)localm.m4	4.1		7/25/83
#####
############################################################
############################################################

CF_SVMAILMlocal, P=CF_LOCALMAIL, F=lsDFMhumSU, S=10, R=20, A=rmail $u
CF_BSMAILMlocal, P=CF_LOCALMAIL, F=rlsDFMmn, S=10, R=20, A=mail -d $u
Mprog,	P=/bin/sh,   F=lsDFMe,   S=10, R=20, A=sh -c $u

S10
R@			MAILER-DAEMON			errors to mailer-daemon

############################################################
############################################################
#####
#####		UUCP Mailer specification
#####
#####		UUCP Project 11/01/85
#####
############################################################
############################################################


# Top two lines use uux, bottom two use smail.  For UUCP to handle domain 
# style addressing, you must use smail.  HINTS.

#Muux,	P=/usr/bin/uux, F=sDFMuU, S=13, R=23, M=65535,
#	A=uux - $h!rmail ($u)
Muux,	P=/bin/smail, F=sDFMhum, S=14, R=24, M=100000,
	A=smail -r -vH$j $h!$u

# S13 rewrites return addresses for uux as smail would: turn "user" into 
# "host!user" and "user@domain" to "host!domain!user".  Unfortunately,
# this also affects the From: line (which is wrong).

S13
R$+<@$w.UUX>		$@$1<@$w.UUX>			intercept 2nd pass
R$+			$:$>4$1				externalize
R$*@$*			$2!$1				a@b -> b!a
R$+			$@$1<@$w.UUX>			tack on our name

S14
R$+<@$=E>		$1			u@cbpavo->u/CBOSGD
R$*<@$+>$*		$@$1<@$2>$3		already ok
#R$+			$@$1<@$w>		tack on our hostname
R$+			$@$1<@$j>		tack on our full address

############################################################
############################################################
#####
#####		SMTP ethernet mailer
#####
#####		UUCP Project 11/01/85
#####
############################################################
############################################################

Mether,	P=[IPC], F=msDFMuCXP, S=11, R=21, A=IPC $h

S11
R$*<@$+>$*		$@$1<@$2>$3		already ok
R$+			$@$1<@$w>		tack on our hostname
#R$+			$@$1<@$j>		tack on our full address


#################################
#  Final Output Post-rewriting  #
#################################

# This rewrites the internal $=T mock domains into their external form.
# The default is to replace the mock domain name with $D.  The last
# two lines are stock.

S4
R@			$@				handle <> error addr
R$+<@$-.UUX>		$2!$1				u@host.UUX => host!u
R$*<$*$=T>$*		$:$1<$2$D>$4			change local info
R$*<$+>$*		$1$2$3				defocus
R@$+:$+:$+		$@@$1,$2:$3			<route-addr> canonical
END-OF-FILE

if [ "$filename" != "/dev/null" ]
then
  size=`wc -c < $filename`

  if [ $size != 10487 ]
  then
    echo $filename changed - should be 10487 bytes, not $size bytes
  fi

  chmod 644 $filename
fi

# ---------- file smail.cf.sh ----------

filename="smail.cf.sh"

if [ -f $filename ]
then
  echo File \"$filename\" already exists\!  Skipping...
  filename=/dev/null		# throw it away
else
  echo extracting file smail.cf.sh...
fi

cat << 'END-OF-FILE' > $filename
cat <<!EOM!
This script will prompt you for the automatically configurable parameters
in the stock version of the sendmail configuration file.  Naturally, any
local extensions will have to be added manually.

Below is a trace of the session that
configured the sendmail.cf on clyde.ATT.COM.
This is a System V machine with sendmail.
===

!EOM!

echo "press return to continue"; read foo

cat <<!EOM!
Enter Date (MM-DD-YY):
06-24-86
Enter This Host's Name:
clyde
Enter This Host's Official Domain:
ATT.COM
Enter Any Equivalent Domain Classes:
ATT
Enter Any Domains For Which This Host Is An Authority:
ATT.UUCP
Does This Host Have SMTP Connections (y/n)?
no
Enter Full Path to Executable That Will Provide Local Mail Delivery:
/bin/lmail
Is /bin/lmail A Berkeley Mailer [i.e., use -r to specify sender] (y/n)?
no
Will This Host Act As A Gateway Between Domains (y/n)?
yes
===
!EOM!
# get date of configuration
CF_DATE=`/bin/sh ./smail.prompt string "Enter Date (MM-DD-YY):"`

# get host name
CF_HOST=`/bin/sh ./smail.prompt string "Enter This Host's Name:"`

# get host domain
CF_DOMAIN=`/bin/sh ./smail.prompt string "Enter This Host's Official Domain:"`

# get domain classes
CF_DCLASS=`/bin/sh ./smail.prompt string "Enter Any Equivalent Domain Classes:"`

# get domain authority
CF_AUTHORITY=`/bin/sh ./smail.prompt string "Enter Any Domains For Which This Host Is An Authority:"`

CF_SMTP=`/bin/sh ./smail.prompt yesno "Does This Host Have SMTP Connections (y/n)?"`
if test "$CF_SMTP" = "yes"
then

#get list of local SMTP connections
	CF_SMTP=`/bin/sh ./smail.prompt file "Enter Full Path to File that Contains List of SMTP Connections:"`

	CF_SMTP="FE$CF_SMTP %s"
else
	CF_SMTP=""
fi

# get path to local delivery agent
CF_LOCALMAIL=`/bin/sh ./smail.prompt file "Enter Full Path to Executable That Will Provide Local Mail Delivery:"`

CF_SYSTEM=`/bin/sh ./smail.prompt yesno "Is $CF_LOCALMAIL A Berkeley Mailer [i.e., use -r to specify sender] (y/n)?"`
if test "$CF_SYSTEM" = "yes"
then
	CF_SVMAIL="#"
	CF_BSMAIL=""
else
	CF_SVMAIL=""
	CF_BSMAIL="#"
fi

CF_GATEWAY=`/bin/sh ./smail.prompt yesno "Will This Host Act As A Gateway Between Domains(y/n)?"`
if test "$CF_GATEWAY" = "yes"
then
	CF_GATEWAY=""
else
	CF_GATEWAY="#"
fi

sed 	\
	-e "s/CF_HOST/Dw$CF_HOST/" \
	-e "s/CF_DOMAIN/DD$CF_DOMAIN/" \
	-e "s/CF_AUTHORITY/DA$CF_AUTHORITY/" \
	-e "s/CF_DCLASS/CDUUCP $CF_DCLASS/" \
	-e "s;CF_SMTP;$CF_SMTP;" \
	-e "s;CF_DATE;$CF_DATE;" \
	-e "s;CF_LOCALMAIL;$CF_LOCALMAIL;" \
	-e "s;CF_BSMAIL;$CF_BSMAIL;" \
	-e "s;CF_SVMAIL;$CF_SVMAIL;" \
	-e "s;CF_GATEWAY;$CF_GATEWAY;" \
	smail.cf.form > sendmail.cf
END-OF-FILE

if [ "$filename" != "/dev/null" ]
then
  size=`wc -c < $filename`

  if [ $size != 2604 ]
  then
    echo $filename changed - should be 2604 bytes, not $size bytes
  fi

  chmod 644 $filename
fi

# ---------- file smail.prompt ----------

filename="smail.prompt"

if [ -f $filename ]
then
  echo File \"$filename\" already exists\!  Skipping...
  filename=/dev/null		# throw it away
else
  echo extracting file smail.prompt...
fi

cat << 'END-OF-FILE' > $filename
loop=true
while test $loop = true
do 
	case "$1" in
	string)
		echo "$2" 1>&2
		read ans
		if test ! -z "$ans"
		then
			echo $ans
			loop=false;
		fi
	;;
	file)
		echo "$2" 1>&2
		read ans
		case "$ans" in
		/*)
			if test -f "$ans"
			then
				echo $ans
				loop=false;
			else
				echo "file '$ans' not found" 1>&2
			fi
		;;
		*)
			echo "must give FULL PATH to file" 1>&2
		;;
		esac
	;;
	yesno)
		echo "$2" 1>&2
		read ans
		case "$ans" in
		y|Y|yes|Yes|YES)
			echo "yes"
			loop=false
		;;
		n|N|no|No|NO)
			echo "no"
			loop=false
		;;
		*)
			echo "Please enter yes or no" 1>&2
		;;
		esac
	;;
	*)

		echo "usage: $0 string|yesno prompt_message" 1>&2
		echo BOGUS_PROMPT_STRING
		loop=false
	;;
	esac
done
END-OF-FILE

if [ "$filename" != "/dev/null" ]
then
  size=`wc -c < $filename`

  if [ $size != 717 ]
  then
    echo $filename changed - should be 717 bytes, not $size bytes
  fi

  chmod 644 $filename
fi

# ---------- file sysexits.h ----------

filename="sysexits.h"

if [ -f $filename ]
then
  echo File \"$filename\" already exists\!  Skipping...
  filename=/dev/null		# throw it away
else
  echo extracting file sysexits.h...
fi

cat << 'END-OF-FILE' > $filename
# define EX_OK		0	/* successful termination */
# define EX_USAGE	64	/* command line usage error */
# define EX_NOHOST	68	/* host name unknown */
# define EX_UNAVAILABLE	69	/* service unavailable */
# define EX_SOFTWARE	70	/* internal software error */
# define EX_OSFILE	72	/* critical OS file missing */
# define EX_CANTCREAT	73	/* can't create (user) output file */
END-OF-FILE

if [ "$filename" != "/dev/null" ]
then
  size=`wc -c < $filename`

  if [ $size != 368 ]
  then
    echo $filename changed - should be 368 bytes, not $size bytes
  fi

  chmod 644 $filename
fi

# ---------- file u.Path.local ----------

filename="u.Path.local"

if [ -f $filename ]
then
  echo File \"$filename\" already exists\!  Skipping...
  filename=/dev/null		# throw it away
else
  echo extracting file u.Path.local...
fi

cat << 'END-OF-FILE' > $filename
# Put local aliases in this file that you don't want to bother
# the whole world with (e.g. pc's) or that you want to keep secret.
# Change the name of the file to u.Path.`hostname`
myname	topsecret(DIRECT), 4urisonly(LOCAL), mypc(LOCAL)
END-OF-FILE

if [ "$filename" != "/dev/null" ]
then
  size=`wc -c < $filename`

  if [ $size != 238 ]
  then
    echo $filename changed - should be 238 bytes, not $size bytes
  fi

  chmod 644 $filename
fi

# ---------- file u.Path.top.1 ----------

filename="u.Path.top.1"

if [ -f $filename ]
then
  echo File \"$filename\" already exists\!  Skipping...
  filename=/dev/null		# throw it away
else
  echo extracting file u.Path.top.1...
fi

cat << 'END-OF-FILE' > $filename
#
# DOMAIN GATEWAY LIST FOR UUCP AND OTHER TOP-LEVEL DOMAINS
# This file is pathalias input for UUCP domain addressing.
#
# All gateway hosts (those in this file) must understand domain!user.
# Note that most lines are still commented out, because many hosts don't 
# recognise domain!user.
#
# Problems and changes to domains@registry.UUCP
# 		9/20/85

# TOP LEVEL DOMAINS AND THEIR GATEWAYS

# UUCP top level domain
cbosgd	.uucp
ihnp4	.uucp
seismo	.uucp
ucbvax	.uucp
harvard	.uucp
mcvax	.uucp
decuac	.uucp

# ARPANET and related domains
seismo	.arpa, .com, .gov, .edu, .org, .net, .us
ucbvax	.arpa, .com, .gov, .edu, .org, .net, .us
harvard	.arpa, .com, .gov, .edu, .org, .net, .us
talcott	.arpa, .com, .gov, .edu, .org, .net, .us

# CSNET
harvard	.csnet
talcott	.csnet

# MAILNET
harvard	.mailnet
talcott	.mailnet

# BITNET
psuvax1	.bitnet
talcott	.bitnet

# United Kingdom/Great Britain
ucl-cs	.uk, .gb
ukc	.uk, .gb

# Israel
humus	.il, .israel

# Korea
kaist	.kr, .korea

# Australia
munnari	.au, .oz, .oz.au
mulga	.au, .oz, .oz.au

# Canada
ubc-vision	.ca, .cdn, .canada
watmath		.ca, .cdn, .canada
garvield	.ca, .cdn, .canada

# Japan
kddlab		.jp, .junet, .jpn
END-OF-FILE

if [ "$filename" != "/dev/null" ]
then
  size=`wc -c < $filename`

  if [ $size != 1168 ]
  then
    echo $filename changed - should be 1168 bytes, not $size bytes
  fi

  chmod 644 $filename
fi

# ---------- file u.Path.uucp.1 ----------

filename="u.Path.uucp.1"

if [ -f $filename ]
then
  echo File \"$filename\" already exists\!  Skipping...
  filename=/dev/null		# throw it away
else
  echo extracting file u.Path.uucp.1...
fi

cat << 'END-OF-FILE' > $filename
#
# DOMAIN GATEWAY LIST FOR UUCP AND OTHER TOP-LEVEL DOMAINS
# This file is pathalias input for UUCP domain addressing.
#
# All gateway hosts (those in this file) must understand domain!user.
#
# Problems and changes to domains@registry.UUCP
# 		9/20/85

# TOP LEVEL REGISTRY ALIAS (.UUCP implied)

cbosgd		=	registry

# UUCP 2nd level domains and their gateways.

#O	AT&T
cbosgd	.att.com, .att
# will include ihnp4 as soon as ihnp4 handles subdom.mach.att.com

#O	BellCore - Bell Communications Research
bellcore	.bellcore.com
mouton		.bellcore.com

#O	Digital Equipment Corp
decuac	.dec.com, .dec
decwrl	.dec.com, .dec

#O	Concurrent Computer Corporation
peora	.ccur.uucp
END-OF-FILE

if [ "$filename" != "/dev/null" ]
then
  size=`wc -c < $filename`

  if [ $size != 674 ]
  then
    echo $filename changed - should be 674 bytes, not $size bytes
  fi

  chmod 644 $filename
fi

echo done

exit 0