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