rs@uunet.UU.NET (Rich Salz) (07/10/87)
Submitted-by: Wombat <rsk@j.cc.purdue.edu>
Posting-number: Volume 10, Issue 53
Archive-name: ease/Part03
#! /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 3 (of 4)."
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'config-files/FINIS/base.cpp' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'config-files/FINIS/base.cpp'\"
else
echo shar: Extracting \"'config-files/FINIS/base.cpp'\" \(7566 characters\)
sed "s/^X//" >'config-files/FINIS/base.cpp' <<'END_OF_FILE'
X/***********************************************************
X ***********************************************************
X ****
X **** General configuration information
X ****
X **** This information is basically just "boiler-plate"; it must be
X **** there, but is essentially constant.
X ****
X **** Information in this file should be independent of location --
X **** i.e., although there are some policy decisions made, they are
X **** not specific to Berkeley per se.
X ****
X **** $Id: base.cpp,v 1.3 85/05/04 17:00:43 acu Exp Locker: acu $
X ****
X ***********************************************************
X ***********************************************************/
X
X
X#include "version.cpp"
X
X
X/************************
X ** Special macros **
X ************************/
X
Xmacro
X m_daemon = "MAILER-DAEMON";
X /* my name */
X
X m_ufrom = "From ${m_sreladdr} ${m_udate}";
X /* UNIX header format */
X
X m_addrops = ".:%@!^=/[]";
X /* delimiter (operator) characters */
X
X m_defaddr = concat (
X ifset (m_sname, "${m_sname} "),
X "<${m_sreladdr}>"
X );
X /* format of a total name */
X
X m_smtp = "${m_oname} Sendmail ${m_version}/${berkhosts} ready at ${m_adate}";
X /* SMTP login message */
X
X
X/***************
X ** Class **
X ***************/
X
Xclass
X uucphosts = {};
X
X/*****************
X ** Options **
X *****************/
X
Xoptions
X o_alias = "/usr/lib/aliases";
X /* location of alias file */
X
X o_ewait = "10";
X /* wait up to ten minutes for alias file rebuild */
X
X o_bsub = ".";
X /* substitution for space (blank) characters */
X
X o_delivery = d_background;
X /* default delivery mode (deliver in background) */
X
X /***
X o_qwait = "";
X /* (don't) connect to "expensive" mailers */
X
X o_tmode = "0600";
X /* temporary file mode */
X
X o_gid = "3";
X /* default GID (network) */
X
X o_fsmtp = "/usr/lib/sendmail.hf";
X /* location of help file */
X
X o_slog = "9";
X /* log level */
X
X /***
X o_dnet = "ARPA";
X /* default network name */
X
X o_hformat = "";
X /* default messages to old style */
X
X o_qdir = "/usr/spool/mqueue";
X /* queue directory */
X
X o_tread = "2h";
X /* read timeout -- violates protocols */
X
X o_flog = "/usr/lib/sendmail.st";
X /* status file */
X
X o_safe = "";
X /* queue everything before transmission */
X
X o_qtimeout = "3d";
X /* default timeout interval */
X
X o_timezone = "EST";
X /* time zone names (V6 only) */
X
X o_dmuid = "5";
X /* default UID (network) */
X
X o_wizpass = "XXXXXXXXXXXXX";
X /* wizard's password */
X
X o_loadq = "999";
X /* load average at which we just queue messages */
X
X o_loadnc = "999";
X /* load average at which we refuse connections */
X
X
X/*****************************
X ** Message precedences **
X *****************************/
X
Xprecedence
X first-class = 0;
X special-delivery = 100;
X junk = -100;
X
X
X/***********************
X ** Trusted users **
X ***********************/
X
Xtrusted
X {root, daemon, uucp, network};
X {aat};
X
X
X/***************************
X ** Format of headers **
X ***************************/
X
Xheader
X define ("Received:", concat (ifset (m_shostname, "from ${m_shostname} "),
X "by ${m_oname}; ${m_adate}"));
X define ("Subject:", "");
X
X /***
X define ("Posted-Date:", "${m_odate}");
X ***/
X
X for (f_return)
X define ("Return-Path:", "<${m_sreladdr}>");
X
X for (f_date) {
X define ("Resent-Date:", "${m_odate}");
X define ("Date:", "${m_odate}");
X };
X
X for (f_from) {
X define ("Resent-From:", "${m_defaddr}");
X define ("From:", "${m_defaddr}");
X };
X
X for (f_full)
X define ("Full-Name:", "${m_sname}");
X
X /***
X for (f_locm)
X define ("Received-Date:", "${m_adate}");
X ***/
X
X for (f_mesg) {
X define ("Resent-Message-Id:", "<${m_ctime}.${m_qid}@${m_oname}>");
X define ("Message-Id:", "<${m_ctime}.${m_qid}@${m_oname}>");
X };
X
X
X/*************************
X *************************
X ** Rewriting rules **
X *************************
X *************************/
X
X/*************************
X ** Field definitions **
X *************************/
X
Xfield
X anypath : match (0*);
X path, usr, hostpath,
X domain : match (1*);
X this_host : match (1) in m_sitename;
X hostname : match (1);
X campushost : match (1) in campushosts;
X localdomain : match (1) in localname;
X topdomain_id : match (1) in topdomain;
X uucphost : match (1) in uucphosts;
X phonehost : match (1) in phonehosts;
X
X/********************************
X * Sender Field Pre-rewriting *
X ********************************/
X
Xruleset SEND_PRW {
X
X/***
X if ( anypath < anypath > anypath )
X retry ( $1$2$3 ); /* defocus */
X
X}
X
X/***********************************
X * Recipient Field Pre-rewriting *
X ***********************************/
X
Xruleset RECP_PRW {
X
X/***
X if ( anypath < anypath > anypath )
X retry ( $1$2$3 ); /* defocus */
X
X}
X
X
X/*********************************
X * Final Output Post-rewriting *
X *********************************/
X
Xruleset FINAL_RW {
X
X if ( @ )
X return (); /* handle <> error addr */
X
X /* externalize local domain info */
X
X /***
X if ( anypath < anypath "LOCAL" > anypath )
X retry ( $1 < $2 $localname > $3 ); /* change local info */
X
X /***
X if ( anypath < anypath "LOCAL.ARPA" > anypath )
X retry ( $1 < $2 $localname > $3 ); /* change local info */
X
X if ( anypath < path > anypath )
X retry ( $1$2$3 ); /* defocus */
X
X if ( @path: @path: usr )
X retry ( @$1,@$2:$3); /* <route-addr> canonical */
X
X /* UUCP must always be presented in old form */
X
X if ( usr @ hostname ".UUCP" )
X retry ( $2!$1); /* u@h.UUCP => h!u */
X
X /* delete duplicate local names -- mostly for arpaproto.mc */
X
X if ( usr % this_host @ this_host )
X retry ( $1@$3 ); /* u%UCB@UCB => u@UCB */
X
X if ( usr % this_host @ this_host ".ARPA" )
X retry ( $1@$3 ".ARPA" ); /* u%UCB@UCB => u@UCB */
X
X}
X
X
X/***************************
X * Name Canonicalization *
X ***************************/
X
Xruleset NAME_CANON {
X
X /* handle "from:<>" special case */
X
X if ( <> )
X return ( @ ); /* turn into magic token */
X
X /* basic textual canonicalization -- note RFC733 heuristic here */
X
X if ( anypath < anypath < anypath < path > anypath > anypath > anypath )
X retry ( $4 ); /* 3-level <> nesting */
X
X if ( anypath < anypath < path > anypath > anypath )
X retry ( $3 ); /* 2-level <> nesting */
X
X if ( anypath < path > anypath )
X retry ( $2 ); /* basic RFC821/822 parsing */
X
X if ( usr " at " path )
X retry ( $1@$2 ); /* "at" -> "@" for RFC 822 */
X
X /* make sure <@a,@b,@c:user@d> syntax is easy to parse -- undone later */
X
X if ( @path, usr )
X retry ( @$1:$2 ); /* change all "," to ":" */
X
X /* localize and dispose of route-based addresses */
X
X if ( @path: usr )
X return ( LOCAL_RW ( <@$1>:$2 ) ); /* handle <route-addr> */
X
X /* more miscellaneous cleanup */
X
X if ( path )
X next ( HOSTDEP_RW ( $1 ) ); /* host dependent cleanup */
X
X if ( path: anypath; @domain )
X return ( $1:$2;@$3 ); /* list syntax */
X
X if ( usr @ domain )
X next ( $1<@$2> ); /* focus on domain */
X
X if ( path < path @ domain > )
X retry ( $1$2<@$3> ); /* move gaze right */
X
X if ( path < @domain > )
X return ( LOCAL_RW ( $1<@$2> ) ); /* already canonical */
X
X /* convert old-style addresses to a domain-based address */
X
X if ( usr % hostpath )
X return ( LOCAL_RW ( $1<@$2> ) ); /* user%host */
X
X if ( hostname:usr )
X return ( LOCAL_RW ( $2<@$1> ) ); /* host:user */
X
X if ( hostname.usr )
X return ( LOCAL_RW ( $2<@$1> ) ); /* host.user */
X
X if ( hostname^usr )
X retry ( $1!$2); /* convert ^ to ! */
X
X if ( hostname!usr )
X return ( LOCAL_RW ( $2<@$1".UUCP"> ) ); /* resolve uucp names */
X
X if ( hostname=usr )
X return ( LOCAL_RW ( $2<@$1".BITNET"> ) ); /* resolve bitnet names */
END_OF_FILE
if test 7566 -ne `wc -c <'config-files/FINIS/base.cpp'`; then
echo shar: \"'config-files/FINIS/base.cpp'\" unpacked with wrong size!
fi
# end of 'config-files/FINIS/base.cpp'
fi
if test -f 'maketd/abrv.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'maketd/abrv.c'\"
else
echo shar: Extracting \"'maketd/abrv.c'\" \(6197 characters\)
sed "s/^X//" >'maketd/abrv.c' <<'END_OF_FILE'
X/* abbreviation related routines
X * Written & hacked by Stephen Uitti, PUCC staff, ach@pucc-j, 1985
X * maketd is copyright (C) Purdue University, 1985
X *
X * Permission is hereby given for its free reproduction and
X * modification for non-commercial purposes, provided that this
X * notice and all embedded copyright notices be retained.
X * Commercial organisations may give away copies as part of their
X * systems provided that they do so without charge, and that they
X * acknowledge the source of the software.
X */
X
X#ifdef BSD2_9
X#include <sys/types.h>
X#endif
X#include <stdio.h>
X#include <ctype.h>
Xextern char *malloc();
X
X#include "srtunq.h"
X#include "abrv.h"
X#include "maketd.h"
X
Xstruct srtent abrv; /* include file abrevs */
Xchar *abrvtbl[MXABR]; /* translation table strings */
Xint abrvlen[MXABR]; /* string lengths (for speed) */
X
X/* lngsrt - string length more important than lexicographical compare.
X * return > 0 if b is longer than a.
X * return < 0 if b is shorter than a.
X * if a & b are the same length, return strcmp(a, b), which means
X * that 0 is returned if the strings are THE SAME,
X * if b > a: return > 0
X * if b < a: return < 0
X */
Xint
Xlngsrt(a, b)
Xchar *a, *b;
X{
X register i;
X
X if ((i = strlen(b) - strlen(a)) != 0)
X return i;
X else
X return strcmp(a, b);
X}
X
X/* hincl - include header optimizer:
X * Compress multiple leading /'s to just one.
X * Remove leading "./".
X * Doesn't change date, just returns pointer into begining of path.
X */
Xchar *
Xhincl(p)
Xregister char *p;
X{
X if (*p == '/') /* compress multiple leading /'s */
X while (p[1] == '/') /* to just one */
X p++;
X if (strncmp("./", p, 2) == 0) {
X p += 2; /* leading "./" can confuse make */
X while (*p == '/') /* don't change ".//a.h" to "/a.h" */
X p++;
X }
X return p;
X}
X
X/* srchincl - search line for make defines of A-Z
X * Put entries into abrvtbl.
X */
Xvoid
Xsrchincl(p)
Xregister char *p;
X{
X register char *q, *r;
X register i;
X
X if (shortincl && *p != '\0') {
X while (*p == SPC || *p == '\t')
X p++; /* ignore white space */
X q = p; /* what letter */
X if (isupper(*p)) { /* A-Z, for now */
X p++;
X while (*p == SPC || *p == '\t')
X p++; /* ignore white space */
X if (*p++ == '=') {
X while (*p == SPC || *p == '\t')
X p++;
X if ((i = strlen(p)) != 0) {
X if ((r = malloc((unsigned)(i + 1))) == NULL)
X err("Out of memory in define search");
X if (abrvtbl[*q - 'A'])
X fprintf(stderr, "%s: warning - %c redefined in %s\n",
X prgnm, *q, makename);
X abrvtbl[*q - 'A'] = r;
X while (*p != '\0' && *p != '#' && *p != '\n')
X *r++ = *p++;
X *r = '\0'; /* null terminate result */
X } /* if non-null string */
X } /* if = */
X } /* if A-Z */
X } /* if shortinclude & string */
X}
X
X/* abrvsetup - set up abrev table, spit out the abrevs. Use
X * any A-Z definitions found in Makefile, no duplicates. Add
X * /usr/include & /usr/include/sys if "all" dependencies are
X * being generated (including /usr/include based files).
X * Try to use I=/usr/include and S=/usr/include/sys, but don't
X * make a stink about it.
X */
Xvoid
Xabrvsetup()
X{
X register i; /* temp */
X register char *p; /* temp */
X register slot; /* slot search point */
X register j; /* temp */
X static abrdone = FALSE; /* do this only once */
X register flushi = FALSE; /* print I=.. */
X register flushs = FALSE; /* print S=.. */
X static char *istring = "I=/usr/include";
X static char *sstring = "S=/usr/include/sys";
X
X if (abrdone)
X return;
X if (shortincl) {
X abrdone = TRUE; /* we've done this */
X /* add /usr/include/sys, /usr/include if not already there */
X if (alldep) {
X if (abrvtbl['S'-'A'] == NULL) {
X flushs = TRUE;
X srchincl(sstring);
X } else if ((p = srtin(&abrv, &sstring[2], lngsrt)) != NULL)
X fprintf(stderr, "%s: %s - %s\n", prgnm, p, &sstring[2]);
X if (abrvtbl['I'-'A'] == NULL) {
X flushi = TRUE;
X srchincl(istring);
X } else if ((p = srtin(&abrv, &istring[2], lngsrt)) != NULL)
X fprintf(stderr, "%s: %s - %s\n", prgnm, p, &istring[2]);
X }
X if (!replace) { /* no new defines with replace */
X srtgti(&abrv); /* init tree traversal */
X slot = 0; /* start at bgn */
X while ((p = srtgets(&abrv)) != NULL) {
X j = strlen(p);
X for (i = 0; i < MXABR; i++) { /* look for this definition */
X if (abrvtbl[i] == NULL)
X continue; /* check non-null entries */
X if (*abrvtbl[i] == '\0')
X continue; /* check non-null entries */
X if (strcmp(p, abrvtbl[i]) == 0)
X break; /* exact match found */
X else if (strlen(abrvtbl[i]) == j + 1 &&
X strncmp(p, abrvtbl[i], j) == 0 &&
X abrvtbl[i][j] == '/')
X break; /* match of "p/" found */
X }
X if (i == MXABR) { /* not found */
X for (i = slot; i < MXABR; i++) /* find free slot */
X if (abrvtbl[i] == NULL)
X break;
X if (i < MXABR) { /* free slot found */
X /* if (!usestdout && !replace) */
X fprintf(makefd, "%c=%s\n", 'A' + i, p);
X abrvtbl[i++] = p;
X slot = i; /* reduce free slot search time */
X }
X } /* if not found */
X } /* while */
X } /* if !replace */
X if (flushi && !usestdout && !replace)
X fprintf(makefd, "%s\n", istring);
X if (flushs && !usestdout && !replace)
X fprintf(makefd, "%s\n", sstring);
X for (i = 0; i < MXABR; i++) { /* set up string lengths */
X if (abrvtbl[i] == NULL) {
X abrvlen[i] = 0;
X } else {
X abrvlen[i] = strlen(abrvtbl[i]);
X if (verbose)
X fprintf(stderr, "%s: %c='%s'\n",
X prgnm, i + 'A', abrvtbl[i]);
X } /* if */
X } /* for */
X } /* if */
X}
X
X/* findabr - find an abbreviation in abrvtbl for string p (if any).
X * if multiple abbreations work, use longest.
X * (ie: /usr/include & /usr/include/sys; use /usr/include/sys)
X * if found, return index
X * else: MXABR
X * Do not match abbreviations of less than 3 characters.
X */
Xint
Xfindabr(p)
Xregister char *p; /* string pointer */
X{
X register i; /* for index */
X register j; /* found index */
X
X for (i = 0, j = MXABR; i < MXABR; i++)
X if (abrvlen[i] > 2) /* changing "." to $A is evil */
X if (strncmp(abrvtbl[i], p, abrvlen[i]) == 0)
X if (j == MXABR || (abrvlen[i] > abrvlen[j]))
X j = i;
X return j;
X}
END_OF_FILE
if test 6197 -ne `wc -c <'maketd/abrv.c'`; then
echo shar: \"'maketd/abrv.c'\" unpacked with wrong size!
fi
# end of 'maketd/abrv.c'
fi
if test -f 'src/emitcf.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/emitcf.c'\"
else
echo shar: Extracting \"'src/emitcf.c'\" \(7227 characters\)
sed "s/^X//" >'src/emitcf.c' <<'END_OF_FILE'
X/* $Header: /usr/src/local/etc/ease/RCS/emitcf.c,v 1.3 85/11/22 20:14:11 jss Exp $ */
X
X/*
X * emitcf.c -- This file contains routines associated with the writing
X * and formatting of a translated sendmail configuration file.
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
X#define REGLINE 60 /* length of output lines which may be continued */
X#define MAXLINE 256 /* liberal maximum line length */
X
Xextern short Rformat; /* read-format flag for a class */
Xextern char *MacScan ();
Xextern char MakeMac ();
Xextern void PrintError (),
X FatalError (),
X PrintWarning (),
X ErrorReport ();
X
Xvoid PrintDef ();
X
Xstatic char ClassCH; /* printable class macro char */
X
X/*
X * EmitDef () -- Emit a definition line (Ease block definition) in cf
X * format.
X *
X */
Xvoid
XEmitDef (blockdef, targ, defstr1, defstr2)
Xregister enum bdefs blockdef; /* type of definition */
Xregister struct he *targ; /* target to be defined */
Xchar *defstr1, *defstr2; /* one or two definition strings */
X{
X /*
X * This routine is about as pretty as a translated ease file...
X * Each type of line (Ease block) is handled case by case below.
X *
X */
X switch (blockdef) {
X case def_macro: printf ("D%c", MakeMac (targ, ID_MACRO));
X PrintDef (def_macro, MacScan (defstr1));
X if (ISMACRO(targ->idd))
X PrintWarning ("Redefining macro %s.\n", targ->psb);
X targ->idd |= ID_MACRO; /* signal definition */
X break;
X
X case def_class: if (Rformat) /* read format */
X printf ("F");
X else
X printf ("C");
X printf ("%c", ClassCH = MakeMac (targ, ID_CLASS));
X if (Rformat) { /* read format */
X printf ("%s\n", defstr1);
X Rformat = FALSE;
X } else
X PrintDef (def_class, defstr1);
X if (ISCLASS(targ->idd))
X PrintWarning ("Redefining class %s.\n", targ->psb);
X targ->idd |= ID_CLASS; /* signal definition */
X break;
X
X case def_option: printf ("O%c", *defstr1);
X PrintDef (def_option, defstr2);
X break;
X
X case def_prec: printf ("P%s=%d\n", targ->psb, targ->idval.prec);
X break;
X
X case def_trusted: printf ("T");
X PrintDef (def_trusted, defstr1);
X break;
X
X case def_header: printf ("H");
X if (defstr1 != NULL)
X printf ("?%s?", defstr1);
X PrintDef (def_header, defstr2);
X break;
X
X case def_mailer: if (ISMAILER(targ->idtype)) {
X if (ISMAILER(targ->idd))
X PrintWarning ("Redefining mailer %s.\n", targ->psb);
X } else if (ISTYPED(targ->idtype)) {
X PrintError ("Redeclaration of identifier as mailer:", targ->psb);
X return;
X }
X targ->idd |= ID_MAILER; /* signal definition */
X printf ("M%s, ", targ->psb);
X PrintDef (def_mailer, defstr1);
X break;
X
X case def_ruleset: printf ("R");
X PrintDef (def_ruleset, defstr1);
X break;
X
X default: FatalError ("Bad case in EmitDef ()", (char *) NULL);
X }
X}
X
X
X/*
X * PrintContinued () -- Print a line definition (buf) by splitting it over
X * more than one line. The two definition types
X * accepted for this method of continuation are class
X * and trusted user lists, indicated in the argument
X * btype
X *
X */
Xvoid
XPrintContinued (btype, buf)
Xenum bdefs btype; /* block (line) type for definition */
Xregister char *buf; /* buffer containing the definition */
X{
X register char *tmp; /* breakpoint search pointer */
X register char tc; /* temporary swap byte */
X int buflen; /* length of definition buffer */
X
X buflen = strlen (buf);
X tmp = buf + REGLINE;
X while ((*--tmp != ' ') && (tmp != buf)) /* look for suitable break */
X /* null */ ;
X if (tmp == buf) {
X for (tmp = buf + REGLINE; (*tmp != ' ') && (tmp - buf != buflen); tmp++)
X /* null */ ;
X if ((tmp - buf) >= MAXLINE)
X PrintWarning ("Member name may be too long.\n", (char *) NULL);
X }
X tc = *tmp; /* swap break char with null char */
X *tmp = '\0';
X printf ("%s\n", buf);
X if ((*tmp = tc) == '\0')
X return;
X else
X tmp++;
X if (btype == def_class) /* start next line */
X printf ("C%c", ClassCH);
X else
X printf ("T");
X if (strlen (tmp) < REGLINE) /* continue the line */
X printf ("%s\n", tmp);
X else
X PrintContinued (btype, tmp);
X}
X
X
X/*
X * PrintDef () -- Handles special cases (like line continuation) when
X * printing definitions.
X *
X */
Xvoid
XPrintDef (btype, dstr)
Xregister enum bdefs btype; /* block type (output line type) */
Xregister char *dstr; /* definition string */
X{
X register char *tmp;
X
X for (tmp = dstr; *tmp != '\0'; tmp++) /* search for line continuations */
X if ((*tmp == '\\') && (*++tmp == '\n'))
X if (btype != def_header) {
X ErrorReport ("Non-header string contains line continuation\n");
X return;
X } else
X break;
X
X /*
X * Perform case by case handling of definition printing.
X *
X */
X switch (btype) {
X case def_header : if (*tmp-- == '\n') {
X *tmp = '\0';
X if (tmp - dstr >= MAXLINE)
X PrintWarning ("Header may be too long.\n",
X (char *) NULL);
X printf ("%s\n\t", dstr);
X tmp += 2;
X PrintDef (def_header, tmp);
X } else {
X if (strlen (dstr) >= MAXLINE)
X PrintWarning ("Header may be too long.\n",
X (char *) NULL);
X printf ("%s\n", dstr);
X }
X break;
X
X case def_mailer : if (strlen (dstr) >= MAXLINE)
X PrintWarning ("Mailer definition may be too long.\n",
X (char *) NULL);
X printf ("%s\n", dstr);
X break;
X
X case def_ruleset: if (strlen (dstr) >= MAXLINE)
X PrintWarning ("Rewriting rule may be too long.\n",
X (char *) NULL);
X printf ("%s\n", dstr);
X break;
X
X case def_option : if (strlen (dstr) >= MAXLINE)
X PrintWarning ("Option assignment may be too long.\n",
X (char *) NULL);
X printf ("%s\n", dstr);
X break;
X
X case def_macro : if (strlen (dstr) >= MAXLINE)
X PrintWarning ("Macro assignment may be too long.\n",
X (char *) NULL);
X printf ("%s\n", dstr);
X break;
X
X case def_prec : if (strlen (dstr) >= MAXLINE)
X PrintWarning ("Precedence relation may be too long.\n",
X (char *) NULL);
X printf ("%s\n", dstr);
X break;
X
X case def_trusted:
X case def_class : if (strlen (dstr) < REGLINE)
X printf ("%s\n", dstr);
X else /* use line continuation feature */
X PrintContinued (btype, dstr);
X break;
X
X default : FatalError ("Invalid case in PrintDef ()", (char *) NULL);
X }
X}
X
X
X/*
X * StartRuleset () -- Prints a ruleset heading for the ruleset identifier
X * contained in the argument rsid.
X *
X */
Xvoid
XStartRuleset (rsid)
Xregister struct he *rsid; /* ruleset identifier */
X{
X if (!ISRULESET(rsid->idtype))
X if (ISTYPED(rsid->idtype))
X PrintError ("Identifier not of ruleset type:", rsid->psb);
X else
X PrintError ("Ruleset identifier not bound to a number:", rsid->psb);
X else {
X if (ISRULESET(rsid->idd))
X PrintWarning ("Redefining ruleset %s.\n", rsid->psb);
X rsid->idd |= ID_RULESET;
X printf ("S%s\n", rsid->idval.rsn);
X }
X}
END_OF_FILE
if test 7227 -ne `wc -c <'src/emitcf.c'`; then
echo shar: \"'src/emitcf.c'\" unpacked with wrong size!
fi
# end of 'src/emitcf.c'
fi
if test -f 'src/parser.y' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/parser.y'\"
else
echo shar: Extracting \"'src/parser.y'\" \(14482 characters\)
sed "s/^X//" >'src/parser.y' <<'END_OF_FILE'
X%{
X/* $Header: /usr/src/local/etc/ease/RCS/parser.y,v 1.3 85/12/10 18:02:11 jss Exp $ */
X
X/*
X * parser.y -- EASE parser.
X *
X * Contains code for yacc(1) which produces a parser (y.tab.c)
X * for Ease, a specification format for sendmail configuration
X * files.
X *
X * author -- James S. Schoner, Purdue University Computing Center,
X * West Lafayette, Indiana 47907
X *
X * date -- July 2, 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
Xextern void BindID ();
Xextern void EmitDef ();
Xextern char *ListAppend ();
Xextern char *MakeCond ();
Xextern char *MakeRStr ();
Xextern char *ConvOpt ();
Xextern char *ConvFlg ();
Xextern char *MacScan ();
Xextern char *ConvMat ();
Xextern void StartRuleset ();
Xextern char *MakePosTok ();
Xextern char *GetField ();
Xextern char *Bracket ();
Xextern char *MakeRSCall ();
Xextern char *CheckMailer ();
Xextern char *CheckRS ();
Xextern char *MakeField ();
Xextern char MakeMac ();
Xextern void AssignType ();
Xextern void RemoveSymbol ();
Xextern void yyerror ();
X
Xextern short RMatch; /* ruleset match flag */
X
Xchar *Cbuf = " "; /* character buffer */
Xchar *Mbuf = "$ "; /* macro buffer */
Xchar *Tsb; /* pointer to temporary string buffer */
Xchar *Flaglist; /* pointer to header flag list */
X
X%}
X
X%union { /* value stack element type */
X int ival; /* integer token */
X char *psb; /* string token */
X struct he *phe; /* pointer to hash entry */
X enum opts optval; /* sendmail options */
X enum flgs flgval; /* mailer flags */
X enum mats mpval; /* mailer attribute parameters */
X}
X
X%start config
X
X%token <phe> IDENT
X%token <psb> SCONST
X%token <ival> ICONST SEPCHAR
X%token BIND MACRO CLASS OPTIONS PRECEDENCE TRUSTED HEADER RULESET MAILER
X%token IF RETRY NEXT RETURN RESOLVE CONCAT IFSET FOR CANON READCLASS
X%token MPATH MFLAGS MSENDER MRECIPIENT MARGV MEOL MMAXSIZE
X%token AAOPT AOPT BBOPT COPT DOPT DOPTI DOPTB DOPTQ DDOPT EOPT EOPTP EOPTE
X%token EOPTM EOPTW EOPTZ FFOPT FOPT GOPT HHOPT IOPT LLOPT MOPT NNOPT OOPT QQOPT
X%token ROPT SSOPT SOPT TTOPT TOPT UOPT VOPT WWOPT XOPT XXOPT
X%token FFLAG RFLAG SSFLAG NFLAG LFLAG SFLAG MFLAG FFFLAG DDFLAG MMFLAG XFLAG
X%token PPFLAG UFLAG HFLAG AAFLAG UUFLAG EFLAG XXFLAG LLFLAG PFLAG IIFLAG CCFLAG
X%token ASGN COMMA LBRACE RBRACE LPAREN RPAREN SEMI DOLLAR MATCH IN HOSTNUM
X%token DEFINE FIELD COLON STAR HOST USER
X
X%type <psb> mval strval ifcon conval ifres elseres nameset namelist
X%type <psb> doptid eoptid idlist fcond dlist mflags route mdefs
X%type <psb> matchaddr matchtok action actionstmt mailerspec mtdef
X%type <psb> rwaddr rwtok ftype reftok rword cantok resolution
X%type <psb> userspec hword hostid dheader
X%type <ival> anychar
X%type <phe> cdef
X%type <optval> optid
X%type <flgval> flagid
X%type <mpval> mvar
X
X%left COMMA
X%left LPAREN RPAREN
X%nonassoc SCONST
X
X%%
Xconfig : /* empty */
X | config blockdef
X | error blockdef
X ;
X
Xblockdef : BIND bindings
X | MACRO macdefs
X | CLASS classdefs
X | OPTIONS optdefs
X | PRECEDENCE precdefs
X | TRUSTED tlist
X | HEADER hdefs
X | MAILER mlist
X | RULESET rdef
X | FIELD fdefs
X ;
X
Xbindings : /* empty */
X | bindings IDENT ASGN RULESET ICONST SEMI {
X BindID ($2, $5, ID_RULESET);
X }
X | error SEMI {
X yyerrok;
X }
X ;
X
Xmacdefs : /* empty */
X | macdefs IDENT ASGN mval SEMI {
X EmitDef (def_macro, $2, $4, (char *) NULL);
X }
X | error SEMI {
X yyerrok;
X }
X ;
X
Xmval : strval %prec COMMA {
X $$ = $1;
X }
X | CONCAT LPAREN conval RPAREN {
X $$ = $3;
X }
X ;
X
Xstrval : SCONST {
X $$ = $1;
X }
X | strval SCONST {
X $$ = ListAppend ($1, $2, (char *) NULL);
X free ($1);
X }
X ;
X
Xconval : strval COMMA ifcon {
X $$ = ListAppend ($1, $3, (char *) NULL);
X free ($1);
X free ($3);
X }
X | ifcon COMMA strval {
X $$ = ListAppend ($1, $3, (char *) NULL);
X free ($1);
X free ($3);
X }
X | error {
X $$ = NULL;
X }
X ;
X
Xifcon : IFSET LPAREN IDENT COMMA ifres RPAREN {
X $$ = MakeCond ($3, $5);
X }
X ;
X
Xifres : mval elseres {
X if ($2 != NULL) {
X $$ = ListAppend ($1, $2, "$|");
X free ($1);
X free ($2);
X } else
X $$ = $1;
X }
X | error {
X $$ = NULL;
X }
X ;
X
Xelseres : /* empty */ {
X $$ = NULL;
X }
X | COMMA mval {
X $$ = $2;
X }
X ;
X
Xclassdefs : /* empty */
X | classdefs IDENT ASGN nameset {
X EmitDef (def_class, $2, $4, (char *) NULL);
X }
X | error
X ;
X
Xnameset : LBRACE namelist RBRACE SEMI {
X $$ = $2;
X }
X | LBRACE RBRACE SEMI {
X $$ = NULL;
X }
X | LBRACE error RBRACE SEMI {
X $$ = NULL;
X }
X | READCLASS LPAREN strval RPAREN SEMI {
X $$ = MakeRStr ($3, (char *) NULL);
X }
X | READCLASS LPAREN strval COMMA strval RPAREN SEMI {
X $$ = MakeRStr ($3, $5);
X }
X | READCLASS LPAREN error RPAREN SEMI {
X $$ = NULL;
X }
X | error SEMI {
X $$ = NULL;
X yyerrok;
X }
X ;
X
Xnamelist : IDENT {
X $$ = ListAppend ($1->psb, (char *) NULL, (char *) NULL);
X RemoveSymbol ($1);
X }
X | strval {
X $$ = $1;
X }
X | namelist COMMA IDENT {
X $$ = ListAppend ($1, $3->psb, " ");
X free ($1);
X RemoveSymbol ($3);
X }
X | namelist COMMA strval {
X $$ = ListAppend ($1, $3, " ");
X free ($1);
X free ($3);
X }
X ;
X
Xoptdefs : /* empty */
X | optdefs optid ASGN strval SEMI {
X EmitDef (def_option, (struct he *) NULL, ConvOpt ($2), $4);
X }
X | optdefs DOPT ASGN doptid SEMI {
X EmitDef (def_option, (struct he *) NULL, ConvOpt (opt_d), $4);
X }
X | optdefs EOPT ASGN eoptid SEMI {
X EmitDef (def_option, (struct he *) NULL, ConvOpt (opt_e), $4);
X }
X | error SEMI {
X yyerrok;
X }
X ;
X
Xoptid : AAOPT {
X $$ = opt_A;
X }
X | AOPT {
X $$ = opt_a;
X }
X | BBOPT {
X $$ = opt_B;
X }
X | COPT {
X $$ = opt_c;
X }
X | DDOPT {
X $$ = opt_D;
X }
X | FFOPT {
X $$ = opt_F;
X }
X | FOPT {
X $$ = opt_f;
X }
X | GOPT {
X $$ = opt_g;
X }
X | HHOPT {
X $$ = opt_H;
X }
X | IOPT {
X $$ = opt_i;
X }
X | LLOPT {
X $$ = opt_L;
X }
X | MOPT {
X $$ = opt_m;
X }
X | NNOPT {
X $$ = opt_N;
X }
X | OOPT {
X $$ = opt_o;
X }
X | QQOPT {
X $$ = opt_Q;
X }
X | ROPT {
X $$ = opt_r;
X }
X | SSOPT {
X $$ = opt_S;
X }
X | SOPT {
X $$ = opt_s;
X }
X | TTOPT {
X $$ = opt_T;
X }
X | TOPT {
X $$ = opt_t;
X }
X | UOPT {
X $$ = opt_u;
X }
X | VOPT {
X $$ = opt_v;
X }
X | WWOPT {
X $$ = opt_W;
X }
X | XOPT {
X $$ = opt_x;
X }
X | XXOPT {
X $$ = opt_X;
X }
X ;
X
Xdoptid : DOPTI {
X $$ = ConvOpt (d_opt_i);
X }
X | DOPTB {
X $$ = ConvOpt (d_opt_b);
X }
X | DOPTQ {
X $$ = ConvOpt (d_opt_q);
X }
X ;
X
Xeoptid : EOPTP {
X $$ = ConvOpt (e_opt_p);
X }
X | EOPTE {
X $$ = ConvOpt (e_opt_e);
X }
X | EOPTM {
X $$ = ConvOpt (e_opt_m);
X }
X | EOPTW {
X $$ = ConvOpt (e_opt_w);
X }
X | EOPTZ {
X $$ = ConvOpt (e_opt_z);
X }
X ;
X
Xprecdefs : /* empty */
X | precdefs IDENT ASGN ICONST SEMI {
X BindID ($2, $4, ID_PREC);
X EmitDef (def_prec, $2, (char *) NULL, (char *) NULL);
X }
X ;
X
Xtlist : /* empty */
X | tlist LBRACE IDENT idlist RBRACE SEMI {
X EmitDef (def_trusted, (struct he *) NULL,
X ListAppend ($3->psb, $4, " "), (char *) NULL);
X free ($4);
X RemoveSymbol ($3);
X }
X | tlist LBRACE RBRACE SEMI
X | error SEMI {
X yyerrok;
X }
X ;
X
Xhdefs : /* empty */
X | hdefs FOR fcond dheader SEMI {
X EmitDef (def_header, (struct he *) NULL, $3, $4);
X }
X | hdefs FOR fcond LBRACE { Flaglist = $3; }
X dheaders RBRACE SEMI
X | hdefs DEFINE dlist SEMI {
X EmitDef (def_header, (struct he *) NULL, (char *) NULL, $3);
X }
X | error SEMI {
X yyerrok;
X }
X ;
X
Xfcond : LPAREN RPAREN {
X $$ = NULL;
X }
X | LPAREN mflags RPAREN {
X $$ = $2;
X }
X | LPAREN error RPAREN {
X $$ = NULL;
X }
X ;
X
Xmflags : flagid {
X $$ = ListAppend (ConvFlg ($1), (char *) NULL, (char *) NULL);
X }
X | mflags COMMA flagid {
X $$ = ListAppend ($1, ConvFlg($3), (char *) NULL);
X free ($1);
X }
X ;
X
Xflagid : FFLAG {
X $$ = flg_f;
X }
X | RFLAG {
X $$ = flg_r;
X }
X | SSFLAG {
X $$ = flg_S;
X }
X | NFLAG {
X $$ = flg_n;
X }
X | LFLAG {
X $$ = flg_l;
X }
X | SFLAG {
X $$ = flg_s;
X }
X | MFLAG {
X $$ = flg_m;
X }
X | FFFLAG {
X $$ = flg_F;
X }
X | DDFLAG {
X $$ = flg_D;
X }
X | MMFLAG {
X $$ = flg_M;
X }
X | XFLAG {
X $$ = flg_x;
X }
X | PPFLAG {
X $$ = flg_P;
X }
X | UFLAG {
X $$ = flg_u;
X }
X | HFLAG {
X $$ = flg_h;
X }
X | AAFLAG {
X $$ = flg_A;
X }
X | UUFLAG {
X $$ = flg_U;
X }
X | EFLAG {
X $$ = flg_e;
X }
X | XXFLAG {
X $$ = flg_X;
X }
X | LLFLAG {
X $$ = flg_L;
X }
X | PFLAG {
X $$ = flg_p;
X }
X | IIFLAG {
X $$ = flg_I;
X }
X | CCFLAG {
X $$ = flg_C;
X }
X ;
X
Xdheader : /* empty */ {
X $$ = NULL;
X }
X | DEFINE dlist {
X $$ = $2;
X }
X | error {
X $$ = NULL;
X }
X ;
X
Xdheaders : /* empty */
X | dheaders DEFINE dlist SEMI {
X EmitDef (def_header, (struct he *) NULL, Flaglist, $3);
X }
X | error
X ;
X
Xdlist : LPAREN strval COMMA mval RPAREN {
X $$ = ListAppend ($2, MacScan ($4), " ");
X free ($2);
X free ($4);
X }
X | LPAREN error RPAREN {
X $$ = NULL;
X }
X ;
X
Xmlist : /* empty */
X | mlist IDENT LBRACE mdefs RBRACE SEMI {
X EmitDef (def_mailer, $2, $4, (char *) NULL);
X }
X | mlist IDENT LBRACE RBRACE SEMI {
X EmitDef (def_mailer, $2, (char *) NULL, (char *) NULL);
X }
X | error SEMI {
X yyerrok;
X }
X ;
X
Xmdefs : mtdef {
X $$ = $1;
X }
X | mdefs COMMA mtdef {
X $$ = ListAppend ($1, $3, ", ");
X free ($1);
X free ($3);
X }
X ;
X
Xmtdef : mvar ASGN mval {
X $$ = ListAppend (ConvMat ($1), MacScan ($3), "=");
X free ($3);
X }
X | MFLAGS ASGN LBRACE mflags RBRACE {
X $$ = ListAppend (ConvMat (mat_flags), $4, "=");
X }
X | MSENDER ASGN IDENT {
X $$ = ListAppend (ConvMat (mat_sender), CheckRS ($3), "=");
X }
X | MRECIPIENT ASGN IDENT {
X $$ = ListAppend (ConvMat (mat_recipient), CheckRS ($3), "=");
X }
X | error {
X $$ = NULL;
X }
X ;
X
Xmvar : MPATH {
X $$ = mat_path;
X }
X | MARGV {
X $$ = mat_argv;
X }
X | MEOL {
X $$ = mat_eol;
X }
X | MMAXSIZE {
X $$ = mat_maxsize;
X }
X ;
X
Xrdef : /* empty */
X | rdef IDENT { StartRuleset ($2); } rulelist
X ;
X
Xrulelist : LBRACE ruledefs RBRACE {
X RMatch = FALSE;
X }
X | error {
X RMatch = FALSE;
X }
X ;
X
Xruledefs : /* empty */ {
X RMatch = TRUE;
X }
X | ruledefs IF LPAREN matchaddr RPAREN actionstmt {
X EmitDef (def_ruleset, (struct he *) NULL,
X ListAppend ($4, $6, "\t"), (char *) NULL);
X free ($4);
X free ($6);
X }
X | error SEMI {
X yyerrok;
X }
X ;
X
Xmatchaddr : /* empty */ {
X $$ = NULL;
X }
X | matchaddr matchtok {
X $$ = ListAppend ($1, $2, (char *) NULL);
X free ($1);
X }
X | error {
X $$ = NULL;
X }
X ;
X
Xmatchtok : IDENT {
X $$ = GetField ($1);
X }
X | anychar {
X *Cbuf = $1;
X $$ = ListAppend (Cbuf, (char *) NULL, (char *) NULL);
X }
X | mval {
X $$ = MacScan ($1);
X }
X | DOLLAR IDENT {
X Mbuf[1] = MakeMac ($2, ID_MACRO);
X $$ = ListAppend (Mbuf, (char *) NULL, (char *) NULL);
X }
X ;
X
Xactionstmt : action LPAREN rwaddr RPAREN SEMI {
X $$ = ListAppend ($1, $3, (char *) NULL);
X free ($3);
X }
X | RESOLVE LPAREN resolution RPAREN SEMI {
X $$ = $3;
X }
X | error SEMI {
X $$ = NULL;
X yyerrok;
X }
X ;
X
Xaction : RETRY {
X $$ = NULL;
X }
X | NEXT {
X $$ = "$:";
X }
X | RETURN {
X $$ = "$@";
X }
X ;
X
Xrwaddr : /* empty */ {
X $$ = NULL;
X }
X | rwaddr rwtok {
X $$ = ListAppend ($1, $2, (char *) NULL);
X free ($1);
X }
X | rwaddr IDENT LPAREN rwaddr RPAREN {
X $$ = ListAppend ($1, (Tsb = MakeRSCall ($2, $4)), (char *) NULL);
X free ($1);
X free ($4);
X free (Tsb);
X }
X | error {
X $$ = NULL;
X }
X ;
X
Xrwtok : anychar {
X *Cbuf = $1;
X $$ = ListAppend (Cbuf, (char *) NULL, (char *) NULL);
X }
X | mval {
X $$ = MacScan ($1);
X }
X | cantok {
X $$ = $1;
X }
X | reftok {
X $$ = $1;
X }
X ;
X
Xcantok : CANON LPAREN IDENT RPAREN {
X $$ = Bracket ($3->psb, TRUE);
X RemoveSymbol ($3);
X }
X | CANON LPAREN SCONST RPAREN {
X $$ = Bracket (MacScan ($3), TRUE);
X free ($3);
X }
X | CANON LPAREN reftok RPAREN {
X $$ = Bracket ($3, TRUE);
X free ($3);
X }
X ;
X
Xreftok : DOLLAR IDENT {
X Mbuf[1] = MakeMac ($2, ID_MACRO);
X $$ = ListAppend (Mbuf, (char *) NULL, (char *) NULL);
X }
X | DOLLAR ICONST {
X $$ = ListAppend (MakePosTok ($2), (char *) NULL, (char *) NULL);
X }
X ;
X
Xanychar : SEPCHAR {
X $$ = $1;
X }
X | COLON {
X $$ = ':';
X }
X | STAR {
X $$ = '*';
X }
X | SEMI {
X $$ = ';';
X }
X | LBRACE {
X $$ = '{';
X }
X | RBRACE {
X $$ = '}';
X }
X | COMMA {
X $$ = ',';
X }
X | ASGN {
X $$ = '=';
X }
X ;
X
Xresolution : mailerspec COMMA route {
X $$ = ListAppend ($1, $3, (char *) NULL);
X free ($1);
X free ($3);
X }
X | error {
X $$ = NULL;
X }
X ;
X
Xmailerspec : MAILER LPAREN rword RPAREN {
X $$ = ListAppend ("$#", $3, (char *) NULL);
X }
X ;
X
Xroute : HOST LPAREN hword RPAREN COMMA userspec {
X $$ = ListAppend (Tsb = ListAppend ("$@", $3, (char *) NULL),
X $6, (char *) NULL);
X free (Tsb);
X free ($6);
X }
X | userspec {
X $$ = $1;
X }
X ;
X
Xhword : hostid {
X $$ = $1;
X }
X | HOSTNUM LPAREN reftok RPAREN {
X $$ = Bracket ($3, FALSE);
X free ($3);
X }
X ;
X
Xhostid : /* empty */ {
X $$ = NULL;
X }
X | hostid IDENT {
X $$ = ListAppend ($1, $2->psb, (char *) NULL);
X RemoveSymbol ($2);
X free ($1);
X }
X | hostid rwtok {
X $$ = ListAppend ($1, $2, (char *) NULL);
X free ($1);
X }
X ;
X
Xuserspec : USER LPAREN rwaddr RPAREN {
X $$ = ListAppend ("$:", $3, (char *) NULL);
X free ($3);
X }
X ;
X
Xrword : IDENT {
X $$ = CheckMailer ($1);
X }
X | reftok {
X $$ = $1;
X }
X ;
X
Xfdefs : /* empty */
X | fdefs IDENT idlist COLON ftype SEMI {
X AssignType (ListAppend ($2->psb, $3, " "), $5);
X free ($3);
X }
X | error SEMI {
X yyerrok;
X }
X ;
X
Xidlist : /* empty */ {
X $$ = NULL;
X }
X | idlist COMMA IDENT {
X $$ = ListAppend ($1, $3->psb, " ");
X free ($1);
X }
X ;
X
Xftype : MATCH LPAREN ICONST RPAREN cdef {
X $$ = ListAppend (MakeField ($3, $5, FALSE),
X (char *) NULL, (char *) NULL);
X }
X | MATCH LPAREN ICONST STAR RPAREN {
X $$ = ListAppend (MakeField ($3, (struct he *) NULL, TRUE),
X (char *) NULL, (char *) NULL);
X }
X | error {
X $$ = NULL;
X }
X ;
X
Xcdef : /* empty */ {
X $$ = NULL;
X }
X | IN IDENT {
X $$ = $2;
X }
X ;
END_OF_FILE
if test 14482 -ne `wc -c <'src/parser.y'`; then
echo shar: \"'src/parser.y'\" unpacked with wrong size!
fi
# end of 'src/parser.y'
fi
if test -f 'src/strops.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/strops.c'\"
else
echo shar: Extracting \"'src/strops.c'\" \(10730 characters\)
sed "s/^X//" >'src/strops.c' <<'END_OF_FILE'
X/* $Header: /usr/src/local/etc/ease/RCS/strops.c,v 1.2 85/10/29 23:45:39 jss Exp $ */
X
X/*
X * strops.c -- Contains string operation routines used for constructing
X * definitions in cf format.
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 <strings.h>
X#include "symtab.h"
X
X#define MAXTOKPOS 99 /* maximum number of token positions */
X#define MAXNAME 1024 /* maximum length of an identifier */
X
Xextern struct he *LookupSymbol ();
Xextern char MakeMac ();
Xextern void FatalError (),
X PrintError (),
X ErrorReport ();
X
Xshort Rformat = FALSE; /* class read format flag */
Xstatic char *Ptok = "$ "; /* positional token structure */
Xstatic char *Cfield = "$= "; /* class reference structure */
Xstatic char *Ofield = "$-"; /* one token match structure */
Xstatic char *Zfield = "$*"; /* zero or more tokens structure */
Xstatic char *Pfield = "$+"; /* one or more tokens structure */
Xstatic char *Mtest = "$? "; /* conditional macro test string */
X
X
X/*
X * ConvOpt () -- Convert an Ease option identifier (optid) by returning a
X * string representation of the cf format.
X *
X */
Xchar *
XConvOpt (optid)
Xregister enum opts optid;
X{
X switch (optid) {
X case opt_A : return ("A");
X case opt_a : return ("a");
X case opt_B : return ("B");
X case d_opt_b: return ("b");
X case opt_c : return ("c");
X case opt_D : return ("D");
X case opt_d : return ("d");
X case opt_e :
X case e_opt_e: return ("e");
X case opt_F : return ("F");
X case opt_f : return ("f");
X case opt_g : return ("g");
X case opt_H : return ("H");
X case opt_i :
X case d_opt_i: return ("i");
X case opt_L : return ("L");
X case opt_m :
X case e_opt_m: return ("m");
X case opt_N : return ("N");
X case opt_o : return ("o");
X case e_opt_p: return ("p");
X case opt_Q : return ("Q");
X case d_opt_q: return ("q");
X case opt_r : return ("r");
X case opt_S : return ("S");
X case opt_s : return ("s");
X case opt_T : return ("T");
X case opt_t : return ("t");
X case opt_u : return ("u");
X case opt_v : return ("v");
X case opt_W : return ("W");
X case e_opt_w: return ("w");
X case opt_x : return ("x");
X case opt_X : return ("X");
X case e_opt_z: return ("z");
X default : FatalError ("Bad case in ConvOpt ()", (char *) NULL);
X }
X /*NOTREACHED*/
X}
X
X
X/*
X * ConvFlg () -- Convert an Ease mailer flag identifier (flgid) by
X * string representation of the cf format.
X *
X */
Xchar *
XConvFlg (flgid)
Xregister enum flgs flgid; /* flag identifier */
X{
X switch (flgid) {
X case flg_f: return ("f");
X case flg_r: return ("r");
X case flg_S: return ("S");
X case flg_n: return ("n");
X case flg_l: return ("l");
X case flg_s: return ("s");
X case flg_m: return ("m");
X case flg_F: return ("F");
X case flg_D: return ("D");
X case flg_M: return ("M");
X case flg_x: return ("x");
X case flg_P: return ("P");
X case flg_u: return ("u");
X case flg_h: return ("h");
X case flg_A: return ("A");
X case flg_U: return ("U");
X case flg_e: return ("e");
X case flg_X: return ("X");
X case flg_L: return ("L");
X case flg_p: return ("p");
X case flg_I: return ("I");
X case flg_C: return ("C");
X default : FatalError ("Bad case in ConvFlg ()", (char *) NULL);
X }
X /*NOTREACHED*/
X}
X
X
X/*
X * ConvMat () -- Convert an Ease mailer attribute (mat) by returning a
X * string representation of the cf format.
X *
X */
Xchar *
XConvMat (mat)
Xregister enum mats mat; /* mailer attribute flag */
X{
X switch (mat) {
X case mat_path : return ("P");
X case mat_flags : return ("F");
X case mat_sender : return ("S");
X case mat_recipient : return ("R");
X case mat_argv : return ("A");
X case mat_eol : return ("E");
X case mat_maxsize : return ("M");
X default : FatalError ("Bad case in ConvMat ()", (char *) NULL);
X }
X /*NOTREACHED*/
X}
X
X
X/*
X * MacScan () -- Scan a string (pstring) for macros, replacing the Ease
X * form with the one-character form required by cf format.
X *
X */
Xchar *
XMacScan (pstring)
Xchar *pstring; /* macro expandable string */
X{
X register char *searchptr; /* string search pointer */
X register char *bptr, *eptr; /* macro begin and end pointers */
X char macname [MAXNAME]; /* macro name buffer */
X
X if ((searchptr = pstring) == NULL)
X return ((char *) NULL);
X while (*searchptr != '\0') /* find and rewrite all macros */
X if (*searchptr == '\\') {
X searchptr = searchptr + 2;
X continue;
X } else if (*searchptr++ == '$' && *searchptr == '{') {
X if (sscanf (searchptr + 1, "%[^}]", macname) != 1) {
X PrintError ("Invalid macro format:", searchptr + 1);
X return ((char *) NULL);
X }
X *searchptr++ = MakeMac (LookupSymbol (macname), ID_MACRO);
X bptr = eptr = searchptr;
X while (*eptr++ != '}') /* delete old macro chars */
X /* empty */ ;
X do
X *bptr++ = *eptr;
X while (*eptr++ != '\0');
X }
X return (pstring);
X}
X
X
X/*
X * MakeRStr () -- Construct and return a pointer to a class read string
X * using the filename fname and read format rformat.
X *
X */
Xchar *
XMakeRStr (fname, rformat)
Xchar *fname, /* file name for class read */
X *rformat; /* format for class read */
X{
X register char *res; /* resultant read string */
X
X Rformat = TRUE; /* set read format flag */
X if (rformat == NULL)
X return (fname);
X res = (char *) realloc (fname, strlen (fname) + strlen (rformat) + 2);
X if (res == NULL)
X FatalError ("System out of string space in MakeRStr ()", (char *) NULL);
X res = strcat (res, " "); /* construct read string */
X res = strcat (res, rformat);
X free (rformat);
X return (res);
X}
X
X
X/*
X * ListAppend () -- Append string list2 to string list1 using the
X * separator sep. A pointer to the newly constructed
X * string is returned.
X *
X */
Xchar *
XListAppend (list1, list2, sep)
Xchar *list1, /* first string */
X *list2, /* second string */
X *sep; /* string separator */
X{
X register char *res; /* resultant string */
X
X res = (char *) malloc (strlen (list1) + strlen (list2) + strlen (sep) + 1);
X if (res == NULL)
X FatalError ("System out of string space in ListAppend ()", (char *) NULL);
X res = strcpy (res, list1);
X if (list1 != NULL) /* use separator if first string not null */
X res = strcat (res, sep);
X res = strcat (res, list2);
X return (res);
X}
X
X
X/*
X * MakeCond () -- Construct a macro conditional string in cf format. The
X * conditional is based on the macro testmac, with an "if
X * set" result ifstring, which may contain an optional
X * "if not set" result string appended to it.
X *
X */
Xchar *
XMakeCond (testmac, ifstring)
Xstruct he *testmac; /* macro for conditional testing */
Xchar *ifstring; /* "if macro set" result string(s) */
X{
X register char *res; /* resultant conditional string */
X
X Mtest[2] = MakeMac (testmac, ID_MACRO); /* get one-char macro rep */
X res = (char *) malloc (strlen (ifstring) + 6);
X if (res == NULL)
X FatalError ("System out of string space in MakeCond ()", (char *) NULL);
X res = strcpy (res, Mtest);
X res = strcat (res, ifstring); /* build result part */
X res = strcat (res, "$."); /* end of conditional */
X free (ifstring);
X return (res);
X}
X
X
X/*
X * MakePosTok () -- Construct and return a positional token string
X * representation from the parameter num.
X *
X */
Xchar *
XMakePosTok (num)
Xregister int num; /* numerical value of positional token */
X{
X if (num > MAXTOKPOS) {
X ErrorReport ("Positional token too large.\n");
X return ((char *) NULL);
X } else {
X if (num > 9) { /* two-digit positional token */
X Ptok[1] = '0' + (num / 10);
X Ptok[2] = '0' + (num % 10);
X Ptok[3] = '\0';
X } else {
X Ptok[1] = '0' + num;
X Ptok[2] = '\0';
X }
X return (Ptok);
X }
X}
X
X
X/*
X * Bracket () -- Construct and return a cf string form of the
X * canonicalization of the string identifier passed in
X * the string parameter psb if dflag is true, else
X * simply bracket the identifier without dollar signs
X * for numeric hostname specifications.
X *
X */
Xchar *
XBracket (psb, dflag)
Xchar *psb; /* identifier to be canonicalized */
Xshort dflag; /* dollar flag */
X{
X register char *res; /* resultant cf form */
X register short extra; /* extra space needed for malloc */
X
X extra = dflag ? 5 : 3;
X res = (char *) malloc (strlen (psb) + extra);
X if (res == NULL)
X FatalError ("System out of string space in Bracket ()", (char *) NULL);
X if (dflag)
X res = strcpy (res, "$[");
X else
X res = strcpy (res, "[");
X res = strcat (res, psb);
X if (dflag)
X res = strcat (res, "$");
X res = strcat (res, "]");
X return (res);
X}
X
X
X/*
X * MakeRSCall () -- Construct and return a cf string form of a call
X * to a ruleset (cid), which would pass to it the
X * remainder of a rewriting address (rwaddr).
X *
X */
Xchar *
XMakeRSCall (cid, rwaddr)
Xregister struct he *cid; /* called ruleset identifier */
Xregister char *rwaddr; /* remainder of rewriting address */
X{
X register char *res; /* resultant cf string for the call */
X
X if (!ISRULESET(cid->idtype)) { /* check validity of ruleset */
X PrintError ("Undefined ruleset identifier:", cid->psb);
X return ((char *) NULL);
X }
X res = (char *) malloc (strlen (cid->idval.rsn) + strlen (rwaddr) + 3);
X if (res == NULL)
X FatalError ("System out of string space in MakeRSCall ()", (char *) NULL);
X res = strcpy (res, "$>"); /* construct the call string */
X res = strcat (res, cid->idval.rsn);
X res = strcat (res, rwaddr);
X return (res);
X}
X
X
X/*
X * MakeField () -- Construct and return the cf string format for a
X * field variable. The match count (count), an optional
X * class (class), and a match repetition flag (fstar)
X * are used to determine what type of field string to
X * construct.
X *
X */
Xchar *
XMakeField (count, class, fstar)
Xregister int count; /* match count (0 or 1) */
Xregister struct he *class; /* optional class type */
Xregister short fstar; /* repetition flag */
X{
X switch (count) {
X case 0: if (class == NULL) /* any token is valid */
X if (fstar)
X return (Zfield);
X else {
X ErrorReport ("Invalid field type.\n");
X return ((char *) NULL);
X }
X else { /* match 0 from class */
X Cfield[1] = '~';
X Cfield[2] = MakeMac (class, ID_CLASS);
X return (Cfield);
X }
X case 1: if (class == NULL) /* any token is valid */
X if (fstar)
X return (Pfield);
X else
X return (Ofield);
X else { /* match 1 from class */
X Cfield[1] = '=';
X Cfield[2] = MakeMac (class, ID_CLASS);
X return (Cfield);
X }
X default: ErrorReport ("Invalid field type.\n");
X }
X /*NOTREACHED*/
X}
END_OF_FILE
if test 10730 -ne `wc -c <'src/strops.c'`; then
echo shar: \"'src/strops.c'\" unpacked with wrong size!
fi
# end of 'src/strops.c'
fi
echo shar: End of archive 3 \(of 4\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 4 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
--
Rich $alz "Anger is an energy"
Cronus Project, BBN Labs rsalz@bbn.com
Moderator, comp.sources.unix sources@uunet.upoHAh