[net.sources] sendmail/pathalias interface

gjm@ihnp4.UUCP (Gary J. Murakami) (01/13/84)

Here are the details on the sendmail "nameserver" enhancement that I
use for interfacing to pathalias.

-------------------------------------------------------------------

sendmail.h,main.c,parseaddr.c:
	nameserver enhancement
	
	# machine pathalias nameserver
	DM/usr/lib/mail/uupath

	# uucp optimization and routing
	R$-!$+			$:$<M$1!$2	uupath pathalias routing

	The RHS is expanded and the result is compressed into a single
	string used as the sole argument to the command in macro M.
	The output of the command (single line) is returned if the
	command is succesful, otherwise the RHS input argument is
	returned.  In the interests of efficiency, the command must be
	an executable object that accepts a single argument (address).

-------------------------------------------------------------------
/************************************************************************
* NAME									*
*	uupath - translate path using pathalias routing 		*
* SYNPOSIS								*
*	uupath address							*
* DESCRIPTION								*
*	The single argument address is separated into host!rest-of-path	*
*	and the routing file is read for the first "host" line.  The	*
*	path is translated using the right hand side alias and ouput	*
*	to stdout.  If the host is not found, the original address is	*
*	output and an exit code of 1 is returned.			*
************************************************************************/

#include <stdio.h>
#include <string.h>

#define	PATHFILE	"/usr/lib/mail/paths"
#define	LENSTR	512

extern void exit();
extern int fclose(),fprintf(),fscanf(),printf(),puts();
extern FILE *fopen();

main(argc,argv)
int	argc;
char	**argv;
{
	FILE	*fp;
	char	*bang,host[LENSTR],*user,route[LENSTR];
	
	if (argc != 2)
	{	(void) fprintf(stderr,"Usage: %s address\n",*argv);
		exit(2);
	}
	if ((fp = fopen(PATHFILE,"r")) == NULL)
	{	(void) fprintf(stderr,"%s: open fail on %s\n",*argv,PATHFILE);
		exit(2);
	}
	if ((bang = strchr(*++argv,'!')) == NULL)
	{	(void) puts(*argv);
		exit(1);
	}
	*bang = '\0';
	user = ++bang;
	while (fscanf(fp,"%*d %s %s\n",host,route) != EOF)
	{
		/* (void) printf("%s %s\n",host,route); /* DEBUG */
		if (strcmp(*argv,host) == 0)
		{
			(void) printf(route,user);
			(void) putchar('\n');
			exit(0);
		}
	}
	(void) printf("%s!%s\n",*argv,user);
	(void) fclose(fp);
	exit(1);
}

-------------------------------------------------------------------
the diff's are attached... sorry for the additional unrelated details
-------------------------------------------------------------------
diff osrc/sendmail.h src/sendmail.h:
	
27a28,37
>  *  definitions for byte/block operations
>  */
> #ifdef USG
> #include <memory.h>
> #define	bzero(d,l)	memset(d,'\0',l)
> #define	bcopy(s,d,l)	memcpy(d,s,l)
> #define bmove(s,d,l)	memcpy(d,s,l)
> #endif USG
> 
> /*
285a296
> # define CALLNAME	'\035'	/* call nameserver */

-------------------------------------------------------------------
diff osrc/main.c src/main.c
	null message fix aka /bin/mail
	nameserver enhancement
	freeze/thaw fixes for frozen configuration
	
66c66
< 	extern int finis();
---
> 	extern int collect(),finis();
525a526,528
> # ifdef LOG
> 			syslog(LOG_INFO, "queue run started, interval=%d", QueueIntvl);
> # endif LOG
585c588,589
< 		collect(FALSE);
---
> 		if (collect(FALSE) == FALSE)
> 			finis();
699a704
> 	'<', CALLNAME,
758c763
< 	extern char edata;
---
> 	char *start;
777a783
> 	start = Version;
781,782c787,788
< 	    write(f, (char *) &edata, fhdr.frzinfo.frzbrk - &edata) !=
< 					(fhdr.frzinfo.frzbrk - &edata))
---
> 	    write(f, (char *) start, fhdr.frzinfo.frzbrk - start) !=
> 					(fhdr.frzinfo.frzbrk - start))
785a792
> 	syslog(LOG_INFO, "froze start=0x%X end=0x%X", (char *) start, fhdr.frzinfo.frzbrk);
809c816
< 	extern char edata;
---
> 	char *start;
837a845
> 	start = Version;
840,841c848,849
< 	if (read(f, (char *) &edata, fhdr.frzinfo.frzbrk - &edata) !=
< 					(fhdr.frzinfo.frzbrk - &edata))
---
> 	if (read(f, (char *) start, fhdr.frzinfo.frzbrk - start) !=
> 					(fhdr.frzinfo.frzbrk - start))
883a892,895
> 
> #ifdef USG
> 	setpgrp();
> #endif USG

-------------------------------------------------------------------
diff osrc/parseaddr.c src/parseaddr.c

0a1
> # include <fcntl.h>
462a464,470
> 	char command[MAXLINE];		/* nameserver command name */
> 	char namearg[MAXLINE];		/* nameserver command arguement */
> 	char nameret[MAXLINE];		/* nameserver result */
> 	FILE *fnames;			/* nameserver stream */
> 	int fildes[2],nstatus,pid;	/* nameserver pipe, exit, pid */
> 	extern int execl(),fcntl(),pipe(); /* system calls */
> 	extern char *macvalue();	/* nameserver defined in macro */
680a689,730
> 		}
> 		else if (**npvp == CALLNAME)	/* nameserver call	*/
> 		{
> 			bmove((char *) &npvp[2], (char *) pvp,
> 				(avp - npvp - 2) * sizeof *avp);
> 			(void) strcpy(namearg,"");
> 			for (avp = &npvp[2]; *avp != NULL; avp++)
> 				(void) strcat(namearg,*avp);
> 			(void) strcpy(command,macvalue(*npvp[1],CurEnv));
> # ifdef DEBUG
> 			if (tTd(21, 3))
> 				printf("-----nameserver: %s\n", command);
> # endif DEBUG
> 			if (pipe(fildes) == 0)
> 			{
> 				if ((pid = fork()) == 0) /* child */
> 				{
> 					(void) close(fildes[0]);
> 					(void) close(1);
> 					(void) fcntl(fildes[1],F_DUPFD,1);
> 					(void) close(fildes[1]);
> 					(void) execl(command,namearg,0);
> 					exit(1);
> 				}
> 				if (pid > 0) /* parent */
> 				{
> 					(void) close(fildes[1]);
> 					fnames = fdopen(fildes[0],"r");
> 					fgets(nameret,MAXLINE,fnames);
> 					if (wait(&nstatus) == pid
> 					    && nstatus == 0)
> 						pvp = prescan(nameret,'\n');
> 					(void) fclose(fnames);
> 				}
> 			}
> # ifdef DEBUG
> 			if (tTd(21, 3))
> 			{
> 				printf("nameserver return:");
> 				printav(pvp);
> 			}
> # endif DEBUG

-------------------------------------------------------------------