uumail -- an opath/pathalias based uucp mailer

sources-request at panda.UUCP sources-request at panda.UUCP
Wed Nov 20 22:21:02 AEST 1985


Mod.sources:  Volume 3, Issue 49
Submitted by: genrad!rice!neuro1!sob


Following is the shar for uumail, my version of a pathalias-database
mailer. This program can also understand domain names in the uucp
tradition (! over @) and can handle the new flags in 4.3 uucp.

Please read the README for more information.

This program has been checked-out on a Sun-2, Masscomp, and Sperry5000.

Thanks to Eric Roskos for the use of opath.

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

Stan Barber
Baylor College of Medicine
Houston, Texas

#! /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
#	README.orig
#	address.1
#	address.c
#	domains
#	gethostnam.c
#	getpath.c
#	makefile
#	opath.3
#	opath.c
#	palias
#	rmail.c
#	uuconf.h
#	uumail.1
#	uumail.c
#	uupath.1
#	uupath.c
# This archive created: Wed Nov 20 07:16:35 1985
export PATH; PATH=/bin:$PATH
echo shar: extracting "'README'" '(2366 characters)'
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
sed 's/^X//' << \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 at host.domain).
You can put as many addresses on a line as you like.

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 at 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.
XSYSIII 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 c-library gethostname to be used. If you
are a BSD site, define this.
XSYSTEMNAME 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.


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 uumail and uupath are included.

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

XStan Barber
Baylor College of Medicine
Houston, Texas
SHAR_EOF
if test 2366 -ne "`wc -c < 'README'`"
then
	echo shar: error transmitting "'README'" '(should have been 2366 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'README.orig'" '(875 characters)'
if test -f 'README.orig'
then
	echo shar: will not over-write existing file "'README.orig'"
else
sed 's/^X//' << \SHAR_EOF > 'README.orig'
The makefile can make two programs.  One is a filter that can be used
to expand network paths.  To install it you rename the program that you
want filtered.  The new file name is simply the old one with a period (.) 
appended to the end.  The filter program (filter) is then renamed to the 
original name of the program to be filtered.
	ie mail druxn!kak gets converted to
	mail. pur-ee!decvax!...!druxn!kak

The second file the makefile makes is uupath.  This will tell you the network
paths of its arguments
name tell you the path to it.

Don't forget to modify the defines for the location of the network map.  The
default location is /etc/usemap

If you have any questions just ask.

			Jeff Donnelly  (217) 333-6106
			University of Illinois
			pur-ee!uiucdcs!donnelly

Jeff may not help much -- his new number is 217-333-7937;
Kolstad can help some also:  214-669-3700
SHAR_EOF
if test 875 -ne "`wc -c < 'README.orig'`"
then
	echo shar: error transmitting "'README.orig'" '(should have been 875 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'address.1'" '(3563 characters)'
if test -f 'address.1'
then
	echo shar: will not over-write existing file "'address.1'"
else
sed 's/^X//' << \SHAR_EOF > 'address.1'
X.TH ADDRESS 1 local
X.SH NAME
address - display the path generated by \fBdeliver\fR for an
RFC822-format address.
X.SH SYNOPSIS
address rfc-address [ ... ]
X.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.
XFor 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.

X.SH "ADDRESS FORMAT"
Briefly, the RFC822-format address is of the form
X.nf
X.sp 1
	<localaddress>@<hostname>.<network>
X.sp 1
X.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.

X.SH EXAMPLES
X.HP 5
joe
X.br
The message is sent to the user ``joe'' on the local system.
X.HP 5
joe at ucbvax
X.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.
X.HP 5
joe at ucbvax.UUCP
X.br
XSame as joe at ucbvax
X.HP 5
joe at ucbvax.ARPA
X.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.
X.HP 5
joe%mit-multics.ARPA at ucbvax
X.br
The message is sent to ucbvax, who then uses the address
joe at 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).
X.HP 5
joe%vanderbilt.MAILNET%mit-multics.ARPA at ucbvax
X.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 at vanderbilt via MAILNET.  Since the above machines each have access
to the networks named in the address, this address will work correctly.
X.SH FILES
/usr/lib/uucp/domains - Domain/gateway table
X.br
/usr/lib/uucp/archive - Pathalias database
X.SH "SEE ALSO"
opath(3)
X.SH AUTHOR
Eric Roskos, PE SDC, 1/16/85
SHAR_EOF
if test 3563 -ne "`wc -c < 'address.1'`"
then
	echo shar: error transmitting "'address.1'" '(should have been 3563 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'address.c'" '(885 characters)'
if test -f 'address.c'
then
	echo shar: will not over-write existing file "'address.c'"
else
sed 's/^X//' << \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.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.2 85/09/16 18:31:53 sob Exp $";

char *opath();
int Debug;

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

	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 885 -ne "`wc -c < 'address.c'`"
then
	echo shar: error transmitting "'address.c'" '(should have been 885 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'domains'" '(1093 characters)'
if test -f 'domains'
then
	echo shar: will not over-write existing file "'domains'"
else
sed 's/^X//' << \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
#
X.WA.UUCP,,,%R!%U
X.OR.UUCP,,,%R!%U
X.N-CA.UUCP,,,%R!%U
X.S-CA.UUCP,,,%R!%U
X.MTN.UUCP,,,%R!%U
X.S-CEN.UUCP,,,%R!%U
X.MID-W.UUCP,,,%R!%U
X.S-EAST.UUCP,,,%R!%U
X.ATL.UUCP,,,%R!%U
X.N-ENG.UUCP,,,%R!%U
X.HI.UUCP,,,%R!%U
X.W-CAN.UUCP,,,%R!%U
X.E-CAN.UUCP,,,%R!%U
X.EUR.UUCP,,,%R!%U
X.UK.UUCP,,,%R!%U
X.AUS.UUCP,,,%R!%U
X.ISRAEL.UUCP,,,%R!%U
X.ATT.UUCP,>ihnp4,,%P!%D!%U
X.HP.UUCP,,,%R!%U
X.PE.UUCP,,,%R!%U
X.UUCP,,,%R!%U
X.CSNET,>rice,,%P!%U%%%D at CSNET-RELAY.ARPA
X.MAILNET,>rice,,%P!%U%%%D at MULTICS.MIT.EDU
# .BITNET,>rice,,%P!%U%%%D at WISCVM.ARPA
X.XEROX,>rice,,%P!%U.%D at XEROX.ARPA
X.DEC,>decwrl,,%P!%U@%D
X.ARPA,>rice,,%P!%U@%D
X.EDU,>rice,,%P!%U@%D
X.COM,>rice,,%P!%U@%D
X.GOV,>rice,,%P!%U@%D
X.MIL,>rice,,%P!%U@%D
X.OTH,>rice,,%P!%U@%D
X.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 # end of overwriting check
echo shar: extracting "'gethostnam.c'" '(1266 characters)'
if test -f 'gethostnam.c'
then
	echo shar: will not over-write existing file "'gethostnam.c'"
else
sed 's/^X//' << \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.2 85/08/03 00:25:16 UUCP Exp $";
#endif lint

#ifndef GETHOSTNAME
#include "uuconf.h"

void
gethostname(name, len)
char	*name;
{
	FILE	*whoami, *fopen(), *popen();
	char	*ptr, *index();
#ifdef SYSIII
	struct utsname utsn;
#endif

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

	/* try /etc/whoami */
	if ((whoami = fopen("/etc/whoami", "r")) != 0) {
		(void) fgets(name, len, whoami);
		(void) fclose(whoami);
		if ((ptr = index(name, '\n')) != 0)
			*ptr = '\0';
	}
	if (*name)
		return;

	/* 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 1266 -ne "`wc -c < 'gethostnam.c'`"
then
	echo shar: error transmitting "'gethostnam.c'" '(should have been 1266 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'getpath.c'" '(2798 characters)'
if test -f 'getpath.c'
then
	echo shar: will not over-write existing file "'getpath.c'"
else
sed 's/^X//' << \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
 *
 * Author: J. Donnelly   3/82
 *
 */

/* 22-jun-83 Sheppard
 * modified to rewind path file (if open), rather than open again
 *
 * $Log:	getpath.c,v $
 * 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"

static char rcsid[] = "$Header: getpath.c,v 1.9 85/11/14 20:21:49 sob Exp $";



XFILE * fopen (), *in;

getpath (sysname, pathname)
char   *sysname, *pathname;
{
    char    name[NAMESIZ],*p,t;

#ifdef DBM
    datum lhs,rhs;
#endif
#ifdef DEBUG
if (Debug>2)
	printf("In getpath: Sysname = %s, Pathfile = %s\n",sysname,paths);
#endif
#ifdef DBM
   if (dbminit(paths) <0) return(EX_NOINPUT);
    	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) {
	if ((in = fopen(paths, "r")) == NULL)
	    return(EX_NOINPUT);
    }
    else
	rewind(in);

    for (;;)
    {
	p = &name[0];
	while ((t = getc(in)) != EOF && (*p++ = t) != ' ' && t != '\t'); /* read the system name */
	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
}
SHAR_EOF
if test 2798 -ne "`wc -c < 'getpath.c'`"
then
	echo shar: error transmitting "'getpath.c'" '(should have been 2798 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'makefile'" '(2613 characters)'
if test -f 'makefile'
then
	echo shar: will not over-write existing file "'makefile'"
else
sed 's/^X//' << \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.3 85/08/03 00:38:33 UUCP 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
# 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.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
# 
###############################################################
X.SUFFIXES: .c,v .h,v

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

LIBS=

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

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

all: uumail rmail

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)

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 README.orig opath.3 address.1
	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 README.orig opath.3 address.1> shar.out

SHAR_EOF
if test 2613 -ne "`wc -c < 'makefile'`"
then
	echo shar: error transmitting "'makefile'" '(should have been 2613 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'opath.3'" '(4896 characters)'
if test -f 'opath.3'
then
	echo shar: will not over-write existing file "'opath.3'"
else
sed 's/^X//' << \SHAR_EOF > 'opath.3'
X.TH OPATH 3 "PE SDC"
X.SH NAME
opath - Generate a UUCP route from an RFC822 address
X.br
oupath - Generate a UUCP route from a (possibly disconnected) UUCP path
X.SH SYNOPSIS
char *opath(s)
X.br
char *s;
X.sp 1
char *oupath(s)
X.br
char *s;
X.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.
X.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.
X.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.
X.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.
X.SH "FILES"
\fI/usr/lib/uucp/archive\fR - The pathalias database, in DBM(3) format.
XSee PATHALIAS(1) for information; pathalias is a public-domain program
distributed via the Usenet's net.sources facility.
X.br
X.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:
X.br
X.in 1i
<domain>,<path>,<reserved>,<template>
X.br
X.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.
X.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:
X.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 ``!''.
X.IP U
The user name from the original address is inserted.
X.IP N
The site name from the original address, with the domain specifiers
removed, is inserted.
X.IP D
The site name from the original address, including the domain specifiers,
is inserted.
X.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.
X.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.
X.PP
XFollowing are some example entries for the domain table.  Note that all
domain names begin with a ``.''.
X.sp 1
X.nf
X.in 1i
# This is a comment
\&.HP.UUCP,,,%R!%U
\&.UUCP,,,%R!%U
\&.CSNET,>decwrl,,%P!%U%%%S at CSNET-RELAY.ARPA
\&.EDU,>ucbvax,,%P!%D
X.in
X.fi
X.sp 1
X.SH "SEE ALSO"
PATHALIAS(1), ADDRESS(1), RMAIL(1)
X.SH "AUTHOR"
Eric Roskos, Perkin-Elmer Corp. SDC.
X.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 4896 -ne "`wc -c < 'opath.3'`"
then
	echo shar: error transmitting "'opath.3'" '(should have been 4896 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'opath.c'" '(5753 characters)'
if test -f 'opath.c'
then
	echo shar: will not over-write existing file "'opath.c'"
else
sed 's/^X//' << \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;
{
XFILE *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];
XFILE *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;
{
XFILE *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 # end of overwriting check
echo shar: extracting "'palias'" '(151 characters)'
if test -f 'palias'
then
	echo shar: will not over-write existing file "'palias'"
else
sed 's/^X//' << \SHAR_EOF > 'palias'
neuro1 %s
rice  rice!%s
baylor baylor!%s
kitty baylor!kitty!%s
shell shell!%s
decwrl shell!ihnp4!decwrl!%s
ihnp4 shell!ihnp4!%s
psuvax shell!psuvax!%s
SHAR_EOF
if test 151 -ne "`wc -c < 'palias'`"
then
	echo shar: error transmitting "'palias'" '(should have been 151 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'rmail.c'" '(2622 characters)'
if test -f 'rmail.c'
then
	echo shar: will not over-write existing file "'rmail.c'"
else
sed 's/^X//' << \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 # end of overwriting check
echo shar: extracting "'uuconf.h'" '(2942 characters)'
if test -f 'uuconf.h'
then
	echo shar: will not over-write existing file "'uuconf.h'"
else
sed 's/^X//' << \SHAR_EOF > 'uuconf.h'
/* $Header: uuconf.h,v 1.4 85/10/02 02:16:21 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.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_BASE

# 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 */
#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

/* 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 2942 -ne "`wc -c < 'uuconf.h'`"
then
	echo shar: error transmitting "'uuconf.h'" '(should have been 2942 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'uumail.1'" '(2272 characters)'
if test -f 'uumail.1'
then
	echo shar: will not over-write existing file "'uumail.1'"
else
sed 's/^X//' << \SHAR_EOF > 'uumail.1'
X.TH "UUMAIL" "8" "Baylor College of Medicine"
X.fi
X.ad b
X.SH NAME
uumail \- rewrite address & route mail using uucpmap database 
X.br
uupath \- print the uucp path to a host
X.SH SYNOPSIS
X.B uumail [ \fIoptions\fR ] \fIaddress\fR
X.br
X.B uupath \fIhostname\fR
X.SH DESCRIPTION
X.B Uumail
is designed to be used as a mail delivery program to correctly
route mail over uucp connections.
X.SS Standard Options
X.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 
X.B LOGNAME
and
X.B USER
) or using getlogin(3).
X.IP "-m" 16
The -m option causes the mail to also be sent to the sender of the message.
X.IP "-c" 16
The -c option causes
X.B uucico 
to be started immediately after queuing the mail.
The default just queues the mail.
X.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).
X.SS Compile-time Configurable Options
X.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 
X.I -d
flag with a number between 1 and 6.
X.IP "-g[A-Z]" 16
If your 
X.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.

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

X.SH AUTHORS
X.br
XStan Barber, Baylor College of Medicine
X.br
Getpath routine by John Donnelly, University of Illinois
X.br
Gethostname routine by Peter Honeyman, Princeton
X.br
Opath routine by Eric Roskos, Perkin-Elmer

SHAR_EOF
if test 2272 -ne "`wc -c < 'uumail.1'`"
then
	echo shar: error transmitting "'uumail.1'" '(should have been 2272 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'uumail.c'" '(11965 characters)'
if test -f 'uumail.c'
then
	echo shar: will not over-write existing file "'uumail.c'"
else
sed 's/^X//' << \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.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.7 85/11/18 12:36:48 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,			/* 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)) != 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);
		exit(EX_NOHOST);
	    }
	}
    else 
    if (index(p,'@') == NULL) strcpy(path,oupath(p)); 
	    else strcpy(path,opath(p));
#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)) != 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);
		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)
XFILE *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)
XFILE *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 11965 -ne "`wc -c < 'uumail.c'`"
then
	echo shar: error transmitting "'uumail.c'" '(should have been 11965 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'uupath.1'" '(759 characters)'
if test -f 'uupath.1'
then
	echo shar: will not over-write existing file "'uupath.1'"
else
sed 's/^X//' << \SHAR_EOF > 'uupath.1'
X.TH "UUPATH" "1" "Baylor College of Medicine"
X.fi
X.ad b
X.SH NAME
uupath \- print mail routing information using uucpmap database
X.SH SYNOPSIS
X.B uupath  \fIhost1 host2 host3 ...\fR
X.SH DESCRIPTION
X.B Uupath
is designed to be used to query the uucpmap database for mail routing
paths used by
X.I uumail.
X.SS Arguments
X.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
X.I uupath.

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

X.SH AUTHORS
X.br
Jeff Donnelly, University of Illinois
X.br
XStan 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 # end of overwriting check
echo shar: extracting "'uupath.c'" '(1155 characters)'
if test -f 'uupath.c'
then
	echo shar: will not over-write existing file "'uupath.c'"
else
sed 's/^X//' << \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 # end of overwriting check
#	End of shell archive
exit 0



More information about the Mod.sources mailing list