[mod.sources] uumail release 2

sources-request@panda.UUCP (12/24/85)

Mod.sources:  Volume 3, Issue 68
Submitted by: Stan Barber <genrad!neuro1!sob>


This version of uumail contains all the fixes reported since
the last release. Thanks to those that reported problems and
especially those that sent along fixes or improvements.

This version also contains some improvements that I saw in
the GATech Sendmail Configuration version of uumail to help
uumail "know" when the database is being rebuilt. Please 
be sure to read the README >ESPECIALLY IF YOU RUN A 
DBM-formated database< ....

The next version of uumail will contain some more options
to allow header munging and path optimization (I hope).
If you already have some ideas or code that you'd like to
donate to the cause, send it along.

Have a good holiday, or if this comes out in 1986, Have
a good year.

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	README
#	makefile
#	domains
#	palias
#	address.1
#	address.c
#	gethostnam.c
#	getpath.c
#	opath.3
#	opath.c
#	rmail.c
#	uuconf.h
#	uumail.1
#	uumail.c
#	uupath.1
#	uupath.c
# This archive created: Tue Dec 24 09:31:18 1985
export PATH; PATH=/bin:$PATH
echo shar: extracting "'README'" '(4023 characters)'
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
cat << \SHAR_EOF > 'README'
This is an updated version of uumail (and uupath) that can 
access a pathalias-generated database to facilitate routine mail.

These program can cope with DBM and standard line-oriented forms of 
pathalias-generated databases.

This version of uumail can be used as uupath by linking uumail to
uupath. Also, this version can handle domain addresses (user@host.domain).
You can put as many addresses on a line as you like.

This version fixes a few bugs in the previous release. Some additional 
functionality and robustness are added as well. The bugs included 
lack of initilization of some variables in address.c, inconsistant calling
of getpath in uumail, address and opath, and failure to handle % in addresses
correctly. Additional features include  the ability of getpath to detect when
the database is being updated and wait or abort as necessary, the ability to 
retry accessing the database when it will not open (as might be the case when
updating it), the ability (if the database is sorted) to search a plain-text
database much faster.

 *    IF YOU ARE USING A DBM DATABASE, READ THIS!
 *    If the special sentinel value of @@@ is not present in the
 *    database, then getpath will assumed that the database is being
 *    rebuilt and will block for TIMEOUT (default = 180) seconds.  
 *    If, after 5 such blocks, the sentinel is not present,
 *    the error code EX_TEMPFAIL is returned.
 *    The same is true if the dbm files cannot be initialized.
 *    Please be sure to add the sentinal to the DBM database when
 *    it is created.
 *

There are some compile flags to be aware of when making uumail.
Here is a list of them.

DEBUG compiles in the debugging code.
OPATH causes the opath subroutine to be used to resolve addresses.
If you do not use this flag, you cannot use the user@host.domain style
addresses with uumail.
DBM causes uumail to use the DBM format patalias database. If you do not
have the dbm libraries, do not use this flag.
SYSIII will make adjustments for system that are derived from UNIX System
III or System V.
NOGRADE should be used if your uux does not understand the -g flag.
NORETURN should be used if your uux does not understand the -a flag.
LOG will enable logging of uumail traffic.
UGLYUUCP causes the From_ line produced by uumail to contain the
"remote from hostname" string.
GETHOSTNAME will cause the system call gethostname to be used. If you
are a BSD site, define this.
SYSTEMNAME will cause the systemname to be derived from the file
/usr/lib/uucp/SYSTEMNAME. This should be defined if your machine
is a Sperry 5000.
SORTED will cause the non-DBM database to be searched fasted, BUT
it assumes that this database is SORTED. If you do not sort your
database, do not define this.

If you want to install this system, use "make install". If you want
to have it do all the work for incoming mail, type "make mailer". You
probably do not want to "make mailer" if you run sendmail.

Here is the mailer segment of a sendmail configuration file that you
can use to define the uumail program as a mailer.
-------------------------------------------------------------------
############################################################
#### This is a special mailer that takes advantage of    ###
#### usemap database for addresses to UUCP sites         ###
############################################################

Muumail, P=/usr/lib/uucp/uumail,F=sDFhuUM,S=13,R=23,M=1000000,
	A=uumail -h -gC -f$g $h!$u
--------------------------------------------------------------
Please be sure that the S= and R= rules are correct for your
system. They should match the uucp mailer rules exactly.

A manual page for address, opath, uumail and uupath are included.

Please forward comments and bug fixes to me at sob@rice.edu or 
ihnp4!shell!neuro1!sob or texsun!drilltech!sob

Stan Barber
Baylor College of Medicine
Houston, Texas

P.S. My thanks to all those who reported bugs from the previous release.
Please continue to send them in, and I will try to keep fixing them.
SHAR_EOF
if test 4023 -ne "`wc -c < 'README'`"
then
	echo shar: error transmitting "'README'" '(should have been 4023 characters)'
fi
fi
echo shar: extracting "'makefile'" '(3265 characters)'
if test -f 'makefile'
then
	echo shar: will not over-write existing file "'makefile'"
else
cat << \SHAR_EOF > 'makefile'
####################################################################
# makefile for uumail & uupath
# program to integrate with pathalias created uucpmap databases
# programs originally developed by Jeff Donnelly
# updated to use pathalias database by Stan Barber
# $Header: makefile,v 1.4 85/12/10 20:40:45 sob Exp $
#
# the following defines should be configured for you site
# add -DDBM to CCFLAGS if your pathalias database used the
# dbm(3) routines
# if you are a ATT system III or system V site
# or a masscomp add the -DSYSIII flags
# If you want to use the opath subroutine to deal with
# domain names add the -DOPATH flag to the CFLAGS line
# you may want to modify the LIBS line to correspond to 
# libraries that you may need at you site
# see conf.h for other changes that may need be made
# If you DO NOT use a DBM formatted database and would like to
# get the best possible speed from uumail, add the -DSORTED
# flag and be sure to sort your database
# IMPORTANT INFORMATION ABOUT UUCP
# If your uucp does not understand the -g (grade) flag
# add the -DNOGRADE flag to CFLAGS.
# If your uucp does not know about the -a (returnto) flag
# add the -DNORETURN flag to CFLAGS
# $Log:	makefile,v $
# Revision 1.4  85/12/10  20:40:45  sob
# Added install, mailer and all make options. Also defined BINDIR, UUCPDIR
# and other useful things
# 
# Revision 1.3  85/08/03  00:38:33  UUCP
# Added support for shar and RCS.
# Changed name of gethostname to gethostnam to allow RCS to work right.
# Stan Barber
# 
# Revision 1.2  85/07/11  19:28:52  sob
# updated with gethostname.c
# 
# Revision 1.1  85/07/11  19:23:22  sob
# Initial revision
# 
###############################################################
.SUFFIXES: .c,v .h,v

CFLAGS= -O -DSYSIII -DDEBUG -DOPATH -DUGLYUUCP -DLOG -DSORTED

LIBS=

BINDIR=/usr/lbin

UUCPDIR=/usr/lib/uucp

LIBDIR=/usr/lib

.c,v.c:
	co -q $*.c

.h,v.h:
	co -q $*.h

all: uumail rmail address

uumail: getpath.o uumail.o gethostnam.o opath.o
	cc $(CFLAGS) getpath.o uumail.o gethostnam.o opath.o -o uumail $(LIBS)

address:address.o opath.o getpath.o
	cc $(CFLAGS) address.o opath.o getpath.o -o address $(LIBS)

getpath.o: getpath.c uuconf.h

uupath.o: uupath.c uuconf.h

uumail.o: uumail.c uuconf.h

gethostnam.o:gethostnam.c

address.o:address.c

opath.o:opath.c

rmail: rmail.c gethostnam.o
	cc $(CFLAGS) rmail.c gethostnam.o -o rmail $(LIBS)

install: uumail address domains palias
	cp address $(BINDIR)
	cp uumail domains palias $(UUCPDIR)
	@echo "To install rmail in place of the current rmail, type"
	@echo "make mailer"
	ln $(UUCPDIR)/uumail $(BINDIR)/uupath

mailer: rmail
	make install
	rm -rf /bin/rmail
	cp rmail /bin/rmail
	

lint:
	lint $(CFLAGS) getpath.c uumail.c gethostnam.c opath.c

clean: 
	rm -f *.o *.CKP *.BAK *.bak

doc: uumail.1 uupath.1 address.1 opath.3
	nroff -man uumail.1 >uumail.cat; nroff -man uupath.1 >uupath.cat; nroff -man address.1 >address.cat; nroff -man opath.3 >opath.cat

shar: domains palias rmail.c opath.c address.c uumail.c uuconf.h gethostnam.c uupath.c getpath.c README makefile uumail.1 uupath.1  opath.3 address.1
	shar README domains palias rmail.c opath.c address.c uumail.c uuconf.h gethostnam.c uupath.c getpath.c makefile uumail.1 uupath.1  opath.3 address.1> shar.out

SHAR_EOF
if test 3265 -ne "`wc -c < 'makefile'`"
then
	echo shar: error transmitting "'makefile'" '(should have been 3265 characters)'
fi
fi
echo shar: extracting "'domains'" '(1093 characters)'
if test -f 'domains'
then
	echo shar: will not over-write existing file "'domains'"
else
cat << \SHAR_EOF > 'domains'
#
# Domain Table
#
# Format: <domain>,<prefix>,<suffix>,<template>
#
# Where <template> may contain:
#       %P - prefix string
#       %S - suffix string
#       %U - destination user name
#       %N - destination site name
#       %D - destination site name with domain suffix
#       %% - a percent (%) sign
#       %R - pathalias route to the destination site
#
.WA.UUCP,,,%R!%U
.OR.UUCP,,,%R!%U
.N-CA.UUCP,,,%R!%U
.S-CA.UUCP,,,%R!%U
.MTN.UUCP,,,%R!%U
.S-CEN.UUCP,,,%R!%U
.MID-W.UUCP,,,%R!%U
.S-EAST.UUCP,,,%R!%U
.ATL.UUCP,,,%R!%U
.N-ENG.UUCP,,,%R!%U
.HI.UUCP,,,%R!%U
.W-CAN.UUCP,,,%R!%U
.E-CAN.UUCP,,,%R!%U
.EUR.UUCP,,,%R!%U
.UK.UUCP,,,%R!%U
.AUS.UUCP,,,%R!%U
.ISRAEL.UUCP,,,%R!%U
.ATT.UUCP,>ihnp4,,%P!%D!%U
.HP.UUCP,,,%R!%U
.PE.UUCP,,,%R!%U
.UUCP,,,%R!%U
.CSNET,>rice,,%P!%U%%%D@CSNET-RELAY.ARPA
.MAILNET,>rice,,%P!%U%%%D@MULTICS.MIT.EDU
# .BITNET,>rice,,%P!%U%%%D@WISCVM.ARPA
.XEROX,>rice,,%P!%U.%D@XEROX.ARPA
.DEC,>decwrl,,%P!%U@%D
.ARPA,>rice,,%P!%U@%D
.EDU,>rice,,%P!%U@%D
.COM,>rice,,%P!%U@%D
.GOV,>rice,,%P!%U@%D
.MIL,>rice,,%P!%U@%D
.OTH,>rice,,%P!%U@%D
.BITNET,>psuvax,,%P!%U@%D
SHAR_EOF
if test 1093 -ne "`wc -c < 'domains'`"
then
	echo shar: error transmitting "'domains'" '(should have been 1093 characters)'
fi
fi
echo shar: extracting "'palias'" '(151 characters)'
if test -f 'palias'
then
	echo shar: will not over-write existing file "'palias'"
else
cat << \SHAR_EOF > 'palias'
baylor baylor!%s
decwrl shell!ihnp4!decwrl!%s
ihnp4 shell!ihnp4!%s
kitty baylor!kitty!%s
neuro1 %s
psuvax shell!psuvax!%s
rice  rice!%s
shell shell!%s
SHAR_EOF
if test 151 -ne "`wc -c < 'palias'`"
then
	echo shar: error transmitting "'palias'" '(should have been 151 characters)'
fi
fi
echo shar: extracting "'address.1'" '(3589 characters)'
if test -f 'address.1'
then
	echo shar: will not over-write existing file "'address.1'"
else
cat << \SHAR_EOF > 'address.1'
.TH ADDRESS 1 local
.SH NAME
address - display the path generated by \fBdeliver\fR for an
RFC822-format address.
.SH SYNOPSIS
address rfc-address [ ... ]
.SH DESCRIPTION
This program allows you to check the UUCP mail routing path that will
be generated by the UUCP mailer \fBdeliver\fR if you specify an
RFC822-format address \fBrfc-address\fR in the ``To:'' field of the mail header.
For each RFC-style address on the command line, \fBaddress\fR echoes the
address to the standard output, followed by a colon, followed by
the UUCP address that will be used to send the message to that address.

.SH "ADDRESS FORMAT"
Briefly, the RFC822-format address is of the form
.nf
.sp 1
	<localaddress>@<hostname>.<network>
.sp 1
.fi
where <hostname> is the name of the system you are sending the message
to, <network> is a modifier for <hostname> identifying the network in
which the address is to be interpreted (UUCP, ARPA, MAILNET, CSNET, etc);
and <localaddress> is an address string to be interpreted on the host
machine.

The <localaddress> field may contain further remote addresses to be
interpreted on the host machine.  Typically this will be an address for
mailing via another network; and in particular, the <localaddress> may
(recursively) be identical in format to the RFC address, but with
the symbol `%' replacing the symbol `@' in the standard address format.
Where this form is used, the rightmost % is replaced by an
@ before the host machine sends the message out.

On our system, the presently
valid <network>s are UUCP, ARPA, CSNET, and MAILNET.
The recently proposed UUCP domain names are also accepted, although
they are treated the same as plain ``UUCP''.
Omitting
the <network> causes the network to default to UUCP.  The <hostname>
should be the name of a remote machine to which the message is
directed; see \fI/usr/lib/uucp/uuaddress.alpha\fR for a list of all
known UUCP hostnames.  It is \fInot\fR necessary to specify a UUCP pathname
when using this format; the pathname is automatically determined for you
and substituted into the address before mailing.  The selected pathname
is determined using the \fBpathalias\fR database, and is supposed
to be optimal, taking into consideration information provided by
each site about how often they send mail out, etc.

.SH EXAMPLES
.HP 5
joe
.br
The message is sent to the user ``joe'' on the local system.
.HP 5
joe@ucbvax
.br
The message is sent to joe on the UUCP system named ``ucbvax''; this
address is automatically translated to a proper (and ostensibly
optimal) UUCP path.
.HP 5
joe@ucbvax.UUCP
.br
Same as joe@ucbvax
.HP 5
joe@ucbvax.ARPA
.br
The message is addressed to joe at ucbvax, using the ARPA network.
The message will be routed to the ARPAnet via a UUCP-ARPAnet gateway.
.HP 5
joe%mit-multics.ARPA@ucbvax
.br
The message is sent to ucbvax, who then uses the address
joe@mit-multics.ARPA to send the message on to mit-multics via the
ARPAnet.  Since ucbvax is on the arpanet, this address will work correctly
(as long as there is someone named joe on the MIT multics machine).
.HP 5
joe%vanderbilt.MAILNET%mit-multics.ARPA@ucbvax
.br
The message is sent via UUCP to ucbvax, who then sends the message
to mit-multics via the arpanet; mit-multics then sends the message
to joe@vanderbilt via MAILNET.  Since the above machines each have access
to the networks named in the address, this address will work correctly.
.SH FILES
/usr/lib/uucp/domains - Domain/gateway table
.br
/usr/lib/uucp/palias - Pathalias database
.SH "SEE ALSO"
opath(3), uupath(1), uumail(8)
.SH AUTHOR
Eric Roskos, CONCURRENT COMPUTERS
SHAR_EOF
if test 3589 -ne "`wc -c < 'address.1'`"
then
	echo shar: error transmitting "'address.1'" '(should have been 3589 characters)'
fi
fi
echo shar: extracting "'address.c'" '(1035 characters)'
if test -f 'address.c'
then
	echo shar: will not over-write existing file "'address.c'"
else
cat << \SHAR_EOF > 'address.c'
/*
 * address - run opath to see what a translated RFC822 address will come
 * out as.
 *
 * By E. Roskos 1/16/85
 * $Log:	address.c,v $
 * Revision 1.3  85/11/24  14:50:01  sob
 * Added corrections provided by regina!mark
 * 
 * Revision 1.2  85/09/16  18:31:53  sob
 * Added DEBUG flag
 * 
 * Revision 1.1  85/09/16  17:50:24  sob
 * Initial revision
 * 
 */
#define _DEFINE
#include "uuconf.h"

static char rcsid[] = "$Header: address.c,v 1.3 85/11/24 14:50:01 sob Exp $";

EXTERN char *paths;
char *opath();
int Debug;

main(argc,argv)
int argc;
char **argv;
{
char *p;
int uswitch;

paths = DATABASE;
ConfFile=CONFIGFILE;

	if (argc < 2)
	{
		fprintf(stderr,"usage: %s rfcaddress [...]\n",
			argv[0]);
		exit(1);
	}

	while (--argc)
	{
		p = *++argv;
		if (*p=='-')
		{
			switch(*++p)
			{
			case 'u': uswitch++;
				  continue;
			case 'd': Debug++;
			          continue;
			default:  printf("unknown switch: %c\n",*p);
				  continue;
			}
			continue;
		}
		printf("%s: %s\n",p,uswitch?oupath(p):opath(p));
	}

	exit(0);
}
SHAR_EOF
if test 1035 -ne "`wc -c < 'address.c'`"
then
	echo shar: error transmitting "'address.c'" '(should have been 1035 characters)'
fi
fi
echo shar: extracting "'gethostnam.c'" '(1372 characters)'
if test -f 'gethostnam.c'
then
	echo shar: will not over-write existing file "'gethostnam.c'"
else
cat << \SHAR_EOF > 'gethostnam.c'
#ifndef lint
static char	sccsid[] = "@(#)gethostnam.c	6.1 (down!honey) 85/01/21";
static char	rcsid[] = "$Header: gethostnam.c,v 6.3 85/11/23 05:30:04 UUCP Exp $";
#endif lint

#ifndef GETHOSTNAME
#include "uuconf.h"

void
gethostname(name, len)
char	*name;
{
	FILE	*whoami, *fopen(), *popen();
	char	*ptr, *index();
#if defined(SYSIII) && !defined(SYSTEMNAME)
	struct utsname utsn;
#endif

	*name = '\0';
#ifndef SYSTEMNAME
#ifdef SYSIII
	if (uname(&utsn) != -1)
	{
		strcpy(name,utsn.nodename);
		len = strlen(name);
	  	return;
	}
#endif
#endif

#ifdef SYSTEMNAME
	/* try /usr/lib/uucp/SYSTEMNAME */
	if ((whoami = fopen("/usr/lib/uucp/SYSTEMNAME", "r")) != 0) {
		(void) fgets(name, len, whoami);
		(void) fclose(whoami);
		if ((ptr = index(name, '\n')) != 0)
			*ptr = '\0';
	}
	if (*name)
		return;
#endif
	/* try /usr/include/whoami.h */
	if ((whoami = fopen("/usr/include/whoami.h", "r")) != 0) {
		while (!feof(whoami)) {
			char	buf[100];

			if (fgets(buf, 100, whoami) == 0)
				break;
			if (sscanf(buf, "#define sysname \"%[^\"]\"", name))
				break;
		}
		(void) fclose(whoami);
		if (*name)
			return;
	}

	/* ask uucp */
	if ((whoami = popen("uuname -l", "r")) != 0) {
		(void) fgets(name, len, whoami);
		(void) pclose(whoami);
		if ((ptr = index(name, '\n')) != 0)
			*ptr = '\0';
	}
	if (*name)
		return;
	
	/* failure */
	return;
}
#endif GETHOSTNAME
SHAR_EOF
if test 1372 -ne "`wc -c < 'gethostnam.c'`"
then
	echo shar: error transmitting "'gethostnam.c'" '(should have been 1372 characters)'
fi
fi
echo shar: extracting "'getpath.c'" '(6606 characters)'
if test -f 'getpath.c'
then
	echo shar: will not over-write existing file "'getpath.c'"
else
cat << \SHAR_EOF > 'getpath.c'
/*
 * Name: getpath -- return the full usenet path of the given name
 *
 * Paramaters: sysname (input) -- The system name to be expanded
 *	       pathname (output)  The usenet path of the given system name
 *	       pathfile (input) the file to search for the system name
 *
 * Returns: EX_OK     -- path found
 *	    EX_NOHOST -- path not found
 *	    EX_NOINPUT-- unable to open usemap
 *          EX_TEMPFAIL -- database being rebuilt
 *
 * Author: J. Donnelly   3/82
 *
 */

/*    IF YOU ARE USING A DBM DATABASE, READ THIS!
 *    If the special sentinel value of @@@ is not present in the
 *    database, then it is assumed that the database is being
 *    rebuilt and the requesting process is blocked for TIMEOUT
 *    (default = 180) seconds.  If, after 5 such blocks, the
 *    sentinel is not present, the error code EX_TEMPFAIL is returned.
 *    The same is true if the dbm files cannot be initialized.
 */

/* 22-jun-83 Sheppard
 * modified to rewind path file (if open), rather than open again
 *
 * $Log:	getpath.c,v $
 * Revision 1.14  85/12/13  15:23:21  sob
 * Added patches from umd-cs!steve
 * 
 * Revision 1.13  85/12/10  20:36:58  sob
 * Added modifications suggested in gatech's version of uumail.
 * Now, the DBM version of the database needs to have a SENTINAL in it
 * to indicate that the DATABASE is not being updated. Also added similiar
 * indicators to the non-DBM version to compare modification times and act
 * accordingly. 
 * 
 * Revision 1.12  85/12/02  15:48:39  sob
 * Combined speed hacks and old way of reading database and
 * added compile flag SORTED. If database is SORTED and not DBM, use
 * -DSORTED in CFLAGS to make it fast. If database is not sorted
 * DO NOT use this flag.
 * 
 * Revision 1.11  85/11/24  15:03:41  sob
 * Added changes suggested by regina!mark
 * 
 * Revision 1.10  85/11/24  04:21:45  sob
 * Added efficiency hacks supplied by meccts!asby (Shane P. McCarron)
 * 
 * Revision 1.9  85/11/14  20:21:49  sob
 * Added #ifdef DEBUG to allow compilation without DEBUG
 * 
 * Revision 1.8  85/11/08  03:04:49  sob
 * release version
 * 
 * Revision 1.7  85/09/30  02:47:40  sob
 * Altered to use path filename from global variable.
 * 
 * Revision 1.6  85/08/03  00:48:57  UUCP
 * Cleaned up with lint.
 * Stan Barber
 * 
 * Revision 1.5  85/07/19  17:45:13  UUCP
 * Added \t as a valid seperation character for the database
 * in the non DBM case. This is what pathalias uses.
 * 
 * Revision 1.4  85/07/19  16:44:07  UUCP
 * revised to return proper things in accordance with sysexits
 * Stan
 * 
 * Revision 1.3  85/07/11  19:30:31  sob
 * added "uuconf.h" include file and deleted duplicated information
 * 
 * Revision 1.2  85/07/10  18:30:59  sob
 * updated to add DBM capabilities
 * Stan Barber, Baylor College of Medicine
 * 
 * Revision 1.1  85/07/10  18:03:28  sob
 * Initial revision
 * 
 */

#include	"uuconf.h"
#ifndef DBM
#include <sys/types.h>
#include <sys/stat.h>
#endif

static char rcsid[] = "$Header: getpath.c,v 1.14 85/12/13 15:23:21 sob Exp $";

FILE * fopen (), *in;

int getpath (sysname, pathname,pathfile)
char   *sysname, *pathname,*pathfile;
{
    int retval,indx;
#ifdef DBM
    datum lhs,rhs;
#else
	struct stat st;
        time_t modtime;
#ifdef SORTED
	int scomp();

	long lo,hi;
	long cur;
	long last;
	static char buf[256];
#else
    char    name[NAMESIZ],*p,t;
#endif
#endif

#ifdef DEBUG
if (Debug>2)
	printf("In getpath: Sysname = %s, Pathfile = %s\n",sysname,paths);
#endif

#ifdef DBM
    for (indx = 0; indx < 5; indx++)
    {
	if ((retval = dbminit (pathfile)) >= 0)
	    break;
	
#ifdef DEBUG
	if (Debug>2)
	    fprintf (stderr, "Database unavailable.  Sleeping.\n");
#endif
	sleep (TIMEOUT);
    }

    if (retval < 0)
	return(EX_NOINPUT);

    lhs.dptr = SENTINEL;
    lhs.dsize = strlen (SENTINEL) + 1;
    for (indx = 0; indx < 5; indx++)
    {
	rhs = fetch (lhs);
	if (rhs.dsize > 0)
	    break;
	
#ifdef DEBUG
	if (Debug>2)
	    fprintf (stderr, "Database incomplete.  Sleeping.\n");
#endif
	sleep (TIMEOUT);
    }
    if (rhs.dsize <= 0)
	return(EX_TEMPFAIL);

    	lhs.dptr = sysname;
	lhs.dsize = strlen(sysname)+1;
	rhs = fetch(lhs);
	if (rhs.dptr == NULL) return(EX_NOHOST); /* no name found */
	strcpy(pathname,rhs.dptr);
        return(EX_OK);			/* system name found */

#else
if (in == NULL) 
    {
	for (indx = 0; indx < 5; indx++)
	    {
		if ((in = fopen(pathfile, "r")) != NULL)
		    break;
	
#ifdef DEBUG
		if (Debug>2)
		    fprintf (stderr, "Database unavailable.  Sleeping.\n");
#endif
		sleep (TIMEOUT);
	    }
    if (in == NULL)
	return(EX_NOINPUT);
    }
    else
	rewind(in);
    indx = 0;
restart:
	indx++;
	if (indx > 5) return(EX_TEMPFAIL);
	stat(pathfile, &st);
	modtime=st.st_mtime; /* original last modification time */

#ifdef SORTED
	lo = 0;
	hi = st.st_size;
	last = 0;
	cur = hi >> 1;

	while (cur > lo && cur < hi)
	{
		stat(pathfile,&st);
		if (st.st_mtime > modtime) goto restart;
		fseek(in, cur, 0);
		fgets(buf, sizeof(buf), in);
		cur = ftell(in);
		fgets(buf, sizeof(buf), in);

#ifdef	DEBUG
	if (Debug > 4)
		printf("Found site %s\n", buf);
#endif
		if (scomp(sysname, buf) < 0) hi = cur;
		else
		if (scomp(sysname, buf) > 0) lo = cur;
		else
		{
			buf[strlen(buf)-1] = '\0';
			strcpy(pathname, (char *)index(buf, '\t') + 1);
			return(EX_OK);
		}
		cur = lo + ((hi - lo)>>1);
		if (last == cur) 
		{
			fseek(in, lo, 0);
			do
			{
				fgets(buf, sizeof(buf), in);
				lo = ftell(in);
				if (scomp(sysname, buf) == 0)
				{
					buf[strlen(buf)-1] = '\0';
					strcpy(pathname, (char *)index(buf, '\t') + 1);
					return(EX_OK);
				}
			} while (lo <= hi);
			break;
		} /* end if */
		last = cur;
	} /* end while */
	return(EX_NOHOST);
#else

    for (;;)
    {
	p = &name[0];
	while ((t = getc(in)) != EOF && (*p++ = t) != ' ' && t != '\t'); /* read the system name */
        stat(pathfile,&st);
        if (st.st_mtime > modtime) goto restart;		/* database update in progress */
	if( t == EOF) return(EX_NOHOST);
	*--p = '\0';					/* set end of string */
	p = &name[0];
#ifdef DEBUG
	if (Debug>4) printf("Found %s\n",p);
#endif
	if (strcmp (p,sysname) == 0)
	    break;
	while ((getc (in) != '\n'));			/* skip this path */
    }
    p = pathname;					/* save start loc of pathname */
    while ((*pathname++ = getc (in)) != '\n');
    *--pathname = '\0';
    pathname = p;
    return(EX_OK);			/* system name found */

#endif
#endif
}

#ifdef	SORTED
#define MAPTAB(c) ((c=='\t')?'\0':c)

int scomp(a,b)
char *a,*b;
{
int r;
	while (!(r=(MAPTAB(*a)-MAPTAB(*b))) && *a && *b && *a!='\t' && *b!='\t')
	{
	       a++; b++;
	}
	return(r);
}
#endif
SHAR_EOF
if test 6606 -ne "`wc -c < 'getpath.c'`"
then
	echo shar: error transmitting "'getpath.c'" '(should have been 6606 characters)'
fi
fi
echo shar: extracting "'opath.3'" '(4889 characters)'
if test -f 'opath.3'
then
	echo shar: will not over-write existing file "'opath.3'"
else
cat << \SHAR_EOF > 'opath.3'
.TH OPATH 3 "CONCURRENT"
.SH NAME
opath - Generate a UUCP route from an RFC822 address
.br
oupath - Generate a UUCP route from a (possibly disconnected) UUCP path
.SH SYNOPSIS
char *opath(s)
.br
char *s;
.sp 1
char *oupath(s)
.br
char *s;
.SH DESCRIPTION
These routines use the \fBpathalias\fR database to generate UUCP routing
paths from your local site to specified remote sites on either the UUCP
network or other connected networks.
.PP
\fBopath\fR takes one argument, an RFC822 address, as described in
ADDRESS(1).  From this, it generates and returns a UUCP path to the site
named in the argument.
.PP
\fBoupath\fR takes one argument, a UUCP path.  If the next site on this
path is named \fIx\fR, \fBoupath\fR will prepend a path from your site to
\fIx\fR, if \fIx\fR is nonadjacent to your site.  If \fIx\fR is a domain,
i.e. contains a dot (.), \fBoupath\fR will generate a path to a gateway
for this domain.  Note that \fBoupath\fR will \fInot\fR alter the argument
path, other than to make the above transformations; it does not check whether
sites in the argument are adjacent to one another, or whether they represent
an optimal path; it is assumed that if the user has specified a path, then
he wants to use that path.
.PP
The principal difference between \fBopath\fR and \fBoupath\fR is that the
former gives precedence to ``@'', whereas the latter gives precedence
to ``!''.  The former is intended to be invoked when receiving mail from
a user interface or a non-UUCP source (if the subsequent transport mechanism
is to be UUCP), whereas the latter is intended solely to be used by UUCP
internal software, principally \fBrmail\fR, in routing mail through the
UUCP network.
.SH "FILES"
\fI/usr/lib/uucp/palias\fR - The pathalias database.
See PATHALIAS(1) for information; pathalias is a public-domain program
distributed via the Usenet's net.sources facility.
.br
.sp 1
\fI/usr/lib/uucp/domains\fR - The domain/gateway table.  Each line of this
file consists of either a ``#'' followed by arbitrary comment text, or
an entry of the form:
.br
.in 1i
<domain>,<path>,<reserved>,<template>
.br
.in
Where <domain> is the string (in capital letters) identifying a particular
<path> is a string which may be included at an arbitrary point in the
generated route, <reserved> is currently unused, and <template> is a string
indicating the format of the generated route.
.PP
The <template> is a printf-style string; it is \fBnot\fR quoted, and
begins at the character immediately following the comma which separates
<template> from <reserved>.  The <template> may consist of arbitrary ASCII
characters, which are copied unchanged into the generated route; or of
a percent (%) sign followed by one of the following characters:
.IP P
The <path> string is inserted.  The <path> may consist either of a string
which is inserted unchanged; or of the character ``>'' followed by the
name of a UUCP site, in which case the entire <path> string is replaced
with a string representing the path to the named site.  The last token on
this string is the site named in the original <path> string, without a
following ``!''.
.IP U
The user name from the original address is inserted.
.IP N
The site name from the original address, with the domain specifiers
removed, is inserted.
.IP D
The site name from the original address, including the domain specifiers,
is inserted.
.IP R
The UUCP path to the site named in the original address is looked up in
the pathalias database and inserted.  Note that this path is looked up
only when the %R is seen while scanning the <template>, so an error message
for an invalid site name is generated if and only if it appears in an
address with a domain which contains a %R in its template.
.PP
When making entries in the domain table, domain names which are a suffix of
another domain name in the table should be ordered such that the longer
string(s) appear first.  For example, .WA.UUCP should preceed .UUCP in
the table.  A linear search is made of the table, and the first domain
found in the table which is a suffix of the domain in the designated address
is used as the domain in generating the routing.
.PP
Following are some example entries for the domain table.  Note that all
domain names begin with a ``.''.
.sp 1
.nf
.in 1i
# This is a comment
\&.HP.UUCP,,,%R!%U
\&.UUCP,,,%R!%U
\&.CSNET,>decwrl,,%P!%U%%%S@CSNET-RELAY.ARPA
\&.EDU,>ucbvax,,%P!%D
.in
.fi
.sp 1
.SH "SEE ALSO"
pathalias(1), address(1), rmail(1), uumail(8)
.SH "AUTHOR"
Eric Roskos, CONCURRENT COMPUTERS
.SH "NOTE"
The <reserved> field in the domain table currently has a function which
may be determined by examining the source code for opath.  However, this
function is a vestigal function provided for sites that used an earlier
version of opath; future opath versions will use this field for a different
purpose, and new users of opath therefore should \fBnot\fR use this field.
SHAR_EOF
if test 4889 -ne "`wc -c < 'opath.3'`"
then
	echo shar: error transmitting "'opath.3'" '(should have been 4889 characters)'
fi
fi
echo shar: extracting "'opath.c'" '(5753 characters)'
if test -f 'opath.c'
then
	echo shar: will not over-write existing file "'opath.c'"
else
cat << \SHAR_EOF > 'opath.c'
/*
 * opath.c - get an optimal uucp path from the path database, using an
 * RFC882-style address as input.  The '%' character is properly translated,
 * and gateway-substitution is done to get mail onto other networks.
 *
 *
 * Eric Roskos, Perkin-Elmer Corp. SDC
 * Version 3.2 created 85/09/12 15:21:51
 * $Log:	opath.c,v $
 * Revision 3.7  85/11/14  20:22:16  sob
 * Added #ifdef DEBUG to allow compiliation without DEBUG
 * 
 * Revision 3.6  85/11/08  03:05:22  sob
 * release version
 * 
 * Revision 3.5  85/10/09  03:20:07  sob
 * Added strindex call to make striping the printf stuff more pleasing.
 * 
 * Revision 3.4  85/09/30  02:49:12  sob
 * Updated to use getpath revised by Stan Barber
 * 
 * Revision 3.3  85/09/16  18:32:26  sob
 * This version will use the getpath subroutine used by uupath/uumail
 * and is not dependant on whether it is DBM or not.
 * Also uses the uuconf include file.
 * 
 * Revision 3.2  85/09/16  17:50:07  sob
 * Added to RCS
 * 
 */

static char *opathsccsid = "@(#)opath.c	3.2 (peora) 15:21:51 - 85/09/12";
static char opathrcsid[] = "$Header: opath.c,v 3.7 85/11/14 20:22:16 sob Exp $";
#ifdef OPATH
#include "uuconf.h"

/**
 ** User-configurable parameters
 **/

/**
 ** Global Variables
 **/

static char pval[150]; /* the path string is built here */

/*
 * the following are used to pass results by side-effect from the domain()
 * routine.
 */

static char prefix[80], suffix[80], fullsite[80];

/**
 ** Subroutines
 **/

/*
 * The Domain Table and its associated routines
 */

static struct domains
{
	char dom[50];
	char pre[50];
	char suf[50];
	char map[50];
} domtab[100];

/* Inline routine to copy a domain into the domain table */

#define DOMCPY(fld) { int i = 0; q=dp->fld; while (*p!=','&&*p!='\n'&&*p) \
		    {*q++ = *p++; if (i++>=48) break;} \
		    *q++ = '\0'; if (!*p) { \
		    fprintf(stderr,"opath: fld(s) missing in %s at %s\n", \
		    s, buf); \
		    dp++; continue;} p++; }

/* Load the domain table from disk */

static int
loaddomtab(s)
char *s;
{
FILE *f;
char buf[100];
register char *p,*q;
struct domains *dp;

	f = fopen(s,"r");
	if (f==NULL)
	{
		fprintf(stderr,"opath: can't open domain file '%s'\n",s);
		exit(1);
	}

	dp = domtab;

	while (fgets(buf,100,f))
	{
		if (buf[0]=='#') continue; /* comments start with "#" */
		p = buf;
		DOMCPY(dom);
		DOMCPY(pre);
		DOMCPY(suf);
		DOMCPY(map);
		if (dp->map[0] == '\0')
		{
			fprintf(stderr,"opath: bad route template in %s\n",s);
			strcpy(dp->map,"Invalid");
		}
		dp++;
	}

	dp->map[0] = '\0';  /* mark end of table */
	fclose(f);

	return(0);
}

/* Get a UUCP path from the pathalias database 
 * and compensate for the format.
 * Typically the format is
 * site1!site2!site3!%s to be used in *printf statements.
 * We don't want the !%s, so we cut it off.
 * Pretty gross, but it works.
 */

static char *
gpath(s)
char *s;
{
static char path[100];
int getpath(),x;
	getpath(s,&path[0],paths);
        x=strindex(&path[0],"!%s");
	if (x >0) path[x] = '\0';
#ifdef DEBUG
	if (Debug>1)fprintf(stderr,"Getpath returns: %s\n",&path[0]);
#endif
	return(&path[0]);
}

/* returns location of tx in sx */
strindex(sx,tx)
char * sx, *tx;
{
	int i,n;
	n = strlen(tx);
	for (i=0;sx[i] != '\0'; i++)
		if (strncmp(sx+i,tx,n) ==0)
			return(i);
	return (-1);
}

/* String compare: entire first argument must match suffix of 2nd argument */

static int
domcmp(ss,tt)
char *ss, *tt;
{
char *s, *t;
int cmp;

	s = ss + strlen(ss) - 1;
	t = tt + strlen(tt) - 1;

	do
	{
		if (*s - *t) break;
		s--;
		t--;
	} while (s >= ss);

	if (++s == ss) return(0);
	else return(1);
}

/* Look up a domain, and by side effect set prefix and suffix appropriately */

char *domain(s)
char *s;
{
struct domains *d;
char *p;
static int loaded = 0;

	if (!loaded++) loaddomtab(ConfFile);

	if (*s!='.') /* default to UUCP domain */
	{
		prefix[0]=suffix[0]='\0';
		return("%R!%U");
	}

	for (p=s; *p; p++) if (*p>='a' && *p<='z') *p -= 'a'-'A';

	for (d = &domtab[0]; (int)d->map[0]; d++)
	{
		if (domcmp(d->dom,s)==0) break;
	}

	strcpy(prefix,(d->pre[0]=='>')? gpath(&d->pre[1]) : d->pre);
	strcpy(suffix,d->suf);

	return(d->map);
}

/* opath: generates a UUCP path from an RFC-822 address */

#define COPYON(s) {char *r; r=s; while (*r) *p++ = *r++; *p = '\0';}

char *
opath(s)
char *s;
{
char user[50],site[50];
static char cm[150];
FILE *f;
char *p, *q, *t;
char *d;
int i;
int found;
char *suf;

	for (p=user,q=s;(*p = *q)!='@'; p++,q++)
		if (*q=='\0') return(s);
	*p = '\0';

	strcpy(fullsite,++q);

	for (p=site;(*p = *q)!='.'; p++,q++)
		if (*q=='\0') break;
	*p = '\0';

	d = domain(q);

	if (d[0]=='\0') return(s); /* unknown domain - do nothing */

	for (p=pval, q=d; *q; q++)
	{
		if (*q=='%')
		{
			switch(*++q)
			{
			case 'P':
				COPYON(prefix);
				break;

			case 'S':
				COPYON(suffix);
				break;

			case 'U':
				COPYON(user);
				break;

			case 'N':
				COPYON(site);
				break;

			case 'D':
				COPYON(fullsite);
				break;

			case 'R':
				COPYON(gpath(site));
				break;

			case '%':
				*p++ = '%';
				break;
			}
		}
		else
			*p++ = *q;
	}

	return(pval);
}

/* oupath: generates a uucp path from a (possibly disconnected) uucp path */

char *oupath(s)
char *s;
{
char *p,*q;
static char adr[100];
char first[100];
int found;

	for (p=s,q=first,found=0; *p!='!' && *p!='\0'; p++)
	{
		if (*p=='.') found++;
		*q++ = *p;
	}
	if (*p=='\0') return (s);

	*q = '\0';

	if (found)
	{
		strcpy(adr,++p);
		strcat(adr,"@");
		strcat(adr,first);
		return(opath(adr));
	}
	else
	{
	int i;
		strcpy(adr,gpath(first));
		strcat(adr,/* ++ */p);

		return(adr);
	}
}


opathlog(fmt,a,b,c,d)
char *fmt;
int a,b,c,d;
{
FILE *f;

	f = fopen(logfile,"a");
	if (f==NULL) return;

	fprintf(f,fmt,a,b,c,d);
	fclose(f);
}
#endif
SHAR_EOF
if test 5753 -ne "`wc -c < 'opath.c'`"
then
	echo shar: error transmitting "'opath.c'" '(should have been 5753 characters)'
fi
fi
echo shar: extracting "'rmail.c'" '(2622 characters)'
if test -f 'rmail.c'
then
	echo shar: will not over-write existing file "'rmail.c'"
else
cat << \SHAR_EOF > 'rmail.c'
#ifndef lint
static char rcsid[]="$Header: rmail.c,v 1.3 85/11/08 03:05:31 sob RELEASE $";

#endif

/*
**  RMAIL -- UUCP mail server.
**
**	This program reads the >From ... remote from ... lines that
**	UUCP is so fond of and turns them into something reasonable.
**	It calls uumail giving it a -f option built from these
**	lines.
*/

#define _DEFINE

#include "uuconf.h"
extern FILE *popen();
extern char *index();
extern char *rindex();

# define MAILER	"/usr/lib/uucp/uumail"

main(argc, argv)
	char **argv;
{
	FILE *out;	/* output to mail handler */
	char lbuf[512];	/* one line of the message */
	char from[512];	/* accumulated path of sender */
	char ufrom[64];	/* user on remote system */
	char sys[64];	/* a system in path */
	char junk[512];	/* scratchpad */
	char cmd[2000];
	register char *cp;
	register char *uf;	/* ptr into ufrom */
	int i;

# ifdef DEBUG
	if (argc > 1 && strcmp(argv[1], "-T") == 0)
	{
		Debug = TRUE;
		argc--;
		argv++;
	}
# endif DEBUG

	if (argc < 2)
	{
		fprintf(stderr, "Usage: rmail user ...\n");
		exit(EX_USAGE);
	}

	(void) strcpy(from, "");
	(void) strcpy(ufrom, "/dev/null");

	for (;;)
	{
		(void) fgets(lbuf, sizeof lbuf, stdin);
		if (strncmp(lbuf, "From ", 5) != 0 && strncmp(lbuf, ">From ", 6) != 0)
			break;
		(void) sscanf(lbuf, "%s %s", junk, ufrom);
		cp = lbuf;
		uf = ufrom;
		for (;;)
		{
			cp = index(cp+1, 'r');
			if (cp == NULL)
			{
				register char *p = rindex(uf, '!');

				if (p != NULL)
				{
					*p = '\0';
					if (uf != NULL) 
						(void) strcpy(sys, uf);
					else
						gethostname(sys,32);
					uf = p + 1;
					break;
				}
				cp = "remote from somewhere";
			}
#ifdef DEBUG
			if (Debug)
				printf("cp='%s'\n", cp);
#endif
			if (strncmp(cp, "remote from ", 12)==0)
				break;
		}
		if (cp != NULL)
			(void) sscanf(cp, "remote from %s", sys);
		(void) strcat(from, sys);
		(void) strcat(from, "!");
#ifdef DEBUG
		if (Debug)
			printf("ufrom='%s', sys='%s', from now '%s'\n", uf, sys, from);
#endif
	}
	(void) strcat(from, uf);

/*	(void) sprintf(cmd, "exec %s -em -f%s", MAILER, from);*/
	(void) sprintf(cmd, "exec %s -f%s", MAILER,from);
	while (*++argv != NULL)
	{
		(void) strcat(cmd, " '");
		if (**argv == '(')
			(void) strncat(cmd, *argv + 1, strlen(*argv) - 2);
		else
			(void) strcat(cmd, *argv);
		(void) strcat(cmd, "'");
	}
#ifdef DEBUG
	if (Debug)
		printf("cmd='%s'\n", cmd);
#endif
	out = popen(cmd, "w");
	fputs(lbuf, out);
	while (fgets(lbuf, sizeof lbuf, stdin))
		fputs(lbuf, out);
	i = pclose(out);
	if ((i & 0377) != 0)
	{
		fprintf(stderr, "pclose: status 0%o\n", i);
		exit(EX_OSERR);
	}

	exit((i >> 8) & 0377);
}
SHAR_EOF
if test 2622 -ne "`wc -c < 'rmail.c'`"
then
	echo shar: error transmitting "'rmail.c'" '(should have been 2622 characters)'
fi
fi
echo shar: extracting "'uuconf.h'" '(3241 characters)'
if test -f 'uuconf.h'
then
	echo shar: will not over-write existing file "'uuconf.h'"
else
cat << \SHAR_EOF > 'uuconf.h'
/* $Header: uuconf.h,v 1.5 85/12/10 20:42:30 sob Exp $
 * Configuration for uumail and uupath utilities
 * Please see the header for makefile for changes you may
 * need to make there.
 * $Log:	uuconf.h,v $
 * Revision 1.5  85/12/10  20:42:30  sob
 * Added defines for new parts of getpath, SENTINAL and TIMEOUT
 * 
 * Revision 1.4  85/10/02  02:16:21  sob
 * Added LOCALMAIL definition
 * 
 * Revision 1.3  85/09/30  02:50:51  sob
 * Added pwd.h to list of include files
 * 
 * Revision 1.2  85/07/11  19:29:34  sob
 * *** empty log message ***
 * 
 * Revision 1.1  85/07/11  19:22:20  sob
 * Initial revision
 * 
 */
#include <stdio.h>
#include <ctype.h>
#include <pwd.h>
#include <signal.h>
#include <setjmp.h>

/*
 * sysexits is a file of exit codes that are used in sendmail
 * and other programs ...
 */
#include <sysexits.h>
/* if you don't have sysexits.h here are the useful parts */
#ifndef EX_OK

# define EX_OK		0	/* successful termination */


# define EX_USAGE	64	/* command line usage error */
# define EX_DATAERR	65	/* data format error */
# define EX_NOINPUT	66	/* cannot open input */
# define EX_NOHOST	68	/* host name unknown */
# define EX_UNAVAILABLE	69	/* service unavailable */
# define EX_SOFTWARE	70	/* internal software error */
# define EX_OSERR	71	/* system error (e.g., can't fork) */
# define EX_OSFILE	72	/* critical OS file missing */
# define EX_CANTCREAT	73	/* can't create (user) output file */
# define EX_IOERR	74	/* input/output error */
# define EX_TEMPFAIL    75      /* temp failure; user should retry */
#endif

typedef char bool;

#ifdef DBM
#include <dbm.h>
#endif

#ifdef SYSIII
#define index strchr
#define rindex strrchr
#include <sys/utsname.h>
#endif

#define NAMESIZ 32 /* system name size */
#define PATHSIZ 16*NAMESIZ /* path length */

#define TRUE	1
#define FALSE	0

#ifndef TIMEOUT
#define TIMEOUT ((unsigned) 180)
#endif TIMEOUT

#ifndef SENTINEL
#define SENTINEL "@@@"
#endif SENTINEL

/* Here's where you should put in the the name of the file
 * in which the uucpmap data is kept.
 * For those using DBM, this will be the root filename for the database
 * (eg... file.pag and file.dir with root name file)
 */

#define DATABASE "/usr/lib/uucp/palias"
#define CONFIGFILE "/usr/lib/uucp/domains"
#define LOGFILE "/usr/adm/uumail.log"
/* this needs to be a printf-like string to deliver LOCAL mail */
/* usually this is either /bin/mail or /bin/binmail */

#define LOCALMAIL "/bin/bellmail %s"

#ifdef _DEFINE
#define EXTERN 
#else
#define EXTERN extern
#endif

EXTERN int Debug;
EXTERN char *paths;
EXTERN char *ConfFile;
EXTERN char Myname[NAMESIZ];
EXTERN char *logfile;
EXTERN char	OpMode;		/* operation mode, see below */
/* These don't do anything yet.... next time they will do something */
#define MD_DELIVER	'm'		/* be a mail sender */
#define MD_ARPAFTP	'a'		/* old-style arpanet protocols */
#define MD_SMTP		's'		/* run SMTP on standard input */
#define MD_DAEMON	'd'		/* run as a daemon */
#define MD_VERIFY	'v'		/* verify: don't collect or deliver */
#define MD_TEST		't'		/* test mode: resolve addrs only */
#define MD_INITALIAS	'i'		/* initialize alias database */
#define MD_PRINT	'p'		/* print the queue */
#define MD_FREEZE	'z'		/* freeze the configuration file */
SHAR_EOF
if test 3241 -ne "`wc -c < 'uuconf.h'`"
then
	echo shar: error transmitting "'uuconf.h'" '(should have been 3241 characters)'
fi
fi
echo shar: extracting "'uumail.1'" '(2280 characters)'
if test -f 'uumail.1'
then
	echo shar: will not over-write existing file "'uumail.1'"
else
cat << \SHAR_EOF > 'uumail.1'
.TH "UUMAIL" "8" "Baylor College of Medicine"
.fi
.ad b
.SH NAME
uumail \- rewrite address & route mail using uucpmap database 
.br
uupath \- print the uucp path to a host
.SH SYNOPSIS
.B uumail [ \fIoptions\fR ] \fIaddress\fR
.br
.B uupath \fIhostname\fR
.SH DESCRIPTION
.B Uumail
is designed to be used as a mail delivery program to correctly
route mail over uucp connections.
.SS Standard Options
.IP "-f\fIaddress\fR" 16
The -f option sets the address of the sender of the mail. If this flag 
is not used, the sender will be established by usings environmental variables
(like 
.B LOGNAME
and
.B USER
) or using getlogin(3).
.IP "-m" 16
The -m option causes the mail to also be sent to the sender of the message.
.IP "-c" 16
The -c option causes
.B uucico 
to be started immediately after queuing the mail.
The default just queues the mail.
.IP "-h" 16
The -h option causes no From_ line to be added to the beginning of file.
This is useful when uumail is being used as a mailer for sendmail(8).
.SS Compile-time Configurable Options
.IP "-d[1-6]" 16
The -d option turns on the limited debugging facility built into the
mailer.  In debug mode, the mailer does not actually mail anything, but
tells you what it would do if it did do it. The level of debugging can
be set by following the 
.I -d
flag with a number between 1 and 6.
.IP "-g[A-Z]" 16
If your 
.B uux(1)
supports grading of transactions, the -g option can be used to set the
grade of this mail. A grade of \fIC\fR is used by default.

.SS Arguments
.IP \fIhost!user\fR 16
where host is a system node name on the network and user is the login
name of the addressee.
.IP \fIuser@host.domain\fR
same as above with the addition of a domain specifier like
.B .ARPA, .GOV, .COM, .EDU
etc.
.SH FILES
.IP "/usr/lib/uucp/palias" 20
Path file produced by pathalias.
.IP "/usr/lib/uucp/uucp/domains" 20
Domain rewriting rules for opath(3).
.IP "/usr/adm/uumail.log" 20
Log of uumail activity.
.SH "SEE ALSO"
pathalias(1), Pnews(1), Rnmail(1), rn(1), postnews(1), readnews(1),
opath(3), sendmail(8)

.SH AUTHORS
.br
Stan Barber, Baylor College of Medicine
.br
Getpath routine by John Donnelly, University of Illinois
.br
Gethostname routine by Peter Honeyman, Princeton
.br
Opath routine by Eric Roskos, CONCURRENT Computers

SHAR_EOF
if test 2280 -ne "`wc -c < 'uumail.1'`"
then
	echo shar: error transmitting "'uumail.1'" '(should have been 2280 characters)'
fi
fi
echo shar: extracting "'uumail.c'" '(12804 characters)'
if test -f 'uumail.c'
then
	echo shar: will not over-write existing file "'uumail.c'"
else
cat << \SHAR_EOF > 'uumail.c'
/*
 *  U U M A I L
 *  This program when invoked in the form:
 *  uumail host!user will consult the local usemap for
 *  the proper routing.
 * 
 *  If it finds it, it will invoke the proper uux call
 *  to send the mail.
 *  Otherwise it aborts with an error 68 (host unknown)
 * $Log:	uumail.c,v $
 * Revision 2.9  85/12/10  20:36:01  sob
 * Added new return flag from getpath EX_TEMPFAIL to signal that the
 * path database is currently being updated.
 * 
 * Revision 2.8  85/12/02  16:51:39  sob
 * Added a fix to cope with percents in addresses returned by opath.
 * Thank to steve@umd-cs.UUCP for the bug report.
 * 
 * Revision 2.7  85/11/18  12:36:48  sob
 * Added the -h option to cause uumail NOT to add a From_ line.
 * 
 * Revision 2.6  85/11/14  20:20:06  sob
 * Added #ifdef DEBUG to allow compiliation with out DEBUG installed
 * 
 * Revision 2.5  85/11/14  20:14:11  sob
 * Another little buggie in the log format...sheesh.
 * 
 * Revision 2.4  85/11/13  15:53:18  sob
 * Reformated the log file a little bit.
 * 
 * Revision 2.3  85/11/08  03:03:51  sob
 * This is the release version.
 * 
 * 
 * Revision 2.2  85/09/30  02:51:18  sob
 * This version uses opath when defined during compile time.
 * With a bit of cleaning up, this is a release version.
 * 
 * Revision 2.1  85/09/30  02:46:06  sob
 * *** empty log message ***
 * 
 * Revision 2.0  85/09/09  18:22:56  UUCP
 * *** empty log message ***
 * 
 * Revision 2.0  85/09/09  18:22:56  UUCP
 * Added flags to conform with sendmail. Also updated the flags it could send
 * to uux to conform with 4.3 uux command.
 * Will add name resolution and header checking.
 * Also will allow multiple addresses per line.
 * 
 * Revision 1.7  85/08/03  00:49:14  UUCP
 * Cleaned up with lint.
 * Stan Barber
 * 
 * Revision 1.6  85/07/11  19:30:00  sob
 * changed PATHSIZE to PATHSIZ to conform with uupath
 * 
 * Revision 1.5  85/07/11  18:08:13  sob
 * This one works both as uumail and uupath!
 * Stan
 * 
 * Revision 1.4  85/07/10  18:35:05  sob
 * moved DBM to getpath
 * Stan Barber
 * 
 * Revision 1.3  85/07/09  01:28:14  sob
 * First attempt to integrate uupath
 * Not successful. Changed PATHALIAS define
 * to DBM... will ultimately alter getpath as well
 * added gethostname call to fill in for local host.
 * 
 * Revision 1.2  85/07/08  05:29:16  sob
 * This one works with pathalias database...
 * need to modify to substitue for uupath.
 * Stan
 * 
 * Revision 1.1  85/07/08  03:11:10  sob
 * Initial revision
 * 
 */
#define _DEFINE

#include "uuconf.h"


EXTERN bool uupath;
extern int      errno;
extern struct passwd *getpwuid();
extern FILE	*popen();
extern char     *ctime();
extern char	*getlogin();
extern char	*index();
extern char	*rindex();
extern char	*malloc();
extern char     *getenv();
EXTERN char	progname[12];
EXTERN char  *paths;
int local;
char templet[64];
char * from;


static char Version[] ="$Header: uumail.c,v 2.9 85/12/10 20:36:01 sob Exp $";

main(argc, argv)
	char **argv;
{
	FILE *out, *tmpf;	/* output to uux, temp file */
	char lbuf[512]; /* for pipe to uux */
	char sender[512];	/* accumulated path of sender */
	char sys[64];	/* a system in path */
	char cmd[2000];
	char **av;
	int i,
            error = 0,
            bangcnt, hopcount = 30,
	    metoo=0, noheader = 0,
	    startuux ;
		
    char    c,
            grade = 'C',
	   name[20], 			/* The system name (if any) */
	   *fname,
	   *path,			/* uupath to the system */
           *sysname,			/* points to the system name */
           *p, *q, *r,			/* tmp pointer to argv's */
	   *rsys,
	   *FullName;
	   bool GrabTo,safecf,NoAlias;
	   extern intsig();

	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
		(void) signal(SIGINT, intsig);
	if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
		(void) signal(SIGHUP, intsig);
	(void) signal(SIGTERM, intsig);
	(void) signal(SIGPIPE, SIG_IGN);


	for (i = 3; i < 20; i++)
		(void) close(i);
	errno = 0;
	gethostname(Myname,32);
	paths=DATABASE;
	logfile=LOGFILE;
	argv[argc] = NULL;
	av = argv;
	p = rindex(*av, '/');
	if (p++ == NULL)
		p = *av;
	strcpy(progname ,p);
	if(strcmp(p,"uupath") == 0)
		uupath = TRUE;
	while ((p = *++av) != NULL && p[0] == '-')
	{
		switch (p[1])
		{

		  case 'C':	/* select configuration file */
			ConfFile = &p[2];
			safecf = FALSE;

			break;

		  case 'g':   /* set grade */
			grade = p[2];
			break;
	
# ifdef DEBUG
		  case 'd':	/* debug */
			Debug= atoi(&p[2]);
			if (Debug == 0) Debug = 1;
			setbuf(stdout, (char *) NULL);
			printf("Version %s\n", Version);
			break;
# endif DEBUG

		  case 'f':	/* from address */
		  case 'r':	/* obsolete -f flag */
			p += 2;
			if (*p == '\0' && ((p = *++av) == NULL || *p == '-'))
			{
				p = *++av;
				if (p == NULL || *p == '-')
				{
					syserr("No \"from\" person");
					av--;
					break;
				}
			}
			if (from != NULL)
			{
				syserr("More than one \"from\" person");
				break;
			}
			from = p;
			break;

		  case 'w':	/* just print the path */
			uupath = TRUE;
			break;
		  case 'm':	/* send to me too */
			metoo = TRUE;
			break;
		  case 'c':	/* connect to non-local mailers */
			startuux= TRUE;
			break;
		  case 'h':	/* don't add a From line */
			noheader = TRUE;
			break;
			}
    
		}

    if(*av==NULL && GrabTo!= TRUE)
	{
		fprintf(stderr,"Usage: %s [flags] address\n",progname);
		exit(EX_USAGE);
	}

	if (ConfFile == NULL) ConfFile = CONFIGFILE;

	if(from==NULL || strlen(from) == 0){
		if (((from = getenv("LOGNAME")) == NULL) || (strlen(from) == 0))
			from = getenv("USER");
		if ((from == NULL) || (strlen(from) == 0))
			from = getlogin();
		if ((from == NULL) || (strlen(from) == 0))
			from = getpwuid(geteuid())->pw_name;
	}

if (!uupath)
{    
#ifdef DEBUG
	if (Debug) printf("Mail from %s\n",from);
#endif
	/*
	 * Make temporary file for letter
	 * (I wish ACCESS(2) would take care of this better !!)
	 */
	if ((p=getenv("HOME"))== NULL)
		p="/tmp";
	sprintf(&templet[0],"%s/.uumXXXXXX",p);
	mktemp(templet);
	unlink(templet);
	if ((i=open(templet,2)) < 0)
		{
			p="/tmp";
	
			sprintf(&templet[0],"%s/.uumXXXXXX",p);
			mktemp(templet);
			unlink(templet);
		}
	else
		{
			close(i);
			unlink(templet);
		}
#ifdef DEBUG
	if (Debug>2) printf("Temp file is %s\n",templet);
#endif
	if((tmpf = fopen(templet, "w")) == NULL){
		fprintf(stderr, "%s : can't open %s for writing\n", progname,templet);
		fclose(stdin);
		exit(EX_CANTCREAT);

		}
	while(fgets(lbuf,sizeof lbuf,stdin))
		fputs(lbuf,tmpf);
	fclose(tmpf);
	fclose(stdin);
/* file now saved */
	if((tmpf = fopen(templet, "r")) == NULL){
		fprintf(stderr, "%s : can't open %s for reading\n", progname,templet);
		exit(EX_OSERR);
	}
	
}	
    (void) strcpy(sender, "");

    path = malloc(PATHSIZ);

    av--;

    if(metoo)
	{
	*av = from;
	av --;
	}
	
    while (av++ != NULL && *av != NULL)
    {
    local = bangcnt = 0;
	
    
    q = p = *av;
	
    sysname = &name[0];

    
    if (uupath) 

	{
	(void) strcpy(sysname ,p);
#ifdef OPATH
	if ((error = getpath (&name[0], path,paths)) != EX_OK)
	    {
		if (error == EX_NOHOST) fprintf (stderr, "System %s not found in network map\n", &name[0]);
		if (error == EX_NOINPUT) fprintf(stderr,"Database %s could not be opened\n",paths);
		if (error == EX_TEMPFAIL) fprintf(stderr,"Database %s is being updated\nTry again later.\n",paths);
		exit(EX_NOHOST);
	    }
	}
    else 
    if (index(p,'@') == NULL) strcpy(path,oupath(p)); 
	    else strcpy(path,opath(p));

/* fix string to allow % to be untranslated by printf and 
 * friends 
 */
   if ((r=index(path,'%')) != NULL)
	{
		char t[PATHSIZ];
		strncpy(t,path,(r-path));
		strcat(t,"%");
		strcat(t,r);
		path = &t[0];
#ifdef DEBUG
	if (Debug>3)
		fprintf(stderr,"In percent fix, %s\n",t);
#endif
	}




#ifdef DEBUG
    if (Debug >1) fprintf(stderr,"Opath returns %s\n",path);
#endif

    if (path[0] == '!')  /* no match in pathalias database */
	{
		deadletter(tmpf,local);
		unlink(templet);
		exit(EX_NOHOST);
	}
   
   if (strcmp(path,p) == 0)
	{
	strcpy(path,Myname);
	local = 1;
	}

#else
	}
	else
{
	do						/* count bangs */
		{
		    while (((c = *p++) != '!') && (c != '\0'));
			    if (c == '!') bangcnt++;
		}
	while (c != '\0' && bangcnt == 1);
		;
	if (bangcnt >= 1)				/* expand path */
		{
		    while ((*sysname++ = *q++) != '!');
			    *--sysname = '\0';

			}
	/* insert code here to look at uucp neighbors & local host */
	if (bangcnt == 0) {
			strcpy(sysname,Myname);
			local = 1;
			}
	}
#ifdef DEBUG
	if (Debug>1) printf("sysname = %s\n",&name[0]);
#endif
	
	if (!local && (error = getpath (&name[0], path,paths)) != EX_OK)
	    {
		if (error == EX_NOHOST) fprintf (stderr, "System %s not found in network map\n", &name[0]);
		if (error == EX_NOINPUT) fprintf(stderr,"Database %s could not be opened\n",paths);
		if (error == EX_TEMPFAIL) fprintf(stderr,"Database %s is being updated\nTry again later.\n",paths);
		exit(EX_NOHOST);
	    }

       if (local) path = sysname;
#endif


#ifdef DEBUG
       if(Debug>1) printf("Path = %s\n",path);
#endif

	p = q;					/* save name */
	for (i = 0; i < 1 && *p != '\0'; p++)
	    if (*p == '/')
		i++;
	fname = &sender[0];

        if (uupath)
		sprintf(fname,path,"username");
	else
		sprintf(fname,path,q);

	p = &sender[0];
	rsys = &sys[0];

	if (!local)
		{
		while((*rsys++ = *p++) != '!');
		*--rsys = '\0';
		}
		else
/* local host, remove @ sign */
		{
		strcpy(rsys,*av);
		q=rsys;
		if (index(rsys,'@') != 0)
			{ 
				while (*q++ !='@');
				*--q='\0';
			}
		/* assume that if it has a bang in it uux
			will either reject it or know what to do with it */
		/* this is a little gross */
		if ((q = index(rsys,'!')) != 0)
			{
			local=0;
			strcpy(&sys[0],rsys);
			sys[q-rsys]='\0';
			p=q+1;
			}
	}
		
	if ((!local && *fname =='\0') || (local && &sys[0]=='\0')) {
		fprintf(stdout, "null name\n");
		exit(EX_DATAERR);
	}
#ifdef DEBUG
	if (Debug>3)
		printf("p = %s sys = %s fname = %s\n",p, &sys[0],fname);
#endif

	if (uupath)
		{
		printf ("Path to %s:  %s\n", *av, fname);
		continue;
		}
	else
	{
		if (local)
			sprintf(cmd, LOCALMAIL, &sys[0]);
		else {
			strcpy(cmd,"uux - ");
		if (!startuux)
			strcat(cmd,"-r");
#ifndef NORETURN
		if (from)
			{
			strcat(cmd," -a");
			strcat(cmd,from);
			}
#endif
#ifndef NOGRADE
		if (grade)
			{
			char work[10];
			sprintf(work," -g%c",grade);
			strcat(cmd,work);
			}
#endif		
		if (index(p, '!'))
			{
				char work[100];
				sprintf(work, " %s!rmail \\(%s\\)",  &sys[0], p);
				strcat(cmd,work);
			}
		else
			{
				char work[100];
				sprintf(work, " %s!rmail %s", &sys[0], p);
				strcat(cmd,work);
			}
		}
#ifdef DEBUG
	if (Debug) fprintf(stderr,"Command is %s\n",cmd);
#endif
		rewind(tmpf);
#ifdef DEBUG
		if (Debug)
			out = fopen("UUMAIL.TEST","w");
		else
#endif
			out = popen(cmd, "w");
/*		fputs(lbuf, out); */
		if (!noheader) Putfrom(tmpf,out);
		while (fgets(lbuf, sizeof lbuf, tmpf))
			fputs(lbuf, out);

/* may not be needed */
		if (local)
			fprintf(out,"\n.\n");

#ifdef DEBUG
		if (Debug)
			i = fclose(out);
		else
#endif
			i = pclose(out);
		if ((i & 0377) != 0)
			{
				fprintf(stderr, "pclose: status 0%o\n", i);
				deadletter(tmpf,local);
#ifdef DEBUG
				if (Debug <3) unlink(templet);
#endif
				exit(EX_OSERR);
			}
#ifdef LOG
		maillog(cmd);
#endif
	   }
    }
#ifdef DEBUG
    if (Debug <3) unlink(templet);
#endif
exit(EX_OK);
}

/* print an error message on stderr */

syserr(string)
char * string;
{
	fprintf(stderr,"%s\n",string);
}

/* make a unix type From line and send it out the stream */

Putfrom(into,outto)
FILE *into, *outto;
{
	char	*asctime();
	struct	tm *bp, *localtime();
	char	*tp, *zp;
	int	n,fromflag=0;
	char buf[128];
	long iop;

	/*
	 * Format time
	 */
	time(&iop);
	bp = localtime(&iop);
	tp = asctime(bp);
/*	zp = tzname[bp->tm_isdst];*/
/*	sprintf(buf, "%s%s %.16s %.3s %.5s", from, tp, zp, tp+20);*/
	sprintf(buf, "From %s %.16s %.4s", from, tp, tp+20);

#ifdef UGLYUUCP
	if (!local){
			strcat(buf," remote from ");
			strcat(buf,Myname);
		   }
#endif
	strcat(buf,"\n");
	write(outto->_file,buf,strlen(buf));
	fflush(outto);

	if (fgets(buf,sizeof(buf),into) != NULL)
	if((strncmp(&buf[0], "From ", 5) == 0 || strncmp(&buf[0], "From:", 5) == 0))
 		write(outto->_file,">",1);
	
	write(outto->_file,buf,strlen(buf));
}


/* attempt to return dead letter */
/* we'll do better on this one next time */

deadletter(retlet, here)
FILE *retlet;
int here;
{
	if(getlogin() != NULL) syserr("Letter failed....\n");
}

/* go here on a signal we want to catch */
intsig()
{
	unlink(templet);
	exit(EX_OK);
}

/* put command strings in the logfile */

#ifdef LOG

maillog(command)
char * command;
{
	FILE *f;
	char atime[24];
	long clock;
	time (&clock);
	strncpy(atime,ctime(&clock),24);

	if ((f=fopen(logfile,"a")) != NULL)
		{
			fprintf(f,"%s: %s - %s\n",progname,atime,command);
			fclose(f);
		}
}

#endif
SHAR_EOF
if test 12804 -ne "`wc -c < 'uumail.c'`"
then
	echo shar: error transmitting "'uumail.c'" '(should have been 12804 characters)'
fi
fi
echo shar: extracting "'uupath.1'" '(759 characters)'
if test -f 'uupath.1'
then
	echo shar: will not over-write existing file "'uupath.1'"
else
cat << \SHAR_EOF > 'uupath.1'
.TH "UUPATH" "1" "Baylor College of Medicine"
.fi
.ad b
.SH NAME
uupath \- print mail routing information using uucpmap database
.SH SYNOPSIS
.B uupath  \fIhost1 host2 host3 ...\fR
.SH DESCRIPTION
.B Uupath
is designed to be used to query the uucpmap database for mail routing
paths used by
.I uumail.
.SS Arguments
.IP "host1 host2 host3 ..."
where host1, host2, host3 and so on are system node names on the network.
Many hostnames may be entered as arguements to
.I uupath.

.SH FILES
.IP "/usr/lib/uucp/palias" 
Path file produced by pathalias.
.SH "SEE ALSO"
pathalias(1), Pnews(1), Rnmail(1), rn(1), postnews(1), readnews(1), uumail(8)

.SH AUTHORS
.br
Jeff Donnelly, University of Illinois
.br
Stan Barber, Baylor College of Medicine & Rice University

SHAR_EOF
if test 759 -ne "`wc -c < 'uupath.1'`"
then
	echo shar: error transmitting "'uupath.1'" '(should have been 759 characters)'
fi
fi
echo shar: extracting "'uupath.c'" '(1155 characters)'
if test -f 'uupath.c'
then
	echo shar: will not over-write existing file "'uupath.c'"
else
cat << \SHAR_EOF > 'uupath.c'
/*
 * Name: uupath
 *
 * Calls getpath to lookup the usenet path
 *
 * Author: J. Donnelly  3/82
 * $Log:	uupath.c,v $
 * Revision 1.3  85/08/03  01:26:17  UUCP
 * *** empty log message ***
 * 
 * Revision 1.2  85/07/19  17:47:05  UUCP
 * updated to define Debug for compatability with getpath
 * 
 * Revision 1.1  85/07/11  18:35:59  sob
 * Initial revision
 * 
 *
 */

#include	"uuconf.h"
bool Debug;

static char rcsid[] = "$Header: uupath.c,v 1.3 85/08/03 01:26:17 UUCP Exp $";

main (argc, argv) char *argv[];
{
    char    path[PATHSIZ],work[BUFSIZ];
    int     i,
            retval;					/* value returned from getpath */

    if (argc < 2)
    {
	printf ("Usage: uupath sysname1 sysname2 ...\n");
	exit (EX_USAGE);
    }

    for (i = 1; i < argc; i++)
    {
	retval = getpath (argv[i], &path[0],DATABASE);		/* lookup usenet path */
	if (retval == EX_NOHOST)
	    printf ("Can't find path to %s\n", argv[i]);

	else
	    if (retval == EX_NOINPUT)
	    {
		printf ("Can't open the network map\n");
		exit (EX_TEMPFAIL);
	    }

	    else
		{
		sprintf (&work[0],"Path to %s:  %s\n", argv[i], &path[0]);
    		printf(&work[0],"username");
		}
	}
}
SHAR_EOF
if test 1155 -ne "`wc -c < 'uupath.c'`"
then
	echo shar: error transmitting "'uupath.c'" '(should have been 1155 characters)'
fi
fi
exit 0
#	End of shell archive