home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume17 / ease2 / part02 < prev    next >
Encoding:
Internet Message Format  |  1989-02-08  |  46.6 KB

  1. Subject:  v17i088:  Ease2.0, a language for sendmail.cf files, Part02/03
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4.  
  5. Submitted-by: "Arnold D. Robbins" <arnold@EMORYU1.ARPA>
  6. Posting-number: Volume 17, Issue 88
  7. Archive-name: ease2/part02
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line, then unpack
  11. # it by saving it into a file and typing "sh file".  To overwrite existing
  12. # files, type "sh file -c".  You can also feed this as standard input via
  13. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  14. # will see the following message at the end:
  15. #        "End of archive 2 (of 3)."
  16. # Contents:  src/emitcf.c src/lexan.l src/parser.y src/strops.c
  17. # Wrapped by rsalz@papaya.bbn.com on Wed Feb  8 16:55:43 1989
  18. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  19. if test -f 'src/emitcf.c' -a "${1}" != "-c" ; then 
  20.   echo shar: Will not clobber existing file \"'src/emitcf.c'\"
  21. else
  22. echo shar: Extracting \"'src/emitcf.c'\" \(7475 characters\)
  23. sed "s/^X//" >'src/emitcf.c' <<'END_OF_FILE'
  24. X/*    $Header: emitcf.c,v 2.0 88/06/15 14:40:47 root Exp $    */
  25. X
  26. X/*
  27. X * $Log:    emitcf.c,v $
  28. X * Revision 2.0  88/06/15  14:40:47  root
  29. X * Baseline release for net posting. ADR.
  30. X * 
  31. X */
  32. X
  33. X/*
  34. X *    emitcf.c  -- This file contains routines associated with the writing
  35. X *             and formatting of a translated sendmail configuration file.
  36. X *
  37. X *    author      -- James S. Schoner, Purdue University Computing Center,
  38. X *                         West Lafayette, Indiana  47907
  39. X *
  40. X *      date      -- July 9, 1985
  41. X *
  42. X *    Copyright (c) 1985 by Purdue Research Foundation
  43. X *
  44. X *    All rights reserved.
  45. X *
  46. X */
  47. X
  48. X#include <stdio.h>
  49. X#include "symtab.h"
  50. X#include "fixstrings.h"
  51. X
  52. X#define REGLINE 60    /* length of output lines which may be continued */
  53. X#define MAXLINE 256    /* liberal maximum line length             */
  54. X
  55. Xextern short Rformat;            /* read-format flag for a class  */
  56. Xextern char *MacScan ();
  57. Xextern char  MakeMac ();
  58. Xextern void  PrintError (),
  59. X         FatalError (),
  60. X         PrintWarning (),
  61. X         ErrorReport ();
  62. X
  63. Xvoid  PrintDef ();
  64. X
  65. Xstatic char ClassCH;            /* printable class macro char    */
  66. X
  67. X/*
  68. X *    EmitDef () -- Emit a definition line (Ease block definition) in cf 
  69. X *              format.
  70. X *
  71. X */
  72. Xvoid
  73. XEmitDef (blockdef, targ, defstr1, defstr2)
  74. Xregister enum bdefs blockdef;    /* type of definition        */
  75. Xregister struct he *targ;    /* target to be defined      */
  76. Xchar *defstr1, *defstr2;    /* one or two definition strings */
  77. X{
  78. X    /*
  79. X     *  This routine is about as pretty as a translated ease file...
  80. X     *  Each type of line (Ease block) is handled case by case below.
  81. X     *
  82. X     */
  83. X    switch (blockdef) {
  84. X        case def_macro:        printf ("D%c", MakeMac (targ, ID_MACRO));
  85. X                    PrintDef (def_macro, MacScan (defstr1));
  86. X                    if (ISMACRO(targ->idd))
  87. X                        PrintWarning ("Redefining macro %s.\n", targ->psb);
  88. X                    targ->idd |= ID_MACRO;  /* signal definition */
  89. X                    break;
  90. X
  91. X        case def_class:        if (Rformat)    /* read format */
  92. X                        printf ("F");
  93. X                    else
  94. X                        printf ("C");
  95. X                    printf ("%c", ClassCH = MakeMac (targ, ID_CLASS));
  96. X                    if (Rformat) {    /* read format */
  97. X                        printf ("%s\n", defstr1);
  98. X                        Rformat = FALSE;
  99. X                    } else
  100. X                        PrintDef (def_class, defstr1);
  101. X                    if (ISCLASS(targ->idd))
  102. X                        PrintWarning ("Redefining class %s.\n", targ->psb);
  103. X                    targ->idd |= ID_CLASS;  /* signal definition */
  104. X                    break;
  105. X
  106. X        case def_option:    if (defstr1 == NULL)
  107. X                        FatalError ("No option passed in EmitDef()", (char *)NULL);
  108. X                    printf ("O%c", *defstr1);
  109. X                    PrintDef (def_option, defstr2);
  110. X                    break;
  111. X
  112. X        case def_prec:        printf ("P%s=%d\n", targ->psb, targ->idval.prec);
  113. X                    break;
  114. X
  115. X        case def_trusted:    printf ("T");
  116. X                    PrintDef (def_trusted, defstr1);
  117. X                    break;
  118. X
  119. X        case def_header:    printf ("H");
  120. X                    if (defstr1 != NULL)
  121. X                        printf ("?%s?", defstr1);
  122. X                    PrintDef (def_header, defstr2);
  123. X                    break;
  124. X
  125. X        case def_mailer:    if (ISMAILER(targ->idtype)) {
  126. X                        if (ISMAILER(targ->idd))
  127. X                            PrintWarning ("Redefining mailer %s.\n", targ->psb);
  128. X                    } else if (ISTYPED(targ->idtype)) {
  129. X                        PrintError ("Redeclaration of identifier as mailer:", targ->psb);
  130. X                        return;
  131. X                    }
  132. X                    targ->idd |= ID_MAILER;  /* signal definition */
  133. X                    printf ("M%s, ", targ->psb);
  134. X                    PrintDef (def_mailer, defstr1);
  135. X                    break;
  136. X
  137. X        case def_ruleset:    printf ("R");
  138. X                    PrintDef (def_ruleset, defstr1);
  139. X                    break;
  140. X
  141. X        default:        FatalError ("Bad case in EmitDef ()", (char *) NULL);
  142. X    }
  143. X}
  144. X
  145. X
  146. X/*
  147. X *      PrintContinued () -- Print a line definition (buf) by splitting it over
  148. X *                 more than one line.  The two definition types 
  149. X *                 accepted for this method of continuation are class
  150. X *                 and trusted user lists, indicated in the argument 
  151. X *                 btype 
  152. X *
  153. X */
  154. Xvoid
  155. XPrintContinued (btype, buf)
  156. Xenum bdefs     btype;    /* block (line) type for definition */
  157. Xregister char *buf;    /* buffer containing the definition */
  158. X{
  159. X    register char *tmp;    /* breakpoint search pointer   */
  160. X    register char  tc;    /* temporary swap byte         */
  161. X    int  buflen;        /* length of definition buffer */    
  162. X
  163. X    buflen = strlen (buf);
  164. X    tmp = buf + REGLINE;
  165. X    while ((*--tmp != ' ') && (tmp != buf))     /* look for suitable break */
  166. X        /* null */ ;
  167. X    if (tmp == buf) {
  168. X        for (tmp = buf + REGLINE; (*tmp != ' ') && (tmp - buf != buflen); tmp++)
  169. X            /* null */ ;
  170. X        if ((tmp - buf) >= MAXLINE)
  171. X            PrintWarning ("Member name may be too long.\n", (char *) NULL);
  172. X    }
  173. X    tc = *tmp;        /* swap break char with null char */
  174. X    *tmp = '\0';
  175. X    printf ("%s\n", buf);
  176. X    if ((*tmp = tc) == '\0')
  177. X        return;
  178. X    else
  179. X        tmp++;
  180. X    if (btype == def_class)        /* start next line   */
  181. X        printf ("C%c", ClassCH);
  182. X    else
  183. X        printf ("T");
  184. X    if (strlen (tmp) < REGLINE)    /* continue the line */
  185. X        printf ("%s\n", tmp);
  186. X    else
  187. X        PrintContinued (btype, tmp);
  188. X}
  189. X
  190. X
  191. X/*
  192. X *    PrintDef () -- Handles special cases (like line continuation) when 
  193. X *               printing definitions.
  194. X *
  195. X */
  196. Xvoid
  197. XPrintDef (btype, dstr)
  198. Xregister enum bdefs btype;    /* block type (output line type) */
  199. Xregister char *dstr;        /* definition string         */
  200. X{
  201. X    register char *tmp;
  202. X
  203. X    if (dstr == (char *)NULL)
  204. X        dstr = "";
  205. X
  206. X    for (tmp = dstr; *tmp != '\0'; tmp++)     /* search for line continuations */
  207. X        if ((*tmp == '\\') && (*++tmp == '\n'))
  208. X            if (btype != def_header) {
  209. X                ErrorReport ("Non-header string contains line continuation\n");
  210. X                return;
  211. X            } else
  212. X                break;
  213. X
  214. X    /*
  215. X     *  Perform case by case handling of definition printing.
  216. X     *
  217. X     */
  218. X    switch (btype) {
  219. X        case def_header :  if (*tmp-- == '\n') {
  220. X                    *tmp = '\0';
  221. X                    if (tmp - dstr >= MAXLINE)
  222. X                        PrintWarning ("Header may be too long.\n", 
  223. X                                  (char *) NULL);
  224. X                    printf ("%s\n\t", dstr);
  225. X                    tmp += 2;
  226. X                        PrintDef (def_header, tmp);
  227. X                   } else {
  228. X                    if (strlen (dstr) >= MAXLINE)
  229. X                        PrintWarning ("Header may be too long.\n", 
  230. X                                  (char *) NULL);
  231. X                    printf ("%s\n", dstr);
  232. X                   }
  233. X                   break;
  234. X
  235. X        case def_mailer :  if (strlen (dstr) >= MAXLINE)
  236. X                    PrintWarning ("Mailer definition may be too long.\n", 
  237. X                              (char *) NULL);
  238. X                   printf ("%s\n", dstr);
  239. X                   break;
  240. X
  241. X        case def_ruleset:  if (strlen (dstr) >= MAXLINE)
  242. X                    PrintWarning ("Rewriting rule may be too long.\n", 
  243. X                              (char *) NULL);
  244. X                   printf ("%s\n", dstr);
  245. X                   break;
  246. X
  247. X        case def_option :  if (strlen (dstr) >= MAXLINE)
  248. X                    PrintWarning ("Option assignment may be too long.\n", 
  249. X                              (char *) NULL);
  250. X                   printf ("%s\n", dstr);
  251. X                   break;
  252. X
  253. X        case def_macro  :  if (strlen (dstr) >= MAXLINE)
  254. X                    PrintWarning ("Macro assignment may be too long.\n", 
  255. X                              (char *) NULL);
  256. X                   printf ("%s\n", dstr);
  257. X                   break;
  258. X
  259. X        case def_prec   :  if (strlen (dstr) >= MAXLINE)
  260. X                    PrintWarning ("Precedence relation may be too long.\n", 
  261. X                              (char *) NULL);
  262. X                   printf ("%s\n", dstr);
  263. X                   break;
  264. X
  265. X        case def_trusted:
  266. X        case def_class  :  if (strlen (dstr) < REGLINE)
  267. X                    printf ("%s\n", dstr);
  268. X                   else        /* use line continuation feature */
  269. X                       PrintContinued (btype, dstr);
  270. X                   break;
  271. X
  272. X        default         :  FatalError ("Invalid case in PrintDef ()", (char *) NULL);
  273. X    }
  274. X}
  275. X
  276. X
  277. X/*
  278. X *    StartRuleset () -- Prints a ruleset heading for the ruleset identifier
  279. X *                   contained in the argument rsid.
  280. X *
  281. X */
  282. Xvoid
  283. XStartRuleset (rsid)
  284. Xregister struct he *rsid;    /* ruleset identifier */
  285. X{
  286. X    if (!ISRULESET(rsid->idtype))
  287. X        if (ISTYPED(rsid->idtype))
  288. X            PrintError ("Identifier not of ruleset type:", rsid->psb);
  289. X        else
  290. X            PrintError ("Ruleset identifier not bound to a number:", rsid->psb);
  291. X    else {
  292. X        if (ISRULESET(rsid->idd))
  293. X            PrintWarning ("Redefining ruleset %s.\n", rsid->psb);
  294. X        rsid->idd |= ID_RULESET;
  295. X        printf ("S%s\n", rsid->idval.rsn);
  296. X    }
  297. X}
  298. END_OF_FILE
  299. if test 7475 -ne `wc -c <'src/emitcf.c'`; then
  300.     echo shar: \"'src/emitcf.c'\" unpacked with wrong size!
  301. fi
  302. chmod +x 'src/emitcf.c'
  303. # end of 'src/emitcf.c'
  304. fi
  305. if test -f 'src/lexan.l' -a "${1}" != "-c" ; then 
  306.   echo shar: Will not clobber existing file \"'src/lexan.l'\"
  307. else
  308. echo shar: Extracting \"'src/lexan.l'\" \(6834 characters\)
  309. sed "s/^X//" >'src/lexan.l' <<'END_OF_FILE'
  310. X%{
  311. X/*    $Header: lexan.l,v 2.0 88/06/15 15:11:30 root Exp $ */
  312. X
  313. X/*
  314. X * $Log:    lexan.l,v $
  315. X * Revision 2.0  88/06/15  15:11:30  root
  316. X * Baseline release for net posting. ADR.
  317. X * 
  318. X */
  319. X
  320. X/*
  321. X *    lexan.l -- Lexical Analyzer for EASE.
  322. X *
  323. X *           Contains code for lex(1) which generates a lexical
  324. X *           analyzer (lex.yy.c) for Ease, a high-level specification 
  325. X *           format for sendmail configuration files.
  326. X *
  327. X *    author -- James S. Schoner, Purdue University Computing Center,
  328. X *                    West Lafayette, Indiana  47907
  329. X *
  330. X *    date   -- July 1, 1985
  331. X *
  332. X *    Copyright (c) 1985 by Purdue Research Foundation
  333. X *
  334. X *    All rights reserved.
  335. X *
  336. X */
  337. X
  338. X#include "fixstrings.h"
  339. X#include "symtab.h"
  340. X#include "lexdefs.h"
  341. X
  342. X#define  LEXnewline '\n'
  343. X#define     LEXeof        '\0'
  344. X#define  MaxFN        200            /* maximum file name length */
  345. X
  346. Xextern struct he *LookupSymbol ();
  347. Xextern void      ErrorReport ();
  348. X
  349. Xint  Lcount;                /* line counter            */
  350. Xchar FNbuf[MaxFN];            /* file name buffer        */
  351. Xshort RMatch  = FALSE;            /* ruleset match flag          */
  352. X
  353. X#undef input
  354. X# define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):Getc(yyin,yyout))==10?(yylineno++,yytchar):yytchar)==EOF?0:yytchar)
  355. X
  356. Xchar
  357. XGetc (yyin, yyout)
  358. X    FILE *yyin, *yyout;
  359. X{
  360. X    static char linbuf[BUFSIZ], *pc = linbuf;
  361. X    char c;
  362. X
  363. X    /* initialize buffer: first call only */
  364. X    if (*pc == '\0' && pc == linbuf) {
  365. X        if (fgets(linbuf, BUFSIZ, yyin)==NULL)
  366. X            return EOF;
  367. X        fprintf(yyout, "# %s", linbuf);  /* echo input as comment */
  368. X    }
  369. X    c = *pc++;
  370. X    if (c == '\n') {
  371. X        pc = linbuf;
  372. X        if (fgets(linbuf, BUFSIZ, yyin) == NULL)
  373. X            *pc = EOF;
  374. X        else
  375. X            /* echo input as comment */
  376. X            fprintf(yyout, "# %s", linbuf);
  377. X    }
  378. X    return c;
  379. X}
  380. X
  381. X/*
  382. X * Table of keywords. NOTE: This is in sorted order, and
  383. X * must stay that way if anything else is added to it.
  384. X */
  385. Xstatic struct resword {
  386. X    char    *r_text;
  387. X    int    r_tokval;
  388. X} reswords[] = {
  389. X    { "Argv",        MARGV },
  390. X    { "Eol",        MEOL },
  391. X    { "Flags",        MFLAGS },
  392. X    { "Maxsize",        MMAXSIZE },
  393. X    { "Path",        MPATH },
  394. X    { "Recipient",        MRECIPIENT },
  395. X    { "Sender",        MSENDER },
  396. X    { "bind",        BIND },
  397. X    { "canon",        CANON },
  398. X    { "class",        CLASS },
  399. X    { "concat",        CONCAT },
  400. X    { "d_background",    DOPTB },
  401. X    { "d_interactive",    DOPTI },
  402. X    { "d_queue",        DOPTQ },
  403. X    { "define",        DEFINE },
  404. X    { "f_addrw",        CCFLAG },
  405. X    { "f_arpa",        AAFLAG },
  406. X    { "f_date",        DDFLAG },
  407. X    { "f_dot",        XXFLAG },
  408. X    { "f_escape",        EEFLAG },
  409. X    { "f_expensive",    EFLAG },
  410. X    { "f_ffrom",        FFLAG },
  411. X    { "f_from",        FFFLAG },
  412. X    { "f_full",        XFLAG },
  413. X    { "f_llimit",        LLFLAG },
  414. X    { "f_locm",        LFLAG },
  415. X    { "f_mesg",        MMFLAG },
  416. X    { "f_mult",        MFLAG },
  417. X    { "f_noreset",        SSFLAG },
  418. X    { "f_noufrom",        NFLAG },
  419. X    { "f_retsmtp",        PFLAG },
  420. X    { "f_return",        PPFLAG },
  421. X    { "f_rfrom",        RFLAG },
  422. X    { "f_rport",        RRFLAG },
  423. X    { "f_smtp",        IIFLAG },
  424. X    { "f_strip",        SFLAG },
  425. X    { "f_ufrom",        UUFLAG },
  426. X    { "f_upperh",        HFLAG },
  427. X    { "f_upperu",        UFLAG },
  428. X    { "field",        FIELD },
  429. X    { "for",        FOR },
  430. X    { "h_exit",        EOPTE },
  431. X    { "h_mail",        EOPTM },
  432. X    { "h_mailz",        EOPTZ },
  433. X    { "h_print",        EOPTP },
  434. X    { "h_write",        EOPTW },
  435. X    { "header",        HEADER },
  436. X    { "host",        HOST },
  437. X    { "hostnum",        HOSTNUM },
  438. X    { "if",            IF },
  439. X    { "ifset",        IFSET },
  440. X    { "in",            IN },
  441. X    { "macro",        MACRO },
  442. X    { "mailer",        MAILER },
  443. X    { "map",        MAP },
  444. X    { "match",        MATCH },
  445. X    { "next",        NEXT },
  446. X    { "o_alias",        AAOPT },
  447. X    { "o_bsub",        BBOPT },
  448. X    { "o_checkpoint",    CCOPT },
  449. X    { "o_delivery",        DOPT },
  450. X    { "o_dmuid",        UOPT },
  451. X    { "o_dnet",        NNOPT },
  452. X    { "o_ewait",        AOPT },
  453. X    { "o_flog",        SSOPT },
  454. X    { "o_fsmtp",        HHOPT },
  455. X    { "o_gid",        GOPT },
  456. X    { "o_handling",        EOPT },
  457. X    { "o_hformat",        OOPT },
  458. X    { "o_loadnc",        XXOPT },
  459. X    { "o_loadq",        XOPT },
  460. X    { "o_newproc",        YYOPT },
  461. X    { "o_pmaster",        PPOPT },
  462. X    { "o_prifactor",    ZOPT },
  463. X    { "o_qdir",        QQOPT },
  464. X    { "o_qfactor",        QOPT },
  465. X    { "o_qtimeout",        TTOPT },
  466. X    { "o_qwait",        COPT },
  467. X    { "o_rebuild",        DDOPT },
  468. X    { "o_recipfactor",    YOPT },
  469. X    { "o_rsend",        MOPT },
  470. X    { "o_safe",        SOPT },
  471. X    { "o_skipd",        IOPT },
  472. X    { "o_slog",        LLOPT },
  473. X    { "o_timezone",        TOPT },
  474. X    { "o_tmode",        FFOPT },
  475. X    { "o_tread",        ROPT },
  476. X    { "o_usave",        FOPT },
  477. X    { "o_validate",        NOPT },
  478. X    { "o_verbose",        VOPT },
  479. X    { "o_waitfactor",    ZZOPT },
  480. X    { "o_wizpass",        WWOPT },
  481. X    { "options",        OPTIONS },
  482. X    { "precedence",        PRECEDENCE },
  483. X    { "readclass",        READCLASS },
  484. X    { "resolve",        RESOLVE },
  485. X    { "retry",        RETRY },
  486. X    { "return",        RETURN },
  487. X    { "ruleset",        RULESET },
  488. X    { "trusted",        TRUSTED },
  489. X    { "user",        USER },
  490. X    { "while",        IF },
  491. X};
  492. X%}
  493. X
  494. X%%
  495. X    int INch;            /* any input character */
  496. X
  497. X[ \t\f]+            ;     /* discard whitepsace  */
  498. X[\n]                Lcount++;
  499. X^\#[ \t]*[0-9]+[ \t]*\".*\"[ \t]*[\n]    {
  500. X                    sscanf (yytext, "%*c%d%s", &Lcount, FNbuf);
  501. X                    }
  502. X[A-Za-z][A-Za-z0-9_-]*        {
  503. X                register int l, h, m, r, c;
  504. X
  505. X                l = 0;
  506. X                h = (sizeof (reswords) / sizeof(reswords[0])) - 1;
  507. X                while (l <= h) {
  508. X                    m = (h + l) / 2;
  509. X                    c = yytext[0] - reswords[m].r_text[0];
  510. X                    r = c ? c : strcmp (yytext, reswords[m].r_text);
  511. X                    if (r < 0)
  512. X                        h = m - 1;
  513. X                    else if (r > 0)
  514. X                        l = m + 1;
  515. X                    else
  516. X                        return reswords[m].r_tokval;
  517. X                }
  518. X
  519. X                /* not a keyword */
  520. X
  521. X                /* store identifiers in symbol table */
  522. X                yylval.phe = LookupSymbol (yytext);
  523. X                return (IDENT);
  524. X                }
  525. X["]((\\\n)|(\\\")|[^"\n])*    {
  526. X                if ((INch = input()) == LEXnewline) {
  527. X                    ErrorReport ("End of line in string.\n");
  528. X                    unput (INch);
  529. X                }
  530. X                fixquotes ();
  531. X                yylval.psb = (char *) malloc (strlen (yytext) + 1);
  532. X                strcpy (yylval.psb, yytext + 1);
  533. X                return (SCONST);
  534. X                }
  535. X[0][0-7]*            {
  536. X                sscanf (yytext, "%o", &yylval.ival);  /* octal constant */
  537. X                return (ICONST);
  538. X                }
  539. X[-]?[1-9][0-9]*            {
  540. X                yylval.ival = atoi (yytext);
  541. X                return (ICONST);
  542. X                }
  543. X"="                return (ASGN);
  544. X","                return (COMMA);
  545. X"{"                return (LBRACE);
  546. X"}"                return (RBRACE);
  547. X"("                return (LPAREN);
  548. X")"                return (RPAREN);
  549. X";"                return (SEMI);
  550. X"$"                return (DOLLAR);
  551. X":"                return (COLON);
  552. X"*"                return (STAR);
  553. X"/*"                {
  554. X                /* eat C comments */
  555. X                INch = input ();
  556. X                while ((INch != '*') || 
  557. X                      ((INch = input ()) != '/')) {
  558. X                    if (INch == LEXnewline)
  559. X                        Lcount++;
  560. X                    else
  561. X                        if (INch == LEXeof) {
  562. X                            ErrorReport ("End of file in comment.\n");
  563. X                            break;
  564. X                        }
  565. X                    if (INch != '*')
  566. X                        INch = input ();
  567. X                }
  568. X                }
  569. X[\\]?.                {
  570. X                if (RMatch) {    /* in rulesets, return literal character */
  571. X                    yylval.ival = (yytext[0] == '\\') ? yytext[1] : yytext[0];
  572. X                    return (SEPCHAR);
  573. X                } else {
  574. X                    ErrorReport ("Illegal delimiter character");
  575. X                    printf (": (octal code) \\%03o\n", *yytext);
  576. X                }
  577. X                }
  578. X%%
  579. X
  580. X/*
  581. X * fixquotes --- inside a "quoted string", turn `\"' into just `"'
  582. X *
  583. X * this is most useful inside the Argv strings for mailers,
  584. X * particularly when debugging.
  585. X */
  586. X
  587. Xfixquotes ()
  588. X{
  589. X    register char *cp1, *cp2;
  590. X
  591. X    cp1 = cp2 = yytext;
  592. X    while (*cp2) {
  593. X        /*
  594. X         * if we really wanted to get fancy,
  595. X         * at this point we'd handle C escapes,
  596. X         * but I don't think it's necessary.
  597. X         */
  598. X        if (*cp2 == '\\' && cp2[1] == '"')
  599. X            cp2++;
  600. X        *cp1++ = *cp2++;
  601. X    }
  602. X    *cp1++ = *cp2++;    /* final '\0' */
  603. X}
  604. END_OF_FILE
  605. if test 6834 -ne `wc -c <'src/lexan.l'`; then
  606.     echo shar: \"'src/lexan.l'\" unpacked with wrong size!
  607. fi
  608. chmod +x 'src/lexan.l'
  609. # end of 'src/lexan.l'
  610. fi
  611. if test -f 'src/parser.y' -a "${1}" != "-c" ; then 
  612.   echo shar: Will not clobber existing file \"'src/parser.y'\"
  613. else
  614. echo shar: Extracting \"'src/parser.y'\" \(15988 characters\)
  615. sed "s/^X//" >'src/parser.y' <<'END_OF_FILE'
  616. X%{
  617. X/*    $Header: parser.y,v 2.0 88/06/15 14:42:46 root Exp $    */
  618. X
  619. X/*
  620. X * $Log:    parser.y,v $
  621. X * Revision 2.0  88/06/15  14:42:46  root
  622. X * Baseline release for net posting. ADR.
  623. X * 
  624. X */
  625. X
  626. X/*
  627. X *    parser.y -- EASE parser.
  628. X *
  629. X *            Contains code for yacc(1) which produces a parser (y.tab.c)
  630. X *            for Ease, a specification format for sendmail configuration
  631. X *            files.
  632. X *
  633. X *    author   -- James S. Schoner, Purdue University Computing Center,
  634. X *                          West Lafayette, Indiana  47907
  635. X *
  636. X *    date     -- July 2, 1985
  637. X *
  638. X *    Copyright (c) 1985 by Purdue Research Foundation
  639. X *
  640. X *    All rights reserved.
  641. X *
  642. X */
  643. X
  644. X#include "fixstrings.h"
  645. X#include <stdio.h>
  646. X#include "symtab.h"
  647. X
  648. Xextern void       BindID ();
  649. Xextern void       EmitDef ();
  650. Xextern char      *ListAppend ();
  651. Xextern char       *MakeCond ();
  652. Xextern char      *MakeRStr ();
  653. Xextern char       *ConvOpt ();
  654. Xextern char      *ConvFlg ();
  655. Xextern char      *MacScan ();
  656. Xextern char      *ConvMat ();
  657. Xextern void       StartRuleset ();
  658. Xextern char      *MakePosTok ();
  659. Xextern char      *GetField ();
  660. Xextern char      *Bracket ();
  661. Xextern char      *MakeRSCall ();
  662. Xextern char      *CheckMailer ();
  663. Xextern char      *CheckRS ();
  664. Xextern char      *MakeField ();
  665. Xextern char       MakeMac ();
  666. Xextern void       AssignType ();
  667. Xextern void       RemoveSymbol ();
  668. Xextern void       yyerror ();
  669. X
  670. Xextern short RMatch;        /* ruleset match flag               */
  671. X
  672. Xchar *Cbuf = " ";        /* character buffer                 */
  673. Xchar *Mbuf = "$ ";        /* macro buffer                        */
  674. Xchar *Tsb;            /* pointer to temporary string buffer */
  675. Xchar *Flaglist;            /* pointer to header flag list          */
  676. X
  677. X%}
  678. X
  679. X%union {            /* value stack element type    */
  680. X    int      ival;        /* integer token            */
  681. X    char      *psb;        /* string token               */
  682. X    struct he *phe;        /* pointer to hash entry       */
  683. X    enum opts optval;    /* sendmail options           */
  684. X    enum flgs flgval;    /* mailer flags               */
  685. X    enum mats mpval;    /* mailer attribute parameters */
  686. X}
  687. X
  688. X%start config
  689. X
  690. X%token     <phe>    IDENT
  691. X%token  <psb>    SCONST
  692. X%token  <ival>    ICONST SEPCHAR
  693. X%token BIND CANON CLASS CONCAT FOR HEADER HOST HOSTNUM IF IFSET IN
  694. X%token MACRO MAILER MAP MARGV MATCH MEOL MFLAGS MMAXSIZE MPATH
  695. X%token MRECIPIENT MSENDER NEXT OPTIONS PRECEDENCE READCLASS RESOLVE
  696. X%token RETRY RETURN RULESET TRUSTED USER
  697. X
  698. X%token ASGN COLON COMMA DEFINE DOLLAR FIELD LBRACE LPAREN RBRACE
  699. X%token RPAREN SEMI STAR
  700. X
  701. X%token AAOPT AOPT BBOPT CCOPT COPT DDOPT DOPT DOPTB DOPTI DOPTQ EOPT
  702. X%token EOPTE EOPTM EOPTP EOPTW EOPTZ FFOPT FOPT GOPT HHOPT IOPT LLOPT
  703. X%token MOPT NNOPT NOPT OOPT PPOPT QOPT QQOPT ROPT SOPT SSOPT TOPT TTOPT
  704. X%token UOPT VOPT WWOPT XOPT XXOPT YOPT YYOPT ZOPT ZZOPT
  705. X
  706. X%token AAFLAG CCFLAG DDFLAG EEFLAG EFLAG FFFLAG FFLAG HFLAG IIFLAG LFLAG
  707. X%token LLFLAG MFLAG MMFLAG NFLAG PFLAG PPFLAG RFLAG RRFLAG SFLAG SSFLAG
  708. X%token UFLAG UUFLAG XFLAG XXFLAG
  709. X
  710. X%type    <psb>        mval strval ifcon conval ifres elseres nameset namelist
  711. X%type    <psb>        doptid eoptid idlist fcond dlist mflags route mdefs
  712. X%type    <psb>        matchaddr matchtok action actionstmt mailerspec mtdef
  713. X%type    <psb>        rwaddr rwtok ftype reftok rword cantok resolution
  714. X%type    <psb>        userspec hword hostid dheader
  715. X%type    <psb>        catstring canval canvaltok
  716. X%type    <ival>        anychar
  717. X%type    <phe>        cdef
  718. X%type    <optval>    optid
  719. X%type    <flgval>    flagid
  720. X%type    <mpval>        mvar
  721. X
  722. X%left COMMA
  723. X%left LPAREN RPAREN
  724. X%nonassoc SCONST
  725. X
  726. X%%
  727. Xconfig        :    /* empty */
  728. X        |    config blockdef
  729. X        |    error blockdef
  730. X        ;
  731. X
  732. Xblockdef    :    BIND bindings
  733. X        |    MACRO macdefs
  734. X        |    CLASS classdefs
  735. X        |    OPTIONS optdefs
  736. X        |    PRECEDENCE precdefs
  737. X        |    TRUSTED tlist
  738. X        |    HEADER hdefs
  739. X        |    MAILER mlist
  740. X        |    RULESET rdef
  741. X        |    FIELD fdefs
  742. X        ;
  743. X
  744. Xbindings    :    /* empty */
  745. X        |    bindings IDENT ASGN RULESET ICONST SEMI {
  746. X                BindID ($2, $5, ID_RULESET);
  747. X            }
  748. X        |    error SEMI {
  749. X                yyerrok;
  750. X            }
  751. X        ;
  752. X
  753. Xmacdefs        :    /* empty */
  754. X        |    macdefs IDENT ASGN mval SEMI {
  755. X                EmitDef (def_macro, $2, $4, (char *) NULL);
  756. X            }
  757. X        |    error SEMI {
  758. X                yyerrok;
  759. X            }
  760. X        ;
  761. X
  762. Xmval        :    strval                %prec COMMA {
  763. X                $$ = $1;
  764. X            }
  765. X        |    CONCAT LPAREN conval RPAREN {
  766. X                $$ = $3;
  767. X            }
  768. X        ;
  769. X
  770. Xstrval        :    SCONST {
  771. X                $$ = $1;
  772. X            }
  773. X        |    strval SCONST {
  774. X                $$ = ListAppend ($1, $2, (char *) NULL);
  775. X                free ($1);
  776. X            }
  777. X        ;
  778. X
  779. Xconval        :    strval COMMA ifcon {
  780. X                $$ = ListAppend ($1, $3, (char *) NULL);
  781. X                free ($1);
  782. X                free ($3);
  783. X            }
  784. X        |    ifcon COMMA strval {
  785. X                $$ = ListAppend ($1, $3, (char *) NULL);
  786. X                free ($1);
  787. X                free ($3);
  788. X            }
  789. X        |    error {
  790. X                $$ = NULL;
  791. X            }
  792. X        ;
  793. X
  794. Xifcon        :    IFSET LPAREN IDENT COMMA ifres RPAREN {
  795. X                $$ = MakeCond ($3, $5);
  796. X            }
  797. X        ;
  798. X
  799. Xifres        :    mval elseres {
  800. X                if ($2 != NULL) {
  801. X                    $$ = ListAppend ($1, $2, "$|");
  802. X                    free ($1);
  803. X                    free ($2);
  804. X                } else
  805. X                    $$ = $1;
  806. X            }
  807. X        |    error {
  808. X                $$ = NULL;
  809. X            }
  810. X        ;
  811. X
  812. Xelseres        :    /* empty */ {
  813. X                $$ = NULL;
  814. X            }
  815. X        |    COMMA mval {
  816. X                $$ = $2;
  817. X            }
  818. X        ;
  819. X
  820. Xclassdefs    :    /* empty */ 
  821. X        |    classdefs IDENT ASGN nameset {
  822. X                EmitDef (def_class, $2, $4, (char *) NULL);
  823. X            }
  824. X        |    error
  825. X        ;
  826. X
  827. Xnameset        :    LBRACE namelist RBRACE SEMI {
  828. X                $$ = $2;
  829. X            }
  830. X        |    LBRACE RBRACE SEMI {
  831. X                $$ = NULL;
  832. X            }
  833. X        |    LBRACE error RBRACE SEMI {
  834. X                $$ = NULL;
  835. X            }
  836. X        |    READCLASS LPAREN strval RPAREN SEMI {
  837. X                $$ = MakeRStr ($3, (char *) NULL);
  838. X            }
  839. X        |    READCLASS LPAREN strval COMMA strval RPAREN SEMI {
  840. X                $$ = MakeRStr ($3, $5);
  841. X            }
  842. X        |    READCLASS LPAREN error RPAREN SEMI {
  843. X                $$ = NULL;
  844. X            }
  845. X        |    error SEMI {
  846. X                $$ = NULL;
  847. X                yyerrok;
  848. X            }
  849. X        ;
  850. X
  851. Xnamelist    :    IDENT {
  852. X                $$ = ListAppend ($1->psb, (char *) NULL, (char *) NULL);
  853. X                RemoveSymbol ($1);
  854. X            }
  855. X        |    strval {
  856. X                $$ = $1;
  857. X            }
  858. X        |    namelist COMMA IDENT {
  859. X                $$ = ListAppend ($1, $3->psb, " ");
  860. X                free ($1);
  861. X                RemoveSymbol ($3);
  862. X            }
  863. X        |    namelist COMMA strval {
  864. X                $$ = ListAppend ($1, $3, " ");
  865. X                free ($1);
  866. X                free ($3);
  867. X            }
  868. X        ;
  869. X
  870. Xoptdefs        :    /* empty */
  871. X        |    optdefs optid ASGN strval SEMI {
  872. X                EmitDef (def_option, (struct he *) NULL, ConvOpt ($2), $4);
  873. X            }
  874. X        |    optdefs DOPT ASGN doptid SEMI {
  875. X                EmitDef (def_option, (struct he *) NULL, ConvOpt (opt_d), $4);
  876. X            }
  877. X        |    optdefs EOPT ASGN eoptid SEMI {
  878. X                EmitDef (def_option, (struct he *) NULL, ConvOpt (opt_e), $4);
  879. X            }
  880. X        |    error SEMI {
  881. X                yyerrok;
  882. X            }
  883. X        ;
  884. X
  885. Xoptid        :    AAOPT {
  886. X                $$ = opt_A;
  887. X            }
  888. X        |    AOPT {
  889. X                $$ = opt_a;
  890. X            }
  891. X        |    BBOPT {
  892. X                $$ = opt_B;
  893. X            }
  894. X        |    CCOPT {
  895. X                $$ = opt_C;
  896. X            }
  897. X        |    COPT {
  898. X                $$ = opt_c;
  899. X            }
  900. X        |    DDOPT {
  901. X                $$ = opt_D;
  902. X            }
  903. X        |    FFOPT {
  904. X                $$ = opt_F;
  905. X            }
  906. X        |    FOPT {
  907. X                $$ = opt_f;
  908. X            }
  909. X        |    GOPT {
  910. X                $$ = opt_g;
  911. X            }
  912. X        |    HHOPT {
  913. X                $$ = opt_H;
  914. X            }
  915. X        |    IOPT {
  916. X                $$ = opt_i;
  917. X            }
  918. X        |    LLOPT {
  919. X                $$ = opt_L;
  920. X            }
  921. X        |    MOPT {
  922. X                $$ = opt_m;
  923. X            }
  924. X        |    NNOPT {
  925. X                $$ = opt_N;
  926. X            }
  927. X        |    NOPT {
  928. X                $$ = opt_n;
  929. X            }
  930. X        |    PPOPT {
  931. X                $$ = opt_P;
  932. X            }
  933. X        |    OOPT {
  934. X                $$ = opt_o;
  935. X            }
  936. X        |    QQOPT {
  937. X                $$ = opt_Q;
  938. X            }
  939. X        |    QOPT {
  940. X                $$ = opt_q;
  941. X            }
  942. X        |    ROPT {
  943. X                $$ = opt_r;
  944. X            }
  945. X        |    SSOPT {
  946. X                $$ = opt_S;
  947. X            }
  948. X        |    SOPT {
  949. X                $$ = opt_s;
  950. X            }
  951. X        |    TTOPT {
  952. X                $$ = opt_T;
  953. X            }
  954. X        |    TOPT {
  955. X                $$ = opt_t;
  956. X            }
  957. X        |    UOPT {
  958. X                $$ = opt_u;
  959. X            }
  960. X        |    VOPT {
  961. X                $$ = opt_v;
  962. X            }
  963. X        |    WWOPT {
  964. X                $$ = opt_W;
  965. X            }
  966. X        |    XOPT {
  967. X                $$ = opt_x;
  968. X            }
  969. X        |    XXOPT {
  970. X                $$ = opt_X;
  971. X            }
  972. X        |    YOPT {
  973. X                $$ = opt_y;
  974. X            }
  975. X        |    YYOPT {
  976. X                $$ = opt_Y;
  977. X            }
  978. X        |    ZOPT {
  979. X                $$ = opt_z;
  980. X            }
  981. X        |    ZZOPT {
  982. X                $$ = opt_Z;
  983. X            }
  984. X        ;
  985. X
  986. Xdoptid        :    DOPTI {
  987. X                $$ = ConvOpt (d_opt_i);
  988. X            }
  989. X        |    DOPTB {
  990. X                $$ = ConvOpt (d_opt_b);
  991. X            }
  992. X        |    DOPTQ {
  993. X                $$ = ConvOpt (d_opt_q);
  994. X            }
  995. X        ;
  996. X
  997. Xeoptid        :    EOPTP {
  998. X                $$ = ConvOpt (e_opt_p);
  999. X            }
  1000. X        |    EOPTE {
  1001. X                $$ = ConvOpt (e_opt_e);
  1002. X            }
  1003. X        |    EOPTM {
  1004. X                $$ = ConvOpt (e_opt_m);
  1005. X            }
  1006. X        |    EOPTW {
  1007. X                $$ = ConvOpt (e_opt_w);
  1008. X            }
  1009. X        |    EOPTZ {
  1010. X                $$ = ConvOpt (e_opt_z);
  1011. X            }
  1012. X        ;
  1013. X
  1014. Xprecdefs    :    /* empty */
  1015. X        |    precdefs IDENT ASGN ICONST SEMI {
  1016. X                BindID ($2, $4, ID_PREC);
  1017. X                EmitDef (def_prec, $2, (char *) NULL, (char *) NULL);
  1018. X            }
  1019. X        ;
  1020. X
  1021. Xtlist        :    /* empty */
  1022. X        |    tlist LBRACE IDENT idlist RBRACE SEMI {
  1023. X                EmitDef (def_trusted, (struct he *) NULL, 
  1024. X                     ListAppend ($3->psb, $4, " "), (char *) NULL);
  1025. X                free ($4);
  1026. X                RemoveSymbol ($3);
  1027. X            }
  1028. X        |    tlist LBRACE RBRACE SEMI
  1029. X        |    error SEMI {
  1030. X                yyerrok;
  1031. X            }
  1032. X        ;
  1033. X
  1034. Xhdefs        :    /* empty */
  1035. X        |    hdefs FOR fcond dheader SEMI {
  1036. X                EmitDef (def_header, (struct he *) NULL, $3, $4);
  1037. X            }
  1038. X        |    hdefs FOR fcond LBRACE { Flaglist = $3; } 
  1039. X                dheaders RBRACE SEMI
  1040. X        |    hdefs DEFINE dlist SEMI {
  1041. X                EmitDef (def_header, (struct he *) NULL, (char *) NULL, $3);
  1042. X            }
  1043. X        |    error SEMI {
  1044. X                yyerrok;
  1045. X            }
  1046. X        ;
  1047. X
  1048. Xfcond        :    LPAREN RPAREN {
  1049. X                $$ = NULL;
  1050. X            }
  1051. X        |    LPAREN mflags RPAREN {
  1052. X                $$ = $2;
  1053. X            }
  1054. X        |    LPAREN error RPAREN {
  1055. X                $$ = NULL;
  1056. X            }
  1057. X        ;
  1058. X
  1059. Xmflags        :    flagid {
  1060. X                $$ = ListAppend (ConvFlg ($1), (char *) NULL, (char *) NULL);
  1061. X            }
  1062. X        |    mflags COMMA flagid {
  1063. X                $$ = ListAppend ($1, ConvFlg($3), (char *) NULL);
  1064. X                free ($1);
  1065. X            }
  1066. X        ;
  1067. X
  1068. Xflagid        :    FFLAG {
  1069. X                $$ = flg_f;
  1070. X            }
  1071. X        |    RFLAG {
  1072. X                $$ = flg_r;
  1073. X            }
  1074. X        |    SSFLAG {
  1075. X                $$ = flg_S;
  1076. X            }
  1077. X        |    NFLAG {
  1078. X                $$ = flg_n;
  1079. X            }
  1080. X        |    LFLAG {
  1081. X                $$ = flg_l;
  1082. X            }
  1083. X        |    SFLAG {
  1084. X                $$ = flg_s;
  1085. X            }
  1086. X        |    MFLAG {
  1087. X                $$ = flg_m;
  1088. X            }
  1089. X        |    FFFLAG {
  1090. X                $$ = flg_F;
  1091. X            }
  1092. X        |    DDFLAG {
  1093. X                $$ = flg_D;
  1094. X            }
  1095. X        |    MMFLAG {
  1096. X                $$ = flg_M;
  1097. X            }
  1098. X        |    XFLAG {
  1099. X                $$ = flg_x;
  1100. X            }
  1101. X        |    PPFLAG {
  1102. X                $$ = flg_P;
  1103. X            }
  1104. X        |    UFLAG {
  1105. X                $$ = flg_u;
  1106. X            }
  1107. X        |    HFLAG {
  1108. X                $$ = flg_h;
  1109. X            }
  1110. X        |    AAFLAG {
  1111. X                $$ = flg_A;
  1112. X            }
  1113. X        |    UUFLAG {
  1114. X                $$ = flg_U;
  1115. X            }
  1116. X        |    EFLAG {
  1117. X                $$ = flg_e;
  1118. X            }
  1119. X        |    XXFLAG {
  1120. X                $$ = flg_X;
  1121. X            }
  1122. X        |    LLFLAG {
  1123. X                $$ = flg_L;
  1124. X            }
  1125. X        |    PFLAG {
  1126. X                $$ = flg_p;
  1127. X            }
  1128. X        |    IIFLAG {
  1129. X                $$ = flg_I;
  1130. X            }
  1131. X        |    CCFLAG {
  1132. X                $$ = flg_C;
  1133. X            }
  1134. X        |    EEFLAG {
  1135. X                $$ = flg_E;
  1136. X            }
  1137. X        |    RRFLAG {
  1138. X                $$ = flg_R;
  1139. X            }
  1140. X        ;
  1141. X
  1142. Xdheader        :    /* empty */ {
  1143. X                $$ = NULL;
  1144. X            }
  1145. X        |    DEFINE dlist {
  1146. X                $$ = $2;
  1147. X            }
  1148. X        |    error {
  1149. X                $$ = NULL;
  1150. X            }
  1151. X        ;
  1152. X
  1153. Xdheaders    :    /* empty */
  1154. X        |    dheaders DEFINE dlist SEMI {
  1155. X                EmitDef (def_header, (struct he *) NULL, Flaglist, $3);
  1156. X            }
  1157. X        |    error
  1158. X        ;
  1159. X
  1160. Xdlist        :    LPAREN strval COMMA catstring RPAREN {
  1161. X                $$ = ListAppend ($2, MacScan ($4), " ");
  1162. X                free ($2);
  1163. X                free ($4);
  1164. X            }
  1165. X        |    LPAREN error RPAREN {
  1166. X                $$ = NULL;
  1167. X            }
  1168. X        ;
  1169. X
  1170. Xcatstring    :    SCONST {
  1171. X                $$ = $1;
  1172. X            }
  1173. X        |    ifcon {
  1174. X                $$ = $1;
  1175. X            }
  1176. X        |    CONCAT LPAREN conval RPAREN {
  1177. X                $$ = $3;
  1178. X            }
  1179. X        |    catstring SCONST {
  1180. X                $$ = ListAppend ($1, $2, (char *) NULL);
  1181. X                free ($1);
  1182. X            }
  1183. X        |    catstring ifcon {
  1184. X                $$ = ListAppend ($1, $2, (char *) NULL);
  1185. X                free ($2);
  1186. X            }
  1187. X        ;
  1188. X
  1189. Xmlist        :    /* empty */
  1190. X        |    mlist IDENT LBRACE mdefs RBRACE SEMI {
  1191. X                EmitDef (def_mailer, $2, $4, (char *) NULL);
  1192. X            }
  1193. X        |    mlist IDENT LBRACE RBRACE SEMI {
  1194. X                EmitDef (def_mailer, $2, (char *) NULL, (char *) NULL);
  1195. X            }
  1196. X        |    error SEMI {
  1197. X                yyerrok;
  1198. X            }
  1199. X        ;
  1200. X
  1201. Xmdefs        :    mtdef {
  1202. X                $$ = $1;
  1203. X            }
  1204. X        |    mdefs COMMA mtdef {
  1205. X                $$ = ListAppend ($1, $3, ", ");
  1206. X                free ($1);
  1207. X                free ($3);
  1208. X            }
  1209. X        ;    
  1210. X
  1211. Xmtdef        :    mvar ASGN mval {
  1212. X                $$ = ListAppend (ConvMat ($1), MacScan ($3), "=");
  1213. X                free ($3);
  1214. X            }
  1215. X        |    MFLAGS ASGN LBRACE mflags RBRACE {
  1216. X                $$ = ListAppend (ConvMat (mat_flags), $4, "=");
  1217. X            }
  1218. X        |    MSENDER ASGN IDENT {
  1219. X                $$ = ListAppend (ConvMat (mat_sender), CheckRS ($3), "=");
  1220. X            }
  1221. X        |    MRECIPIENT ASGN IDENT {
  1222. X                $$ = ListAppend (ConvMat (mat_recipient), CheckRS ($3), "=");
  1223. X            }
  1224. X        |    error {
  1225. X                $$ = NULL;
  1226. X            }
  1227. X        ;
  1228. X
  1229. Xmvar        :    MPATH {
  1230. X                $$ = mat_path;
  1231. X            }
  1232. X        |    MARGV {
  1233. X                $$ = mat_argv;
  1234. X            }
  1235. X        |    MEOL {
  1236. X                $$ = mat_eol;
  1237. X            }
  1238. X        |    MMAXSIZE {
  1239. X                $$ = mat_maxsize;
  1240. X            }
  1241. X        ;
  1242. X
  1243. Xrdef        :    /* empty */
  1244. X        |    rdef IDENT { StartRuleset ($2); } rulelist
  1245. X        ;
  1246. X
  1247. Xrulelist    :    LBRACE ruledefs RBRACE {
  1248. X                RMatch = FALSE;
  1249. X            }
  1250. X        |    error {
  1251. X                RMatch = FALSE;
  1252. X            }
  1253. X        ;
  1254. X
  1255. Xruledefs    :    /* empty */ {
  1256. X                RMatch = TRUE;
  1257. X            }
  1258. X        |    ruledefs IF LPAREN matchaddr RPAREN actionstmt {
  1259. X                EmitDef (def_ruleset, (struct he *) NULL, 
  1260. X                     ListAppend ($4, $6, "\t"), (char *) NULL);
  1261. X            free ($4);
  1262. X            free ($6);
  1263. X            }
  1264. X        |    error SEMI {
  1265. X                yyerrok;
  1266. X            }
  1267. X        ;
  1268. X
  1269. Xmatchaddr    :    /* empty */ {
  1270. X                $$ = NULL;
  1271. X            }
  1272. X        |    matchaddr matchtok {
  1273. X                $$ = ListAppend ($1, $2, (char *) NULL);
  1274. X                free ($1);
  1275. X            }
  1276. X        |    error {
  1277. X                $$ = NULL;
  1278. X            }
  1279. X        ;
  1280. X
  1281. Xmatchtok    :    IDENT {
  1282. X                $$ = GetField ($1);
  1283. X            }
  1284. X        |    anychar {
  1285. X                *Cbuf = $1;
  1286. X                $$ = ListAppend (Cbuf, (char *) NULL, (char *) NULL);
  1287. X            }
  1288. X        |    mval {
  1289. X                $$ = MacScan ($1);
  1290. X            }
  1291. X        |    DOLLAR IDENT {
  1292. X                Mbuf[1] = MakeMac ($2, ID_MACRO);
  1293. X                $$ = ListAppend (Mbuf, (char *) NULL, (char *) NULL);
  1294. X            }
  1295. X        ;
  1296. X
  1297. Xactionstmt    :    action LPAREN rwaddr RPAREN SEMI {
  1298. X                $$ = ListAppend ($1, $3, (char *) NULL);
  1299. X                free ($3);
  1300. X            }
  1301. X        |    RESOLVE LPAREN resolution RPAREN SEMI {
  1302. X                $$ = $3;
  1303. X            }
  1304. X        |    error SEMI {
  1305. X                $$ = NULL;
  1306. X                yyerrok;
  1307. X            }
  1308. X        ;
  1309. X
  1310. Xaction        :    RETRY {
  1311. X                $$ = NULL;
  1312. X            }
  1313. X        |    NEXT {
  1314. X                $$ = "$:";
  1315. X            }
  1316. X        |    RETURN {
  1317. X                $$ = "$@";
  1318. X            }
  1319. X        ;
  1320. X
  1321. Xrwaddr        :    /* empty */ {
  1322. X                $$ = NULL;
  1323. X            }
  1324. X        |    rwaddr rwtok {
  1325. X                $$ = ListAppend ($1, $2, (char *) NULL);
  1326. X                free ($1);
  1327. X            }
  1328. X        |    rwaddr IDENT LPAREN rwaddr RPAREN {
  1329. X                $$ = ListAppend ($1, (Tsb = MakeRSCall ($2, $4)), (char *) NULL);
  1330. X                free ($1);
  1331. X                free ($4);
  1332. X                free (Tsb);
  1333. X            }
  1334. X        |    error {
  1335. X                $$ = NULL;
  1336. X            }
  1337. X        ;
  1338. X
  1339. Xrwtok        :    anychar {
  1340. X                *Cbuf = $1;
  1341. X                $$ = ListAppend (Cbuf, (char *) NULL, (char *) NULL);
  1342. X            }
  1343. X        |    mval {
  1344. X                $$ = MacScan ($1);
  1345. X            }
  1346. X        |    cantok {
  1347. X                $$ = $1;
  1348. X            }
  1349. X        |    reftok {
  1350. X                $$ = $1;
  1351. X            }
  1352. X        ;
  1353. X
  1354. Xcantok        :    CANON LPAREN canval RPAREN {
  1355. X                $$ = Bracket ($3, TRUE);
  1356. X                free ($3);
  1357. X            }
  1358. X
  1359. Xcanval        :    canvaltok {
  1360. X                $$ = $1;
  1361. X            }
  1362. X        |    canval canvaltok {
  1363. X                $$ = ListAppend ($1, $2, (char *) NULL);
  1364. X                free ($1);
  1365. X                free ($2);
  1366. X            }
  1367. X        ;
  1368. X
  1369. Xcanvaltok    :    IDENT {
  1370. X                $$ = ListAppend ($1->psb, (char *) NULL, (char *) NULL);
  1371. X                RemoveSymbol ($1);
  1372. X            }
  1373. X        |    SCONST {
  1374. X                $$ = ListAppend (MacScan ($1), (char *) NULL, (char *) NULL);
  1375. X                free ($1);
  1376. X            }
  1377. X        |    reftok {
  1378. X                $$ = $1;
  1379. X            }
  1380. X        |    SEPCHAR {
  1381. X                *Cbuf = $1;
  1382. X                $$ = ListAppend (Cbuf, (char *) NULL, (char *) NULL);
  1383. X            }
  1384. X        |    HOSTNUM LPAREN reftok RPAREN {
  1385. X                $$ = Bracket ($3, FALSE);
  1386. X                free ($3);
  1387. X            }
  1388. X        ;
  1389. X
  1390. Xreftok        :    DOLLAR IDENT {
  1391. X                Mbuf[1] = MakeMac ($2, ID_MACRO);
  1392. X                $$ = ListAppend (Mbuf, (char *) NULL, (char *) NULL);
  1393. X            }
  1394. X        |    DOLLAR ICONST {
  1395. X                $$ = ListAppend (MakePosTok ($2), (char *) NULL, (char *) NULL);
  1396. X            }
  1397. X        ;
  1398. X
  1399. Xanychar        :    SEPCHAR {
  1400. X                $$ = $1;
  1401. X            }
  1402. X        |    COLON {
  1403. X                $$ = ':';
  1404. X            }
  1405. X        |    STAR {
  1406. X                $$ = '*';
  1407. X            }
  1408. X        |    SEMI {
  1409. X                $$ = ';';
  1410. X            }
  1411. X        |    LBRACE {
  1412. X                $$ = '{';
  1413. X            }
  1414. X        |    RBRACE {
  1415. X                $$ = '}';
  1416. X            }
  1417. X        |    COMMA {
  1418. X                $$ = ',';
  1419. X            }
  1420. X        |    ASGN {
  1421. X                $$ = '=';
  1422. X            }
  1423. X        ;
  1424. X
  1425. Xresolution    :    mailerspec COMMA route {
  1426. X                $$ = ListAppend ($1, $3, (char *) NULL);
  1427. X                free ($1);
  1428. X                free ($3);
  1429. X            }
  1430. X        |    error {
  1431. X                $$ = NULL;
  1432. X            }
  1433. X        ;
  1434. X
  1435. Xmailerspec    :    MAILER LPAREN rword RPAREN {
  1436. X                $$ = ListAppend ("$#", $3, (char *) NULL);
  1437. X            }
  1438. X        ;
  1439. X
  1440. Xroute        :    HOST LPAREN hword RPAREN COMMA userspec {
  1441. X                $$ = ListAppend (Tsb = ListAppend ("$@", $3, (char *) NULL),
  1442. X                         $6, (char *) NULL);
  1443. X                free (Tsb);
  1444. X                free ($6);
  1445. X            }
  1446. X        |    userspec {
  1447. X                $$ = $1;
  1448. X            }
  1449. X        ;
  1450. X
  1451. Xhword        :    hostid {
  1452. X                $$ = $1;
  1453. X            }
  1454. X        |    HOSTNUM LPAREN reftok RPAREN {
  1455. X                $$ = Bracket ($3, FALSE);
  1456. X                free ($3);
  1457. X            }
  1458. X        ;
  1459. X
  1460. Xhostid        :    /* empty */ {
  1461. X                $$ = NULL;
  1462. X            }
  1463. X        |    hostid IDENT {
  1464. X                $$ = ListAppend ($1, $2->psb, (char *) NULL);
  1465. X                RemoveSymbol ($2);
  1466. X                free ($1);
  1467. X            }
  1468. X        |    hostid rwtok {
  1469. X                $$ = ListAppend ($1, $2, (char *) NULL);
  1470. X                free ($1);
  1471. X            }
  1472. X        ;
  1473. X
  1474. Xuserspec    :    USER LPAREN rwaddr RPAREN {
  1475. X                $$ = ListAppend ("$:", $3, (char *) NULL);
  1476. X                free ($3);
  1477. X            }
  1478. X        ;
  1479. X
  1480. Xrword        :    IDENT {
  1481. X                $$ = CheckMailer ($1);
  1482. X            }
  1483. X        |    reftok {
  1484. X                $$ = $1;
  1485. X            }
  1486. X        ;
  1487. X
  1488. Xfdefs        :    /* empty */
  1489. X        |    fdefs IDENT idlist COLON ftype SEMI {
  1490. X                AssignType (ListAppend ($2->psb, $3, " "), $5);
  1491. X                free ($3);
  1492. X            }
  1493. X        |    error SEMI {
  1494. X                yyerrok;
  1495. X            }
  1496. X        ;
  1497. X
  1498. Xidlist        :    /* empty */ {
  1499. X                $$ = NULL;
  1500. X            }
  1501. X        |    idlist COMMA IDENT {
  1502. X                $$ = ListAppend ($1, $3->psb, " ");
  1503. X                free ($1);
  1504. X            }
  1505. X        ;
  1506. X
  1507. Xftype        :    MATCH LPAREN ICONST RPAREN cdef {
  1508. X                $$ = ListAppend (MakeField ($3, $5, FALSE, FALSE), 
  1509. X                             (char *) NULL, (char *) NULL);
  1510. X            }
  1511. X        |    MATCH LPAREN ICONST RPAREN MAP IDENT {
  1512. X                $$ = ListAppend (MakeField ($3, $6, FALSE, TRUE), 
  1513. X                             (char *) NULL, (char *) NULL);
  1514. X            }
  1515. X        |    MATCH HOST {
  1516. X                $$ = ListAppend ("$%y", 
  1517. X                             (char *) NULL, (char *) NULL);
  1518. X            }
  1519. X        |    MATCH LPAREN ICONST STAR RPAREN {
  1520. X                $$ = ListAppend (MakeField ($3, (struct he *) NULL, TRUE, FALSE), 
  1521. X                         (char *) NULL, (char *) NULL);
  1522. X            }
  1523. X        |    error {
  1524. X                $$ = NULL;
  1525. X            }
  1526. X        ;
  1527. X
  1528. Xcdef        :    /* empty */ {
  1529. X                $$ = NULL;
  1530. X            }
  1531. X        |    IN IDENT {
  1532. X                $$ = $2;
  1533. X            }
  1534. X        ;
  1535. END_OF_FILE
  1536. if test 15988 -ne `wc -c <'src/parser.y'`; then
  1537.     echo shar: \"'src/parser.y'\" unpacked with wrong size!
  1538. fi
  1539. chmod +x 'src/parser.y'
  1540. # end of 'src/parser.y'
  1541. fi
  1542. if test -f 'src/strops.c' -a "${1}" != "-c" ; then 
  1543.   echo shar: Will not clobber existing file \"'src/strops.c'\"
  1544. else
  1545. echo shar: Extracting \"'src/strops.c'\" \(12669 characters\)
  1546. sed "s/^X//" >'src/strops.c' <<'END_OF_FILE'
  1547. X/*    $Header: strops.c,v 2.0 88/06/15 14:42:55 root Exp $    */
  1548. X
  1549. X/*
  1550. X * $Log:    strops.c,v $
  1551. X * Revision 2.0  88/06/15  14:42:55  root
  1552. X * Baseline release for net posting. ADR.
  1553. X * 
  1554. X */
  1555. X
  1556. X/*
  1557. X *    strops.c   -- Contains string operation routines used for constructing
  1558. X *              definitions in cf format.
  1559. X *
  1560. X *    author       -- James S. Schoner, Purdue University Computing Center,
  1561. X *                        West Lafayette, Indiana  47907
  1562. X *
  1563. X *    date       -- July 9, 1985
  1564. X *
  1565. X *    Copyright (c) 1985 by Purdue Research Foundation
  1566. X *
  1567. X *    All rights reserved.
  1568. X *
  1569. X */
  1570. X
  1571. X#include "fixstrings.h"
  1572. X#include <stdio.h>
  1573. X#include <strings.h>
  1574. X#include "symtab.h"
  1575. X
  1576. X#define MAXTOKPOS   99        /* maximum number of token positions */
  1577. X#define MAXNAME        1024    /* maximum length of an identifier   */
  1578. X
  1579. Xextern struct he *LookupSymbol ();
  1580. Xextern char       MakeMac ();
  1581. Xextern void      FatalError (),
  1582. X          PrintError (),
  1583. X          ErrorReport ();
  1584. X
  1585. Xshort  Rformat = FALSE;            /* class read format flag      */
  1586. Xstatic char   *Ptok   = "$  ";        /* positional token structure     */
  1587. Xstatic char   *Cfield = "$= ";        /* class reference structure      */
  1588. Xstatic char   *Ofield = "$-";        /* one token match structure      */
  1589. Xstatic char   *Zfield = "$*";        /* zero or more tokens structure  */
  1590. Xstatic char   *Pfield = "$+";        /* one or more tokens structure      */
  1591. X
  1592. X/*
  1593. X *  FLUKE jps 25-apr-86
  1594. X *
  1595. X *  Add the three new $%x, $%y, and $!x match operators that Sun introduced
  1596. X *  with release 3.0.
  1597. X *
  1598. X *  BUG (probably) - Sun has assigned a predefined meaning to the $y macro;
  1599. X *  I imagine we will need to teach ease to avoid this letter.
  1600. X */
  1601. Xstatic char   *Hfield = "$%y";        /*    match in /etc/hosts */
  1602. Xstatic char   *Mfield = "$% ";        /*    match in specified YP map */
  1603. Xstatic char   *Nfield = "$! ";        /* no match in specified YP map */
  1604. X
  1605. Xstatic char   *Mtest  = "$? ";        /* conditional macro test string  */
  1606. X
  1607. X
  1608. X/*
  1609. X *    ConvOpt () -- Convert an Ease option identifier (optid) by returning a
  1610. X *              string representation of the cf format.  
  1611. X *
  1612. X */
  1613. Xchar *
  1614. XConvOpt (optid) 
  1615. Xregister enum opts optid;
  1616. X{
  1617. X    switch (optid) {
  1618. X        case opt_A  :    return ("A");
  1619. X        case opt_a  :    return ("a");
  1620. X        case opt_B  :    return ("B");
  1621. X        case d_opt_b:    return ("b");
  1622. X        case opt_C  :    return ("C");
  1623. X        case opt_c  :    return ("c");
  1624. X        case opt_D  :    return ("D");
  1625. X        case opt_d  :    return ("d");
  1626. X        case opt_e  :
  1627. X        case e_opt_e:    return ("e");
  1628. X        case opt_F  :    return ("F");
  1629. X        case opt_f  :    return ("f");
  1630. X        case opt_g  :    return ("g");
  1631. X        case opt_H  :    return ("H");
  1632. X        case opt_i  :
  1633. X        case d_opt_i:    return ("i");
  1634. X        case opt_L  :    return ("L");
  1635. X        case opt_m  :
  1636. X        case e_opt_m:    return ("m");
  1637. X        case opt_N  :    return ("N");
  1638. X        case opt_n  :    return ("n");
  1639. X        case opt_o  :    return ("o");
  1640. X        case opt_P  :    return ("P");
  1641. X        case e_opt_p:    return ("p");
  1642. X        case opt_Q  :    return ("Q");
  1643. X        case opt_q  :    return ("q");
  1644. X        case d_opt_q:    return ("q");
  1645. X        case opt_r  :    return ("r");
  1646. X        case opt_S  :    return ("S");
  1647. X        case opt_s  :    return ("s");
  1648. X        case opt_T  :    return ("T");
  1649. X        case opt_t  :    return ("t");
  1650. X        case opt_u  :    return ("u");
  1651. X        case opt_v  :    return ("v");
  1652. X        case opt_W  :    return ("W");
  1653. X        case e_opt_w:    return ("w");
  1654. X        case opt_x  :    return ("x");
  1655. X        case opt_X  :    return ("X");
  1656. X        case opt_y  :    return ("y");
  1657. X        case opt_Y  :    return ("Y");
  1658. X        case opt_z  :    return ("z");
  1659. X        case opt_Z  :    return ("Z");
  1660. X        case e_opt_z:    return ("z");
  1661. X        default     :    FatalError ("Bad case in ConvOpt ()", (char *) NULL);
  1662. X    }
  1663. X    /*NOTREACHED*/
  1664. X}
  1665. X
  1666. X
  1667. X/*
  1668. X *    ConvFlg () -- Convert an Ease mailer flag identifier (flgid) by 
  1669. X *              string representation of the cf format.  
  1670. X *
  1671. X */
  1672. Xchar *
  1673. XConvFlg (flgid)
  1674. Xregister enum flgs flgid;    /* flag identifier */
  1675. X{
  1676. X    switch (flgid) {
  1677. X        case flg_f:    return ("f");
  1678. X        case flg_r:    return ("r");
  1679. X        case flg_S:    return ("S");
  1680. X        case flg_n:    return ("n");
  1681. X        case flg_l:    return ("l");
  1682. X        case flg_s:    return ("s");
  1683. X        case flg_m:    return ("m");
  1684. X        case flg_F:    return ("F");
  1685. X        case flg_D:    return ("D");
  1686. X        case flg_M:    return ("M");
  1687. X        case flg_x:    return ("x");
  1688. X        case flg_P:    return ("P");
  1689. X        case flg_u:    return ("u");
  1690. X        case flg_h:    return ("h");
  1691. X        case flg_A:    return ("A");
  1692. X        case flg_U:    return ("U");
  1693. X        case flg_e:    return ("e");
  1694. X        case flg_X:    return ("X");
  1695. X        case flg_L:    return ("L");
  1696. X        case flg_p:    return ("p");
  1697. X        case flg_I:    return ("I");
  1698. X        case flg_C:    return ("C");
  1699. X        case flg_E:    return ("E");
  1700. X        case flg_R:    return ("R");
  1701. X        default   :    FatalError ("Bad case in ConvFlg ()", (char *) NULL);
  1702. X    }
  1703. X    /*NOTREACHED*/
  1704. X}
  1705. X
  1706. X
  1707. X/*
  1708. X *    ConvMat () -- Convert an Ease mailer attribute (mat) by returning a
  1709. X *              string representation of the cf format.  
  1710. X *
  1711. X */
  1712. Xchar *
  1713. XConvMat (mat)
  1714. Xregister enum mats mat;        /* mailer attribute flag */
  1715. X{
  1716. X    switch (mat) {
  1717. X        case mat_path        : return ("P");
  1718. X        case mat_flags        : return ("F");
  1719. X        case mat_sender        : return ("S");
  1720. X        case mat_recipient    : return ("R");
  1721. X        case mat_argv        : return ("A");
  1722. X        case mat_eol        : return ("E");
  1723. X        case mat_maxsize    : return ("M");
  1724. X        default            : FatalError ("Bad case in ConvMat ()", (char *) NULL);
  1725. X    }
  1726. X    /*NOTREACHED*/
  1727. X}
  1728. X
  1729. X
  1730. X/*
  1731. X *    MacScan () -- Scan a string (pstring) for macros, replacing the Ease
  1732. X *              form with the one-character form required by cf format.
  1733. X *
  1734. X */
  1735. Xchar *
  1736. XMacScan (pstring)
  1737. Xchar *pstring;        /* macro expandable string */
  1738. X{
  1739. X    register char *searchptr;    /* string search pointer     */
  1740. X    register char *bptr, *eptr;    /* macro begin and end pointers */
  1741. X    char macname [MAXNAME];        /* macro name buffer        */
  1742. X
  1743. X    if ((searchptr = pstring) == NULL)
  1744. X        return ((char *) NULL);
  1745. X    while (*searchptr != '\0')     /* find and rewrite all macros  */
  1746. X        if (*searchptr == '\\') {
  1747. X            searchptr = searchptr + 2;
  1748. X            continue;
  1749. X        } else if (*searchptr++ == '$' && *searchptr == '{') {
  1750. X            if (sscanf (searchptr + 1, "%[^}]", macname) != 1) {
  1751. X                PrintError ("Invalid macro format:", searchptr + 1);
  1752. X                return ((char *) NULL);
  1753. X            } 
  1754. X            *searchptr++ = MakeMac (LookupSymbol (macname), ID_MACRO);
  1755. X            bptr = eptr = searchptr;
  1756. X            while (*eptr++ != '}')    /* delete old macro chars */
  1757. X                /* empty */ ;
  1758. X            do
  1759. X                *bptr++ = *eptr;
  1760. X            while (*eptr++ != '\0');
  1761. X        }
  1762. X    return (pstring);
  1763. X}
  1764. X
  1765. X
  1766. X/*
  1767. X *    MakeRStr () -- Construct and return a pointer to a class read string 
  1768. X *               using the filename fname and read format rformat.  
  1769. X *
  1770. X */
  1771. Xchar *
  1772. XMakeRStr (fname, rformat)
  1773. Xchar *fname,            /* file name for class read */
  1774. X     *rformat;            /* format for class read    */
  1775. X{
  1776. X    register char *res;    /* resultant read string    */
  1777. X
  1778. X    Rformat = TRUE;        /* set read format flag     */
  1779. X    if (rformat == NULL)
  1780. X        return (fname);
  1781. X    res = (char *) realloc (fname, strlen (fname) + strlen (rformat) + 2);
  1782. X    if (res == NULL)
  1783. X        FatalError ("System out of string space in MakeRStr ()", (char *) NULL);
  1784. X    res = strcat (res, " ");    /* construct read string */
  1785. X    res = strcat (res, rformat);
  1786. X    free (rformat);
  1787. X    return (res);
  1788. X}
  1789. X
  1790. X
  1791. X/*
  1792. X *    ListAppend () -- Append string list2 to string list1 using the 
  1793. X *             separator sep.  A pointer to the newly constructed
  1794. X *             string is returned.
  1795. X *
  1796. X */
  1797. Xchar *
  1798. XListAppend (list1, list2, sep)
  1799. Xchar *list1,            /* first string     */
  1800. X     *list2,            /* second string      */
  1801. X     *sep;            /* string separator    */
  1802. X{
  1803. X    register char *res;    /* resultant string    */
  1804. X
  1805. X    res = (char *) malloc (strlen (list1) + strlen (list2) + strlen (sep) + 1);
  1806. X    if (res == NULL)
  1807. X        FatalError ("System out of string space in ListAppend ()", (char *) NULL);
  1808. X    res = strcpy (res, list1);
  1809. X    if (list1 != NULL)    /* use separator if first string not null */
  1810. X        res = strcat (res, sep);
  1811. X    res = strcat (res, list2);
  1812. X    return (res);
  1813. X}
  1814. X
  1815. X
  1816. X/*
  1817. X *    MakeCond () -- Construct a macro conditional string in cf format.  The
  1818. X *               conditional is based on the macro testmac, with an "if
  1819. X *               set" result ifstring, which may contain an optional 
  1820. X *               "if not set" result string appended to it.
  1821. X *
  1822. X */
  1823. Xchar *
  1824. XMakeCond (testmac, ifstring)
  1825. Xstruct he *testmac;        /* macro for conditional testing          */
  1826. Xchar       *ifstring;         /* "if macro set" result string(s)           */
  1827. X{
  1828. X    register char *res;    /* resultant conditional string             */
  1829. X
  1830. X    Mtest[2] = MakeMac (testmac, ID_MACRO);       /* get one-char macro rep */
  1831. X    res = (char *) malloc (strlen (ifstring) + 6);
  1832. X    if (res == NULL)
  1833. X        FatalError ("System out of string space in MakeCond ()", (char *) NULL);
  1834. X    res = strcpy (res, Mtest);
  1835. X    res = strcat (res, ifstring);        /* build result part      */
  1836. X    res = strcat (res, "$.");        /* end of conditional     */
  1837. X    free (ifstring);
  1838. X    return (res);
  1839. X}
  1840. X
  1841. X
  1842. X/*
  1843. X *    MakePosTok () -- Construct and return a positional token string 
  1844. X *             representation from the parameter num.
  1845. X *
  1846. X */
  1847. Xchar *
  1848. XMakePosTok (num)
  1849. Xregister int num;            /* numerical value of positional token */
  1850. X{
  1851. X    if (num > MAXTOKPOS) {
  1852. X        ErrorReport ("Positional token too large.\n");
  1853. X        return ((char *) NULL);
  1854. X    } else {
  1855. X        if (num > 9) {    /* two-digit positional token */
  1856. X            Ptok[1] = '0' + (num / 10);
  1857. X            Ptok[2] = '0' + (num % 10);
  1858. X            Ptok[3] = '\0';
  1859. X        } else {
  1860. X            Ptok[1] = '0' + num;
  1861. X            Ptok[2] = '\0';
  1862. X        }
  1863. X    return (Ptok);
  1864. X    }
  1865. X}
  1866. X
  1867. X
  1868. X/*
  1869. X *    Bracket () -- Construct and return a cf string form of the 
  1870. X *              canonicalization of the string identifier passed in
  1871. X *              the string parameter psb if dflag is true, else
  1872. X *              simply bracket the identifier without dollar signs
  1873. X *              for numeric hostname specifications.
  1874. X *
  1875. X */
  1876. Xchar *
  1877. XBracket (psb, dflag)
  1878. Xchar *psb;            /* identifier to be canonicalized */
  1879. Xshort dflag;            /* dollar flag               */
  1880. X{
  1881. X    register char *res;    /* resultant cf form           */
  1882. X    register short extra;    /* extra space needed for malloc  */
  1883. X    
  1884. X    extra = dflag ? 5 : 3;
  1885. X    res = (char *) malloc (strlen (psb) + extra);
  1886. X    if (res == NULL)
  1887. X        FatalError ("System out of string space in Bracket ()", (char *) NULL);
  1888. X    if (dflag)
  1889. X        res = strcpy (res, "$[");
  1890. X    else
  1891. X        res = strcpy (res, "[");
  1892. X    res = strcat (res, psb);
  1893. X    if (dflag)
  1894. X        res = strcat (res, "$");
  1895. X    res = strcat (res, "]");
  1896. X    return (res);
  1897. X}
  1898. X
  1899. X
  1900. X/*
  1901. X *    MakeRSCall () -- Construct and return a cf string form of a call
  1902. X *             to a ruleset (cid), which would pass to it the
  1903. X *             remainder of a rewriting address (rwaddr).
  1904. X *
  1905. X */
  1906. Xchar *
  1907. XMakeRSCall (cid, rwaddr)
  1908. Xregister struct he *cid;    /* called ruleset identifier         */
  1909. Xregister char *rwaddr;        /* remainder of rewriting address    */
  1910. X{
  1911. X    register char *res;    /* resultant cf string for the call  */
  1912. X    
  1913. X    if (!ISRULESET(cid->idtype)) {    /* check validity of ruleset */
  1914. X        PrintError ("Undefined ruleset identifier:", cid->psb);
  1915. X        return ((char *) NULL);
  1916. X    }
  1917. X    /*
  1918. X     * FLUKE jps - 8-may-86 - boost string size by 1 to accomodate space
  1919. X     * character.
  1920. X     */
  1921. X    res = (char *) malloc (strlen (cid->idval.rsn) + strlen (rwaddr) + 4);
  1922. X    if (res == NULL)
  1923. X        FatalError ("System out of string space in MakeRSCall ()", (char *) NULL);
  1924. X    res = strcpy (res, "$>");    /* construct the call string */
  1925. X    res = strcat (res, cid->idval.rsn);
  1926. X    res = strcat (res, " ");  /* FLUKE jps - work around sendmail bug:
  1927. X                   * whitespace is needed to separate tokens:
  1928. X                   * for example:  $>30$D will confuse
  1929. X                   * sendmail, but $>30 $D is OK.
  1930. X                   */
  1931. X    res = strcat (res, rwaddr);
  1932. X    return (res);
  1933. X}
  1934. X
  1935. X
  1936. X/*
  1937. X *    MakeField () -- Construct and return the cf string format for a
  1938. X *            field variable.  The match count (count), an optional
  1939. X *            class (class), and a match repetition flag (fstar)
  1940. X *            are used to determine what type of field string to
  1941. X *            construct.
  1942. X *
  1943. X *  FLUKE jps 25-apr-86 - Modified to add a fourth parameter "isYPmap".  This
  1944. X *  supports Sun's new Yellow Pages match patterns added in release 3.0.
  1945. X *
  1946. X */
  1947. Xchar *
  1948. X    MakeField (count, class, fstar, isYPmap)
  1949. Xregister int count;        /* match count (0 or 1) */
  1950. Xregister struct he *class;    /* optional class type  */
  1951. Xregister short fstar;        /* repetition flag    */
  1952. Xregister short isYPmap;        /* "class" name is really a YP map name */
  1953. X{
  1954. X    switch (count) {
  1955. X        case 0:      if (class == NULL)    /* any token is valid */
  1956. X                if (fstar)
  1957. X                    return (Zfield);
  1958. X                else {
  1959. X                    ErrorReport ("Invalid field type.\n");
  1960. X                    return ((char *) NULL);
  1961. X                }
  1962. X              else {        /* match 0 from class or map */
  1963. X                if (isYPmap) {
  1964. X                    /*  "class" is a misnomer here; it's really
  1965. X                     *  a simple macro name for a YP map.
  1966. X                     *  FLUKE jps 25-apr-86
  1967. X                     */
  1968. X                    Nfield[2] = MakeMac (class, ID_MACRO);
  1969. X                    return (Nfield);
  1970. X                } else {
  1971. X                Cfield[1] = '~';
  1972. X                Cfield[2] = MakeMac (class, ID_CLASS);
  1973. X                return (Cfield);
  1974. X              }
  1975. X              }
  1976. X        case 1:      if (class == NULL)    /* any token is valid */
  1977. X                if (fstar)
  1978. X                    return (Pfield);
  1979. X                else
  1980. X                    return (Ofield);
  1981. X              else {        /* match 1 from class or map */
  1982. X                if (isYPmap) {
  1983. X                    /*  "class" is a misnomer here; it's really
  1984. X                     *  a simple macro name for a YP map.
  1985. X                     *  FLUKE jps 25-apr-86
  1986. X                     */
  1987. X                    Mfield[2] = MakeMac (class, ID_MACRO);
  1988. X                    return (Mfield);
  1989. X                } else {
  1990. X                Cfield[1] = '=';
  1991. X                Cfield[2] = MakeMac (class, ID_CLASS);
  1992. X                return (Cfield);
  1993. X                }
  1994. X              }
  1995. X        default:  ErrorReport ("Invalid field type.\n");
  1996. X    }
  1997. X    /*NOTREACHED*/
  1998. X}
  1999. END_OF_FILE
  2000. if test 12669 -ne `wc -c <'src/strops.c'`; then
  2001.     echo shar: \"'src/strops.c'\" unpacked with wrong size!
  2002. fi
  2003. chmod +x 'src/strops.c'
  2004. # end of 'src/strops.c'
  2005. fi
  2006. echo shar: End of archive 2 \(of 3\).
  2007. cp /dev/null ark2isdone
  2008. MISSING=""
  2009. for I in 1 2 3 ; do
  2010.     if test ! -f ark${I}isdone ; then
  2011.     MISSING="${MISSING} ${I}"
  2012.     fi
  2013. done
  2014. if test "${MISSING}" = "" ; then
  2015.     echo You have unpacked all 3 archives.
  2016.     rm -f ark[1-9]isdone
  2017. else
  2018.     echo You still need to unpack the following archives:
  2019.     echo "        " ${MISSING}
  2020. fi
  2021. ##  End of shell archive.
  2022. exit 0
  2023.