[mod.sources] Smail - a smarter net mailer

sources-request@genrad.UUCP (06/06/85)

From:  Steven List @ Benetics Corporation  (luke!steven)

The following shar file contains the man page and source for a smarter
mailer interface for use with networks.  It is based (as the copyright
indicates) on the program nmail by Kim Chr. Madsen (diku!kimcm).  The
program just didn't quite do it as it was.

The changes include allowing multiple destinations of various forms
rather than the node and recipient arguments of the original.  Also, I
wrote the man page.

This program works fine with Rnmail, Pnews, rn, readnews, and postnews.
That is, it works with recmail!  Any comments would be welcome, since
this is my first posting to the net.  This little goodie has allowed us
here to make full use of the output of pathalias and to feel that we're
becoming a real part of the network.

Steven
--
                               /-\  
:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:
:            Steven List @ Benetics Corporation                         :
:                        (415) 940-6300                                 :
:            {cdp,idi,oliveb,sun,tolerant}!bene!luke!steven             :
:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:
                               \-/                                       

------------------------------ Cut Here ------------------------------
#!/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:
#	smail.c
#	smail.1
# This archive created: Wed Jun  5 17:34:05 1985
export PATH; PATH=/bin:$PATH
echo shar: extracting "'smail.c'" '(7702 characters)'
if test -f 'smail.c'
then
	echo shar: over-writing existing file "'smail.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'smail.c'
X/*
X * smail -- An interface to mail, made to handle 
X *	    mail via the UUCP-network. A network
X *	    connection database is kept in:
X *	      /usr/lib/uucp/paths
X *	    and is maintained with pathalias(1).
X *
X * call --  smail destination...
X *            where destination may be:
X *				recipient
X *				recipient@system
X *				recipient@system.MODE
X *				system![system!...]recipient
X *
X * (c) 1985 by Kim Chr. Madsen
X *	       Datalogisk Institut (Institute of Datalogy)
X *	       University of Copenhagen.
X *	       {decvax,philabs,seismo}!mcvax!diku!kimcm
X * modified by Steven M. List 6/85
X *			   Benetics Corporation
X *             Mt. View, CA
X *             {cdp,idi,oliveb,sun,tolerant}!bene!luke!steven
X *
X */
X
X#include <stdio.h>
X
X/* ------------------------------------------------------------ */
X/* some globally useful defines                                 */
X/* ------------------------------------------------------------ */
X
X#define	PATHS	"/usr/lib/uucp/paths"
X#define MAIL	"/bin/mail"
X#define	VERSION	"smail -- version 0.1 preliminary version."
X#define	HOSTSZ	10
X#define	PATHSZ	80
X#define TRUE	 1
X#define FALSE	 0
X
X/* ------------------------------------------------------------ */
X/* some globals                                                 */
X/* ------------------------------------------------------------ */
X
Xtypedef unsigned char boolean;
X
Xboolean	debug = FALSE;
X
X/* ------------------------------------------------------------ */
X/* place to read path entries into                              */
X/* ------------------------------------------------------------ */
X
Xstruct smail_entry {
X	char	hostname[HOSTSZ+1];
X	char	pathstr[PATHSZ]
X};
X
Xextern char *getenv();
X
X/* ------------------------------------------------------------ */
X/* do it here - NOW!                                            */
X/* ------------------------------------------------------------ */
X
Xmain(argc, argv)
Xint		argc;
Xchar	*argv[];
X{
X	struct smail_entry t1;			/* work space for path entries	*/
X	FILE	*pathfile;				/* pathalias produced path file	*/
X	char	*paths = PATHS;			/* file name of path database	*/
X	char	*mail = MAIL;			/* path name of mailer to use	*/
X	char	*tmp;					/* temporary pointer			*/
X	char	*host;					/* destination host system		*/
X	char	*recipient;				/* destination user name		*/
X	char	*mailarg[32];			/* args to mail program			*/
X	char	narg = 0;				/* number of args to mail pgm	*/
X	boolean	found = FALSE;			/* true if node in path db		*/
X
X	register char carg;				/* current command arg			*/
X	char	buf[BUFSIZ];			/* temporary buffer for dest	*/
X
X	char	*calloc ();
X
X	/* ------------------------------------------------------------ */
X	/* MAILER environment variable overrides definition             */
X	/* ------------------------------------------------------------ */
X
X	if ((tmp = getenv("MAILER")) != NULL)
X	{
X		fprintf (stderr,"%s is requested as mail program\n",tmp);
X		mail = tmp;
X	}
X
X	/* ------------------------------------------------------------ */
X	/* process command line options                                 */
X	/* ------------------------------------------------------------ */
X
X	while(argc > 1 && argv[1][0] == '-')
X	{
X		argv++;
X		argc--;
X		switch(argv[0][1])
X		{
X			case 'd':	/* Just type some debugging information */
X				debug = TRUE;
X				break;
X			case 'm':	/* Another mail program requested */
X				argv++;
X				argc--;
X				if (argc > 1)
X				{
X					mail = argv[0];
X					if (debug) printf ("Mail program = %s\n",mail);
X				}
X				else
X				{
X					fprintf (stderr,"Mail program expected\n");
X					exit(1);
X				}
X				break;
X			case 'p':	/* An alternative path database requested */
X				argv++;
X				argc--;
X				if (argc > 1)
X				{
X					paths = argv[0];
X					if (debug) printf ("Database = %s\n",paths);
X				}
X				else
X				{
X					fprintf(stderr,"Alternate database expected\n");
X					exit(1);
X				}
X				break;
X			default:
X				fprintf (stderr, "Unknown option: %s\n", *argv);
X		}
X	}
X
X	/* ------------------------------------------------------------ */
X	/* open the path database                                       */
X	/* ------------------------------------------------------------ */
X
X	if (!(pathfile = fopen(paths, "r")))
X	{
X		fprintf (stderr,"cannot open %s\n",paths);
X		exit(1);
X	}
X
X	if (debug) printf ("%s\n", VERSION);
X
X	/* ------------------------------------------------------------ */
X	/* for each destination on the command line,                    */
X	/*   find the host and recipient names and create an arg to     */
X	/*   the mailer                                                 */
X	/* ------------------------------------------------------------ */
X
X	mailarg[narg] = calloc (1, strlen (mail) + 1);
X	strcpy (mailarg[narg++], mail);
X
X	for (carg = 1; carg < argc; carg++)
X	{
X		fprintf (stderr, "checking arg #%d <%s>\n", carg, argv[carg]);
X		if (argv[carg][0] == '\0' || argv[carg][0] == ' ') continue;
X		strcpy (buf, argv[carg]);
X		crackrecip (buf, &recipient, &host);
X
X		found = FALSE;
X		while(!found &&
X				fscanf(pathfile,"%s\t%[^\n]",t1.hostname,t1.pathstr)==2)
X		{
X			if (strncmp(t1.hostname, host, HOSTSZ) == 0)
X			{
X				mailarg[narg] = calloc (1, strlen (t1.pathstr) + 
X									strlen (recipient) + 2);
X				sprintf (mailarg[narg++], t1.pathstr, recipient);
X				found = TRUE;
X			}
X		}
X
X		if (!found)
X		{
X			fprintf(stderr, "Sorry, no information about %s\n",host);
X			mailarg[narg] = calloc (1, strlen (argv[carg]) + 1);
X			strcpy (mailarg[narg++], argv[carg]);
X		}
X		fprintf (stderr, "Sending mail to %s\n",mailarg[narg-1]);
X		rewind (pathfile);
X	}
X	(void) fclose(pathfile);
X
X	fprintf (stderr, "Sending mail to a total of %d destinations\n", narg-1);
X
X	if (narg <= 1)
X	{
X		fprintf(stderr, "Sorry, no destinations\n");
X		if (debug)
X		{
X			printf("what?\n");
X		}
X	}
X	else
X	{
X	/* ------------------------------------------------------------ */
X	/* if debugging, log the command that WOULD be executed         */
X	/* ------------------------------------------------------------ */
X
X		if (debug)
X		{
X			printf ("Mailcmd = %s",mail);
X			for (carg = 0; carg < narg; carg++)
X				printf (" %s", mailarg[carg]);
X			printf ("\n");
X		}
X	/* ------------------------------------------------------------ */
X	/* otherwise, do it right here and now                          */
X	/* ------------------------------------------------------------ */
X
X		else
X		{
X			execv (mail, mailarg);
X			perror ("returned from execv");
X			fprintf (stderr, "Cannot execv %s\n",mail);
X			exit(1);
X		}
X	}
X}
Xcrackrecip (buf, recip, host)
Xregister char *buf;
Xregister char **recip;
Xregister char **host;
X{
X#	include	<sys/utsname.h>
X
X	register char *sp;
X	register char *ep;
X
X	static struct utsname name;
X
X	char	*strrchr ();
X
X	if (debug)
X	{
X		printf ("Cracking %s for host and recip\n", buf);
X	}
X
X	if (sp = strrchr (buf, '@'))	/* internet style				*/
X	{
X		sp++;						/* start of node name			*/
X		if (ep = strrchr (sp, '.'))	/* path type (should be UUCP	*/
X		{
X			*ep = '\0';
X		}
X		*host = sp;
X
X		*(sp-1) = '\0';
X
X		if (sp = strrchr (buf, '!'))	/* multiple nodes			*/
X		{
X			*recip = sp + 1;
X		}
X		else
X		{
X			*recip = buf;
X		}
X		if (debug)
X		{
X			printf ("INTERNET style: r = %s  h = %s\n",
X				*recip, *host);
X		}
X	}
X	else if (sp = strrchr (buf, '!'))	/* uucp style				*/
X	{
X		*recip = sp + 1;
X		*sp = '\0';
X			
X		if (sp = strrchr (buf, '!'))	/* multiple nodes			*/
X		{
X			*host = sp + 1;
X		}
X		else
X		{
X			*host = buf;
X		}
X		if (debug)
X		{
X			printf ("UUCP style: r = %s  h = %s\n",
X				*recip, *host);
X		}
X	}
X	else								/* assume local - no host	*/
X	{
X		*recip = buf;
X		if (uname (&name) == -1)
X		{
X			perror ("uname failure");
X			exit (99);
X		}
X		*host = name.nodename;
X		if (debug)
X		{
X			printf ("UNKNOWN style: r = %s  h = %s\n",
X				*recip, *host);
X		}
X	}
X
X	return;
X}
SHAR_EOF
if test 7702 -ne "`wc -c 'smail.c'`"
then
	echo shar: error transmitting "'smail.c'" '(should have been 7702 characters)'
fi
echo shar: extracting "'smail.1'" '(1981 characters)'
if test -f 'smail.1'
then
	echo shar: over-writing existing file "'smail.1'"
fi
sed 's/^X//' << \SHAR_EOF > 'smail.1'
X.TH "smail" "1" "Benetics Local"
X.fi
X.ad b
X.SH NAME
Xsmail - send mail using various addressing schemes
X.SH SYNOPSIS
Xsmail [ -d ] [ -m \fIaltmailer\fR ] [ -p \fIaltpathdb\fR ]
X.br
X	  \fIdestination\fR...
X.SH DESCRIPTION
XSmail is a veneer over the standard /bin/mail program found in UNIX
XSystem III systems.  It accepts destination specifications in several
Xdifferent formats, allowing its use between various mail packages and
Xthe mailer.
X.SS Options
X.IP "-d" 16
XThe -d option turns on the limited debugging facility built into the
Xmailer.  In debug mode, the mailer does not actually mail anything, but
Xtells you what it would do if it did do it.
X.IP "-m \fIaltmailer\fR" 16
XThe -m option specifies an optional mailer to use.  This supersedes the
Xdefault mailer in the program ("/bin/mail") and the
Xenvironment variable MAILER.  The environment variable MAILER may be
Xused to define an alternate mailer in the absence of the -m option.
X.IP "" 16
XThis option also provides some means of debugging.  The mailer may be
Xdefined to be /bin/echo or some other program or shell script.
X.IP "-p \fIaltpathdb\fR" 16
XThe -p option allows the specification of an alternate path file.  The
Xdefault path file is "/usr/lib/uucp/paths".  The path file is the output
Xof program pathalias (produced by Peter Honeyman), and contains one
Xentry for each known node on the network.
X.SS Arguments
X.IP \fIdestination\fR 16
XThe destination(s) specified may take one of the following forms:
X.RS 22
X.P
Xperson
X.P
Xnode![node!...]person
X.P
Xperson@node
X.P
Xnode![node!...]person@node
X.P
Xperson@node.NET
X.P
Xnode![node!...]person@node.NET
X.RE
X.IP "" 16
Xwhere node is a system node name on the network and person is the login
Xname of the addressee.  256 destinations may be specified.
XThe mail program will be invoked only once for all destinations
Xspecified.
X.SH FILES
X.IP "/usr/lib/uucp/paths" 20
XPath file produced by pathalias.
X.SH "SEE ALSO"
Xpathalias(1), Pnews(1), Rnmail(1), rn(1), postnews(1), readnews(1)
SHAR_EOF
if test 1981 -ne "`wc -c 'smail.1'`"
then
	echo shar: error transmitting "'smail.1'" '(should have been 1981 characters)'
fi
#	End of shell archive
exit 0