[net.sources] nmail

njh@root44.UUCP (Nigel Horne) (07/24/85)

A while ago someone posted nmail, a program to automatically route for you.
Here's the version I run with various hacks. It takes the output of
pathalias, but if you have a small machine and can't run pathalias on
it use the program mkpath which was originally distributed with it.
Flames to /dev/null, comments/fixes to me. (See my address in the .signature).


#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	nmail.1
#	nmail.c
# This archive created: Wed Jul 24 16:28:11 1985
echo shar: extracting nmail.1 '(968 characters)'
cat << \SHAR_EOF > nmail.1
.TH NMAIL local
.SH NAME
nmail  \-  a UUCP network mail interface
.SH SYNOPSIS
.B nmail
[
-p
]
person@site ...
.SH DESCRIPTION
.I Nmail
searches each argument for an explanation point.
If it finds one, it replaces everything through
the explanation point with the line it finds in
the database.  Everything up to the explanation
point is used as a key into the database.  The
new arguments are echoed, then the normal mailer
is executed with the new arguments.
An element in the database should look like:
.nf

(site name)	(printf string)

.fi
This happens to be the format output by the
.I pathalias(1)
program.  The database must be sorted.
.SH OPTIONS
.TP
.B \-p	Returns the pathname only to standard output.  This
option is usefull for emacs mail.
.SH FILES
.TP 20
.I /usr/local/lib/paths
the sorted database
.TP 20
.I /usr/ucb/mail
the mailer
.SH "SEE ALSO"
pathalias(1), mail(1)
.SH AUTHOR
Mike Mitchell  (duke!mcnc!ikonas!mcm)
.br
Nigel Horne	<njh@rootcl.UUCP>
SHAR_EOF
if test 968 -ne "`wc -c nmail.1`"
then
echo shar: error transmitting nmail.1 '(should have been 968 characters)'
fi
echo shar: extracting nmail.c '(4654 characters)'
cat << \SHAR_EOF > nmail.c
/*
 * nmail.c -- a network mail interface.
 * This program accepts as arguments the standard network
 * addresses, and expands the section of an argument up to a
 * "!" into the actual path the letter must take to get to that
 * site.  For example, to get to swd at duke, the argument
 * "duke!swd" is expanded to "mcnc!duke!swd".  "decvax!ittvax!swatt"
 * would expand to "mcnc!duke!decvax!ittvax!swatt".
 *
 * This program uses the output of the mkpath program developed by
 * Mike Mitchell at ikonas (duke!mcnc!ikonas!mcm).
 *
 * The input data should look like:
 *	sitename (any number of blanks or tabs) printf-string to get there
 *
 * The input data must be sorted.
 *
 * Version 2.0.1 24/7/85
 *
 * Written by Mike Mitchell (decvax!duke!mcnc!ikonas!mcm)
 *
 *
 * M o d i f i c a t i o n    H i s t o r y
 *
 * BFE	3/8/83	wi001	Changed MAILER to /usr/ucb/mail
 *			Added -p option to return the path to stdio only,
 *			this is usefull for emacs mail.
 * BFE	3/9/83	wi002	We are going to substitute this program for standard
 *			mail since it goes on unnoticed to the user.  We only
 *			need to remove a line which prints 'mail ...' just
 *			before the actual mail call.  This way it is truely
 *			invisible to the user.
 * dbw	11/8/83	wi003	Change the MAILER to use MAILER environment variable
 *			with the default being a compile-time option, MAILER.
 *			Change the path	library to live in a compile-time
 *			option DATA.
 * rootcl!njh		I've commented all my changes.
 */

#include <stdio.h>

/* wi001 - changed mailer location */
/* wi003 - change mailer location via makefile */
#define MAILER	"/usr/ucb/mail"		/* the mail program to use */
/*#define MAILER	"/bin/mail"		/* the mail program to use */
/* wi003 - change data location via makefile */
#define DATA	"/usr/local/lib/paths"	/* where the data is kept */
#define OK	1	/* all expansions done correctly */
#define BAD	0	/* an expansion done incorrectly */
/*#define	DEBUG		/* debugging from rootcl!njh */

char	*malloc();
char	*calloc();	/* correct definition rootcl!njh */
char	*index();
char	*strcpy();

main(argc,argv,envp)
int argc;
char **argv;
char **envp;
{
	register FILE *fd;
	char route[BUFSIZ],tmp[BUFSIZ];
	char site[BUFSIZ];
	register char *cp;
	register char **args, *pos;
	/* wi001 - added pflg */
	register num,rc,flag,pflg = 0;


	/* wi001 - accept a '-p' option */
	if(argc > 1 && argv[1][0] == '-' && argv[1][1] == 'p') {
		pflg++;
		argc--;
		argv++;
	}

	args = (char **)calloc((unsigned)argc+1, sizeof(char *));
	if (args == NULL) {
		fprintf(stderr, "Cannot get memory for argument list.\n");
		exit(1);
	}
	/* wi001 - if -p is present then delete 'mail' from argument */
	if (!pflg) {
		args[0] = "mail";
		num = 1;
	} else
		num = 0;	/* rootcl!njh */
	fd = fopen(DATA,"r");
	if (fd == (FILE *)NULL){	/* rootcl!njh */
		fprintf(stderr, "Can't read %s\n", DATA);
		exit(2);
	}
	flag = OK;
	while(--argc) {
#ifdef	DEBUG	/* rootcl!njh */
		printf("while: argc = %d\n", argc);
#endif
		argv++;
		/*
		 * rootcl!njh: use user@site, not site!user.
		 */
		if ((cp=index(*argv, '@')) == NULL) {
			pos = malloc((unsigned)strlen(*argv) + 1);
			if (pos == NULL) {
				fprintf(stderr, "Cannot get memory for name %s\n", *argv);
				exit(1);
			}
			strcpy(pos,*argv);
			args[num++] = pos;
		} else {
			*cp++ = '\0';
			while(fscanf(fd,"%s%s",site,route) != EOF) {
#ifdef	DEBUG
				printf("got site %s route %s\n", site, route);
#endif
				rc = strcmp(site, cp);
				/*if (rc > 0) break;	/* removed rootcl!njh */
				if (rc == 0) {
#ifdef	DEBUG	/* rootcl!njh */
					printf("%s found, route %s\n", site, route);
#endif	DEBUG
					sprintf(tmp, route, *argv);
#ifdef	DEBUG	/* rootcl!njh */
					printf("route will be %s\n", tmp);
#endif	DEBUG
					pos = malloc((unsigned)strlen(tmp)+1);
					if (pos == NULL) {
						fprintf(stderr, "Can't get mem for path %s\n", tmp);
						exit(1);
					}
					strcpy(pos,tmp);
					args[num++] = pos;
					break;
				}
			}
			if (rc != 0) {
				printf("Can't get to %s from here\n",*argv);
				flag = BAD;
				break;	/* rootcl!njh */
			}
			rewind(fd);
		}
	}
	if (flag == OK) {
		/* wi001 - do the mailing only if -p was not specified */
		/* wi002 - print here only if pflg is on (for emacs use) */
		if (pflg) {
#ifdef	DEBUG	/* rootcl!njh */
			puts("pflg set");
#endif	DEBUG
			args[num] = NULL;
			for (rc = 0; rc < num; rc++)
				printf("%s ",args[rc]);
			putchar('\n');
		} else {
			execve(MAILER,args,envp);
			/*
			 * If all else fails! rootcl!njh
			 */
			execve("/bin/mail", args, envp);	
			fprintf(stderr, "execve of %s failed!\n", MAILER);
			flag = BAD;	/* rootcl!njh */
		}
	}
	exit(flag == OK ? 0 : 1);
}
SHAR_EOF
if test 4654 -ne "`wc -c nmail.c`"
then
echo shar: error transmitting nmail.c '(should have been 4654 characters)'
fi
#	End of shell archive
exit 0
-- 
--

Nigel Horne, Technical Manager, Root Computers Ltd.
<njh@rootcl.UUCP>	Phone:	+44 1 726 6501 Telex:	894519
{deccra,edai,glasgow,hrc63,ist,kcl-cs,qmc-cs,rlvd,pmllab,stc,warwick,uel,
	ukc,unisoft}!root44!rootcl!njh