[comp.sources.unix] v17i087: Ease2.0, a language for sendmail.cf files, Part01/03

rsalz@uunet.uu.net (Rich Salz) (02/09/89)

Submitted-by: Arnold D. Robbins <arnold@EMORY.EDU>
Posting-number: Volume 17, Issue 87
Archive-name: ease2/part01

This is a fresh posting of the entire source for 'ease', the language
for writing sendmail(8) configuration files. It incorporates all the
enhancements in my December posting of diffs, plus some bug fixes,
and support for undocumented/unimplemented sendmail features. I have
also included, my 'cfc' program, which turns raw sendmail files into
something close to real 'ease'. All changes and improvements are actually
documented in the documentation.

Besides my own contributions, this posting includes code from Stephen Schaefer
of Bowling Green State University, Jeff Stearns of John Fluke Manufacturing
Company, Raymond Schnitzler of Bellcore, and Andrew Partan of the Corporation
for Open systems. Based on suggestions from Rich Salz of BBN, I have reworked
the lexical analyzer to use a binary search on a table of keywords. This makes
the program much smaller, and also slightly faster.

I have retired the 'maketd' program for making dependencies, and replaced
it with the standard BSD Makefile method. I have also removed the config
files from the original posting, since they were never completed.

More or less by default, I have become the "official" maintainer of ease.
However, I think at this point it does all it needs to do; I don't intend
to devote lots of work to it. However, if you find (and fix) bugs, I would
be interested in seeing what you do.

Enjoy,

Arnold Robbins
Unix Systems Programmer
Emory University Computing Center

#! /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 1 (of 3)."
# Contents:  MANIFEST README cfc cfc/cfc.1 doc doc/Makefile doc/ap1
#   doc/ap2 doc/ap3 doc/ap4 doc/cover local local/Makefile
#   local/ease.1 local/ease.ksh local/ease.sh src src/Makefile
#   src/errors.c src/fixstrings.c src/fixstrings.h src/idman.c
#   src/main.c src/symtab.c src/symtab.h
# Wrapped by rsalz@papaya.bbn.com on Wed Feb  8 16:55:42 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(1057 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X MANIFEST                   1	
X README                     1	
X cfc                        1	
X cfc/cfc.1                  1	
X cfc/cfc.c                  3	
X doc                        1	
X doc/Makefile               1	
X doc/ap1                    1	
X doc/ap2                    1	
X doc/ap3                    1	
X doc/ap4                    1	
X doc/cover                  1	
X doc/ease.paper             3	
X local                      1	
X local/Makefile             1	
X local/ease.1               1	
X local/ease.ksh             1	
X local/ease.sh              1	
X src                        1	
X src/Makefile               1	
X src/emitcf.c               2	
X src/errors.c               1	
X src/fixstrings.c           1	
X src/fixstrings.h           1	
X src/idman.c                1	
X src/lexan.l                2	
X src/main.c                 1	
X src/parser.y               2	
X src/strops.c               2	
X src/symtab.c               1	
X src/symtab.h               1	
END_OF_FILE
if test 1057 -ne `wc -c <'MANIFEST'`; then
    echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1616 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XREADME - Wed Jun 15 14:52:41 EDT 1988
X
XThis is a fresh posting of the entire source for 'ease', the language
Xfor writing sendmail(8) configuration files. It incorporates all the
Xenhancements in my December posting of diffs, plus some bug fixes,
Xand support for undocumented/unimplemented sendmail features. I have
Xalso included, my 'cfc' program, which turns raw sendmail files into
Xsomething close to real 'ease'. All changes and improvements are actually
Xdocumented in the documentation.
X
XBesides my own contributions, this posting includes code from Stephen Schaefer
Xof Bowling Green State University, Jeff Stearns of John Fluke Manufacturing
XCompany, Raymond Schnitzler of Bellcore, and Andrew Partan of the Corporation
Xfor Open systems. Based on suggestions from Rich Salz of BBN, I have reworked
Xthe lexical analyzer to use a binary search on a table of keywords. This makes
Xthe program much smaller, and also slightly faster.
X
XI have retired the 'maketd' program for making dependencies, and replaced
Xit with the standard BSD Makefile method. I have also removed the config
Xfiles from the original posting, since they were never completed.
X
XMore or less by default, I have become the "official" maintainer of ease.
XHowever, I think at this point it does all it needs to do; I don't intend
Xto devote lots of work to it. However, if you find (and fix) bugs, I would
Xbe interested in seeing what you do.
X
XEnjoy,
X
XArnold Robbins
XUnix Systems Programmer
XEmory University Computing Center
XUUCP:		gatech!emoryu1!arnold
XBITNET:		arnold@emoryu1.BITNET
XInternet:	arnold@emoryu1.ARPA	(current)
X		arnold@emory.edu	(soon)
END_OF_FILE
if test 1616 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
chmod +x 'README'
# end of 'README'
fi
if test ! -d 'cfc' ; then
    echo shar: Creating directory \"'cfc'\"
    mkdir 'cfc'
fi
if test -f 'cfc/cfc.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'cfc/cfc.1'\"
else
echo shar: Extracting \"'cfc/cfc.1'\" \(3571 characters\)
sed "s/^X//" >'cfc/cfc.1' <<'END_OF_FILE'
X...
X... $Header: cfc.1,v 2.0 88/06/15 15:17:36 arnold Exp $
X... 
X... $Log:	cfc.1,v $
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 8 local
X.SH NAME
Xcfc \- Sendmail cf file compiler
X.SH SYNOPSIS
X.B cfc
X[
X.B \-c
X] [
X.B \-u
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
XOnce it is through, the user need only spend some time in a good screen
Xeditor doing the following:
X.RS
X.P
XChanging the RULESET_n names into more descriptive names, and
Xadding ruleset bindings.
X.P
XApplying quoting to necessary string literals, principally in the
Xdefinitions of headers. The
X.I ease
Xdocumentation on header formats should be consulted.
X.P
XAdding new field names.
X.I Cfc
Xjust uses very generic field names, everywhere, when names like ``user,''
X``host,'' and ``relay'' might be more descriptive.
X.P
XMiscellanious formatting.
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.
XFinally, the block close on rulesets often comes after the comments that
Xprecede the next ruleset or mailer specification.
X.RE
X.P
XIn short,
X.I cfc
Xdoes over 90% of the tedious work of translating a
X.B sendmail.cf
Xinto
X.I ease
Xformat.
XThe rest of the work can be done in a day or less.
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 takes two 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.RE
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 and Arnold D. Robbins,
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.SH AUTHOR
X.nf
XArnold Robbins
XEmory University Computing Center
Xarnold@emory.edu
X.fi
END_OF_FILE
if test 3571 -ne `wc -c <'cfc/cfc.1'`; then
    echo shar: \"'cfc/cfc.1'\" unpacked with wrong size!
fi
chmod +x 'cfc/cfc.1'
# end of 'cfc/cfc.1'
fi
if test ! -d 'doc' ; then
    echo shar: Creating directory \"'doc'\"
    mkdir 'doc'
fi
if test -f 'doc/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doc/Makefile'\"
else
echo shar: Extracting \"'doc/Makefile'\" \(547 characters\)
sed "s/^X//" >'doc/Makefile' <<'END_OF_FILE'
X#
X# $Header: Makefile,v 1.2 87/12/23 11:30:27 root Locked $
X#
X# $Log:	Makefile,v $
X# Revision 1.2  87/12/23  11:30:27  root
X# Added new appendix. ADR.
X# 
X# Revision 1.1  87/12/23  10:40:45  root
X# Initial revision
X# 
X#
X#
X#	Makefile for Ease document.
X#
X#	James S. Schoner
X#	Purdue University Computing Center
X#
Xall:	cover mainbody apen1 apen2 apen3 apen4
X	
Xcover: FRC
X	troff -ms cover
X
Xmainbody:
X	tbl ease.paper | troff -ms
X
Xapen1:
X	tbl ap1 | troff -ms
X
Xapen2:
X	tbl ap2 | troff -ms
X
Xapen3:
X	tbl ap3 | troff -ms
X
Xapen4:
X	tbl ap4 | troff -ms
X
XFRC:
X
END_OF_FILE
if test 547 -ne `wc -c <'doc/Makefile'`; then
    echo shar: \"'doc/Makefile'\" unpacked with wrong size!
fi
chmod +x 'doc/Makefile'
# end of 'doc/Makefile'
fi
if test -f 'doc/ap1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doc/ap1'\"
else
echo shar: Extracting \"'doc/ap1'\" \(1394 characters\)
sed "s/^X//" >'doc/ap1' <<'END_OF_FILE'
X.DS C
X\s+5\fBAppendix A\fR
X
X
X\fBPre-Declared Macros\fR\s-5
X.DE
X.sp 5
X.TS 
Xcenter box;
Xc|c|c
Xl|l|l.
X\fBEase\fR Macro	Raw Equivalent	Meaning*
X=
X\fIm_odate\fR	a	The origination date in Arpanet format
X\fIm_adate\fR	b	The current date in Arpanet format
X\fIm_hops\fR	c	The hop count
X\fIm_udate\fR	d	The date in UNIX (ctime) format
X\fIm_smtp\fR	e	The SMTP entry message
X\fIm_saddr\fR	f	The sender (from) address
X\fIm_sreladdr\fR	g	The sender address relative to the recipient
X\fIm_rhost\fR	h	The recipient host
X\fIm_qid\fR	i	The queue id
X\fIm_oname\fR	j	The official domain name for this site
X\fIm_ufrom\fR	l	The format of the UNIX from line
X\fIm_daemon\fR	n	The name of the daemon (for error messages)
X\fIm_addrops\fR	o	The set of "operators" in addresses
X\fIm_pid\fR	p	Sendmail's pid
X\fIm_defaddr\fR	q	The default format of sender address
X\fIm_protocol\fR	r	Protocol used
X\fIm_shostname\fR	s	Sender's host name
X\fIm_ctime\fR	t	A numeric representation of the current time
X\fIm_ruser\fR	u	The recipient user
X\fIm_version\fR	v	The version number of sendmail
X\fIm_sitename\fR	w	The hostname of this site
X\fIm_sname\fR	x	The full name of the sender
X\fIm_stty\fR	y	The id of the sender's tty
X\fIm_rhdir\fR	z	The home directory of the recipient
X.TE
X.FS
X*  Taken from pages 19 and 20 of the Sendmail Installation and Operation Guide
X(SMM:7 in the 4.3 BSD UNIX System Manager's Manual), by Eric Allman.
X.FE
END_OF_FILE
if test 1394 -ne `wc -c <'doc/ap1'`; then
    echo shar: \"'doc/ap1'\" unpacked with wrong size!
fi
chmod +x 'doc/ap1'
# end of 'doc/ap1'
fi
if test -f 'doc/ap2' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doc/ap2'\"
else
echo shar: Extracting \"'doc/ap2'\" \(2432 characters\)
sed "s/^X//" >'doc/ap2' <<'END_OF_FILE'
X...
X... $Header: ap2,v 1.5 88/06/15 10:11:53 root Locked $
X... 
X... $Log:	ap2,v $
X... Revision 1.5  88/06/15  10:11:53  root
X... Added undocumented/unimplemented options. Fixed so it would troff well. ADR.
X... 
X... Revision 1.4  88/01/21  17:10:33  root
X... Added new option; change location of Sendmail doc to 4.3 SMM. ADR.
X... 
X... Revision 1.3  87/09/04  14:55:36  root
X... Fixed typo in new options. ADR.
X... 
X... Revision 1.2  87/03/03  17:05:41  root
X... Changes for 4.3 version of sendmail. ADR.
X... 
X... Revision 1.1  87/03/03  17:01:24  root
X... Initial revision
X... 
X...
X.DS C
X\s+5\fBAppendix B\fR
X
X\fBSendmail Options\fR\s-5
X.DE
X.PP
XFor a complete description of Sendmail's options and their values, refer to 
XAppendix B of the Sendmail Installation and Operation Guide (SMM:7 in the
X4.3 BSD UNIX System Manager's Manual), by Eric Allman.
X.sp
X.TS 
Xcenter box;
Xc|c
Xl|l.
XSendmail Option (\fBEase\fR)	Sendmail Option (Raw)	Special Values
X=
X\fIo_alias\fR	A	
X\fIo_ewait\fR	a	
X\fIo_bsub\fR	B	
X\fIo_checkpoint\fR	C *
X\fIo_qwait\fR	c	
X\fIo_delivery\fR  (special values below)	d  (special values below)
X     \fId_interactive\fR	     i 
X     \fId_background\fR	    b 
X     \fId_queue\fR	    q
X\fIo_rebuild\fR	D
X\fIo_handling\fR  (special values below)	e  (special values below)
X     \fIh_print\fR	     p 
X     \fIh_exit\fR	     q
X     \fIh_mail\fR	     m
X     \fIh_write\fR	     w
X     \fIh_mailz\fR	     e
X\fIo_tmode\fR	F	
X\fIo_usave\fR	f	
X\fIo_gid\fR	g	
X\fIo_fsmtp\fR	H	
X\fIo_skipd\fR	i	
X\fIo_slog\fR	L	
X\fIo_rsend\fR	m	
X\fIo_dnet\fR	N	
X\fIo_validate\fR	n \(dg
X\fIo_hformat\fR	o	
X\fIo_pmaster\fR	P \(bu
X\fIo_qdir\fR	Q	
X\fIo_qfactor\fR	q
X\fIo_tread\fR	r	
X\fIo_flog\fR	S	
X\fIo_safe\fR	s	
X\fIo_qtimeout\fR	T	
X\fIo_timezone\fR	t	
X\fIo_dmuid\fR	u	
X\fIo_verbose\fR	v	
X\fIo_wizpass\fR	W	
X\fIo_loadq\fR	x	
X\fIo_loadnc\fR	X	
X\fIo_recipfactor\fR	y
X\fIo_newproc\fR	Y
X\fIo_prifactor\fR	z
X\fIo_waitfactor\fR	Z
X.TE
X.PP
X* This option is undocumented and unimplemented in 4.3BSD. It is
Xfor checkpointing mail after \fIN\fR failed connections. \fBEase\fR supports
Xit in anticipation of future developments.
X.PP
X\(dg This option is undocumented in 4.3BSD. It specifies that the right hand
Xside of an alias definition should be checked for validity as an address
Xwhen the alias database is being rebuilt.
X.PP
X\(bu This option is undocumented in 4.3BSD.
XIt specifies the address of a Postmaster who should be carbon-copied on
Xall returned bad mail.
END_OF_FILE
if test 2432 -ne `wc -c <'doc/ap2'`; then
    echo shar: \"'doc/ap2'\" unpacked with wrong size!
fi
chmod +x 'doc/ap2'
# end of 'doc/ap2'
fi
if test -f 'doc/ap3' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doc/ap3'\"
else
echo shar: Extracting \"'doc/ap3'\" \(1366 characters\)
sed "s/^X//" >'doc/ap3' <<'END_OF_FILE'
X...
X... $Header: ap3,v 1.4 88/06/15 10:12:22 root Locked $
X... 
X... $Log:	ap3,v $
X... Revision 1.4  88/06/15  10:12:22  root
X... Added undocumented and unimplemented mailer flag.
X... 
X... Revision 1.3  88/01/21  17:10:57  root
X... Changed location of Sendmail doc to 4.3 SMM. ADR.
X... 
X... Revision 1.2  87/03/03  17:05:53  root
X... Changes for 4.3 version of sendmail. ADR.
X... 
X... Revision 1.1  87/03/03  17:04:52  root
X... Initial revision
X... 
X...
X.DS C
X\s+5\fBAppendix C\fR
X
X
X\fBMailer Flags\fR\s-5
X.DE
X.sp 5
X.PP
XFor a complete description of mailer flags, refer to 
XAppendix C of the Sendmail Installation and Operation Guide (SMM:7 in the
X4.3 BSD UNIX System Manager's Manual), by Eric Allman.
X.sp 5
X.TS 
Xcenter box;
Xc|c
Xl|l.
XMailer Flag (\fBEase\fR)	Mailer Flag (Raw)
X=
X\fIf_ffrom\fR	f
X\fIf_rfrom\fR	r
X\fIf_noreset\fR	S
X\fIf_noufrom\fR	n
X\fIf_locm\fR	l
X\fIf_strip\fR	s 
X\fIf_mult\fR	m
X\fIf_from\fR	F
X\fIf_date\fR	D
X\fIf_mesg\fR	M
X\fIf_full\fR	x	
X\fIf_return\fR	P	
X\fIf_upperu\fR	u	
X\fIf_upperh\fR	h	
X\fIf_arpa\fR	A	
X\fIf_ufrom\fR	U	
X\fIf_expensive\fR	e	
X\fIf_dot\fR	X	
X\fIf_llimit\fR	L	
X\fIf_retsmtp\fR	p	
X\fIf_smtp\fR	I	
X\fIf_addrw\fR	C	
X\fIf_escape\fR	E
X\fIf_rport\fR	R *
X.TE
X.FS
X*  This flag specifies the use of a reserved TCP port. In 4.3BSD it is
Xboth undocumented and unimplemented. \fBEase\fR supports it in anticipation
Xof future developments.
X.FE
END_OF_FILE
if test 1366 -ne `wc -c <'doc/ap3'`; then
    echo shar: \"'doc/ap3'\" unpacked with wrong size!
fi
chmod +x 'doc/ap3'
# end of 'doc/ap3'
fi
if test -f 'doc/ap4' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doc/ap4'\"
else
echo shar: Extracting \"'doc/ap4'\" \(208 characters\)
sed "s/^X//" >'doc/ap4' <<'END_OF_FILE'
X.DS C
X\s+5\fBAppendix D\fR
X
X
X\fBPre-Defined Classes\fR\s-5
X.DE
X.sp 5
X.TS 
Xcenter box;
Xc|c|c
Xl|l|l.
X\fBEase\fR Class	Raw Equivalent	Meaning
X=
X\fIc_myname\fR	w	The list of names by which this host is known
X.TE
END_OF_FILE
if test 208 -ne `wc -c <'doc/ap4'`; then
    echo shar: \"'doc/ap4'\" unpacked with wrong size!
fi
chmod +x 'doc/ap4'
# end of 'doc/ap4'
fi
if test -f 'doc/cover' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doc/cover'\"
else
echo shar: Extracting \"'doc/cover'\" \(640 characters\)
sed "s/^X//" >'doc/cover' <<'END_OF_FILE'
X...
X... $Header: cover,v 1.2 87/12/23 11:30:36 root Locked $
X...
X... $Log:	cover,v $
X... Revision 1.2  87/12/23  11:30:36  root
X... Updated list of authors. ADR.
X... 
X... Revision 1.1  87/12/23  10:16:35  root
X... Initial revision
X... 
X...
X.DA
X.sp 15
X.nr PS 14
X.ps 14
X.DS C
X 
X.DE
X.sp 10
X.nr PS 36
X.ps 36
X.DS C
X\fBEase:\fR
X.DE
X.sp 5
X.nr PS 22
X.ps 22
X.DS C
XA Configuration Language
X  
Xfor Sendmail
X.DE
X.sp 8
X.nr PS 14
X.ps 14
X.DS C
Xby
X
X\fIJames S. Schoner\fR
X\fIPurdue University Computing Center\fR
X
XAmended by
X
X\fIJeff P. Stearns\fR
X\fIJohn Fluke Manufacturing Company\fR
X
X\fIArnold D. Robbins\fR
X\fIEmory University Computing Center\fR
X.DE
END_OF_FILE
if test 640 -ne `wc -c <'doc/cover'`; then
    echo shar: \"'doc/cover'\" unpacked with wrong size!
fi
chmod +x 'doc/cover'
# end of 'doc/cover'
fi
if test ! -d 'local' ; then
    echo shar: Creating directory \"'local'\"
    mkdir 'local'
fi
if test -f 'local/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'local/Makefile'\"
else
echo shar: Extracting \"'local/Makefile'\" \(260 characters\)
sed "s/^X//" >'local/Makefile' <<'END_OF_FILE'
X# Makefile for 'ease'
X#
X
XEASE_SH= ease.ksh
X#EASE_SH= ease.sh
X
Xinstall: ../src/et $(EASE_SH)
X	install -c -s ../src/et /usr/local/lib
X	cp $(EASE_SH) /usr/local/bin/ease
X	chmod 755 /usr/local/bin/ease
X	cp ease.1 /usr/man/manl/ease.l
X
X../src/et:
X	cd ../src ; make
END_OF_FILE
if test 260 -ne `wc -c <'local/Makefile'`; then
    echo shar: \"'local/Makefile'\" unpacked with wrong size!
fi
chmod +x 'local/Makefile'
# end of 'local/Makefile'
fi
if test -f 'local/ease.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'local/ease.1'\"
else
echo shar: Extracting \"'local/ease.1'\" \(788 characters\)
sed "s/^X//" >'local/ease.1' <<'END_OF_FILE'
X.TH EASE 1 local
X.SH NAME
Xease \- build sendmail configuration files from readable descriptions
X.SH SYNOPSIS
X.B ease
X[
X.I cpp
Xoptions ]
X[ input_file ...  ] [
X.B \-o
Xoutput_file ]
X.SH DESCRIPTION
X.I Ease
Xis a simple shell script that
Xruns the C preprocessor, piping the output into the Ease Translator.
X.PP
XIf the
X.B \-o
Xoption is given, the named file will be used for the generated
Xconfiguration information, otherwise the standard output is used.
X.PP
XBy default,
X.I ease
Xwill read and write the standard input and output.
X.SH FILES
X/lib/cpp
X.br
X/usr/local/lib/et
X.SH SEE ALSO
X.I "Ease: A Configuration Language for Sendmail"
Xby James S. Schoner,
Xpublished in the January/February 1986 Usenix
X.IR ;login: .
X.SH DIAGNOSTICS
XA simple usage message if inappropriate arguments are supplied.
END_OF_FILE
if test 788 -ne `wc -c <'local/ease.1'`; then
    echo shar: \"'local/ease.1'\" unpacked with wrong size!
fi
chmod +x 'local/ease.1'
# end of 'local/ease.1'
fi
if test -f 'local/ease.ksh' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'local/ease.ksh'\"
else
echo shar: Extracting \"'local/ease.ksh'\" \(694 characters\)
sed "s/^X//" >'local/ease.ksh' <<'END_OF_FILE'
X#! /bin/ksh
X
X# ease -- run /lib/cpp and send the output into the ease translator
X#
X# usage: ease [ cpp options ] [ input files ] [ -o output_file ]
X
XPATH=/bin:/usr/ucb:/usr/bin
Xexport PATH
X
Xfunction usage
X{
X	echo usage: ease [ cpp options ] [ input files ] [ -o output_file ] 1>&2
X	exit 1
X}
X
Xifiles=
Xofile=
Xopts=
X
Xwhile [ $# -gt 0 ]
Xdo
X	case "$1" in
X	-o)	if [ "$2" ]
X		then
X			ofile="$2"
X			shift
X		else
X			usage
X		fi
X		;;
X	-o?*)	ofile="${1#-o}" ;;
X	-?*)	opts="$opts $1" ;;	# probably -D or -I cpp options
X	*)	ifiles="$ifiles $1" ;;	# will catch plain "-"
X	esac
X	shift
Xdone
X
X# use cat, since it understands the "-" convention
X
Xcat $ifiles | /lib/cpp $opts | cat -s | /usr/local/lib/et - $ofile
END_OF_FILE
if test 694 -ne `wc -c <'local/ease.ksh'`; then
    echo shar: \"'local/ease.ksh'\" unpacked with wrong size!
fi
chmod +x 'local/ease.ksh'
# end of 'local/ease.ksh'
fi
if test -f 'local/ease.sh' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'local/ease.sh'\"
else
echo shar: Extracting \"'local/ease.sh'\" \(686 characters\)
sed "s/^X//" >'local/ease.sh' <<'END_OF_FILE'
X#! /bin/sh
X
X# ease -- run /lib/cpp and send the output into the ease translator
X#
X# usage: ease [ cpp options ] [ input files ] [ -o output_file ]
X
XPATH=/bin:/usr/ucb:/usr/bin
Xexport PATH
X
Xifiles=
Xofile=
Xopts=
X
Xwhile [ $# -gt 0 ]
Xdo
X	case "$1" in
X	-o)	if [ "$2" ]
X		then
X			ofile="$2"
X			shift
X		else
X			echo "usage: ease [ cpp options ] [ input files ] [ -o output_file ]" 1>&2
X			exit 1
X		fi
X		;;
X	-o?*)	ofile="`expr $1 : '-o\(..*\)'`" ;;
X	-?*)	opts="$opts $1" ;;	# probably -D or -I cpp options
X	*)	ifiles="$ifiles $1" ;;	# will catch plain "-"
X	esac
X	shift
Xdone
X
X# use cat, since it understands the "-" convention
X
Xcat $ifiles | /lib/cpp $opts | cat -s | /usr/local/lib/et - $ofile
END_OF_FILE
if test 686 -ne `wc -c <'local/ease.sh'`; then
    echo shar: \"'local/ease.sh'\" unpacked with wrong size!
fi
chmod +x 'local/ease.sh'
# end of 'local/ease.sh'
fi
if test ! -d 'src' ; then
    echo shar: Creating directory \"'src'\"
    mkdir 'src'
fi
if test -f 'src/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/Makefile'\"
else
echo shar: Extracting \"'src/Makefile'\" \(3136 characters\)
sed "s/^X//" >'src/Makefile' <<'END_OF_FILE'
X# Makefile for Ease Translator (et).
X#
X#	$Header: Makefile,v 2.0 88/06/15 14:47:35 root Exp $
X#
X#	$Log:	Makefile,v $
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
XDEST = /usr/local/bin
X
XOWNER = root
XGROUP = staff
XMODE = 755
X
XDEFS =
XCFLAGS = -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
X
XCFILES= $(SRC) $(DEP)
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
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 -c -m ${MODE} -o ${OWNER} -g ${GROUP} -s et ${DEST}
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 -d parser.y
X	mv y.tab.c parser.c
X
X# the following dummy rule is because of the results of 'make depend'
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
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_FILE
if test 3136 -ne `wc -c <'src/Makefile'`; then
    echo shar: \"'src/Makefile'\" unpacked with wrong size!
fi
chmod +x 'src/Makefile'
# end of 'src/Makefile'
fi
if test -f 'src/errors.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/errors.c'\"
else
echo shar: Extracting \"'src/errors.c'\" \(2455 characters\)
sed "s/^X//" >'src/errors.c' <<'END_OF_FILE'
X/*	$Header: errors.c,v 2.0 88/06/15 14:41:10 root Exp $	*/
X
X/*
X * $Log:	errors.c,v $
X * Revision 2.0  88/06/15  14:41:10  root
X * Baseline release for net posting. ADR.
X * 
X */
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 */
X
X#include <stdio.h>
X#include "fixstrings.h"
X
Xextern int  ErrorCount;	 /* error count	               */
Xextern char FNbuf[];	 /* input file name   	       */
Xextern int  Lcount;	 /* line count	     	       */
XFILE *DIAGf = {stderr};  /* file for diagnostic output */
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}
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 *	yyerror () -- Prints source file name (FNbuf), line number (Lcount),
X *		      and error message (sbErr) for each invokation.
X *
X */
Xvoid
Xyyerror (sbErr)
Xchar *sbErr;
X{
X	fprintf (DIAGf, "%s, line %d: %s\n", FNbuf, Lcount, sbErr);
X	ErrorCount++;
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	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	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_FILE
if test 2455 -ne `wc -c <'src/errors.c'`; then
    echo shar: \"'src/errors.c'\" unpacked with wrong size!
fi
chmod +x 'src/errors.c'
# end of 'src/errors.c'
fi
if test -f 'src/fixstrings.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/fixstrings.c'\"
else
echo shar: Extracting \"'src/fixstrings.c'\" \(1701 characters\)
sed "s/^X//" >'src/fixstrings.c' <<'END_OF_FILE'
X/*
X * $Source: /usr/src/local/local.bin/ease/src/RCS/fixstrings.c,v $
X * $Locker:  $
X *
X * $Revision: 2.0 $
X * Check-in $Date: 88/06/15 14:41:19 $
X * $State: Exp $
X *
X * $Author: root $
X *
X * $Log:	fixstrings.c,v $
X * Revision 2.0  88/06/15  14:41:19  root
X * Baseline release for net posting. ADR.
X * 
X * Version 1.3  87/03/05  19:38:33  jeff
X * Edited RCS header and FLUKEid[] string.
X * 
X * Version 1.2  87/02/25  16:55:13  jeff
X * Add some RCS header lines.  No code changes.
X * 
X */
X
X/*  FLUKE jps 16-apr-86 - special hacks for NULL pointers.
X *
X *  The author of ease used a *lot* of NULL pointers.  This isn't much
X *  of a problem on a vax, where NULL pointers look like "".  Not so on a Sun.
X *
X *  We hack around the problem by defining a set of wrappers for the
X *  standard string functions, making it appear as though they accept NULL
X *  pointers.  In the other C files, cpp macros are used to revector the
X *  standard string functions to this file.
X */
X#include <strings.h>
X#define fix(s) ((s) ? (s) : "")
X
Xchar *Xstrcat (s1, s2)
Xchar *s1, *s2; 
X{
X	return (strcat (s1, fix (s2)));
X}
X
Xchar *Xstrncat (s1, s2, n)
Xchar *s1, *s2; 
X{
X	return (strncat (s1, fix (s2), n));
X}
X
XXstrcmp (s1, s2)
Xchar *s1, *s2; 
X{
X	return (strcmp (fix (s1), fix (s2)));
X}
X
XXstrncmp (s1, s2, n)
Xchar *s1, *s2; 
X{
X	return (strncmp (fix (s1), fix (s2), n));
X}
X
Xchar *Xstrcpy (s1, s2)
Xchar *s1, *s2; 
X{
X	return (strcpy (s1, fix (s2)));
X}
X
Xchar *Xstrncpy (s1, s2, n)
Xchar *s1, *s2; 
X{
X	return (strncpy (s1, fix (s2), n));
X}
X
XXstrlen (s)
Xchar *s; 
X{
X	return (strlen (fix (s)));
X}
X
Xchar *Xindex (s, c)
Xchar *s, c; 
X{
X	return (index (fix (s), c));
X}
X
Xchar *Xrindex (s, c)
Xchar *s, c; 
X{
X	return (rindex (fix (s), c));
X}
END_OF_FILE
if test 1701 -ne `wc -c <'src/fixstrings.c'`; then
    echo shar: \"'src/fixstrings.c'\" unpacked with wrong size!
fi
chmod +x 'src/fixstrings.c'
# end of 'src/fixstrings.c'
fi
if test -f 'src/fixstrings.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/fixstrings.h'\"
else
echo shar: Extracting \"'src/fixstrings.h'\" \(811 characters\)
sed "s/^X//" >'src/fixstrings.h' <<'END_OF_FILE'
X/*
X * $Source: /usr/src/local/local.bin/ease/src/RCS/fixstrings.h,v $
X * $Locker:  $
X *
X * $Revision: 2.0 $
X * Check-in $Date: 88/06/15 14:41:57 $
X * $State: Exp $
X *
X * $Author: root $
X *
X * $Log:	fixstrings.h,v $
X * Revision 2.0  88/06/15  14:41:57  root
X * Baseline release for net posting. ADR.
X * 
X * Version 1.3  87/03/05  19:37:50  jeff
X * Edited RCS header and FLUKEid[] string.
X * 
X * Version 1.2  87/02/25  16:55:16  jeff
X * Add some RCS header lines.  No code changes.
X * 
X */
X
X/* FLUKE jps 16-apr-86 - revector the string routines to custom-coded ones
X *  which handle NULL pointers.
X */
X#define strcat	Xstrcat
X#define strncat	Xstrncat
X#define strcmp	Xstrcmp
X#define strncmp	Xstrncmp
X#define strcpy	Xstrcpy
X#define strncpy	Xstrncpy
X#define strlen	Xstrlen
X#define index	Xindex
X#define rindex	Xrindex
END_OF_FILE
if test 811 -ne `wc -c <'src/fixstrings.h'`; then
    echo shar: \"'src/fixstrings.h'\" unpacked with wrong size!
fi
chmod +x 'src/fixstrings.h'
# end of 'src/fixstrings.h'
fi
if test -f 'src/idman.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/idman.c'\"
else
echo shar: Extracting \"'src/idman.c'\" \(5664 characters\)
sed "s/^X//" >'src/idman.c' <<'END_OF_FILE'
X/*	$Header: idman.c,v 2.0 88/06/15 14:42:14 root Exp $	*/
X
X/*
X * $Log:	idman.c,v $
X * Revision 2.0  88/06/15  14:42:14  root
X * Baseline release for net posting. ADR.
X * 
X */
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 */
X
X#include <stdio.h>
X#include "symtab.h"
X#include "fixstrings.h"
X
Xextern struct he *LookupSymbol ();
Xextern void	  FatalError (),
X		  ErrorReport (),
X		  PrintWarning (),
X		  PrintError ();
X
Xshort Uchar = 'A';			/* for unique macro names */
X
X
X/*
X *	UniqMac () -- Assigns and returns a unique one-character macro
X *		      name (upper-case) for an Ease macro name.
X *
X */
Xchar
XUniqMac (phe)
Xstruct he *phe;		/* symbol table entry for Ease macro */
X{
X	if ((phe->idval.idc = Uchar++) > 'Z')
X		FatalError ("Too many macro names (26 max)", (char *) NULL);
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:", phe->psb);
X		else
X			PrintError ("Identifier not of ruleset type:", 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:", 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", 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:", 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:", 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_FILE
if test 5664 -ne `wc -c <'src/idman.c'`; then
    echo shar: \"'src/idman.c'\" unpacked with wrong size!
fi
chmod +x 'src/idman.c'
# end of 'src/idman.c'
fi
if test -f 'src/main.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/main.c'\"
else
echo shar: Extracting \"'src/main.c'\" \(4028 characters\)
sed "s/^X//" >'src/main.c' <<'END_OF_FILE'
X/*	$Header: main.c,v 2.0 88/06/15 14:42:41 root Exp $	*/
X
X/*
X * $Log:	main.c,v $
X * Revision 2.0  88/06/15  14:42:41  root
X * Baseline release for net posting. ADR.
X * 
X */
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 */
X
X#include "fixstrings.h"
X#include <stdio.h>
X
Xextern FILE *DIAGf;			/* diagnostic file */
Xextern void InitError (), 
X	    InitSymbolTable (),
X	    DefScan (),
X	    FatalError (),
X            PreLoad ();
X
Xint ErrorCount;				/* translation error count */
Xvoid GetArgs ();			/* gets arguments to "et"  */
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 *		      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	switch (margc) {
X		case 1 : break;
X		case 2 :
X		case 3 : if (strcmp (margv[1], "-") && (freopen (margv[1], "r", stdin) == NULL))
X				FatalError ("Cannot open input stream/file:", margv[1]);
X			 if ((margc == 3) && (freopen (margv[2], "w", stdout) == NULL))
X				FatalError ("Cannot open output file:", margv[2]);
X			 break;
X		default: FatalError ("Usage: et [infile [outfile]]", (char *) NULL);
X			 break;
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}
END_OF_FILE
if test 4028 -ne `wc -c <'src/main.c'`; then
    echo shar: \"'src/main.c'\" unpacked with wrong size!
fi
chmod +x 'src/main.c'
# end of 'src/main.c'
fi
if test -f 'src/symtab.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/symtab.c'\"
else
echo shar: Extracting \"'src/symtab.c'\" \(6060 characters\)
sed "s/^X//" >'src/symtab.c' <<'END_OF_FILE'
X/*	$Header: symtab.c,v 2.0 88/06/15 14:43:04 root Exp $	*/
X
X/*
X * $Log:	symtab.c,v $
X * Revision 2.0  88/06/15  14:43:04  root
X * Baseline release for net posting. ADR.
X * 
X */
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 */
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_ufrom",	'l'},
X			{"m_daemon",	'n'},
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			{"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_FILE
if test 6060 -ne `wc -c <'src/symtab.c'`; then
    echo shar: \"'src/symtab.c'\" unpacked with wrong size!
fi
chmod +x 'src/symtab.c'
# end of 'src/symtab.c'
fi
if test -f 'src/symtab.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/symtab.h'\"
else
echo shar: Extracting \"'src/symtab.h'\" \(2471 characters\)
sed "s/^X//" >'src/symtab.h' <<'END_OF_FILE'
X/*	$Header: symtab.h,v 2.0 88/06/15 14:43:08 root Exp $	*/
X
X/*
X * $Log:	symtab.h,v $
X * Revision 2.0  88/06/15  14:43:08  root
X * Baseline release for net posting. ADR.
X * 
X */
X
X/*
X *	symtab.h    -- Definitions related to the "et" symbol table. 
X *
X *	author	    -- James S. Schoner, Purdue University Computing Center,
X *					 West Lafayette, Indiana  47907
X *
X *	date	    -- July 1, 1985
X *
X *	Copyright (c) 1985 by Purdue Research Foundation
X *
X *	All rights reserved.
X *
X */
X
X#define TRUE      1
X#define FALSE     0
X#define SST       101		/* size of hash table (symbol table) 	     */
X#define RSNMAX    5		/* size of a ruleset number character buffer */
X#define VALRSNMAX 9999		/* max value of ruleset number		     */
X
X
X/* identifier types */
X#define ID_UNTYPED 0
X#define ID_MACRO   01
X#define ID_CLASS   02
X#define ID_RULESET 04
X#define ID_FIELD   010
X#define ID_PREC	   020
X#define ID_MAILER  040
X
X/* identifier type macros */
X#define ISTYPED(x) (x|ID_UNTYPED)
X#define ISMACRO(x) (x&ID_MACRO)
X#define ISCLASS(x) (x&ID_CLASS)
X#define ISRULESET(x) (x&ID_RULESET)
X#define ISFIELD(x) (x&ID_FIELD)
X#define ISPREC(x) (x&ID_PREC)
X#define ISMAILER(x) (x&ID_MAILER)
X
X/* block definition types */
Xenum bdefs {def_macro, def_class, def_option, def_prec, def_trusted, 
X	    def_header, def_mailer, def_ruleset};
X
X/* option types */
Xenum opts {opt_A, opt_a, opt_B, opt_C, opt_c, opt_D, opt_d, opt_e, opt_F,
X	   opt_f, opt_g, opt_H, opt_i, opt_L, opt_m, opt_N, opt_n, opt_o,
X	   opt_P, opt_Q, opt_q, opt_r, opt_S, opt_s, opt_T, opt_t, opt_u,
X	   opt_v, opt_W, opt_x, opt_X, opt_Y, opt_y, opt_Z, opt_z,
X	   d_opt_i, d_opt_b, d_opt_q,
X	   e_opt_p, e_opt_e, e_opt_m, e_opt_w, e_opt_z};
X
X/* flag types */
Xenum flgs {flg_f, flg_r, flg_S, flg_n, flg_l, flg_s, flg_m, flg_F, flg_D,
X	   flg_M, flg_x, flg_P, flg_u, flg_h, flg_A, flg_U, flg_e, flg_X,
X	   flg_L, flg_p, flg_I, flg_C, flg_E, flg_R};
X
X/* mailer parameters */
Xenum mats {mat_path, mat_flags, mat_sender, mat_recipient, mat_argv, 
X	   mat_eol, mat_maxsize};
X
Xstruct he {	/* hash entry structure for symbol table node 	*/
X	unsigned   idtype;	/* identifier type 		*/
X	unsigned   idd;	  	/* identifier definition flag 	*/
X	char      *psb;		/* identifier string buffer 	*/
X	union {
X		char rsn[RSNMAX]; 	/* ruleset number   	      */
X		int prec;	  	/* precedence value 	      */
X		char idc;		/* one char id representation */
X		char *fstring;    	/* field string     	      */
X	} idval;
X	struct he *phe;		/* next hash entry 		*/
X};
END_OF_FILE
if test 2471 -ne `wc -c <'src/symtab.h'`; then
    echo shar: \"'src/symtab.h'\" unpacked with wrong size!
fi
chmod +x 'src/symtab.h'
# end of 'src/symtab.h'
fi
echo shar: End of archive 1 \(of 3\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 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
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.