home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume8 / ease / part02 < prev    next >
Encoding:
Internet Message Format  |  1987-02-10  |  45.3 KB

  1. Subject:  v08i054:  Ease, a language for writing sendmail.cf files, Part02/04
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: ksb@j.cc.purdue.edu
  6. Mod.sources: Volume 8, Issue 54
  7. Archive-name: ease/Part02
  8.  
  9.  
  10. #    This is a shell archive.
  11. #    Remove everything above and including the cut line.
  12. #    Then run the rest of the file through sh.
  13. #----cut here-----cut here-----cut here-----cut here----#
  14. #!/bin/sh
  15. # shar:    Shell Archiver
  16. #    Run the following text with /bin/sh to create:
  17. #    src
  18. if test ! -d src
  19. then
  20. mkdir src
  21. echo "shar: part 01 is missing?"
  22. fi
  23. chdir src
  24. cat << \SHAR_EOF > emitcf.c
  25. /*    $Header: /usr/src/local/etc/ease/RCS/emitcf.c,v 1.3 85/11/22 20:14:11 jss Exp $    */
  26.  
  27. /*
  28.  *    emitcf.c  -- This file contains routines associated with the writing
  29.  *             and formatting of a translated sendmail configuration file.
  30.  *
  31.  *    author      -- James S. Schoner, Purdue University Computing Center,
  32.  *                         West Lafayette, Indiana  47907
  33.  *
  34.  *      date      -- July 9, 1985
  35.  *
  36.  *    Copyright (c) 1985 by Purdue Research Foundation
  37.  *
  38.  *    All rights reserved.
  39.  *
  40.  */
  41.  
  42. #include <stdio.h>
  43. #include "symtab.h"
  44.  
  45. #define REGLINE 60    /* length of output lines which may be continued */
  46. #define MAXLINE 256    /* liberal maximum line length             */
  47.  
  48. extern short Rformat;            /* read-format flag for a class  */
  49. extern char *MacScan ();
  50. extern char  MakeMac ();
  51. extern void  PrintError (),
  52.          FatalError (),
  53.          PrintWarning (),
  54.          ErrorReport ();
  55.  
  56. void  PrintDef ();
  57.  
  58. static char ClassCH;            /* printable class macro char    */
  59.  
  60. /*
  61.  *    EmitDef () -- Emit a definition line (Ease block definition) in cf 
  62.  *              format.
  63.  *
  64.  */
  65. void
  66. EmitDef (blockdef, targ, defstr1, defstr2)
  67. register enum bdefs blockdef;    /* type of definition        */
  68. register struct he *targ;    /* target to be defined      */
  69. char *defstr1, *defstr2;    /* one or two definition strings */
  70. {
  71.     /*
  72.      *  This routine is about as pretty as a translated ease file...
  73.      *  Each type of line (Ease block) is handled case by case below.
  74.      *
  75.      */
  76.     switch (blockdef) {
  77.         case def_macro:        printf ("D%c", MakeMac (targ, ID_MACRO));
  78.                     PrintDef (def_macro, MacScan (defstr1));
  79.                     if (ISMACRO(targ->idd))
  80.                         PrintWarning ("Redefining macro %s.\n", targ->psb);
  81.                     targ->idd |= ID_MACRO;  /* signal definition */
  82.                     break;
  83.  
  84.         case def_class:        if (Rformat)    /* read format */
  85.                         printf ("F");
  86.                     else
  87.                         printf ("C");
  88.                     printf ("%c", ClassCH = MakeMac (targ, ID_CLASS));
  89.                     if (Rformat) {    /* read format */
  90.                         printf ("%s\n", defstr1);
  91.                         Rformat = FALSE;
  92.                     } else
  93.                         PrintDef (def_class, defstr1);
  94.                     if (ISCLASS(targ->idd))
  95.                         PrintWarning ("Redefining class %s.\n", targ->psb);
  96.                     targ->idd |= ID_CLASS;  /* signal definition */
  97.                     break;
  98.  
  99.         case def_option:    printf ("O%c", *defstr1);
  100.                     PrintDef (def_option, defstr2);
  101.                     break;
  102.  
  103.         case def_prec:        printf ("P%s=%d\n", targ->psb, targ->idval.prec);
  104.                     break;
  105.  
  106.         case def_trusted:    printf ("T");
  107.                     PrintDef (def_trusted, defstr1);
  108.                     break;
  109.  
  110.         case def_header:    printf ("H");
  111.                     if (defstr1 != NULL)
  112.                         printf ("?%s?", defstr1);
  113.                     PrintDef (def_header, defstr2);
  114.                     break;
  115.  
  116.         case def_mailer:    if (ISMAILER(targ->idtype)) {
  117.                         if (ISMAILER(targ->idd))
  118.                             PrintWarning ("Redefining mailer %s.\n", targ->psb);
  119.                     } else if (ISTYPED(targ->idtype)) {
  120.                         PrintError ("Redeclaration of identifier as mailer:", targ->psb);
  121.                         return;
  122.                     }
  123.                     targ->idd |= ID_MAILER;  /* signal definition */
  124.                     printf ("M%s, ", targ->psb);
  125.                     PrintDef (def_mailer, defstr1);
  126.                     break;
  127.  
  128.         case def_ruleset:    printf ("R");
  129.                     PrintDef (def_ruleset, defstr1);
  130.                     break;
  131.  
  132.         default:        FatalError ("Bad case in EmitDef ()", (char *) NULL);
  133.     }
  134. }
  135.  
  136.  
  137. /*
  138.  *      PrintContinued () -- Print a line definition (buf) by splitting it over
  139.  *                 more than one line.  The two definition types 
  140.  *                 accepted for this method of continuation are class
  141.  *                 and trusted user lists, indicated in the argument 
  142.  *                 btype 
  143.  *
  144.  */
  145. void
  146. PrintContinued (btype, buf)
  147. enum bdefs     btype;    /* block (line) type for definition */
  148. register char *buf;    /* buffer containing the definition */
  149. {
  150.     register char *tmp;    /* breakpoint search pointer   */
  151.     register char  tc;    /* temporary swap byte         */
  152.     int  buflen;        /* length of definition buffer */    
  153.  
  154.     buflen = strlen (buf);
  155.     tmp = buf + REGLINE;
  156.     while ((*--tmp != ' ') && (tmp != buf))     /* look for suitable break */
  157.         /* null */ ;
  158.     if (tmp == buf) {
  159.         for (tmp = buf + REGLINE; (*tmp != ' ') && (tmp - buf != buflen); tmp++)
  160.             /* null */ ;
  161.         if ((tmp - buf) >= MAXLINE)
  162.             PrintWarning ("Member name may be too long.\n", (char *) NULL);
  163.     }
  164.     tc = *tmp;        /* swap break char with null char */
  165.     *tmp = '\0';
  166.     printf ("%s\n", buf);
  167.     if ((*tmp = tc) == '\0')
  168.         return;
  169.     else
  170.         tmp++;
  171.     if (btype == def_class)        /* start next line   */
  172.         printf ("C%c", ClassCH);
  173.     else
  174.         printf ("T");
  175.     if (strlen (tmp) < REGLINE)    /* continue the line */
  176.         printf ("%s\n", tmp);
  177.     else
  178.         PrintContinued (btype, tmp);
  179. }
  180.  
  181.  
  182. /*
  183.  *    PrintDef () -- Handles special cases (like line continuation) when 
  184.  *               printing definitions.
  185.  *
  186.  */
  187. void
  188. PrintDef (btype, dstr)
  189. register enum bdefs btype;    /* block type (output line type) */
  190. register char *dstr;        /* definition string         */
  191. {
  192.     register char *tmp;
  193.  
  194.     for (tmp = dstr; *tmp != '\0'; tmp++)     /* search for line continuations */
  195.         if ((*tmp == '\\') && (*++tmp == '\n'))
  196.             if (btype != def_header) {
  197.                 ErrorReport ("Non-header string contains line continuation\n");
  198.                 return;
  199.             } else
  200.                 break;
  201.  
  202.     /*
  203.      *  Perform case by case handling of definition printing.
  204.      *
  205.      */
  206.     switch (btype) {
  207.         case def_header :  if (*tmp-- == '\n') {
  208.                     *tmp = '\0';
  209.                     if (tmp - dstr >= MAXLINE)
  210.                         PrintWarning ("Header may be too long.\n", 
  211.                                   (char *) NULL);
  212.                     printf ("%s\n\t", dstr);
  213.                     tmp += 2;
  214.                         PrintDef (def_header, tmp);
  215.                    } else {
  216.                     if (strlen (dstr) >= MAXLINE)
  217.                         PrintWarning ("Header may be too long.\n", 
  218.                                   (char *) NULL);
  219.                     printf ("%s\n", dstr);
  220.                    }
  221.                    break;
  222.  
  223.         case def_mailer :  if (strlen (dstr) >= MAXLINE)
  224.                     PrintWarning ("Mailer definition may be too long.\n", 
  225.                               (char *) NULL);
  226.                    printf ("%s\n", dstr);
  227.                    break;
  228.  
  229.         case def_ruleset:  if (strlen (dstr) >= MAXLINE)
  230.                     PrintWarning ("Rewriting rule may be too long.\n", 
  231.                               (char *) NULL);
  232.                    printf ("%s\n", dstr);
  233.                    break;
  234.  
  235.         case def_option :  if (strlen (dstr) >= MAXLINE)
  236.                     PrintWarning ("Option assignment may be too long.\n", 
  237.                               (char *) NULL);
  238.                    printf ("%s\n", dstr);
  239.                    break;
  240.  
  241.         case def_macro  :  if (strlen (dstr) >= MAXLINE)
  242.                     PrintWarning ("Macro assignment may be too long.\n", 
  243.                               (char *) NULL);
  244.                    printf ("%s\n", dstr);
  245.                    break;
  246.  
  247.         case def_prec   :  if (strlen (dstr) >= MAXLINE)
  248.                     PrintWarning ("Precedence relation may be too long.\n", 
  249.                               (char *) NULL);
  250.                    printf ("%s\n", dstr);
  251.                    break;
  252.  
  253.         case def_trusted:
  254.         case def_class  :  if (strlen (dstr) < REGLINE)
  255.                     printf ("%s\n", dstr);
  256.                    else        /* use line continuation feature */
  257.                        PrintContinued (btype, dstr);
  258.                    break;
  259.  
  260.         default         :  FatalError ("Invalid case in PrintDef ()", (char *) NULL);
  261.     }
  262. }
  263.  
  264.  
  265. /*
  266.  *    StartRuleset () -- Prints a ruleset heading for the ruleset identifier
  267.  *                   contained in the argument rsid.
  268.  *
  269.  */
  270. void
  271. StartRuleset (rsid)
  272. register struct he *rsid;    /* ruleset identifier */
  273. {
  274.     if (!ISRULESET(rsid->idtype))
  275.         if (ISTYPED(rsid->idtype))
  276.             PrintError ("Identifier not of ruleset type:", rsid->psb);
  277.         else
  278.             PrintError ("Ruleset identifier not bound to a number:", rsid->psb);
  279.     else {
  280.         if (ISRULESET(rsid->idd))
  281.             PrintWarning ("Redefining ruleset %s.\n", rsid->psb);
  282.         rsid->idd |= ID_RULESET;
  283.         printf ("S%s\n", rsid->idval.rsn);
  284.     }
  285. }
  286. SHAR_EOF
  287. if test 7227 -ne "`wc -c emitcf.c`"
  288. then
  289. echo shar: error transmitting emitcf.c '(should have been 7227 characters)'
  290. fi
  291. cat << \SHAR_EOF > errors.c
  292. /*    $Header: /usr/src/local/etc/ease/RCS/errors.c,v 1.2 85/10/29 23:40:20 jss Exp $    */
  293.  
  294. /*
  295.  *      errors.c   -- Contains error initialization and reporting routines.
  296.  *
  297.  *      author     -- James S. Schoner, Purdue University Computing Center,
  298.  *                        West Lafayette, Indiana  47907
  299.  *
  300.  *      date       -- July 9, 1985
  301.  *
  302.  *    Copyright (c) 1985 by Purdue Research Foundation
  303.  *
  304.  *    All rights reserved.
  305.  *
  306.  */
  307.  
  308. #include <stdio.h>
  309.  
  310. extern int  ErrorCount;     /* error count                   */
  311. extern char FNbuf[];     /* input file name              */
  312. extern int  Lcount;     /* line count                    */
  313. FILE *DIAGf = {stderr};  /* file for diagnostic output */
  314.  
  315.  
  316. /*
  317.  *    ErrorReport () -- Prints source file name (FNbuf), line number (Lcount),
  318.  *              and error message (sbErr) for each invokation.
  319.  *
  320.  */
  321. void
  322. ErrorReport (sbErr)
  323. char *sbErr;
  324. {
  325.     fprintf (DIAGf, "%s, line %d: %s", FNbuf, Lcount, sbErr);
  326.     ErrorCount++;
  327. }
  328.  
  329.  
  330. /*
  331.  *    FatalError () -- Translator fatal error routine which prints 
  332.  *             error message (sbErr) and an argument (sbArg).
  333.  *
  334.  */
  335. void
  336. FatalError (sbErr, sbArg)
  337. char *sbErr,
  338.      *sbArg;
  339. {
  340.     fprintf (DIAGf, "%s, line %d: Fatal Error In Translator: %s %s\n", 
  341.          FNbuf, Lcount, sbErr, sbArg);
  342.     exit (1);
  343. }
  344.  
  345.  
  346. /*
  347.  *    yyerror () -- Prints source file name (FNbuf), line number (Lcount),
  348.  *              and error message (sbErr) for each invokation.
  349.  *
  350.  */
  351. void
  352. yyerror (sbErr)
  353. char *sbErr;
  354. {
  355.     fprintf (DIAGf, "%s, line %d: %s\n", FNbuf, Lcount, sbErr);
  356.     ErrorCount++;
  357. }
  358.  
  359.  
  360. /*
  361.  *    PrintError () -- Prints source file name (FNbuf), line number
  362.  *             (cline), error message (sbErr), and argument
  363.  *             (sbArg) for each invokation.
  364.  *
  365.  */
  366. void
  367. PrintError (sbErr, sbArg)
  368. char *sbErr;
  369. char *sbArg;
  370. {
  371.     fprintf (DIAGf, "%s, line %d: %s %s.\n", FNbuf, Lcount, sbErr, sbArg);
  372.     ErrorCount++;
  373. }
  374.  
  375.  
  376. /*
  377.  *    PrintWarning () -- Prints a warning message with source file
  378.  *               name (FNbuf), line number (Lcount), warning
  379.  *               (sbWarn), and a possible identifier (sbID).
  380.  *
  381.  */
  382. void
  383. PrintWarning (sbWarn, sbID)
  384. char *sbWarn;
  385. char *sbID;
  386. {
  387.     fprintf (DIAGf, "%s, line %d: Warning: ", FNbuf, Lcount);
  388.     if (sbID != NULL)
  389.         fprintf (DIAGf, sbWarn, sbID);
  390.     else
  391.         fprintf (DIAGf, sbWarn);
  392. }
  393.  
  394.  
  395. /*
  396.  *    InitError () -- Initialize line count (Lcount) to one and error count
  397.  *                (ErrorCount) to zero.
  398.  *
  399.  */
  400. void
  401. InitError ()
  402. {
  403.     Lcount     = 1;
  404.     ErrorCount = 0;
  405. }
  406. SHAR_EOF
  407. if test 2340 -ne "`wc -c errors.c`"
  408. then
  409. echo shar: error transmitting errors.c '(should have been 2340 characters)'
  410. fi
  411. cat << \SHAR_EOF > idman.c
  412. /*    $Header: /usr/src/local/etc/ease/RCS/idman.c,v 1.2 85/10/29 23:41:38 jss Exp $    */
  413.  
  414. /*
  415.  *      idman.c    -- Contains routines for manipulating identifiers and their
  416.  *           symbolic associations.
  417.  *
  418.  *      author    -- James S. Schoner, Purdue University Computing Center,
  419.  *                     West Lafayette, Indiana  47907
  420.  *
  421.  *      date    -- July 9, 1985
  422.  *
  423.  *    Copyright (c) 1985 by Purdue Research Foundation
  424.  *
  425.  *    All rights reserved.
  426.  *
  427.  */
  428.  
  429. #include <stdio.h>
  430. #include "symtab.h"
  431.  
  432. extern struct he *LookupSymbol ();
  433. extern void      FatalError (),
  434.           ErrorReport (),
  435.           PrintWarning (),
  436.           PrintError ();
  437.  
  438. short Uchar = 'A';            /* for unique macro names */
  439.  
  440.  
  441. /*
  442.  *    UniqMac () -- Assigns and returns a unique one-character macro
  443.  *              name (upper-case) for an Ease macro name.
  444.  *
  445.  */
  446. char
  447. UniqMac (phe)
  448. struct he *phe;        /* symbol table entry for Ease macro */
  449. {
  450.     if ((phe->idval.idc = Uchar++) > 'Z')
  451.         FatalError ("Too many macro names (26 max)", (char *) NULL);
  452.     return (phe->idval.idc);
  453. }
  454.  
  455.  
  456. /*
  457.  *    BindID () -- Binds either a ruleset or precedence identifier (phe) to
  458.  *              an integer (vid).  The id type distinction is passed in
  459.  *             the parameter idt.
  460.  *
  461.  */
  462. void
  463. BindID (phe, vid, idt)
  464. register struct he *phe;    /* symbol table entry for an identifier    */
  465. int vid;            /* value of the identifier           */
  466. unsigned idt;            /* identifier type (ruleset or precedence) */
  467. {
  468.     if (ISTYPED(phe->idtype)) {    /* should be undefined */
  469.         PrintWarning ("Redeclaration of %s.\n", phe->psb);
  470.         phe->idtype = ID_UNTYPED;
  471.     }
  472.     phe->idtype |= idt;        /* make defined           */
  473.     if (ISRULESET(phe->idtype)) {
  474.         if (vid > VALRSNMAX) {
  475.             ErrorReport ("Ruleset number too large.\n");
  476.             return;
  477.         } else if (vid < 0) {
  478.             ErrorReport ("Ruleset number must be non-negative.\n");
  479.             return;
  480.         }
  481.         sprintf (phe->idval.rsn, "%d", vid);
  482.     } else 
  483.         phe->idval.prec = vid;
  484. }
  485.  
  486.  
  487. /*
  488.  *    CheckRS () -- Checks validity of a ruleset identifier (phe) and 
  489.  *              returns the ruleset string to which the identifier
  490.  *              is bound.  If the ruleset identifier is invalid, the
  491.  *              null string is returned.
  492.  *
  493.  */
  494. char *
  495. CheckRS (phe)
  496. struct he *phe;        /* symbol table entry for ruleset identifier */
  497. {
  498.     if (!ISRULESET(phe->idtype)) {
  499.         if (!ISTYPED(phe->idtype))
  500.             PrintError ("Ruleset identifier not bound to a number:", phe->psb);
  501.         else
  502.             PrintError ("Identifier not of ruleset type:", phe->psb);
  503.         return (NULL);
  504.     } else
  505.         return (phe->idval.rsn);
  506. }
  507.  
  508.  
  509. /*
  510.  *    MakeMac () -- Declare a macro name (pmac) as a class and/or macro type 
  511.  *              (targtype) and return the unique cf character assigned 
  512.  *              to it.
  513.  *
  514.  */
  515. char
  516. MakeMac (pmac, targtype)
  517. register struct he *pmac;    /* symbol table entry for macro identifier */
  518. unsigned targtype;        /* target declaration type for the macro   */
  519. {
  520.     /*
  521.      *    An Ease macro may be declared as both a singular macro and
  522.      *    a class macro.
  523.      *
  524.      */
  525.     if (ISMACRO(pmac->idtype) || ISCLASS(pmac->idtype)) {
  526.         pmac->idtype |= targtype;
  527.         return (pmac->idval.idc);
  528.     }
  529.     if (ISTYPED(pmac->idtype)) {    /* not a macro or class id */
  530.         PrintError ("Redeclaring or using as macro or class:", pmac->psb);
  531.         return ('\0');
  532.     }
  533.     pmac->idtype |= targtype;    /* previously untyped; declare here */
  534.     return (UniqMac (pmac));
  535. }
  536.     
  537.  
  538. /*
  539.  *    GetField () -- Returns a field type string given a field 
  540.  *               identifier (fid).
  541.  *
  542.  */
  543. char *
  544. GetField (fid)
  545. register struct he *fid;    /* field identifier */
  546. {
  547.     if (!ISFIELD(fid->idtype)) {
  548.         PrintError ("Field type not defined for", fid->psb);
  549.         return (NULL);
  550.     } else 
  551.         return (fid->idval.fstring);
  552. }
  553.  
  554.  
  555. /*
  556.  *    CheckMailer () -- Declares a mailer identifier (mid) as type mailer,
  557.  *              checking that the identifier was not previously 
  558.  *              declared a different type. 
  559.  *
  560.  */
  561. char *
  562. CheckMailer (mid)
  563. register struct he *mid;
  564. {
  565.     if (ISTYPED (mid->idtype) && !ISMAILER (mid->idtype)) {
  566.         PrintError ("Redeclaration as mailer:", mid->psb);
  567.         return (NULL);
  568.     }
  569.     mid->idtype |= ID_MAILER;
  570.     return (mid->psb);
  571. }
  572.  
  573.  
  574. /*
  575.  *    AssignType () -- Assigns to each field identifier in fidlist the
  576.  *             type (in string form) fidtype.  This is accomplished
  577.  *             by making each field identifier symbol table entry
  578.  *             "point" to the type found in fidtype.
  579.  *
  580.  */
  581. void
  582. AssignType (fidlist, fidtype)
  583. register char *fidlist;        /* field identifier list, blank separated */
  584. char *fidtype;            /* field identifier type string          */
  585. {
  586.     register struct he *fid;    /* pointer to a field identifier  */
  587.     char *fres;            /* field type result string      */
  588.     register char *srch;        /* fidlist search pointer      */
  589.     char  sep;            /* fidlist separator character    */
  590.  
  591.     fres = (char *) malloc (strlen (fidtype) + 1);
  592.     if (fres == NULL)
  593.         FatalError ("System out of string space in AssignType ()", (char *) NULL);
  594.     strcpy (fres, fidtype);        /* make clean copy of string type */
  595.  
  596.     /*
  597.      *    Search for all field identifiers and make the type assignment. 
  598.       *
  599.      */
  600.     srch = fidlist;
  601.     while (*srch != '\0') {
  602.         while ((*++srch != ' ') && (*srch != '\0'))
  603.             /* null */ ;
  604.         if (*fidlist != '\0') {                /* found a field id       */
  605.             sep = *srch;
  606.             *srch = '\0';
  607.             fid = LookupSymbol (fidlist);    /* get symbol table entry */
  608.             if (ISFIELD(fid->idtype)) {
  609.                 if (strcmp (fid->idval.fstring, fres))
  610.                     PrintWarning ("Redefinition of field type for %s.\n", fid->psb);
  611.             } else if (ISTYPED(fid->idtype)) {
  612.                 PrintError ("Redeclaration of identifier as a field:", fid->psb);
  613.                 return;
  614.             }
  615.             fid->idtype |= ID_FIELD;    /* type the identifier    */
  616.             fid->idval.fstring = fres;    /* type the field      */
  617.             if ((*srch = sep) != '\0')
  618.                 fidlist = ++srch;
  619.         }
  620.     }
  621. }
  622. SHAR_EOF
  623. if test 5550 -ne "`wc -c idman.c`"
  624. then
  625. echo shar: error transmitting idman.c '(should have been 5550 characters)'
  626. fi
  627. cat << \SHAR_EOF > main.c
  628. /*    $Header: /usr/src/local/etc/ease/RCS/main.c,v 1.2 85/10/29 23:43:38 jss Exp $    */
  629.  
  630. /*
  631.  *      main.c     -- Main procedure for Ease Translator.
  632.  *
  633.  *      author     -- James S. Schoner, Purdue University Computing Center
  634.  *                        West Lafayette, Indiana  47907
  635.  *
  636.  *      date       -- July 9, 1985
  637.  *
  638.  *    Copyright (c) 1985 by Purdue Research Foundation
  639.  *
  640.  *    All rights reserved.
  641.  *
  642.  */
  643.  
  644. #include <stdio.h>
  645.  
  646. extern FILE *DIAGf;            /* diagnostic file */
  647. extern void InitError (), 
  648.         InitSymbolTable (),
  649.         DefScan (),
  650.         FatalError (),
  651.             PreLoad ();
  652.  
  653. int ErrorCount;                /* translation error count */
  654. void GetArgs ();            /* gets arguments to "et"  */
  655.  
  656. /*
  657.  *    main () -- Main procedure for the Ease Translator et.  If no files are 
  658.  *                  given as arguments to et, stdin is translated and written to 
  659.  *               stdout.  If one file is given, it is translated and written 
  660.  *               to stdout.  If two files are given, the first is translated
  661.  *               and written to the second.  If the first filename is "-",
  662.  *               standard input is assumed.  A translation is performed on 
  663.  *               valid Ease input only, producing a regular sendmail 
  664.  *           configuration file. 
  665.  *
  666.  */
  667. void
  668. main (argc, argv)
  669. int argc;        /* argument count for "et"  */
  670. char *argv[];        /* argument vector for "et" */
  671. {
  672.     InitError ();            /* initialize error conditions */
  673.     InitSymbolTable ();        /* initialize the symbol table */
  674.     PreLoad ();            /* preload special identifiers */
  675.     GetArgs (argc, argv);        /* set up argument files       */
  676.     (void) yyparse ();        /* perform translation           */
  677.     if (fflush (stdout) == EOF)
  678.         FatalError ("Cannot flush output stream/file", (char *) NULL);
  679.     DefScan ();                /* warn about undefined idents */
  680.     if (ErrorCount)
  681.         fprintf (DIAGf, "\n\n*** %d error(s) detected.\n", ErrorCount);
  682.     exit (ErrorCount);
  683. }
  684.  
  685.  
  686. /*
  687.  *    GetArgs () -- Processes arguments to the Ease translator "et".  The
  688.  *              arguments are files (margv) which may replace either/both
  689.  *              of the files standard input and standard output.  The 
  690.  *              following cases are possible:
  691.  *            
  692.  *              -- et f.e f.cf
  693.  *                Translate Ease file f.e and write result
  694.  *                to f.cf.
  695.  *
  696.  *              -- et f.e
  697.  *                Translate Ease file f.e and write result to
  698.  *                standard output.
  699.  *
  700.  *              -- et - f.cf
  701.  *                Translate standard input and write result to
  702.  *                f.cf.
  703.  *
  704.  *              -- et
  705.  *                Translate standard input and write result to
  706.  *                standard output.
  707.  *
  708.  *              Finally, a message indicating the volatility of the 
  709.  *              Ease output is written.
  710.  *
  711.  */
  712. void
  713. GetArgs (margc, margv)
  714. register int   margc;        /* argument count  */
  715. register char *margv[];        /* argument vector */
  716. {
  717.     switch (margc) {
  718.         case 1 : break;
  719.         case 2 :
  720.         case 3 : if (strcmp (margv[1], "-") && (freopen (margv[1], "r", stdin) == NULL))
  721.                 FatalError ("Cannot open input stream/file:", margv[1]);
  722.              if ((margc == 3) && (freopen (margv[2], "w", stdout) == NULL))
  723.                 FatalError ("Cannot open output file:", margv[2]);
  724.              break;
  725.         default: FatalError ("Usage: et [infile [outfile]]", (char *) NULL);
  726.              break;
  727.     }
  728.     printf ("###################################################\n");
  729.     printf ("##                                               ##\n");
  730.     printf ("##  WARNING: THIS FILE IS TO BE MODIFIED BY      ##\n");
  731.     printf ("##           THE EASE TRANSLATOR (ET) ONLY.      ##\n");
  732.     printf ("##                                               ##\n");
  733.     printf ("##           ALL OTHER MODIFICATIONS WILL        ##\n");
  734.     printf ("##           DISAPPEAR THE NEXT TIME ET IS RUN.  ##\n");
  735.     printf ("##                                               ##\n");
  736.     printf ("##           MAKE MODIFICATIONS TO THE EASE      ##\n");
  737.     printf ("##           SOURCE ONLY.                        ##\n");
  738.     printf ("##                                               ##\n");
  739.     printf ("###################################################\n");
  740. }
  741. SHAR_EOF
  742. if test 3915 -ne "`wc -c main.c`"
  743. then
  744. echo shar: error transmitting main.c '(should have been 3915 characters)'
  745. fi
  746. cat << \SHAR_EOF > strops.c
  747. /*    $Header: /usr/src/local/etc/ease/RCS/strops.c,v 1.2 85/10/29 23:45:39 jss Exp $    */
  748.  
  749. /*
  750.  *    strops.c   -- Contains string operation routines used for constructing
  751.  *              definitions in cf format.
  752.  *
  753.  *    author       -- James S. Schoner, Purdue University Computing Center,
  754.  *                        West Lafayette, Indiana  47907
  755.  *
  756.  *    date       -- July 9, 1985
  757.  *
  758.  *    Copyright (c) 1985 by Purdue Research Foundation
  759.  *
  760.  *    All rights reserved.
  761.  *
  762.  */
  763.  
  764. #include <stdio.h>
  765. #include <strings.h>
  766. #include "symtab.h"
  767.  
  768. #define MAXTOKPOS   99        /* maximum number of token positions */
  769. #define MAXNAME        1024    /* maximum length of an identifier   */
  770.  
  771. extern struct he *LookupSymbol ();
  772. extern char       MakeMac ();
  773. extern void      FatalError (),
  774.           PrintError (),
  775.           ErrorReport ();
  776.  
  777. short  Rformat = FALSE;            /* class read format flag      */
  778. static char   *Ptok   = "$  ";        /* positional token structure     */
  779. static char   *Cfield = "$= ";        /* class reference structure      */
  780. static char   *Ofield = "$-";        /* one token match structure      */
  781. static char   *Zfield = "$*";        /* zero or more tokens structure  */
  782. static char   *Pfield = "$+";        /* one or more tokens structure      */
  783. static char   *Mtest  = "$? ";        /* conditional macro test string  */
  784.  
  785.  
  786. /*
  787.  *    ConvOpt () -- Convert an Ease option identifier (optid) by returning a
  788.  *              string representation of the cf format.  
  789.  *
  790.  */
  791. char *
  792. ConvOpt (optid) 
  793. register enum opts optid;
  794. {
  795.     switch (optid) {
  796.         case opt_A  :    return ("A");
  797.         case opt_a  :    return ("a");
  798.         case opt_B  :    return ("B");
  799.         case d_opt_b:    return ("b");
  800.         case opt_c  :    return ("c");
  801.         case opt_D  :    return ("D");
  802.         case opt_d  :    return ("d");
  803.         case opt_e  :
  804.         case e_opt_e:    return ("e");
  805.         case opt_F  :    return ("F");
  806.         case opt_f  :    return ("f");
  807.         case opt_g  :    return ("g");
  808.         case opt_H  :    return ("H");
  809.         case opt_i  :
  810.         case d_opt_i:    return ("i");
  811.         case opt_L  :    return ("L");
  812.         case opt_m  :
  813.         case e_opt_m:    return ("m");
  814.         case opt_N  :    return ("N");
  815.         case opt_o  :    return ("o");
  816.         case e_opt_p:    return ("p");
  817.         case opt_Q  :    return ("Q");
  818.         case d_opt_q:    return ("q");
  819.         case opt_r  :    return ("r");
  820.         case opt_S  :    return ("S");
  821.         case opt_s  :    return ("s");
  822.         case opt_T  :    return ("T");
  823.         case opt_t  :    return ("t");
  824.         case opt_u  :    return ("u");
  825.         case opt_v  :    return ("v");
  826.         case opt_W  :    return ("W");
  827.         case e_opt_w:    return ("w");
  828.         case opt_x  :    return ("x");
  829.         case opt_X  :    return ("X");
  830.         case e_opt_z:    return ("z");
  831.         default     :    FatalError ("Bad case in ConvOpt ()", (char *) NULL);
  832.     }
  833.     /*NOTREACHED*/
  834. }
  835.  
  836.  
  837. /*
  838.  *    ConvFlg () -- Convert an Ease mailer flag identifier (flgid) by 
  839.  *              string representation of the cf format.  
  840.  *
  841.  */
  842. char *
  843. ConvFlg (flgid)
  844. register enum flgs flgid;    /* flag identifier */
  845. {
  846.     switch (flgid) {
  847.         case flg_f:    return ("f");
  848.         case flg_r:    return ("r");
  849.         case flg_S:    return ("S");
  850.         case flg_n:    return ("n");
  851.         case flg_l:    return ("l");
  852.         case flg_s:    return ("s");
  853.         case flg_m:    return ("m");
  854.         case flg_F:    return ("F");
  855.         case flg_D:    return ("D");
  856.         case flg_M:    return ("M");
  857.         case flg_x:    return ("x");
  858.         case flg_P:    return ("P");
  859.         case flg_u:    return ("u");
  860.         case flg_h:    return ("h");
  861.         case flg_A:    return ("A");
  862.         case flg_U:    return ("U");
  863.         case flg_e:    return ("e");
  864.         case flg_X:    return ("X");
  865.         case flg_L:    return ("L");
  866.         case flg_p:    return ("p");
  867.         case flg_I:    return ("I");
  868.         case flg_C:    return ("C");
  869.         default   :    FatalError ("Bad case in ConvFlg ()", (char *) NULL);
  870.     }
  871.     /*NOTREACHED*/
  872. }
  873.  
  874.  
  875. /*
  876.  *    ConvMat () -- Convert an Ease mailer attribute (mat) by returning a
  877.  *              string representation of the cf format.  
  878.  *
  879.  */
  880. char *
  881. ConvMat (mat)
  882. register enum mats mat;        /* mailer attribute flag */
  883. {
  884.     switch (mat) {
  885.         case mat_path        : return ("P");
  886.         case mat_flags        : return ("F");
  887.         case mat_sender        : return ("S");
  888.         case mat_recipient    : return ("R");
  889.         case mat_argv        : return ("A");
  890.         case mat_eol        : return ("E");
  891.         case mat_maxsize    : return ("M");
  892.         default            : FatalError ("Bad case in ConvMat ()", (char *) NULL);
  893.     }
  894.     /*NOTREACHED*/
  895. }
  896.  
  897.  
  898. /*
  899.  *    MacScan () -- Scan a string (pstring) for macros, replacing the Ease
  900.  *              form with the one-character form required by cf format.
  901.  *
  902.  */
  903. char *
  904. MacScan (pstring)
  905. char *pstring;        /* macro expandable string */
  906. {
  907.     register char *searchptr;    /* string search pointer     */
  908.     register char *bptr, *eptr;    /* macro begin and end pointers */
  909.     char macname [MAXNAME];        /* macro name buffer        */
  910.  
  911.     if ((searchptr = pstring) == NULL)
  912.         return ((char *) NULL);
  913.     while (*searchptr != '\0')     /* find and rewrite all macros  */
  914.         if (*searchptr == '\\') {
  915.             searchptr = searchptr + 2;
  916.             continue;
  917.         } else if (*searchptr++ == '$' && *searchptr == '{') {
  918.             if (sscanf (searchptr + 1, "%[^}]", macname) != 1) {
  919.                 PrintError ("Invalid macro format:", searchptr + 1);
  920.                 return ((char *) NULL);
  921.             } 
  922.             *searchptr++ = MakeMac (LookupSymbol (macname), ID_MACRO);
  923.             bptr = eptr = searchptr;
  924.             while (*eptr++ != '}')    /* delete old macro chars */
  925.                 /* empty */ ;
  926.             do
  927.                 *bptr++ = *eptr;
  928.             while (*eptr++ != '\0');
  929.         }
  930.     return (pstring);
  931. }
  932.  
  933.  
  934. /*
  935.  *    MakeRStr () -- Construct and return a pointer to a class read string 
  936.  *               using the filename fname and read format rformat.  
  937.  *
  938.  */
  939. char *
  940. MakeRStr (fname, rformat)
  941. char *fname,            /* file name for class read */
  942.      *rformat;            /* format for class read    */
  943. {
  944.     register char *res;    /* resultant read string    */
  945.  
  946.     Rformat = TRUE;        /* set read format flag     */
  947.     if (rformat == NULL)
  948.         return (fname);
  949.     res = (char *) realloc (fname, strlen (fname) + strlen (rformat) + 2);
  950.     if (res == NULL)
  951.         FatalError ("System out of string space in MakeRStr ()", (char *) NULL);
  952.     res = strcat (res, " ");    /* construct read string */
  953.     res = strcat (res, rformat);
  954.     free (rformat);
  955.     return (res);
  956. }
  957.  
  958.  
  959. /*
  960.  *    ListAppend () -- Append string list2 to string list1 using the 
  961.  *             separator sep.  A pointer to the newly constructed
  962.  *             string is returned.
  963.  *
  964.  */
  965. char *
  966. ListAppend (list1, list2, sep)
  967. char *list1,            /* first string     */
  968.      *list2,            /* second string      */
  969.      *sep;            /* string separator    */
  970. {
  971.     register char *res;    /* resultant string    */
  972.  
  973.     res = (char *) malloc (strlen (list1) + strlen (list2) + strlen (sep) + 1);
  974.     if (res == NULL)
  975.         FatalError ("System out of string space in ListAppend ()", (char *) NULL);
  976.     res = strcpy (res, list1);
  977.     if (list1 != NULL)    /* use separator if first string not null */
  978.         res = strcat (res, sep);
  979.     res = strcat (res, list2);
  980.     return (res);
  981. }
  982.  
  983.  
  984. /*
  985.  *    MakeCond () -- Construct a macro conditional string in cf format.  The
  986.  *               conditional is based on the macro testmac, with an "if
  987.  *               set" result ifstring, which may contain an optional 
  988.  *               "if not set" result string appended to it.
  989.  *
  990.  */
  991. char *
  992. MakeCond (testmac, ifstring)
  993. struct he *testmac;        /* macro for conditional testing          */
  994. char       *ifstring;         /* "if macro set" result string(s)           */
  995. {
  996.     register char *res;    /* resultant conditional string             */
  997.  
  998.     Mtest[2] = MakeMac (testmac, ID_MACRO);       /* get one-char macro rep */
  999.     res = (char *) malloc (strlen (ifstring) + 6);
  1000.     if (res == NULL)
  1001.         FatalError ("System out of string space in MakeCond ()", (char *) NULL);
  1002.     res = strcpy (res, Mtest);
  1003.     res = strcat (res, ifstring);        /* build result part      */
  1004.     res = strcat (res, "$.");        /* end of conditional     */
  1005.     free (ifstring);
  1006.     return (res);
  1007. }
  1008.  
  1009.  
  1010. /*
  1011.  *    MakePosTok () -- Construct and return a positional token string 
  1012.  *             representation from the parameter num.
  1013.  *
  1014.  */
  1015. char *
  1016. MakePosTok (num)
  1017. register int num;            /* numerical value of positional token */
  1018. {
  1019.     if (num > MAXTOKPOS) {
  1020.         ErrorReport ("Positional token too large.\n");
  1021.         return ((char *) NULL);
  1022.     } else {
  1023.         if (num > 9) {    /* two-digit positional token */
  1024.             Ptok[1] = '0' + (num / 10);
  1025.             Ptok[2] = '0' + (num % 10);
  1026.             Ptok[3] = '\0';
  1027.         } else {
  1028.             Ptok[1] = '0' + num;
  1029.             Ptok[2] = '\0';
  1030.         }
  1031.     return (Ptok);
  1032.     }
  1033. }
  1034.  
  1035.  
  1036. /*
  1037.  *    Bracket () -- Construct and return a cf string form of the 
  1038.  *              canonicalization of the string identifier passed in
  1039.  *              the string parameter psb if dflag is true, else
  1040.  *              simply bracket the identifier without dollar signs
  1041.  *              for numeric hostname specifications.
  1042.  *
  1043.  */
  1044. char *
  1045. Bracket (psb, dflag)
  1046. char *psb;            /* identifier to be canonicalized */
  1047. short dflag;            /* dollar flag               */
  1048. {
  1049.     register char *res;    /* resultant cf form           */
  1050.     register short extra;    /* extra space needed for malloc  */
  1051.     
  1052.     extra = dflag ? 5 : 3;
  1053.     res = (char *) malloc (strlen (psb) + extra);
  1054.     if (res == NULL)
  1055.         FatalError ("System out of string space in Bracket ()", (char *) NULL);
  1056.     if (dflag)
  1057.         res = strcpy (res, "$[");
  1058.     else
  1059.         res = strcpy (res, "[");
  1060.     res = strcat (res, psb);
  1061.     if (dflag)
  1062.         res = strcat (res, "$");
  1063.     res = strcat (res, "]");
  1064.     return (res);
  1065. }
  1066.  
  1067.  
  1068. /*
  1069.  *    MakeRSCall () -- Construct and return a cf string form of a call
  1070.  *             to a ruleset (cid), which would pass to it the
  1071.  *             remainder of a rewriting address (rwaddr).
  1072.  *
  1073.  */
  1074. char *
  1075. MakeRSCall (cid, rwaddr)
  1076. register struct he *cid;    /* called ruleset identifier         */
  1077. register char *rwaddr;        /* remainder of rewriting address    */
  1078. {
  1079.     register char *res;    /* resultant cf string for the call  */
  1080.     
  1081.     if (!ISRULESET(cid->idtype)) {    /* check validity of ruleset */
  1082.         PrintError ("Undefined ruleset identifier:", cid->psb);
  1083.         return ((char *) NULL);
  1084.     }
  1085.     res = (char *) malloc (strlen (cid->idval.rsn) + strlen (rwaddr) + 3);
  1086.     if (res == NULL)
  1087.         FatalError ("System out of string space in MakeRSCall ()", (char *) NULL);
  1088.     res = strcpy (res, "$>");    /* construct the call string */
  1089.     res = strcat (res, cid->idval.rsn);
  1090.     res = strcat (res, rwaddr);
  1091.     return (res);
  1092. }
  1093.  
  1094.  
  1095. /*
  1096.  *    MakeField () -- Construct and return the cf string format for a
  1097.  *            field variable.  The match count (count), an optional
  1098.  *            class (class), and a match repetition flag (fstar)
  1099.  *            are used to determine what type of field string to
  1100.  *            construct.
  1101.  *
  1102.  */
  1103. char *
  1104. MakeField (count, class, fstar)
  1105. register int count;        /* match count (0 or 1) */
  1106. register struct he *class;    /* optional class type  */
  1107. register short fstar;        /* repetition flag    */
  1108. {
  1109.     switch (count) {
  1110.         case 0:      if (class == NULL)    /* any token is valid */
  1111.                 if (fstar)
  1112.                     return (Zfield);
  1113.                 else {
  1114.                     ErrorReport ("Invalid field type.\n");
  1115.                     return ((char *) NULL);
  1116.                 }
  1117.               else {        /* match 0 from class */
  1118.                 Cfield[1] = '~';
  1119.                 Cfield[2] = MakeMac (class, ID_CLASS);
  1120.                 return (Cfield);
  1121.               }
  1122.         case 1:      if (class == NULL)    /* any token is valid */
  1123.                 if (fstar)
  1124.                     return (Pfield);
  1125.                 else
  1126.                     return (Ofield);
  1127.               else {        /* match 1 from class */
  1128.                 Cfield[1] = '=';
  1129.                 Cfield[2] = MakeMac (class, ID_CLASS);
  1130.                 return (Cfield);
  1131.               }
  1132.         default:  ErrorReport ("Invalid field type.\n");
  1133.     }
  1134.     /*NOTREACHED*/
  1135. }
  1136. SHAR_EOF
  1137. if test 10730 -ne "`wc -c strops.c`"
  1138. then
  1139. echo shar: error transmitting strops.c '(should have been 10730 characters)'
  1140. fi
  1141. cat << \SHAR_EOF > symtab.c
  1142. /*    $Header: /usr/src/local/etc/ease/RCS/symtab.c,v 1.2 85/10/29 23:46:48 jss Exp $    */
  1143.  
  1144. /*
  1145.  *      symtab.c   -- Contains Ease Translator symbol table routines.
  1146.  *
  1147.  *      author     -- James S. Schoner, Purdue University Computing Center,
  1148.  *                        West Lafayette, Indiana  47907
  1149.  *
  1150.  *      date       -- July 9, 1985
  1151.  *
  1152.  *    Copyright (c) 1985 by Purdue Research Foundation
  1153.  *
  1154.  *    All rights reserved.
  1155.  *
  1156.  */
  1157.  
  1158. #include <stdio.h>
  1159. #include <ctype.h>
  1160. #include "symtab.h"
  1161.  
  1162. #define ERRORMAILER "error"        /* predefined error mailer name */
  1163.  
  1164. extern void FatalError (),
  1165.         PrintWarning ();
  1166.  
  1167. struct he *LookupSymbol ();
  1168.  
  1169. struct Defmac {                /* predefined macro struct def  */
  1170.     char *macname;
  1171.     char  macrep;
  1172. };
  1173.  
  1174. struct he *SymTab[SST];            /* hash table base array        */
  1175. static struct Defmac MacDefs[] = {    /* predefined macros            */
  1176.             {"m_smtp",    'e'},
  1177.             {"m_oname",    'j'},
  1178.             {"m_ufrom",    'l'},
  1179.             {"m_daemon",    'n'},
  1180.             {"m_addrops",    'o'},
  1181.             {"m_defaddr",    'q'},
  1182.             {"m_sitename",    'w'},
  1183.             {"m_odate",    'a'},
  1184.             {"m_adate",    'b'},
  1185.             {"m_hops",    'c'},
  1186.             {"m_udate",    'd'},
  1187.             {"m_saddr",    'f'},
  1188.             {"m_sreladdr",    'g'},
  1189.             {"m_rhost",    'h'},
  1190.             {"m_qid",    'i'},
  1191.             {"m_pid",    'p'},
  1192.             {"m_protocol",    'r'},
  1193.             {"m_shostname", 's'},
  1194.             {"m_ctime",    't'},
  1195.             {"m_ruser",    'u'},
  1196.             {"m_version",    'v'},
  1197.             {"m_sname",    'x'},
  1198.             {"m_stty",    'y'},
  1199.             {"m_rhdir",    'z'},
  1200.             {"sentinel",    '\0'}
  1201. };
  1202.  
  1203.  
  1204. /*
  1205.  *    DefScan () -- Scan symbol table to find macros, classes, mailers, 
  1206.  *              and rulesets which have been referenced or declared, but
  1207.  *              not defined.  A warning is printed for each such 
  1208.  *              occurence.  This routine is usually called at the end
  1209.  *              of a successful Ease translation.
  1210.  *
  1211.  */
  1212. void
  1213. DefScan ()
  1214. {
  1215.     register int stindex;        /* symbol table hash index   */
  1216.     register struct he *hcsearch;    /* hash chain search pointer */
  1217.  
  1218.     for (stindex = 0; stindex < SST; stindex++) {
  1219.         if ((hcsearch = SymTab[stindex]) != NULL)
  1220.             while (hcsearch != NULL) {
  1221.                 if ((ISMACRO(hcsearch->idtype) && 
  1222.                      isupper(hcsearch->idval.idc)) &&
  1223.                      !ISMACRO(hcsearch->idd))
  1224.                     PrintWarning ("Macro not defined: %s\n", hcsearch->psb);
  1225.                 if (ISCLASS(hcsearch->idtype) && !ISCLASS(hcsearch->idd))
  1226.                     PrintWarning ("Class not defined: %s\n", hcsearch->psb);
  1227.                 if (ISMAILER(hcsearch->idtype) && !ISMAILER(hcsearch->idd))
  1228.                     PrintWarning ("Mailer not defined: %s\n", hcsearch->psb);
  1229.                 if (ISRULESET(hcsearch->idtype) && !ISRULESET(hcsearch->idd))
  1230.                     PrintWarning ("Ruleset not defined: %s\n", hcsearch->psb);
  1231.                 hcsearch = hcsearch->phe;
  1232.             }
  1233.     }
  1234. }
  1235.                      
  1236.  
  1237. /*
  1238.  *    InitSymbolTable () -- Invoked by main () to initialize the symbol table.
  1239.  *
  1240.  */
  1241. void
  1242. InitSymbolTable ()
  1243. {
  1244.     int i;
  1245.  
  1246.     for (i = 0; i < SST; i++)        /* initialize base array */
  1247.         SymTab[i] = NULL;
  1248. }
  1249.  
  1250.  
  1251. /*
  1252.  *    PreLoad () -- Invoked by main () to preload special macro names 
  1253.  *              and mailer declarations.
  1254.  *
  1255.  */
  1256. void
  1257. PreLoad ()
  1258. {
  1259.     struct Defmac *macptr;
  1260.     struct he     *symptr;
  1261.  
  1262.     /* preload special (lower-case) macros */
  1263.     for (macptr = &MacDefs[0]; (*macptr).macrep != '\0'; macptr++) {
  1264.         symptr = LookupSymbol ((*macptr).macname);
  1265.         symptr->idtype |= ID_MACRO;
  1266.         symptr->idval.idc = (*macptr).macrep;
  1267.     }
  1268.  
  1269.     /* preload error mailer declaration */
  1270.     symptr = LookupSymbol (ERRORMAILER);
  1271.     symptr->idtype |= ID_MAILER;
  1272.     symptr->idd |= ID_MAILER;
  1273. }
  1274.     
  1275.  
  1276. /*
  1277.  *    LookupSymbol () -- Returns a pointer to the hash entry already 
  1278.  *               existing, or newly created, which corresponds 
  1279.  *               to string sb.
  1280.  *
  1281.  */
  1282. struct he *
  1283. LookupSymbol (sb)
  1284. char sb[];            /* string buffer containing identifier */
  1285. {
  1286.     struct he *phe;        /* hash entry search pointer  */
  1287.     int      hc;        /* hash code of sb identifier */
  1288.  
  1289.     phe = SymTab[hc = HashCode (sb)];
  1290.     while (phe != NULL)            /* find hash entry for sb */
  1291.         if (!strcmp (phe->psb, sb))
  1292.             return (phe);
  1293.         else
  1294.             phe = phe->phe;
  1295.     /* make new symbol table entry */
  1296.     if ((phe = (struct he *) malloc (sizeof (struct he))) == NULL)
  1297.         FatalError ("System out of space in LookupSymbol ()", (char *) NULL);
  1298.     if ((phe->psb = (char *) malloc (strlen (sb) + 1)) == NULL)
  1299.         FatalError ("System out of space in LookupSymbol ()", (char *) NULL);
  1300.     strcpy (phe->psb, sb);
  1301.     phe->idval.idc = '\0';
  1302.     phe->idtype = ID_UNTYPED;
  1303.     phe->idd = ID_UNTYPED;
  1304.     phe->phe = SymTab[hc];
  1305.     return (SymTab[hc] = phe);
  1306. }
  1307.  
  1308.  
  1309. /*
  1310.  *    RemoveSymbol () -- Removes the symbol table entry phe from the 
  1311.  *               symbol table.
  1312.  *
  1313.  */
  1314. void
  1315. RemoveSymbol (phe)
  1316. struct he *phe;       /* pointer to hash entry to be removed from symbol table */
  1317. {
  1318.     int hc;               /* hash code of entry phe       */
  1319.     struct he *sphe;    /* search pointer for entry phe */
  1320.  
  1321.     if (phe == NULL)
  1322.         return;
  1323.     else {            /* search and remove entry phe  */
  1324.         sphe = SymTab[hc = HashCode (phe->psb)];
  1325.         free (phe->psb);
  1326.         if (sphe == phe)
  1327.             SymTab[hc] = phe->phe;
  1328.         else
  1329.             while (sphe != NULL)
  1330.                 if (sphe->phe == phe) {
  1331.                     sphe->phe = phe->phe;
  1332.                     return;
  1333.                 } else
  1334.                     sphe = sphe->phe;
  1335.     }
  1336. }
  1337.  
  1338.  
  1339. /*
  1340.  *    HashCode () -- Returns the hash code of the string in sb by adding 
  1341.  *               the character values and applying mod by the hash 
  1342.  *               table size.
  1343.  *
  1344.  */
  1345. int
  1346. HashCode (sb)
  1347. char sb[];
  1348. {
  1349.     int ccSum = 0;            /* sum of char values in string sb */
  1350.     int i;
  1351.  
  1352.     for (i = 0; sb[i]; i++)        /* add char codes for sb chars     */
  1353.         ccSum += sb[i];
  1354.     return (ccSum % SST);        /* return sum mod table size       */
  1355. }
  1356. SHAR_EOF
  1357. if test 5288 -ne "`wc -c symtab.c`"
  1358. then
  1359. echo shar: error transmitting symtab.c '(should have been 5288 characters)'
  1360. fi
  1361. cat << \SHAR_EOF > lexan.l
  1362. %{
  1363. /*    $Header: /usr/src/local/etc/ease/RCS/lexan.l,v 1.2 85/10/29 23:42:40 jss Exp $    */
  1364.  
  1365. /*
  1366.  *    lexan.l -- Lexical Analyzer for EASE.
  1367.  *
  1368.  *           Contains code for lex(1) which generates a lexical
  1369.  *           analyzer (lex.yy.c) for Ease, a high-level specification 
  1370.  *           format for sendmail configuration files.
  1371.  *
  1372.  *    author -- James S. Schoner, Purdue University Computing Center,
  1373.  *                    West Lafayette, Indiana  47907
  1374.  *
  1375.  *    date   -- July 1, 1985
  1376.  *
  1377.  *    Copyright (c) 1985 by Purdue Research Foundation
  1378.  *
  1379.  *    All rights reserved.
  1380.  *
  1381.  */
  1382.  
  1383. #include "symtab.h"
  1384. #include "lexdefs.h"
  1385.  
  1386. #define  LEXnewline '\n'
  1387. #define     LEXeof        '\0'
  1388. #define  MaxFN        200            /* maximum file name length */
  1389.  
  1390. extern struct he *LookupSymbol ();
  1391. extern void      ErrorReport ();
  1392.  
  1393. int  Lcount;                /* line counter            */
  1394. char FNbuf[MaxFN];            /* file name buffer        */
  1395. short RMatch  = FALSE;            /* ruleset match flag          */
  1396.  
  1397. %}
  1398.  
  1399. /* lex-specific extensions */
  1400. %e 1100
  1401. %p 3700
  1402. %n 500
  1403.  
  1404. %%
  1405.     int INch;            /* any input character */
  1406.  
  1407. [ \t\f]+            ;     /* discard whitepsace  */
  1408. [\n]                Lcount++;
  1409. ^\#[ \t]*[0-9]+[ \t]*\".*\"[ \t]*$    {
  1410.                     sscanf (yytext, "%*c%d%s", &Lcount, FNbuf);
  1411.                     INch = input ();
  1412.                     }
  1413. match                return (MATCH);
  1414. in                return (IN);
  1415. bind                return (BIND);
  1416. define                return (DEFINE);
  1417. macro                return (MACRO);
  1418. class                return (CLASS);
  1419. options                return (OPTIONS);
  1420. precedence            return (PRECEDENCE);
  1421. trusted                return (TRUSTED);
  1422. header                return (HEADER);
  1423. ruleset                return (RULESET);
  1424. mailer                return (MAILER);
  1425. host                return (HOST);
  1426. user                return (USER);
  1427. hostnum                return (HOSTNUM);
  1428. if                return (IF);
  1429. retry                return (RETRY);
  1430. next                return (NEXT);
  1431. return                return (RETURN);
  1432. resolve                return (RESOLVE);
  1433. for                return (FOR);
  1434. field                return (FIELD);
  1435. concat                return (CONCAT);
  1436. ifset                return (IFSET);
  1437. canon                return (CANON);
  1438. readclass            return (READCLASS);
  1439. Path                return (MPATH);
  1440. Flags                return (MFLAGS);
  1441. Sender                return (MSENDER);
  1442. Recipient            return (MRECIPIENT);
  1443. Argv                return (MARGV);
  1444. Eol                return (MEOL);
  1445. Maxsize                return (MMAXSIZE);
  1446. o_alias                return (AAOPT);
  1447. o_ewait                return (AOPT);
  1448. o_bsub                return (BBOPT);
  1449. o_qwait                return (COPT);
  1450. o_delivery            return (DOPT);
  1451. d_interactive            return (DOPTI);
  1452. d_background            return (DOPTB);
  1453. d_queue                return (DOPTQ);
  1454. o_rebuild            return (DDOPT);
  1455. o_handling            return (EOPT);
  1456. h_print                return (EOPTP);
  1457. h_exit                return (EOPTE);
  1458. h_mail                return (EOPTM);
  1459. h_write                return (EOPTW);
  1460. h_mailz                return (EOPTZ);
  1461. o_tmode                return (FFOPT);
  1462. o_usave                return (FOPT);
  1463. o_gid                return (GOPT);
  1464. o_fsmtp                return (HHOPT);
  1465. o_skipd                return (IOPT);
  1466. o_slog                return (LLOPT);
  1467. o_rsend                return (MOPT);
  1468. o_dnet                return (NNOPT);
  1469. o_hformat            return (OOPT);
  1470. o_qdir                return (QQOPT);
  1471. o_tread                return (ROPT);
  1472. o_flog                return (SSOPT);
  1473. o_safe                return (SOPT);
  1474. o_qtimeout            return (TTOPT);
  1475. o_timezone            return (TOPT);
  1476. o_dmuid                return (UOPT);
  1477. o_verbose            return (VOPT);
  1478. o_wizpass            return (WWOPT);
  1479. o_loadq                return (XOPT);
  1480. o_loadnc            return (XXOPT);
  1481. f_ffrom                return (FFLAG);
  1482. f_rfrom                return (RFLAG);
  1483. f_noreset            return (SSFLAG);
  1484. f_noufrom            return (NFLAG);
  1485. f_locm                return (LFLAG);
  1486. f_strip                return (SFLAG);
  1487. f_mult                return (MFLAG);
  1488. f_from                return (FFFLAG);
  1489. f_date                return (DDFLAG);
  1490. f_mesg                return (MMFLAG);
  1491. f_full                return (XFLAG);
  1492. f_return            return (PPFLAG);
  1493. f_upperu            return (UFLAG);
  1494. f_upperh            return (HFLAG);
  1495. f_arpa                return (AAFLAG);
  1496. f_ufrom                return (UUFLAG);
  1497. f_expensive            return (EFLAG);
  1498. f_dot                return (XXFLAG);
  1499. f_llimit            return (LLFLAG);
  1500. f_retsmtp            return (PFLAG);
  1501. f_smtp                return (IIFLAG);
  1502. f_addrw                return (CCFLAG);
  1503. [A-Za-z][A-Za-z0-9_-]*        {
  1504.                 /* store identifiers in symbol table */
  1505.                 yylval.phe = LookupSymbol (yytext);
  1506.                 return (IDENT);
  1507.                 }
  1508. ["]((\\\n)|(\\\")|[^"\n])*    {
  1509.                 if ((INch = input()) == LEXnewline) {
  1510.                     ErrorReport ("End of line in string.\n");
  1511.                     unput (INch);
  1512.                 }
  1513.                 yylval.psb = (char *) malloc (strlen (yytext) + 1);
  1514.                 strcpy (yylval.psb, yytext + 1);
  1515.                 return (SCONST);
  1516.                 }
  1517. [0][0-7]*            {
  1518.                 sscanf (yytext, "%o", &yylval.ival);  /* octal constant */
  1519.                 return (ICONST);
  1520.                 }
  1521. [-]?[1-9][0-9]*            {
  1522.                 yylval.ival = atoi (yytext);
  1523.                 return (ICONST);
  1524.                 }
  1525. "="                return (ASGN);
  1526. ","                return (COMMA);
  1527. "{"                return (LBRACE);
  1528. "}"                return (RBRACE);
  1529. "("                return (LPAREN);
  1530. ")"                return (RPAREN);
  1531. ";"                return (SEMI);
  1532. "$"                return (DOLLAR);
  1533. ":"                return (COLON);
  1534. "*"                return (STAR);
  1535. "/*"                {
  1536.                 /* eat C comments */
  1537.                 INch = input ();
  1538.                 while ((INch != '*') || 
  1539.                       ((INch = input ()) != '/')) {
  1540.                     if (INch == LEXnewline)
  1541.                         Lcount++;
  1542.                     else
  1543.                         if (INch == LEXeof) {
  1544.                             ErrorReport ("End of file in comment.\n");
  1545.                             break;
  1546.                         }
  1547.                     if (INch != '*')
  1548.                         INch = input ();
  1549.                 }
  1550.                 }
  1551. [\\]?.                {
  1552.                 if (RMatch) {    /* in rulesets, return literal character */
  1553.                     yylval.ival = (yytext[0] == '\\') ? yytext[1] : yytext[0];
  1554.                     return (SEPCHAR);
  1555.                 } else {
  1556.                     ErrorReport ("Illegal delimiter character");
  1557.                     printf (": (octal code) \\%03o\n", *yytext);
  1558.                 }
  1559.                 }
  1560. %%
  1561. SHAR_EOF
  1562. if test 5031 -ne "`wc -c lexan.l`"
  1563. then
  1564. echo shar: error transmitting lexan.l '(should have been 5031 characters)'
  1565. fi
  1566. cat << \SHAR_EOF > symtab.h
  1567. /*    $Header: /usr/src/local/etc/ease/RCS/symtab.h,v 1.2 85/10/29 23:47:47 jss Exp $    */
  1568.  
  1569. /*
  1570.  *    symtab.h    -- Definitions related to the "et" symbol table. 
  1571.  *
  1572.  *    author        -- James S. Schoner, Purdue University Computing Center,
  1573.  *                     West Lafayette, Indiana  47907
  1574.  *
  1575.  *    date        -- July 1, 1985
  1576.  *
  1577.  *    Copyright (c) 1985 by Purdue Research Foundation
  1578.  *
  1579.  *    All rights reserved.
  1580.  *
  1581.  */
  1582.  
  1583. #define TRUE      1
  1584. #define FALSE     0
  1585. #define SST       101        /* size of hash table (symbol table)          */
  1586. #define RSNMAX    5        /* size of a ruleset number character buffer */
  1587. #define VALRSNMAX 9999        /* max value of ruleset number             */
  1588.  
  1589.  
  1590. /* identifier types */
  1591. #define ID_UNTYPED 0
  1592. #define ID_MACRO   01
  1593. #define ID_CLASS   02
  1594. #define ID_RULESET 04
  1595. #define ID_FIELD   010
  1596. #define ID_PREC       020
  1597. #define ID_MAILER  040
  1598.  
  1599. /* identifier type macros */
  1600. #define ISTYPED(x) (x|ID_UNTYPED)
  1601. #define ISMACRO(x) (x&ID_MACRO)
  1602. #define ISCLASS(x) (x&ID_CLASS)
  1603. #define ISRULESET(x) (x&ID_RULESET)
  1604. #define ISFIELD(x) (x&ID_FIELD)
  1605. #define ISPREC(x) (x&ID_PREC)
  1606. #define ISMAILER(x) (x&ID_MAILER)
  1607.  
  1608. /* block definition types */
  1609. enum bdefs {def_macro, def_class, def_option, def_prec, def_trusted, 
  1610.         def_header, def_mailer, def_ruleset};
  1611.  
  1612. /* option types */
  1613. enum opts {opt_A, opt_a, opt_B, opt_c, opt_D, opt_d, opt_e, opt_F, opt_f, 
  1614.        opt_g, opt_H, opt_i, opt_L, opt_m, opt_N, opt_o, opt_Q, opt_r, 
  1615.        opt_S, opt_s, opt_T, opt_t, opt_u, opt_v, opt_W, opt_x, opt_X, 
  1616.        d_opt_i, d_opt_b, d_opt_q,
  1617.        e_opt_p, e_opt_e, e_opt_m, e_opt_w, e_opt_z};
  1618.  
  1619. /* flag types */
  1620. enum flgs {flg_f, flg_r, flg_S, flg_n, flg_l, flg_s, flg_m, flg_F, flg_D,
  1621.        flg_M, flg_x, flg_P, flg_u, flg_h, flg_A, flg_U, flg_e, flg_X,
  1622.        flg_L, flg_p, flg_I, flg_C};
  1623.  
  1624. /* mailer parameters */
  1625. enum mats {mat_path, mat_flags, mat_sender, mat_recipient, mat_argv, 
  1626.        mat_eol, mat_maxsize};
  1627.  
  1628. struct he {    /* hash entry structure for symbol table node     */
  1629.     unsigned   idtype;    /* identifier type         */
  1630.     unsigned   idd;          /* identifier definition flag     */
  1631.     char      *psb;        /* identifier string buffer     */
  1632.     union {
  1633.         char rsn[RSNMAX];     /* ruleset number             */
  1634.         int prec;          /* precedence value           */
  1635.         char idc;        /* one char id representation */
  1636.         char *fstring;        /* field string               */
  1637.     } idval;
  1638.     struct he *phe;        /* next hash entry         */
  1639. };
  1640. SHAR_EOF
  1641. if test 2309 -ne "`wc -c symtab.h`"
  1642. then
  1643. echo shar: error transmitting symtab.h '(should have been 2309 characters)'
  1644. fi
  1645. cat << \SHAR_EOF > Makefile
  1646. # Makefile for Ease Translator (et).
  1647. #
  1648. #    $Header: /usr/src/local/etc/ease/RCS/Makefile,v 1.4 85/10/29 22:57:06 jss Exp $
  1649. #
  1650. #    James S. Schoner, Purdue University Computing Center,
  1651. #              West Lafayette, Indiana  47907
  1652. #
  1653. #    Copyright (c) 1985 by Purdue Research Foundation
  1654. #
  1655. #    All rights reserved.
  1656. #
  1657.  
  1658. INCLUDE =
  1659.  
  1660. DEST = /usr/local/etc
  1661.  
  1662. OWNER = binary
  1663. GROUP = system
  1664. MODE = 751
  1665.  
  1666. DEFS =
  1667. CFLAGS = -O ${DEFS} ${INCLUDE}
  1668.  
  1669. LP = lpr
  1670. LPFLAGS = -J"Ease Source"
  1671.  
  1672. HDR = symtab.h
  1673. SRC = main.c emitcf.c errors.c idman.c strops.c symtab.c
  1674. LST = Makefile lexan.l parser.y ${HDR} ${SRC}
  1675. DEP = y.tab.c lex.yy.c ${SRC}
  1676. OBJ = y.tab.o lex.yy.o main.o emitcf.o errors.o idman.o strops.o symtab.o
  1677.  
  1678. all: et
  1679.  
  1680. et: ${OBJ}
  1681.     cc ${CFLAGS} -o et ${OBJ} -ll
  1682.  
  1683. clean: FRC
  1684.     rm -f et *.o lex.yy.c y.tab.c y.output yacc.acts yacc.tmp \
  1685.           lexdefs.h y.tab.h errs Makefile.bak
  1686.  
  1687. depend: ${DEP} ${HDR}
  1688.     maketd -a ${DEP}
  1689.  
  1690. install: et FRC
  1691.     install -c -m ${MODE} -o ${OWNER} -g ${GROUP} -s et ${DEST}
  1692.  
  1693. lint:   ${DEP} symtab.h FRC
  1694.     lint -hxn ${DEP}
  1695.  
  1696. print:  ${LST} FRC
  1697.     @pr -f ${LST} | ${LP} ${LPFLAGS}
  1698.  
  1699. spotless: clean FRC
  1700.     rcsclean ${LST}
  1701.  
  1702. lexdefs.h y.tab.c: parser.y
  1703.     yacc -d parser.y
  1704.     -(cmp -s y.tab.h lexdefs.h || cp y.tab.h lexdefs.h)
  1705.  
  1706. lex.yy.c: lexan.l
  1707.     lex lexan.l
  1708.  
  1709. ${HDR} ${SRC} lexan.l parser.y:
  1710.     co $@
  1711.  
  1712. FRC:
  1713.     
  1714.  
  1715. # DO NOT DELETE THIS LINE - maketd DEPENDS ON IT
  1716. # Dependencies generated at: Thu Oct 17 14:55:17 EST 1985
  1717.  
  1718. emitcf.o: symtab.h
  1719. emitcf.o: /usr/include/stdio.h
  1720. emitcf.o: emitcf.c
  1721. errors.o: /usr/include/stdio.h
  1722. errors.o: errors.c
  1723. idman.o: symtab.h
  1724. idman.o: /usr/include/stdio.h
  1725. idman.o: idman.c
  1726. lex.yy.o: lexdefs.h
  1727. lex.yy.o: symtab.h
  1728. lex.yy.o: /usr/include/stdio.h
  1729. lex.yy.o: lex.yy.c
  1730. main.o: /usr/include/stdio.h
  1731. main.o: main.c
  1732. strops.o: symtab.h
  1733. strops.o: /usr/include/stdio.h
  1734. strops.o: /usr/include/strings.h
  1735. strops.o: strops.c
  1736. symtab.o: symtab.h
  1737. symtab.o: /usr/include/ctype.h
  1738. symtab.o: /usr/include/stdio.h
  1739. symtab.o: symtab.c
  1740. y.tab.o: symtab.h
  1741. y.tab.o: /usr/include/stdio.h
  1742. y.tab.o: y.tab.c
  1743.  
  1744. # DO NOT ADD ANYTHING HERE - it will go away.
  1745. SHAR_EOF
  1746. if test 2016 -ne "`wc -c Makefile`"
  1747. then
  1748. echo shar: error transmitting Makefile '(should have been 2016 characters)'
  1749. fi
  1750. chdir ..
  1751. #    End of shell archive
  1752. exit 0
  1753.  
  1754.