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 -------------------------------------------------------------------