Ease 3.0: High Level Language for Sendmail (Part 2 of 6)

Bruce Barnett barnett at grymoire.crd.ge.com
Sat Feb 23 18:14:36 AEST 1991


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 6)."
# Contents:  doc/cfc.man src/Makefile src/errors.c src/idman.c
#   src/lexan.patch src/main.c src/symtab.c test/test.mc
# Wrapped by barnett at grymoire on Sat Feb 23 01:13:52 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f doc/cfc.man -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"doc/cfc.man\"
else
echo shar: Extracting \"doc/cfc.man\" \(5708 characters\)
sed "s/^X//" >doc/cfc.man <<'END_OF_doc/cfc.man'
X...
X... $Header: /home/kreskin/u0/barnett/Src/Ease/ease/doc/RCS/cfc.man,v 1.2 1990/04/04 15:42:51 jeff Exp barnett $
X... 
X... $Log: cfc.man,v $
X... Revision 1.2  1990/04/04  15:42:51  jeff
X... Reformatted somewhat for readability.  Added some bugs
X... described by Bruce Barnett.
X...
X... Version 1.1  90/04/04  14:57:38  jeff
X... Initial version
X... 
X... Revision 2.0  88/06/15  15:17:36  arnold
X... Baseline release for net posting. ADR.
X... 
X... Revision 1.3  88/01/21  16:23:21  arnold
X... Some typo fixes.
X... 
X... Revision 1.2  87/04/08  10:21:47  arnold
X... Small bug fixes, compatibility option added, also warnings for
X... unrecognized flags and options. ADR.
X... 
X... Revision 1.1  87/02/16  15:25:32  arnold
X... Initial revision
X... 
X...
X.TH CFC local
X.SH NAME
Xcfc \- Sendmail cf file compiler
X.SH SYNOPSIS
X.B cfc
X[
X.B \-s
X] [
X.B \-i
X] [
X.B \-d
X] [
X.B \-c
X] [
X.B \-u
X] [
X.B \-C \fICLASSES\fP
X] <
X.I sendmail.cf-file
X>
X.I ease-source-file
X.SH DESCRIPTION
X.I Cfc
Xis a filter that reads a raw
X.IR sendmail (8)
Xconfiguration file on its standard input, and produces almost useable
X.IR ease (1)
Xsource on its standard output.
X.P
XIt is designed as a conversion tool, to translate an existing
X.B sendmail.cf
Xfile into
X.I ease
Xwith the idea that all future work will be done in
X.IR ease .
X.P
X.I Cfc
Xpasses all comments through to the output, and converts all predefined
X.I sendmail
Xmacros, options, option values, and mailer flags into the names used by
X.IR ease .
X.P
XIt is suggested you use
X.I cfc
Xto convert a 
X.I sendmail.cf
Xfile into 
X.I ease
Xformat, and then convert the
X.I ease
Xfile back into
X.I sendmail
Xformat.
XYou may have to experiment with the right options and the right combinations
Xbefore
X.I ease
Xwill generate an output file with no errors.
XThen use the
X.I cfdiff
Xscript to compare the original
X.I sendmail.cf
Xfile to the output of
X.IR ease .
XYou should see some differences in formatting, as some 
X.I sendmail
Xlines can be on one or two lines, and some options have more than one form.
XOnce it is determined that these are the only difference, you should feel
Xvery comfortable using 
X.I ease
Xas a high level langauge for 
X.I sendmail 
Xfiles.
XIf you are unable to make the two files identical, you may need to modify the 
X.I ease
Xinput file so the output is correct.
XIf necessary, you can use the
X.IR asm ()
Xfunction in
X.I ease
Xto pass the characters, unchanged, to the output.
X.P
X.I Cfc
Xisn't perfect. 
XYou may wish to modify the 
X.I ease
Xfile for cosmetic reasons:
X.IP
X.I Cfc
Xintroduces tabs on its own, as well as often passing through tabs
Xfrom the
X.I sendmail
Xinput.
XIt will also print a header for each different type of line, e.g. if the
Xinput had seven
X.B O
X(option) lines, there will be seven option blocks.
XThese are usually succesive, and can therefore be merged.
X.IP
XMove some comments.
XThe block close on rulesets often comes after the comments that
Xprecede the next ruleset or mailer specification.
X
X.RE
X.P
XIn short,
X.I cfc
Xdoes over 99% of the tedious work of translating a
X.B sendmail.cf
Xinto
X.I ease
Xformat.
XSuprisingly, the combination of
X.I cfc
Xand
X.I ease
Xcan find bugs in a current
X.B sendmail.cf
Xfile!
X.P
X.I Cfc
Xtakes five options.
X.RS
X.TP
X.B \-c
XIndicates that
X.I cfc
Xshould run in 4.2BSD compatibility mode.
XIn this case, options and mailer flags which are new in the 4.3BSD
Xversion of
X.I sendmail
Xwill not be recognized.
X.TP
X.B \-u
X.I Cfc
Xwill warn about the use of any undocumented options or mailer flags in
Xthe 4.3BSD
X.IR sendmail .
XThe correct
X.I ease
Xoutput will still be produced.
X.TP
X.B \-s
X.I Cfc
Xwill assume the input file is for Sun's sendmail.
XIt will produce a ruleset definition for rule number 30, which Sun uses
Xin their standard configuration file, and older implementations
Xcomplain about. It also adds some declarations that match Sun's
Xadditions to sendmail, so errors won't occur.
X.TP
X.B \-d
X.I Cfc
Xwill cause some definitions to be added that will convert the Ultrix
X.i sendmail.cf
Xfile with fewer errors.
X.TP
X.B \-i
X.I Cfc
Xwill add some declarations that the IDA version of 
X.I sendmail
Xlikes to see.
X.TP
X.B \-C
X<LETTER><LETTER>...
X.I Cfc
Xwill add an additional header of the form
X.I any_in_<LETTER>
Xand
X.I any_not_in_<LETTER>
Xwhere
X.I <LETTER>
Xis a single character that specifes a class used in the sendmail file,
Xbut not defined.
XThis prevents 
X.I ease
Xfrom complaining about undefined classes.
X.RE
X.P
XWith the right compination of options and class definitions, it is
Xeasy to convert a 
X.I sendmail
Xfile into 
X.I ease ,
Xedit the file, and run 
X.I ease
Xon the file, and install the output.
X.\" .SH FILES
X.SH SEE ALSO
X.I "Sendmail Installation and Operation Guide"
Xby Eric Allman
X(SMM:7 in the 4.3 BSD UNIX System Manager's Manual),
X.I "Ease: A Configuration Language for Sendmail"
Xby James S. Schoner, amended by Jeff P. Stearns, Arnold D. Robbins, and Bruce G. Barnett.
X.IR sendmail (8),
X.IR ease (1).
X.SH DIAGNOSTICS
X``\c
X.IR Routine :
Xmalformed input line
X.IR line :
Xfatal error''
Xfor input it doesn't understand.
X.I Routine
Xis the name of the routine in
X.I cfc
Xwhich choked, and
X.I line
Xis the line number in the input.
X.SH BUGS
XOnly recognizes continuation lines (lines that begin with a \s-1TAB\s+1)
Xfor header (H) and mailer (M) definitions.
X.P
XShould read from files on the command line, instead of being a pure filter.
X.P
XShould be a two pass program, and learn the classes which need
Xdefining automatically. The
X.B \-C
Xoption is really a kludge.
X.PP
XIn some cases, you can use the
X\fIasm(".......")\fP
Xcommand to work around problems.
X.SH AUTHOR
X.nf
XArnold Robbins
XEmory University Computing Center
Xarnold at emory.edu
X
XModifications by Bruce G. Barnett
XGeneral Electric, Corporate Research and Development
Xbarnett at crdgw1.ge.com
X
X.fi
END_OF_doc/cfc.man
if test 5708 -ne `wc -c <doc/cfc.man`; then
    echo shar: \"doc/cfc.man\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f src/Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"src/Makefile\"
else
echo shar: Extracting \"src/Makefile\" \(3877 characters\)
sed "s/^X//" >src/Makefile <<'END_OF_src/Makefile'
X# Makefile for Ease Translator (et).
X#
X#	$Header: /home/kreskin/u0/barnett/Src/Ease/ease/src/RCS/Makefile,v 2.1 1990/01/30 13:54:13 jeff Exp barnett $
X#
X#	$Log: Makefile,v $
X# Revision 2.1  1990/01/30  13:54:13  jeff
X# Updated for release 2.1 Aplha.
X#
X# Revision 2.0  88/06/15  14:47:35  root
X# Baseline release for net posting. ADR.
X# 
X#
X#	James S. Schoner, Purdue University Computing Center,
X#			  West Lafayette, Indiana  47907
X#
X#	Copyright (c) 1985 by Purdue Research Foundation
X#
X#	All rights reserved.
X#
X
XINCLUDE =
X
X# where to install the binaries
XBINDIR          =	../bin
X
XOWNER = root
XGROUP = staff
XMODE = 755
X#INSTALL = install -c -m ${MODE} -o ${OWNER} -g ${GROUP}
XINSTALL=cp
X# define this for grammar debugging
X#DEFS =-DYYDEBUG
XDEFS =
X# I had strange errors happen when I use SunOS Optimizer.....
X# In particular, with SunOS 4.0.3, Sparc, and -O (-O2)....
X# Maybe you better not use -O with SunOS
XCFLAGS = -g  ${DEFS} ${INCLUDE}
X#CFLAGS = -O ${DEFS} ${INCLUDE}
X
XLP = lpr
XLPFLAGS = -J"Ease Source"
X
XHDR = symtab.h
XSRC = main.c emitcf.c errors.c idman.c strops.c symtab.c fixstrings.c
XLST = Makefile lexan.l parser.y ${HDR} ${SRC}
XDEP = parser.c lexan.c ${SRC}
XOBJ = parser.o lexan.o main.o emitcf.o errors.o idman.o strops.o symtab.o \
X	fixstrings.o
XCFILES= $(SRC) $(DEP)
X
Xall: et
X
Xet: ${OBJ}
X	cc ${CFLAGS} -o et ${OBJ} -ll
X
Xclean: FRC
X	rm -f et *.o lexan.c parser.c y.output yacc.acts yacc.tmp \
X	      lexdefs.h y.tab.h errs Makefile.bak y.output y.tab.c y.tok.h
X
Xdepend:
X	${CC} -M ${CFLAGS} ${CFILES} | \
X	sed -e ':loop' \
X	    -e 's/\.\.\/[^ /]*\/\.\./../' \
X	    -e 't loop' | \
X	awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
X		else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
X		       else rec = rec " " $$2 } } ; \
X	      END { print rec } ' > makedep
X	echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep
X	echo '$$r makedep' >>eddep
X	echo 'w' >>eddep
X	cp Makefile Makefile.bak
X	ex - Makefile < eddep
X	rm eddep makedep
X
Xinstall: et FRC
X	${INSTALL} et ${BINDIR}
X	${INSTALL} ease.sh ${BINDIR}/ease
X
X
Xlint:   ${DEP} symtab.h FRC
X	lint -hxn ${DEP}
X
Xprint:  ${LST} FRC
X	@pr -f ${LST} | ${LP} ${LPFLAGS}
X
Xspotless: clean FRC
X	rcsclean ${LST}
X
Xy.tab.h parser.c: parser.y
X	@rm -f parser.c
X	yacc -v -d parser.y
X	sed 's/=yylex/=yyyylex/' < y.tab.c >parser.c
X
X# the following dummy rule is because of the results of 'make depend'
X# However, under SunOS Make - it complains. You may have to comment it out
X./lexdefs.h:	lexdefs.h
X
Xlexdefs.h:	y.tab.h
X	-(cmp -s y.tab.h lexdefs.h || cp y.tab.h lexdefs.h)
X
Xlexan.c: lexan.l
X
Xparser.o: y.tok.h
Xy.tok.h:	y.tab.h
X	grep '^#.*define' y.tab.h |\
X	sed 's/^# define \([^ ]*\) [^ ]*$$/	"\1",/' >y.tok.h
X
X${HDR} ${SRC} lexan.l parser.y:
X	co $@
X
XFRC:
X
X# DO NOT DELETE THIS LINE -- make depend uses it
X
Xmain.o: main.c ./fixstrings.h /usr/include/stdio.h
Xemitcf.o: emitcf.c /usr/include/stdio.h ./symtab.h ./fixstrings.h
Xerrors.o: errors.c /usr/include/stdio.h ./fixstrings.h
Xidman.o: idman.c /usr/include/stdio.h ./symtab.h ./fixstrings.h
Xstrops.o: strops.c ./fixstrings.h /usr/include/stdio.h /usr/include/strings.h
Xstrops.o: ./symtab.h
Xsymtab.o: symtab.c ./fixstrings.h /usr/include/stdio.h /usr/include/ctype.h
Xsymtab.o: ./symtab.h
Xfixstrings.o: fixstrings.c /usr/include/strings.h
Xparser.o: parser.c ./fixstrings.h /usr/include/stdio.h ./symtab.h
Xlexan.o: lexan.c /usr/include/stdio.h ./fixstrings.h ./symtab.h ./lexdefs.h
Xmain.o: main.c ./fixstrings.h /usr/include/stdio.h
Xemitcf.o: emitcf.c /usr/include/stdio.h ./symtab.h ./fixstrings.h
Xerrors.o: errors.c /usr/include/stdio.h ./fixstrings.h
Xidman.o: idman.c /usr/include/stdio.h ./symtab.h ./fixstrings.h
Xstrops.o: strops.c ./fixstrings.h /usr/include/stdio.h /usr/include/strings.h
Xstrops.o: ./symtab.h
Xsymtab.o: symtab.c ./fixstrings.h /usr/include/stdio.h /usr/include/ctype.h
Xsymtab.o: ./symtab.h
Xfixstrings.o: fixstrings.c /usr/include/strings.h
END_OF_src/Makefile
if test 3877 -ne `wc -c <src/Makefile`; then
    echo shar: \"src/Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f src/errors.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"src/errors.c\"
else
echo shar: Extracting \"src/errors.c\" \(4962 characters\)
sed "s/^X//" >src/errors.c <<'END_OF_src/errors.c'
X#ifdef FLUKE
X# ifndef LINT
X    static char RCSid[] = "@(#)FLUKE  $Header: /isis/usr2/share/src/local/tc/ease/src/RCS/errors.c,v 2.1 90/01/30 14:17:29 jeff Exp $";
X# endif LINT
X#endif FLUKE
X
X/*
X *  	errors.c   -- Contains error initialization and reporting routines.
X *
X *  	author     -- James S. Schoner, Purdue University Computing Center,
X *				        West Lafayette, Indiana  47907
X *
X *  	date       -- July 9, 1985
X *
X *	Copyright (c) 1985 by Purdue Research Foundation
X *
X *	All rights reserved.
X *
X * $Log:	/isis/usr2/share/src/local/tc/ease/src/RCS/errors.c,v $
X * Version 2.1  90/01/30  14:17:29  jeff
X * Bruce Barnett - extensions for SunOS/Ultrix.
X * 
X * Revision 2.0  88/06/15  14:41:10  root
X * Baseline release for net posting. ADR.
X */
X
X#include <stdio.h>
X#include "fixstrings.h"
X#include <ctype.h>
Xextern int  ErrorCount;	 /* error count	               */
Xextern char FNbuf[];	 /* input file name   	       */
Xextern int  Lcount;	 /* line count	     	       */
XFILE *DIAGf = {stderr};  /* file for diagnostic output */
Xextern char yytext[];	/* current token */
Xextern int yyleng;	/* and it's length */
Xextern int	yylineno;	/* current input line number */
Xextern char *infile;		/* input file name */
Xstatic char *source;
X
X/*
X * yywhere() -- input position for yyparse()
X * from Schreiner and Friedman's book on compiler construction
X */
Xvoid
Xyywhere() 	/* position stamp */
X{
X    char	colon = 0;	/* flag */
X    if (source && *source && strcmp(source,"\"\"")) {
X	char	*cp = source;
X	int	len = strlen(source);
X	
X	if (*cp == '"')
X	  ++cp, len -= 2;
X	if (strlen(cp, "./", 2) == 0)
X	  cp += 2, len -= 2;
X	if (len > 0 )
X	  fprintf(DIAGf, "\"%.*s\"", len, cp);
X	colon = 1;
X    } 	else if (infile && strcmp(infile,"-")) {
X	  fprintf(DIAGf, "\"%s\"",infile);
X	  colon = 1;
X      }
X    if (yylineno > 0 ) {
X	if (colon)
X	  fputs(", ",DIAGf);
X	fprintf(DIAGf, "line %d",
X		yylineno - (*yytext == '\n' || ! *yytext));
X	colon = 1;
X/*	if ((yylineno - (*yytext == '\n' || ! *yytext)) != Lcount)
X	  fprintf(DIAGf, "?%d:?", Lcount); */
X    }
X    if (*yytext) {
X	register int i;
X	for (i=0;i<20;++i)
X	  if (!yytext[i] || yytext[i] == '\n')
X	    break;
X	if (i) {
X	    if (colon)
X	      putc(' ',DIAGf);
X	    fprintf(DIAGf, "near \"%.*s\"",i,yytext);
X	    colon = 1;
X	}
X    }
X    if (colon)
X      fputs(": ",DIAGf);
X}
X
X
X/*
X *	yymark - keep track of source file and line number 
X */
X
Xvoid
Xyymark()	/* retreive from '# digit text' */
X{
X    if (source)
X      cfree(source); 
X    source = (char *) calloc(yyleng,sizeof(char));
X    if (source) {
X      sscanf(yytext, "# %d%s",&yylineno, source);
X/*      fprintf(stderr,"source = '%s' on %s",source,yytext); */
X      Lcount = yylineno;
X      if (strcmp(source,"\"\""))
X	strcpy(FNbuf,source);
X      else if ( infile && strcmp(infile,"-"))
X	sprintf(FNbuf,"\"%s\"",infile);
X/*      fprintf(stderr,"FNbuf = '%s', infile = '%s'\n",FNbuf,infile); */
X	       
X  }
X}
X
X
X
X/*
X *	yyerror () -- Prints source file name (FNbuf), line number (Lcount),
X *		      and error message (sbErr) for each invokation.
X *		      it also prints out a message where the error is.
X *
X */
Xvoid
Xyyerror (sbErr)
Xchar *sbErr;
X{
X    extern int yynerrs;
X    ++ErrorCount;
X    yywhere();
X/*    fprintf(DIAGf, " %s\t[error %d]\n", sbErr, ErrorCount); */
X    fprintf(DIAGf, " %s\n", sbErr);
X/* yynerrs is the number of yacc errors, ErrorCount is larger */
X}
X
X
X
X/*
X *	ErrorReport () -- Prints source file name (FNbuf), line number (Lcount),
X *			  and error message (sbErr) for each invokation.
X *
X */
Xvoid
XErrorReport (sbErr)
Xchar *sbErr;
X{
X/*	fprintf (DIAGf, "%s, line %d: %s", FNbuf, Lcount, sbErr);
X	ErrorCount++; */
X    yyerror(sbErr);
X}
X
X
X/*
X *	FatalError () -- Translator fatal error routine which prints 
X *			 error message (sbErr) and an argument (sbArg).
X *
X */
Xvoid
XFatalError (sbErr, sbArg)
Xchar *sbErr,
X     *sbArg;
X{
X	fprintf (DIAGf, "%s, line %d: Fatal Error In Translator: %s %s\n", 
X		 FNbuf, Lcount, sbErr, sbArg); 
X	exit (1);
X}
X
X
X/*
X *	PrintError () -- Prints source file name (FNbuf), line number
X *			 (cline), error message (sbErr), and argument
X *			 (sbArg) for each invokation.
X *
X */
Xvoid
XPrintError (sbErr, sbArg)
Xchar *sbErr;
Xchar *sbArg;
X{
X    char	Ebuffer[1000];
X    sprintf(Ebuffer,sbErr,sbArg);
X    yyerror(Ebuffer);
X/*    fprintf (DIAGf, "%s, line %d: %s %s.\n", FNbuf, Lcount, sbErr, sbArg);
X	ErrorCount++; */
X}
X
X
X/*
X *	PrintWarning () -- Prints a warning message with source file
X *			   name (FNbuf), line number (Lcount), warning
X *			   (sbWarn), and a possible identifier (sbID).
X *
X */
Xvoid
XPrintWarning (sbWarn, sbID)
Xchar *sbWarn;
Xchar *sbID;
X{
X/*	fprintf (DIAGf, "%s, line %d: Warning: ", FNbuf, Lcount); */
X        yywhere();
X	fprintf(DIAGf,"Warning: ");
X	if (sbID != NULL)
X		fprintf (DIAGf, sbWarn, sbID);
X	else
X		fprintf (DIAGf, sbWarn);
X}
X
X
X/*
X *	InitError () -- Initialize line count (Lcount) to one and error count
X *		        (ErrorCount) to zero.
X *
X */
Xvoid
XInitError ()
X{
X	Lcount     = 1;
X	ErrorCount = 0;
X}
END_OF_src/errors.c
if test 4962 -ne `wc -c <src/errors.c`; then
    echo shar: \"src/errors.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f src/idman.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"src/idman.c\"
else
echo shar: Extracting \"src/idman.c\" \(6609 characters\)
sed "s/^X//" >src/idman.c <<'END_OF_src/idman.c'
X#ifdef FLUKE
X# ifndef LINT
X    static char RCSid[] = "@(#)FLUKE  $Header: /tmp_mnt/home/kreskin/u0/barnett/Src/Ease/ease/src/RCS/idman.c,v 3.0 1991/02/22 18:50:27 barnett Exp $";
X# endif LINT
X#endif FLUKE
X
X/*
X *  	idman.c	-- Contains routines for manipulating identifiers and their
X *		   symbolic associations.
X *
X *  	author	-- James S. Schoner, Purdue University Computing Center,
X *				     West Lafayette, Indiana  47907
X *
X *  	date	-- July 9, 1985
X *
X *	Copyright (c) 1985 by Purdue Research Foundation
X *
X *	All rights reserved.
X *
X * $Log: idman.c,v $
X * Revision 3.0  1991/02/22  18:50:27  barnett
X * Added support for HP/UX and IDA sendmail.
X *
X * Revision 2.1  1990/01/30  14:33:52  jeff
X * Bruce Barnett - changed UniqMac.
X *
X * Revision 2.0  88/06/15  14:42:14  root
X * Baseline release for net posting. ADR.
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include "symtab.h"
X#include "fixstrings.h"
X
Xextern struct he *LookupSymbol ();
Xextern void	  FatalError (),
X		  ErrorReport (),
X		  PrintWarning (),
X		  PrintError ();
X
X
Xchar	IDused[] = "                          "; /* 26 blanks */
X/*
X *	UniqMac () -- Assigns and returns a unique one-character macro
X *		      name (upper-case) for an Ease macro name.
X *
X *	Bruce Barnett:
X *	Special enhancement - if idval is a single character,
X *	and the corresponding letter has not been assigned,
X *	Make the idc character the same as the macro name 
X *
X *	This makes it nice to test cfc/ease completeness.
X *	Also makes reading the ease output easier.
X *
X */
Xchar
XUniqMac (phe)
Xstruct he *phe;		/* symbol table entry for Ease macro */
X{
X    short i;
X
X    if ((strlen(phe->psb) == 1) && 
X	isupper(*(phe->psb)) &&
X	IDused[*(phe->psb) - 'A'] == ' ' ) {
X	IDused[*(phe->psb) - 'A'] = (phe->idval.idc) = *(phe->psb);
X    } else {
X	for (i=0;i<26 && IDused[i] != ' ';i++) 
X	  ;	/* find first unused letter */
X	if (i==26) FatalError ("Too many macro names (26 max)", (char *) NULL);
X	IDused[i] = 
X	  (phe->idval.idc) = 
X	    'A' + i;
X    }
X    return (phe->idval.idc);
X}
X
X
X/*
X *	BindID () -- Binds either a ruleset or precedence identifier (phe) to
X * 		     an integer (vid).  The id type distinction is passed in
X *		     the parameter idt.
X *
X */
Xvoid
XBindID (phe, vid, idt)
Xregister struct he *phe;	/* symbol table entry for an identifier    */
Xint vid;			/* value of the identifier		   */
Xunsigned idt;			/* identifier type (ruleset or precedence) */
X{
X	if (ISTYPED(phe->idtype)) {	/* should be undefined */
X		PrintWarning ("Redeclaration of %s.\n", phe->psb);
X		phe->idtype = ID_UNTYPED;
X	}
X	phe->idtype |= idt;		/* make defined	       */
X	if (ISRULESET(phe->idtype)) {
X		if (vid > VALRSNMAX) {
X			ErrorReport ("Ruleset number too large.\n");
X			return;
X		} else if (vid < 0) {
X			ErrorReport ("Ruleset number must be non-negative.\n");
X			return;
X		}
X		sprintf (phe->idval.rsn, "%d", vid);
X	} else 
X		phe->idval.prec = vid;
X}
X
X
X/*
X *	CheckRS () -- Checks validity of a ruleset identifier (phe) and 
X *		      returns the ruleset string to which the identifier
X *		      is bound.  If the ruleset identifier is invalid, the
X *		      null string is returned.
X *
X */
Xchar *
XCheckRS (phe)
Xstruct he *phe;		/* symbol table entry for ruleset identifier */
X{
X	if (!ISRULESET(phe->idtype)) {
X		if (!ISTYPED(phe->idtype))
X			PrintError ("Ruleset identifier not bound to a number: %s", phe->psb);
X		else
X			PrintError ("Identifier not of ruleset type: %s", phe->psb);
X		return (NULL);
X	} else
X		return (phe->idval.rsn);
X}
X
X
X/*
X *	MakeMac () -- Declare a macro name (pmac) as a class and/or macro type 
X *		      (targtype) and return the unique cf character assigned 
X *		      to it.
X *
X */
Xchar
XMakeMac (pmac, targtype)
Xregister struct he *pmac;	/* symbol table entry for macro identifier */
Xunsigned targtype;		/* target declaration type for the macro   */
X{
X	/*
X	 *	An Ease macro may be declared as both a singular macro and
X	 *	a class macro.
X	 *
X	 */
X	if (ISMACRO(pmac->idtype) || ISCLASS(pmac->idtype)) {
X		pmac->idtype |= targtype;
X		return (pmac->idval.idc);
X	}
X	if (ISTYPED(pmac->idtype)) {	/* not a macro or class id */
X		PrintError ("Redeclaring or using as macro or class: %s", pmac->psb);
X		return ('\0');
X	}
X	pmac->idtype |= targtype;	/* previously untyped; declare here */
X	return (UniqMac (pmac));
X}
X	
X
X/*
X *	GetField () -- Returns a field type string given a field 
X *		       identifier (fid).
X *
X */
Xchar *
XGetField (fid)
Xregister struct he *fid;	/* field identifier */
X{
X	if (!ISFIELD(fid->idtype)) {
X		PrintError ("Field type not defined for %s", fid->psb);
X		return (NULL);
X	} else 
X		return (fid->idval.fstring);
X}
X
X
X/*
X *	CheckMailer () -- Declares a mailer identifier (mid) as type mailer,
X *			  checking that the identifier was not previously 
X *			  declared a different type. 
X *
X */
Xchar *
XCheckMailer (mid)
Xregister struct he *mid;
X{
X	if (ISTYPED (mid->idtype) && !ISMAILER (mid->idtype)) {
X		PrintError ("Redeclaration as mailer: %s", mid->psb);
X		return (NULL);
X	}
X	mid->idtype |= ID_MAILER;
X	return (mid->psb);
X}
X
X
X/*
X *	AssignType () -- Assigns to each field identifier in fidlist the
X *			 type (in string form) fidtype.  This is accomplished
X *			 by making each field identifier symbol table entry
X *			 "point" to the type found in fidtype.
X *
X */
Xvoid
XAssignType (fidlist, fidtype)
Xregister char *fidlist;		/* field identifier list, blank separated */
Xchar *fidtype;			/* field identifier type string		  */
X{
X	register struct he *fid;	/* pointer to a field identifier  */
X	char *fres;			/* field type result string	  */
X	register char *srch;		/* fidlist search pointer	  */
X	char  sep;			/* fidlist separator character    */
X
X	fres = (char *) malloc (strlen (fidtype) + 1);
X	if (fres == NULL)
X		FatalError ("System out of string space in AssignType ()", (char *) NULL);
X	strcpy (fres, fidtype);		/* make clean copy of string type */
X
X	/*
X	 *	Search for all field identifiers and make the type assignment. 
X 	 *
X	 */
X	srch = fidlist;
X	while (*srch != '\0') {
X		while ((*++srch != ' ') && (*srch != '\0'))
X			/* null */ ;
X		if (*fidlist != '\0') {		        /* found a field id       */
X			sep = *srch;
X			*srch = '\0';
X			fid = LookupSymbol (fidlist);	/* get symbol table entry */
X			if (ISFIELD(fid->idtype)) {
X				if (strcmp (fid->idval.fstring, fres))
X					PrintWarning ("Redefinition of field type for %s.\n", fid->psb);
X			} else if (ISTYPED(fid->idtype)) {
X				PrintError ("Redeclaration of identifier as a field: %s", fid->psb);
X				return;
X			}
X			fid->idtype |= ID_FIELD;	/* type the identifier    */
X			fid->idval.fstring = fres;	/* type the field	  */
X			if ((*srch = sep) != '\0')
X				fidlist = ++srch;
X		}
X	}
X}
END_OF_src/idman.c
if test 6609 -ne `wc -c <src/idman.c`; then
    echo shar: \"src/idman.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f src/lexan.patch -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"src/lexan.patch\"
else
echo shar: Extracting \"src/lexan.patch\" \(5320 characters\)
sed "s/^X//" >src/lexan.patch <<'END_OF_src/lexan.patch'
X*** /home/kreskin/u0/barnett/Src/ease/src/lexan.l	Wed Mar  1 15:43:53 1989
X--- lexan.l	Mon May  7 14:12:53 1990
X***************
X*** 59,78 ****
X  	static char linbuf[BUFSIZ], *pc = linbuf;
X  	char c;
X  
X- 
X- 
X- 
X- 
X  	/* initialize buffer: first call only */
X  	if (*pc == '\0' && pc == linbuf) {
X  		if (fgets(linbuf, BUFSIZ, yyin)==NULL)
X  			return EOF;
X!                 if (linbuf[0] == '#' )
X!                     fprintf(yyout, "%s", linbuf);  /* echo input as comment */
X!                 else
X!                     fprintf(yyout, "# %s", linbuf);  /* echo input as comment */
X! 
X  	}
X  	c = *pc++;
X  	if (c == '\n') {
X  		pc = linbuf;
X--- 68,82 ----
X  	static char linbuf[BUFSIZ], *pc = linbuf;
X  	char c;
X  
X  	/* initialize buffer: first call only */
X  	if (*pc == '\0' && pc == linbuf) {
X  		if (fgets(linbuf, BUFSIZ, yyin)==NULL)
X  			return EOF;
X! 		/* echo input as comment */
X! 		if (EchoInputAsComments) {
X! 		    fprintf(yyout, "%s%s", (linbuf[0] == '#' ? "" : "# "), linbuf);
X  		}
X+ 	}
X  	c = *pc++;
X  	if (c == '\n') {
X  		pc = linbuf;
X***************
X*** 79,90 ****
X  		if (fgets(linbuf, BUFSIZ, yyin) == NULL)
X  			*pc = EOF;
X  		else
X! 			/* echo input as comment except cpp comments */
X!                     if (linbuf[0] == '#' )
X!                         fprintf(yyout, "%s", linbuf);  /* echo input as comment */
X!                     else
X!                         fprintf(yyout, "# %s", linbuf);  /* echo input as comment */
X  	}
X  	return c;
X  }
X  
X--- 83,94 ----
X  		if (fgets(linbuf, BUFSIZ, yyin) == NULL)
X  			*pc = EOF;
X  		else
X! 			/* echo input as comment (except cpp comments) */
X! 			if (EchoInputAsComments) {
X! 			    fprintf(yyout, "%s%s",
X! 				(linbuf[0] == '#' ? "" : "# "), linbuf);
X  			}
X+ 	}
X  	return c;
X  }
X  
X***************
X*** 103,109 ****
X  	{ "Path",		MPATH },
X  	{ "Recipient",		MRECIPIENT },
X  	{ "Sender",		MSENDER },
X- 	{ "asm",		ASM },
X  	{ "bind",		BIND },
X  	{ "canon",		CANON },
X  	{ "class",		CLASS },
X--- 107,112 ----
X***************
X*** 112,121 ****
X  	{ "d_interactive",	DOPTI },
X  	{ "d_queue",		DOPTQ },
X  	{ "define",		DEFINE },
X- 	{ "eval",		EVAL },
X  	{ "f_addrw",		CCFLAG },
X  	{ "f_arpa",		AAFLAG },
X- 	{ "f_bsmtp",		BBFLAG },	/* IDA */
X  	{ "f_date",		DDFLAG },
X  	{ "f_dot",		XXFLAG },
X  	{ "f_escape",		EEFLAG },
X--- 115,122 ----
X***************
X*** 125,136 ****
X  	{ "f_full",		XFLAG },
X  	{ "f_llimit",		LLFLAG },
X  	{ "f_locm",		LFLAG },
X- 	{ "f_mail11",		HHFLAG },
X  	{ "f_mesg",		MMFLAG },
X  	{ "f_mult",		MFLAG },
X  	{ "f_noreset",		SSFLAG },
X  	{ "f_noufrom",		NFLAG },
X- 	{ "f_relativize",	VVFLAG },
X  	{ "f_retsmtp",		PFLAG },
X  	{ "f_return",		PPFLAG },
X  	{ "f_rfrom",		RFLAG },
X--- 126,135 ----
X***************
X*** 159,171 ****
X  	{ "match",		MATCH },
X  	{ "next",		NEXT },
X  	{ "o_alias",		AAOPT },
X- 	{ "o_aliasfile",	YYOPT },
X  	{ "o_bsub",		BBOPT },
X  	{ "o_checkpoint",	CCOPT },
X  	{ "o_delivery",		DOPT },
X  	{ "o_dmuid",		UOPT },
X  	{ "o_dnet",		NNOPT },
X- 	{ "o_envelope",		SLOPT },
X  	{ "o_ewait",		AOPT },
X  	{ "o_flog",		SSOPT },
X  	{ "o_fsmtp",		HHOPT },
X--- 158,168 ----
X***************
X*** 174,183 ****
X  	{ "o_hformat",		OOPT },
X  	{ "o_loadnc",		XXOPT },
X  	{ "o_loadq",		XOPT },
X- 	{ "o_maxempty",		BOPT },
X- 	{ "o_maxhops",		HOPT },
X  	{ "o_newproc",		YYOPT },
X- 	{ "o_nfs",		RROPT },	/* SunOS 4.0 */
X  	{ "o_pmaster",		PPOPT },
X  	{ "o_prifactor",	ZOPT },
X  	{ "o_qdir",		QQOPT },
X--- 171,177 ----
X***************
X*** 200,209 ****
X  	{ "o_wizpass",		WWOPT },
X  	{ "options",		OPTIONS },
X  	{ "precedence",		PRECEDENCE },
X- 	{ "quote",		QUOTE },
X  	{ "readclass",		READCLASS },
X  	{ "resolve",		RESOLVE },
X- 	{ "resolved",		RESOLVED },
X  	{ "retry",		RETRY },
X  	{ "return",		RETURN },
X  	{ "ruleset",		RULESET },
X--- 194,201 ----
X***************
X*** 210,218 ****
X  	{ "trusted",		TRUSTED },
X  	{ "user",		USER },
X  	{ "while",		IF },
X- 	{ "ypalias",		YPALIAS },
X- 	{ "ypmap",		YPMAP },
X- 	{ "yppasswd",		YPPASSWD },
X  };
X  %}
X  
X--- 202,207 ----
X***************
X*** 221,231 ****
X  
X  [ \t\f]+			; 	/* discard whitepsace  */
X  [\n]				Lcount++;
X! ^\#[ \t]*[0-9]+[ \t]*\".*\"[ \t]*.*[\n]	{
X! /*			        sscanf (yytext, "%*c%d%s", &Lcount, FNbuf); */
X! 	                        yymark();
X  			        }
X! [A-Za-z_][A-Za-z0-9_-]*		{
X  				register int l, h, m, r, c;
X  
X  				l = 0;
X--- 210,219 ----
X  
X  [ \t\f]+			; 	/* discard whitepsace  */
X  [\n]				Lcount++;
X! ^\#[ \t]*[0-9]+[ \t]*\".*\"[ \t]*[\n]	{
X! 			        sscanf (yytext, "%*c%d%s", &Lcount, FNbuf);
X  			        }
X! [A-Za-z][A-Za-z0-9_-]*		{
X  				register int l, h, m, r, c;
X  
X  				l = 0;
X***************
X*** 292,305 ****
X  						INch = input ();
X  				}
X  				}
X- "/"				return (SLASH);
X  [\\]?.				{
X  				if (RMatch) {	/* in rulesets, return literal character */
X  					yylval.ival = (yytext[0] == '\\') ? yytext[1] : yytext[0];
X  					return (SEPCHAR);
X- 
X  				} else {
X! 					PrintError ("Illegal delimiter character: (octal code) \\%03o", *yytext);
X  				}
X  				}
X  %%
X--- 280,292 ----
X  						INch = input ();
X  				}
X  				}
X  [\\]?.				{
X  				if (RMatch) {	/* in rulesets, return literal character */
X  					yylval.ival = (yytext[0] == '\\') ? yytext[1] : yytext[0];
X  					return (SEPCHAR);
X  				} else {
X! 					ErrorReport ("Illegal delimiter character");
X! 					printf (": (octal code) \\%03o\n", *yytext);
X  				}
X  				}
X  %%
END_OF_src/lexan.patch
if test 5320 -ne `wc -c <src/lexan.patch`; then
    echo shar: \"src/lexan.patch\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f src/main.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"src/main.c\"
else
echo shar: Extracting \"src/main.c\" \(7308 characters\)
sed "s/^X//" >src/main.c <<'END_OF_src/main.c'
X#ifdef FLUKE
X# ifndef LINT
X    static char RCSid[] = "@(#)FLUKE  $Header: /isis/usr2/share/src/local/tc/ease/src/RCS/main.c,v 2.2 90/05/07 11:14:02 jeff Exp $";
X# endif LINT
X#endif FLUKE
X
X/*
X *  	main.c     -- Main procedure for Ease Translator.
X *
X *  	author     -- James S. Schoner, Purdue University Computing Center
X *				        West Lafayette, Indiana  47907
X *
X *  	date       -- July 9, 1985
X *
X *	Copyright (c) 1985 by Purdue Research Foundation
X *
X *	All rights reserved.
X *
X * $Log:	/isis/usr2/share/src/local/tc/ease/src/RCS/main.c,v $
X * Version 2.2  90/05/07  11:14:02  jeff
X * Add support for the "-q" flag which controls whether input lines
X * are passed through as comments in the output stream.
X * 
X * Version 2.1  90/01/30  15:37:16  jeff
X * Filter input file through cpp before processing it.
X * 
X * Revision 2.0  88/06/15  14:42:41  root
X * Baseline release for net posting. ADR.
X * 
X */
X
X
X#ifndef CPP	/* filename of preprocessor */
X#	define CPP	"/lib/cpp"
X#endif	CPP
X
X#ifndef CPPARGS		/* valid arguments  of preprocessor */
X#ifdef sun		/* Sun's cpp has more options - I guess */
X#	define CPPARGS	"BCHpPRTDIUY"
X#else
X#	define CPPARGS	"CDEIPU"
X#endif sun
X#endif	CPP
X
X#include "fixstrings.h"
X#include <stdio.h>
X#include <ctype.h>
X
Xextern FILE *DIAGf;			/* diagnostic file */
Xchar *infile = 0;			/* input file name */
Xchar *outfile = 0;			/* output file name */
Xextern void InitError (), 
X	    InitSymbolTable (),
X	    DefScan (),
X	    FatalError (),
X            PreLoad ();
X
Xint EchoInputAsComments = 1;		/* should input lines be echoed
X					 * as comments?
X					 */
Xint ErrorCount;				/* translation error count */
Xvoid GetArgs ();			/* gets arguments to "et"  */
X
X#ifdef YYDEBUG
Xextern int yydebug;
X#else
Xstatic int yydebug;
X#endif
X
X/*
X *	main () -- Main procedure for the Ease Translator et.  If no files are 
X *	       	   given as arguments to et, stdin is translated and written to 
X *	           stdout.  If one file is given, it is translated and written 
X *	           to stdout.  If two files are given, the first is translated
X *	           and written to the second.  If the first filename is "-",
X *	           standard input is assumed.  A translation is performed on 
X *	           valid Ease input only, producing a regular sendmail 
X *		   configuration file. 
X *
X */
Xvoid
Xmain (argc, argv)
Xint argc;		/* argument count for "et"  */
Xchar *argv[];		/* argument vector for "et" */
X{
X	InitError ();			/* initialize error conditions */
X	InitSymbolTable ();		/* initialize the symbol table */
X	PreLoad ();			/* preload special identifiers */
X	GetArgs (argc, argv);		/* set up argument files       */
X	(void) yyparse ();		/* perform translation	       */
X	if (fflush (stdout) == EOF)
X		FatalError ("Cannot flush output stream/file", (char *) NULL);
X	DefScan ();		        /* warn about undefined idents */
X	if (ErrorCount)
X		fprintf (DIAGf, "\n\n*** %d error(s) detected.\n", ErrorCount);
X	exit (ErrorCount);
X}
X
X
X/*
X *	GetArgs () -- Processes arguments to the Ease translator "et".  The
X *		      arguments are files (margv) which may replace either/both
X *		      of the files standard input and standard output.  The 
X *		      following cases are possible:
X *			
X *		      -- et f.e f.cf
X *				Translate Ease file f.e and write result
X *				to f.cf.
X *
X *		      -- et f.e
X *				Translate Ease file f.e and write result to
X *				standard output.
X *
X *		      -- et - f.cf
X *				Translate standard input and write result to
X *				f.cf.
X *
X *		      -- et
X *				Translate standard input and write result to
X *				standard output.
X *
X *		      et also accepts arguments. These include the /lib/cpp arguments
X *		      and the -d argument for debugging grammars.
X *
X *		      Finally, a message indicating the volatility of the 
X *		      Ease output is written.
X *
X */
Xvoid
XGetArgs (margc, margv)
Xregister int   margc;		/* argument count  */
Xregister char **margv;		/* argument vector */
X{
X     register char  **argp;
X     int	cppflags = 0;
X     int	otherflags = 0;
X     int arg;
X 
X     for (arg = 1; arg < margc; ++arg) {		/* scan arguments */
X 	if (margv[arg][0] == '-') {		/* a flag?*/
X 	    if (isalpha(margv[arg][1])) {	/* yes - a flag */
X 		if (index(CPPARGS,margv[arg][1])) ++cppflags;	/* one belonging to the CPP */
X 		else if (margv[arg][1] == 'd' ) yydebug = 1;
X 		else if (margv[arg][1] == 'q' ) EchoInputAsComments = 0;
X 		else ++otherflags;
X 	    } else if (! margv[arg][1]) { 	/* this argument is just a '-' */
X 		if ( (arg - yydebug - cppflags - otherflags) == 1 )
X 		  infile = margv[arg];	
X 		else if ( (arg - yydebug - cppflags - otherflags) == 2 )
X 		  outfile = margv[arg];
X 		else
X 		  FatalError ("Usage: et [-%s] [infile [outfile]]", CPPARGS);
X 	    } else {
X 		FatalError ("Usage: et [-%s] [infile [outfile]]", CPPARGS);
X 	    } /* end if a -argument */
X 	} else {	/* a filename - i guess */
X 	    if ( (arg - yydebug - cppflags - otherflags) == 1 )
X 	      infile = margv[arg];	
X 	    else if ( (arg - yydebug - cppflags - otherflags) == 2 )
X 	      outfile = margv[arg];
X 	    else
X 	      FatalError ("Usage: et [-d] [-q] [-%s] [infile [outfile]]", CPPARGS);
X 	} /* end if a filename argument */
X     }	/* done with parsing all of the arguments */
X     if (otherflags)
X       FatalError ("Usage: et [-%s] [infile [outfile]]", CPPARGS);
X     if (infile && strcmp(infile,"-") )
X       if (freopen (infile, "r", stdin) == NULL)
X 	FatalError ("Cannot open input stream/file:", infile);
X     if (outfile && strcmp(outfile,"-") )
X       if (freopen (outfile, "w", stdout) == NULL)
X 	FatalError ("Cannot open output stream/file:", outfile);
X     if (cppflags && cpp(margc,margv))
X 	FatalError ("Cannot open preprocessor", CPP);
X 
X	printf ("###################################################\n");
X	printf ("##                                               ##\n");
X	printf ("##  WARNING: THIS FILE IS THE OUTPUT OF THE      ##\n");
X	printf ("##           `EASE' PRECOMPILER FOR SENDMAIL     ##\n");
X	printf ("##           CONFIGURATION FILES.                ##\n");
X	printf ("##                                               ##\n");
X	printf ("##           MAKE MODIFICATIONS TO THE SOURCE    ##\n");
X	printf ("##           FILE ONLY.  CHANGES MADE DIRECTLY   ##\n");
X	printf ("##           TO THIS FILE WILL DISAPPEAR THE     ##\n");
X	printf ("##           NEXT TIME THAT EASE IS RUN.         ##\n");
X	printf ("##                                               ##\n");
X	printf ("###################################################\n");
X}
X
X/* cpp preprocessor code
X * copied from Schreiner and Friedman's book:
X * Introduction to Compiler Construction with Unix
X *
X * Bruce Barnett
X */
X
Xint cpp(argc,argv)
X     int argc;
X     char **argv;
X{
X    char **argp, *cmd;
X    extern FILE *yyin;	/* for lex input */
X    extern FILE *popen();
X    int i;
X
X    for (i = 0, argp = argv; *++argp; )
X      if (**argp == '-' &&
X	  index(CPPARGS, (*argp)[1]))
X	i+=strlen(*argp) + 1;
X    if ( ! (cmd = (char *) calloc(i + sizeof CPP, sizeof(char))))
X      return -1;	/* no room */
X    (void *) strcpy(cmd,CPP);
X    for (argp = argv; *++argp; )
X      if (**argp == '-' &&
X	  index(CPPARGS, (*argp)[1]))
X	strcat(cmd, " "), strcat(cmd, *argp);
X    if (yyin = popen(cmd,"r"))
X      i = 0;	/* all's well */
X    else
X      i = -1;	/* no preprocessor */
X    cfree(cmd);
X    return i;
X}
END_OF_src/main.c
if test 7308 -ne `wc -c <src/main.c`; then
    echo shar: \"src/main.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f src/symtab.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"src/symtab.c\"
else
echo shar: Extracting \"src/symtab.c\" \(6485 characters\)
sed "s/^X//" >src/symtab.c <<'END_OF_src/symtab.c'
X#ifdef FLUKE
X# ifndef LINT
X    static char RCSid[] = "@(#)FLUKE  $Header: /tmp_mnt/home/kreskin/u0/barnett/Src/Ease/ease/src/RCS/symtab.c,v 3.0 1991/02/22 18:50:27 barnett Exp $";
X# endif LINT
X#endif FLUKE
X
X/*
X *  	symtab.c   -- Contains Ease Translator symbol table routines.
X *
X *  	author     -- James S. Schoner, Purdue University Computing Center,
X *				        West Lafayette, Indiana  47907
X *
X *  	date       -- July 9, 1985
X *
X *	Copyright (c) 1985 by Purdue Research Foundation
X *
X *	All rights reserved.
X *
X * $Log: symtab.c,v $
X * Revision 3.0  1991/02/22  18:50:27  barnett
X * Added support for HP/UX and IDA sendmail.
X *
X * Revision 2.1  1990/01/30  15:55:54  jeff
X * SunOS/Ultrix/Ida additions Jan 25 1988 Bruce Barnett
X *
X * Revision 2.0  88/06/15  14:43:04  root
X * Baseline release for net posting. ADR.
X */
X
X#include "fixstrings.h"
X#include <stdio.h>
X#include <ctype.h>
X#include "symtab.h"
X
X#define ERRORMAILER "error"		/* predefined error mailer name */
X
Xextern void FatalError (),
X	    PrintWarning ();
X
Xstruct he *LookupSymbol ();
X
Xstruct Defmac {				/* predefined macro struct def  */
X	char *macname;
X	char  macrep;
X};
X
Xstatic struct he *SymTab[SST];		/* hash table base array        */
Xstatic struct Defmac MacDefs[] = {	/* predefined macros	        */
X			{"m_smtp",	'e'},
X			{"m_oname",	'j'},
X			{"m_uucpname",	'k'}, /* IDA */
X			{"m_ufrom",	'l'},
X			{"m_daemon",	'n'},
X			{"m_domain",	'm'},	/* SunOS */
X			{"m_addrops",	'o'},
X			{"m_defaddr",	'q'},
X			{"m_sitename",	'w'},
X			{"m_odate",	'a'},
X			{"m_adate",	'b'},
X			{"m_hops",	'c'},
X			{"m_udate",	'd'},
X			{"m_saddr",	'f'},
X			{"m_sreladdr",	'g'},
X			{"m_rhost",	'h'},
X			{"m_qid",	'i'},
X			{"m_pid",	'p'},
X			{"m_protocol",	'r'},
X			{"m_shostname", 's'},
X			{"m_ctime",	't'},
X			{"m_ruser",	'u'},
X			{"m_version",	'v'},
X			{"m_sname",	'x'},
X			{"m_stty",	'y'},
X			{"m_rhdir",	'z'},
X			{"sentinel",	'\0'}
X};
X
X/* FLUKE jps 28-apr-86 - Install some wired-in class names */
Xstatic struct Defmac ClassDefs[] = {	/* predefined classes */
X			{"c_myname",	'w'},
X			{"c_mydomain",	'm'},
X			{"class_sentinel",	'\0'}
X};
X
X/*
X *	DefScan () -- Scan symbol table to find macros, classes, mailers, 
X *		      and rulesets which have been referenced or declared, but
X *		      not defined.  A warning is printed for each such 
X *		      occurence.  This routine is usually called at the end
X *		      of a successful Ease translation.
X *
X */
Xvoid
XDefScan ()
X{
X	register int stindex;		/* symbol table hash index   */
X	register struct he *hcsearch;	/* hash chain search pointer */
X
X	for (stindex = 0; stindex < SST; stindex++) {
X		if ((hcsearch = SymTab[stindex]) != NULL)
X			while (hcsearch != NULL) {
X				if ((ISMACRO(hcsearch->idtype) && 
X				     isupper(hcsearch->idval.idc)) &&
X				     !ISMACRO(hcsearch->idd))
X					PrintWarning ("Macro not defined: %s\n", hcsearch->psb);
X#ifdef notdef
X				if (ISCLASS(hcsearch->idtype) && !ISCLASS(hcsearch->idd))
X#else
X				/* FLUKE jps 28-apr-86 */
X				/* print warnings for UPPER CASE names only */
X				if (ISCLASS(hcsearch->idtype) &&
X				    isupper(hcsearch->idval.idc) &&
X				    !ISCLASS(hcsearch->idd))
X#endif
X					PrintWarning ("Class not defined: %s\n", hcsearch->psb);
X				if (ISMAILER(hcsearch->idtype) && !ISMAILER(hcsearch->idd))
X					PrintWarning ("Mailer not defined: %s\n", hcsearch->psb);
X				if (ISRULESET(hcsearch->idtype) && !ISRULESET(hcsearch->idd))
X					PrintWarning ("Ruleset not defined: %s\n", hcsearch->psb);
X				hcsearch = hcsearch->phe;
X			}
X	}
X}
X				     
X
X/*
X *	InitSymbolTable () -- Invoked by main () to initialize the symbol table.
X *
X */
Xvoid
XInitSymbolTable ()
X{
X	int i;
X
X	for (i = 0; i < SST; i++)		/* initialize base array */
X		SymTab[i] = NULL;
X}
X
X
X/*
X *	PreLoad () -- Invoked by main () to preload special macro names 
X *		      and mailer declarations.
X *
X */
Xvoid
XPreLoad ()
X{
X	struct Defmac *macptr;
X	struct he     *symptr;
X
X	/* preload special (lower-case) macros */
X	for (macptr = &MacDefs[0]; (*macptr).macrep != '\0'; macptr++) {
X		symptr = LookupSymbol ((*macptr).macname);
X		symptr->idtype |= ID_MACRO;
X		symptr->idval.idc = (*macptr).macrep;
X	}
X
X	/* preload special (lower-case) classes */
X	for (macptr = &ClassDefs[0]; (*macptr).macrep != '\0'; macptr++) {
X		symptr = LookupSymbol ((*macptr).macname);
X		symptr->idtype |= ID_CLASS;
X		symptr->idval.idc = (*macptr).macrep;
X	}
X
X	/* preload error mailer declaration */
X	symptr = LookupSymbol (ERRORMAILER);
X	symptr->idtype |= ID_MAILER;
X	symptr->idd |= ID_MAILER;
X}
X	
X
X/*
X *	LookupSymbol () -- Returns a pointer to the hash entry already 
X *			   existing, or newly created, which corresponds 
X *			   to string sb.
X *
X */
Xstruct he *
XLookupSymbol (sb)
Xchar sb[];			/* string buffer containing identifier */
X{
X	struct he *phe;		/* hash entry search pointer  */
X	int	  hc;		/* hash code of sb identifier */
X	extern char *malloc ();
X
X	phe = SymTab[hc = HashCode (sb)];
X	while (phe != NULL)			/* find hash entry for sb */
X		if (!strcmp (phe->psb, sb))
X			return (phe);
X		else
X			phe = phe->phe;
X	/* make new symbol table entry */
X	if ((phe = (struct he *) malloc (sizeof (struct he))) == NULL)
X		FatalError ("System out of space in LookupSymbol ()", (char *) NULL);
X	if ((phe->psb = (char *) malloc (strlen (sb) + 1)) == NULL)
X		FatalError ("System out of space in LookupSymbol ()", (char *) NULL);
X	strcpy (phe->psb, sb);
X	phe->idval.idc = '\0';
X	phe->idtype = ID_UNTYPED;
X	phe->idd = ID_UNTYPED;
X	phe->phe = SymTab[hc];
X	return (SymTab[hc] = phe);
X}
X
X
X/*
X *	RemoveSymbol () -- Removes the symbol table entry phe from the 
X *			   symbol table.
X *
X */
Xvoid
XRemoveSymbol (phe)
Xstruct he *phe;	   /* pointer to hash entry to be removed from symbol table */
X{
X	int hc;	   		/* hash code of entry phe       */
X	struct he *sphe;	/* search pointer for entry phe */
X
X	if (phe == NULL)
X		return;
X	else {			/* search and remove entry phe  */
X		sphe = SymTab[hc = HashCode (phe->psb)];
X		free (phe->psb);
X		if (sphe == phe)
X			SymTab[hc] = phe->phe;
X		else
X			while (sphe != NULL)
X				if (sphe->phe == phe) {
X					sphe->phe = phe->phe;
X					return;
X				} else
X					sphe = sphe->phe;
X	}
X}
X
X
X/*
X *	HashCode () -- Returns the hash code of the string in sb by adding 
X *		       the character values and applying mod by the hash 
X *		       table size.
X *
X */
Xint
XHashCode (sb)
Xchar sb[];
X{
X	int ccSum = 0;			/* sum of char values in string sb */
X	int i;
X
X	for (i = 0; sb[i]; i++)		/* add char codes for sb chars     */
X		ccSum += sb[i];
X	return (ccSum % SST);		/* return sum mod table size	   */
X}
END_OF_src/symtab.c
if test 6485 -ne `wc -c <src/symtab.c`; then
    echo shar: \"src/symtab.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f test/test.mc -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"test/test.mc\"
else
echo shar: Extracting \"test/test.mc\" \(4506 characters\)
sed "s/^X//" >test/test.mc <<'END_OF_test/test.mc'
X/*
X * Sendmail configuration file for test rulesets
X *
X * Simon Kenyon November 20th, 1986
X */
X
Xbind
X	EnvelopeTo 		= ruleset  0;
X	From			= ruleset  1;
X	HeaderTo		= ruleset  2;
X	Canonicalize		= ruleset  3;
X	Externalize		= ruleset  4;
X
X	LocalHeaderFrom		= ruleset 10;
X	UucpHeaderFrom		= ruleset 11;
X
X	LocalHeaderTo		= ruleset 20;
X	UucpHeaderTo		= ruleset 21;
X
Xmacro
X	Domain		= "my_domain";
X	Version		= "ruleset tester V1.0";
X
X	m_sitename	= "whatever";
X	m_oname		= "${m_sitename}.${Domain}";
X	m_daemon	= "MAILER-DAEMON";
X	/*m_ufrom		= "From ${m_sreladdr}  ${m_udate} remote from ${m_sitename}";*/
X	m_ufrom		= "From ${m_sreladdr}  ${m_udate}";
X	m_addrops	= ".:%@!^=/[]{}";
X	m_defaddr	= concat (
X				ifset (m_sname, "${m_sname}	<${m_sreladdr}>",
X						"${m_sreladdr}"),
X				""
X			  );
X	m_smtp		= "${m_oname} Sendmail ${m_version}/${Version} ready at ${m_adate}";
X
Xoptions
X	o_alias		= "/usr/lib/aliases";
X	o_delivery	= d_background;
X	o_dmuid		= "1";
X	o_flog		= "/usr/lib/sendmail.st";
X	o_fsmtp		= "/usr/lib/sendmail.hf";
X	o_gid		= "1";
X	o_hformat	= "";
X	o_qdir		= "/usr/spool/mqueue";
X	o_qtimeout	= "3d";
X	o_safe		= "";
X	o_slog		= "9";
X	o_timezone	= "WET";
X	o_tmode		= "0644";
X	o_tread		= "r2h";
X	o_wizpass	= "*";
X
Xprecedence
X	first-class		=    0;
X	special-delivery	=  100;
X	junk			= -100;
X
Xtrusted
X	{root, daemon, uucp, network};
X	{simon};
X
Xheader
X	define ("a:", "The origination date in Arpanet format = ${m_odate}");
X	define ("b:", "The current date in Arpanet format = ${m_adate}");
X	define ("c:", "The hop count = ${m_hops}");
X	define ("d:", "The date in UNIX (ctime) format = ${m_udate}");
X	define ("e:", "The SMTP entry message = ${m_smtp}");
X	define ("f:", "The sender (from) address = ${m_saddr}");
X	define ("g:", "The sender address relative to the recipient = ${m_sreladdr}");
X	define ("h:", "The recipient host = ${m_rhost}");
X	define ("i:", "The queue id = ${m_qid}");
X	define ("j:", "The official domain name for this site = ${m_oname}");
X	define ("l:", "The format of the UNIX from line = ${m_ufrom}");
X	define ("n:", "The name of the daemon (for error messages) = ${m_daemon}");
X	define ("o:", "The set of operators in addresses = ${m_addrops}");
X	define ("p:", "Sendmail's pid = ${m_pid}");
X	define ("q:", "The default format of sender address = ${m_defaddr}");
X	define ("r:", "Protocol used = ${m_protocol}");
X	define ("s:", "Sender's host name = ${m_shostname}");
X	define ("t:", "A numeric representation of the current time = ${m_ctime}");
X	define ("u:", "The recipient user = ${m_ruser}");
X	define ("v:", "The version number of sendmail = ${m_version}");
X	define ("w:", "The hostname of this site = ${m_sitename}");
X	define ("x:", "The full name of the sender = ${m_sname}");
X	define ("y:", "The id of the sender's tty = ${m_stty}");
X	define ("z:", "The home directory of the recipient = ${m_rhdir}");
X
Xfield
X	path		: match (1*);
X
Xruleset Canonicalize {
X	if (path)
X		next ("{3}" $1);
X}
X
Xruleset EnvelopeTo {
X	if (path @ path)
X		resolve (mailer (uucp),
X			 host ("{0_uucp}" $2),
X			 user ("{0_uucp}" $1));
X	if (path ! path)
X		resolve (mailer (uucp),
X			 host ("{0_uucp}" $1),
X			 user ("{0_uucp}" $2));
X	if (path)
X		resolve (mailer (local),
X			 user ("{0_local}" $1));
X}
X
Xruleset From {
X	if (path)
X		return ("{1}" $1);
X}
X
Xruleset HeaderTo {
X	if (path)
X		return ("{2}" $1);
X}
X
Xruleset Externalize {
X	if (path)
X		return ("{4}" $1);
X}
X
Xruleset LocalHeaderFrom {
X	if (path)
X		return ("{S_local}" $1);
X}
X
Xruleset LocalHeaderTo {
X	if (path)
X		return ("{R_local}" $1);
X}
X
Xruleset UucpHeaderFrom {
X	if (path)
X		return ("{S_uucp}" $1);
X}
X
Xruleset UucpHeaderTo {
X	if (path)
X		return ("{R_uucp}" $1);
X}
X
Xmailer
X	local {
X		Path		= "/usr/src/local/EUnet/ease/test/args",
X		Flags		= {f_date,
X				   f_from,
X				   f_locm,
X				   f_mesg,
X				   f_mult,
X				   f_noufrom,
X				   f_rfrom,
X				   f_strip},
X		Sender		= LocalHeaderFrom,
X		Recipient 	= LocalHeaderTo,
X		Argv		= "args mail -d ${m_ruser}"
X	};
X	prog {
X		Path		= "/usr/src/local/EUnet/ease/test/args",
X		Flags		= {f_date,
X				   f_expensive,
X				   f_from,
X				   f_locm,
X				   f_mesg,
X				   f_noufrom,
X				   f_strip},
X		Sender		= LocalHeaderFrom,
X		Recipient 	= LocalHeaderTo,
X		Argv		= "args sh -c ${m_ruser}"
X	};
X	uucp {
X		Path		= "/usr/src/local/EUnet/ease/test/args",
X		Flags		= {f_date,
X				   f_from,
X				   f_mesg,
X				   f_strip,
X				   f_ufrom,
X				   f_upperh,
X				   f_upperu},
X		Sender		= UucpHeaderFrom,
X		Recipient 	= UucpHeaderTo,
X		Maxsize		= "65535",
X		Argv		= "args uumail -h -oc -gA -f${m_sreladdr} ${m_rhost}!${m_ruser}"
X	};
END_OF_test/test.mc
if test 4506 -ne `wc -c <test/test.mc`; then
    echo shar: \"test/test.mc\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 2 \(of 6\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 6 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
--
Bruce G. Barnett	barnett at crd.ge.com	uunet!crdgw1!barnett



More information about the Alt.sources mailing list