home *** CD-ROM | disk | FTP | other *** search
- From: Bruce Israel <talcott!mimsy.umd.edu:gymble!israel>
- Subject: translation tables in sendmail
- Newsgroups: mod.sources
- Approved: jpn@panda.UUCP
-
- Mod.sources: Volume 3, Issue 31
- Submitted by: Bruce Israel <talcott!mimsy.umd.edu:gymble!israel>
-
-
- Here are my modifications to sendmail that I announced recently. I
- am posting these due to the number of requests. These modifications
- allow translations to be used in the sendmail.cf file, such as
- pathalias information and other stuff. Run the shar in a clean
- directory and then read the README. Enjoy.
-
- Bruce Israel
-
- University of Maryland, Computer Science Dept.
- {rlgvax,seismo}!umcp-cs!israel (Usenet) israel@Maryland (Arpanet)
-
- : Run this shell script with "sh" not "csh"
- PATH=:/bin:/usr/bin:/usr/ucb
- export PATH
- all=FALSE
- if [ x$1 = x-a ]; then
- all=TRUE
- fi
- /bin/echo 'Extracting 4.2diffs'
- sed 's/^X//' <<'//go.sysin dd *' >4.2diffs
- diff -c main.c.old main.c
- *** /usr/4.2/src/usr.lib/sendmail/src/main.c Sun Sep 25 21:06:10 1983
- --- /usr/israel/sendmail/src/main.c Wed Mar 6 15:45:26 1985
- ***************
- *** 695,700 ****
- --- 695,707 ----
- '*', MATCHZANY, '+', MATCHANY, '-', MATCHONE, '=', MATCHCLASS,
- '~', MATCHNCLASS,
-
- + #ifdef ROUTING /* ******************************** */
- +
- + /* for RHS translation table */
- + '&', EQUIVREPL,
- +
- + #endif ROUTING /* ******************************** */
- +
- /* these are RHS metasymbols */
- '#', CANONNET, '@', CANONHOST, ':', CANONUSER, '>', CALLSUBR,
-
- ***************
- *** 808,813 ****
- --- 815,822 ----
- union frz fhdr;
- extern char edata;
- extern char Version[];
- + extern char **environ;
- + char **envsave;
-
- if (freezefile == NULL)
- return (FALSE);
- ***************
- *** 835,840 ****
- --- 844,855 ----
- (void) close(f);
- return (FALSE);
- }
- + /**
- + ** Arrrrg! Since the pointer to the environment is in BSS, and our
- + ** bss get's blasted over when the freeze file is read in, we need to
- + ** save and restore the environ pointer for getenv()
- + **/
- + envsave = environ; /* save pointer to environment */
-
- /* now read in the freeze file */
- if (read(f, (char *) &edata, fhdr.frzinfo.frzbrk - &edata) !=
- ***************
- *** 844,849 ****
- --- 859,866 ----
- write(2, "Cannot read freeze file\n", 24);
- _exit(EX_SOFTWARE);
- }
- +
- + environ = envsave;
-
- (void) close(f);
- return (TRUE);
- diff -c parseaddr.c.old parseaddr.c
- *** /usr/4.2/src/usr.lib/sendmail/src/parseaddr.c Mon Jul 25 23:20:46 1983
- --- /usr/israel/sendmail/src/parseaddr.c Thu Oct 31 17:45:31 1985
- ***************
- *** 2,7 ****
- --- 2,9 ----
-
- SCCSID(@(#)parseaddr.c 4.1 7/25/83);
-
- + char **copyplist();
- +
- /*
- ** PARSEADDR -- Parse an address
- **
- ***************
- *** 204,214 ****
- --- 206,241 ----
-
- char *DelimChar; /* set to point to the delimiter */
-
- + #ifdef ROUTING /* ******************************** */
- +
- + char **prescan1();
- +
- + #endif ROUTING /* ******************************** */
- +
- char **
- prescan(addr, delim)
- char *addr;
- char delim;
- {
- + static char buf[MAXNAME+MAXATOM];
- + static char *av[MAXATOM+1];
- +
- + #ifdef ROUTING /* ******************************** */
- +
- + return(prescan1(addr,delim,buf,av,sizeof buf));
- + }
- +
- + char **
- + prescan1(addr,delim,buf,av,bufsize)
- + char *addr;
- + char delim;
- + char buf[];
- + char *av[];
- + int bufsize;
- + {
- +
- + #endif ROUTING /* ******************************** */
- +
- register char *p;
- register char *q;
- register int c;
- ***************
- *** 219,226 ****
- char *tok;
- int state;
- int newstate;
- - static char buf[MAXNAME+MAXATOM];
- - static char *av[MAXATOM+1];
-
- q = buf;
- bslashmode = FALSE;
- --- 246,251 ----
- ***************
- *** 249,255 ****
- if (c != NOCHAR)
- {
- /* squirrel it away */
- ! if (q >= &buf[sizeof buf - 5])
- {
- usrerr("Address too long");
- DelimChar = p;
- --- 274,280 ----
- if (c != NOCHAR)
- {
- /* squirrel it away */
- ! if (q >= &buf[bufsize - 5])
- {
- usrerr("Address too long");
- DelimChar = p;
- ***************
- *** 396,401 ****
- --- 421,429 ----
- }
- if (c == MATCHCLASS || c == MATCHREPL || c == MATCHNCLASS)
- return (ONE);
- + #ifdef ROUTING /* ******************************** */
- + if (c == EQUIVREPL) return (ONE);
- + #endif ROUTING /* ******************************** */
- if (c == '"')
- return (QST);
- if (!isascii(c))
- ***************
- *** 442,447 ****
- --- 470,478 ----
- {
- char **first; /* first token matched */
- char **last; /* last token matched */
- + #ifdef ROUTING /* ******************************** */
- + char *equiv; /* equivalence name for match */
- + #endif ROUTING /* ******************************** */
- };
-
- # define MAXMATCH 9 /* max params per rewrite */
- ***************
- *** 528,533 ****
- --- 559,571 ----
- else if (*rp == MATCHNCLASS)
- goto backup;
-
- + #ifdef ROUTING /* ******************************** */
- +
- + mlp -> equiv = getequiv(rp[1],s);
- +
- + #endif ROUTING /* ******************************** */
- +
- +
- /* explicit fall-through */
-
- case MATCHONE:
- ***************
- *** 536,541 ****
- --- 574,582 ----
- mlp->first = avp;
- mlp->last = avp++;
- mlp++;
- + #ifdef ROUTING /* ******************************** */
- + mlp -> equiv = NULL;
- + #endif ROUTING /* ******************************** */
- break;
-
- case MATCHZANY:
- ***************
- *** 543,548 ****
- --- 584,592 ----
- mlp->first = avp;
- mlp->last = avp - 1;
- mlp++;
- + #ifdef ROUTING /* ******************************** */
- + mlp -> equiv = NULL;
- + #endif ROUTING /* ******************************** */
- break;
-
- default:
- ***************
- *** 576,581 ****
- --- 620,628 ----
- {
- /* back out binding */
- mlp--;
- + #ifdef ROUTING /* ******************************** */
- + mlp -> equiv = NULL;
- + #endif ROUTING /* ******************************** */
- }
- }
-
- ***************
- *** 630,636 ****
- register char **pp;
-
- rp = *rvp;
- ! if (*rp != MATCHREPL)
- {
- if (avp >= &npvp[MAXATOM])
- {
- --- 677,687 ----
- register char **pp;
-
- rp = *rvp;
- ! if (*rp != MATCHREPL
- ! #ifdef ROUTING /* ******************************** */
- ! && *rp != EQUIVREPL
- ! #endif ROUTING /* ******************************** */
- ! )
- {
- if (avp >= &npvp[MAXATOM])
- {
- ***************
- *** 641,651 ****
- --- 692,722 ----
- continue;
- }
-
- + #ifdef ROUTING /* ******************************** */
- +
- + /* if the $& is not followed by a digit, put the
- + '&' on the output string. */
- +
- + if (*rp == EQUIVREPL && (rp[1] < '1' || rp[1] > '9'))
- + {
- + *avp++ = "&";
- + continue;
- + }
- +
- + #endif ROUTING /* ******************************** */
- +
- /* substitute from LHS */
- m = &mlist[rp[1] - '1'];
- # ifdef DEBUG
- if (tTd(21, 15))
- {
- + #ifdef ROUTING /* ******************************** */
- + if (*rp == EQUIVREPL) {
- + printf("$&%c:%x=\"%s\"\n",
- + rp[1], *m->equiv, *m->equiv);
- + }
- + else {
- + #endif ROUTING /* ******************************** */
- printf("$%c:", rp[1]);
- pp = m->first;
- while (pp <= m->last)
- ***************
- *** 655,662 ****
- printf("%s\"", *pp++);
- }
- printf("\n");
- ! }
- # endif DEBUG
- pp = m->first;
- while (pp <= m->last)
- {
- --- 726,763 ----
- printf("%s\"", *pp++);
- }
- printf("\n");
- ! #ifdef ROUTING /* ******************************** */
- ! }
- ! #endif ROUTING /* ******************************** */
- ! };
- # endif DEBUG
- +
- + #ifdef ROUTING /* ******************************** */
- +
- + if (*rp == EQUIVREPL) {
- + char buf[1024];
- + char *av[MAXATOM+1];
- + char *Dchar = DelimChar; /* save! */
- +
- + pp = copyplist(prescan1(m -> equiv,
- + '\0',buf,av,sizeof buf),TRUE);
- +
- + /* restore saved version, recursive */
- + DelimChar = Dchar;
- +
- + while (*pp)
- + {
- + if (avp >= &npvp[MAXATOM])
- + {
- + syserr("rewrite: expansion too long");
- + return;
- + }
- + *avp++ = *pp++;
- + }
- + }
- + else
- + {
- + #endif ROUTING /* ******************************** */
- pp = m->first;
- while (pp <= m->last)
- {
- ***************
- *** 667,672 ****
- --- 768,776 ----
- }
- *avp++ = *pp++;
- }
- + #ifdef ROUTING /* ******************************** */
- + }
- + #endif ROUTING /* ******************************** */
- }
- *avp++ = NULL;
- if (**npvp == CALLSUBR)
- diff -c readcf.c.old readcf.c
- *** /usr/4.2/src/usr.lib/sendmail/src/readcf.c Sun Sep 25 21:06:11 1983
- --- /usr/israel/sendmail/src/readcf.c Fri Feb 1 17:59:14 1985
- ***************
- *** 110,119 ****
- rwp->r_lhs = copyplist(rwp->r_lhs, TRUE);
-
- /* expand and save the RHS */
- ! while (*++p == '\t')
- continue;
- q = p;
- ! while (*p != '\0' && *p != '\t')
- p++;
- *p = '\0';
- expand(q, exbuf, &exbuf[sizeof exbuf], CurEnv);
- --- 110,119 ----
- rwp->r_lhs = copyplist(rwp->r_lhs, TRUE);
-
- /* expand and save the RHS */
- ! while (*++p == '\t' || *p == ' ')
- continue;
- q = p;
- ! while (*p != '\0' && *p != '\t' && *p != ' ')
- p++;
- *p = '\0';
- expand(q, exbuf, &exbuf[sizeof exbuf], CurEnv);
- ***************
- *** 140,165 ****
- (void) chompheader(&buf[1], TRUE);
- break;
-
- - case 'C': /* word class */
- case 'F': /* word class from file */
- ! /* read list of words from argument or file */
- ! if (buf[0] == 'F')
- {
- ! /* read from file */
- ! for (p = &buf[2]; *p != '\0' && !isspace(*p); p++)
- ! continue;
- ! if (*p == '\0')
- ! p = "%s";
- ! else
- ! {
- ! *p = '\0';
- ! while (isspace(*++p))
- ! continue;
- ! }
- ! fileclass(buf[1], &buf[2], p);
- ! break;
- }
-
- /* scan the list of words and set class for all */
- for (p = &buf[2]; *p != '\0'; )
- {
- --- 140,161 ----
- (void) chompheader(&buf[1], TRUE);
- break;
-
- case 'F': /* word class from file */
- !
- ! /* read from file */
- ! for (p = &buf[2]; *p != '\0' && !isspace(*p); p++)
- ! continue;
- ! if (*p == '\0') p = "%s";
- ! else
- {
- ! *p = '\0';
- ! while (isspace(*++p)) continue;
- }
- + fileclass(buf[1], &buf[2], p);
- + break;
-
- + case 'C': /* word class */
- +
- /* scan the list of words and set class for all */
- for (p = &buf[2]; *p != '\0'; )
- {
- ***************
- *** 179,184 ****
- --- 175,221 ----
- }
- break;
-
- +
- + #ifdef ROUTING /* ******************************** */
- +
- + case 'E': /* word equivalence class */
- +
- + /* scan the list of words as a <word, translation>
- + pair, and set class for all */
- +
- + for (p = &buf[2]; *p != '\0'; )
- + {
- + register char *wd;
- + register char *wd2;
- + char delim;
- + STAB *s;
- +
- + while (*p != '\0' && isspace(*p))
- + p++;
- + wd = p;
- + while (*p != '\0' && !isspace(*p))
- + p++;
- + delim = *p;
- + *p = '\0';
- + if (wd[0] != '\0')
- + s = setclass(buf[1], wd);
- + *p = delim;
- +
- + while (*p != '\0' && isspace(*p))
- + p++;
- + wd2 = p;
- + while (*p != '\0' && !isspace(*p))
- + p++;
- + delim = *p;
- + *p = '\0';
- + if (*wd != NULL)
- + makeequiv(buf[1],wd2,s);
- + *p = delim;
- + }
- + break;
- +
- + #endif ROUTING /* ******************************** */
- +
- case 'M': /* define mailer */
- makemailer(&buf[1], safe);
- break;
- ***************
- *** 269,274 ****
- --- 306,322 ----
- **
- ** puts all lines in filename that match a scanf into
- ** the named class.
- + **
- + ** Comment: equivalence class modification
- + ** fileclass has been modified so that if you use a format
- + ** string returning two strings, i.e.:
- + **
- + ** FN/usr/lib/net-gateways "%s%s"
- + **
- + ** it will store the second name as a name translation of
- + ** the first, accessable through the $&<digit> macro.
- + ** - BNI 9/5/84
- + **
- */
-
- fileclass(class, filename, fmt)
- ***************
- *** 279,284 ****
- --- 327,338 ----
- register FILE *f;
- char buf[MAXLINE];
-
- + #ifdef DEBUG
- + if (tTd(86,5))
- + printf("fileclass: class = %c, file = %s, fmt = \"%s\".\n"
- + , class, filename, fmt);
- + #endif DEBUG
- +
- f = fopen(filename, "r");
- if (f == NULL)
- {
- ***************
- *** 291,300 ****
- --- 345,391 ----
- register STAB *s;
- char wordbuf[MAXNAME+1];
-
- + #ifdef ROUTING /* ******************************** */
- + char word2[MAXNAME+1];
- + int ssc;
- + #ifdef DEBUG
- + if (tTd(86,11))
- + printf("fileclass: got line '%s'.\n",buf);
- + #endif DEBUG
- + word2[0] = '\0';
- +
- + if ((ssc=sscanf(buf, fmt, wordbuf, word2, 0)) < 1) {
- + #ifdef DEBUG
- + if(tTd(86,8))
- + printf("fileclass: found nothing on line.\n");
- + #endif DEBUG
- + continue;
- + }
- + #ifdef DEBUG
- + if (tTd(86,8))
- + if (*word2)
- + printf("fileclass: found word translation '%s' --> '%s'.\n",
- + wordbuf,word2);
- + else printf("fileclass: found word '%s'.\n",wordbuf);
- + #endif DEBUG
- +
- + #else ROUTING /* ******************************** */
- +
- if (sscanf(buf, fmt, wordbuf) != 1)
- continue;
- +
- + #endif ROUTING /* ******************************** */
- +
- s = stab(wordbuf, ST_CLASS, ST_ENTER);
- setbitn(class, s->s_class);
- +
- + #ifdef ROUTING /* ******************************** */
- +
- + if (*word2 != NULL)
- + makeequiv(class,word2,s);
- +
- + #endif ROUTING /* ******************************** */
- +
- }
-
- (void) fclose(f);
- ***************
- *** 805,816 ****
- ** word -- the word to enter
- **
- ** Returns:
- ! ** none.
- **
- ** Side Effects:
- ** puts the word into the symbol table.
- */
-
- setclass(class, word)
- int class;
- char *word;
- --- 896,915 ----
- ** word -- the word to enter
- **
- ** Returns:
- ! ** a pointer to the symbol table entry created.
- ! ** - changed from 'no return value' 9/5/84 - BNI
- **
- ** Side Effects:
- ** puts the word into the symbol table.
- */
-
- +
- + #ifdef ROUTING /* ******************************** */
- +
- + STAB *
- +
- + #endif ROUTING /* ******************************** */
- +
- setclass(class, word)
- int class;
- char *word;
- ***************
- *** 819,822 ****
- --- 918,926 ----
-
- s = stab(word, ST_CLASS, ST_ENTER);
- setbitn(class, s->s_class);
- +
- + #ifdef ROUTING /* ******************************** */
- + return (s);
- + #endif ROUTING /* ******************************** */
- +
- }
- diff -c stab.c.old stab.c
- *** /usr/4.2/src/usr.lib/sendmail/src/stab.c Mon Jul 25 23:18:41 1983
- --- /usr/israel/sendmail/src/stab.c Fri Feb 1 17:00:59 1985
- ***************
- *** 106,108 ****
- --- 106,185 ----
-
- return (s);
- }
- +
- + #ifdef ROUTING /* ******************************** */
- +
- + /*
- + ** MAKEEQUIV -- make a name equivalence entry
- + **
- + ** Parameters:
- + ** class -- the class the equivalence is in.
- + ** name -- The name to be translated into.
- + ** s -- a symbol table entry to the orginal name.
- + **
- + ** Returns:
- + ** none.
- + **
- + ** Side Effects:
- + ** none.
- + **
- + ** Author:
- + ** Bruce Israel -- 9/4/84.
- + **
- + */
- +
- + makeequiv(class,name,s)
- + char class;
- + char *name;
- + STAB *s;
- + {
- + EQUIV *eq;
- +
- + #ifdef DEBUG
- + if (tTd(87,5))
- + printf("makeequiv: defining '%s' --> '%s' in class '%c'.\n",
- + s -> s_name, name, class);
- + #endif DEBUG
- +
- + eq = (EQUIV *) xalloc(sizeof *eq);
- + eq -> class = class;
- + eq -> equivname = newstr(name);
- + eq -> next = s ->s_equiv;
- + s -> s_equiv = eq;
- + }
- +
- + /*
- + ** GETQUIV -- get a name equivalence for a class
- + **
- + ** Parameters:
- + ** class -- the class the equivalence is in.
- + ** s -- The symbol table entry of the word.
- + **
- + ** Returns:
- + ** a pointer to a string containing the translation
- + ** name. If the symbol table entry has no translation
- + ** name, the original name will be returned.
- + **
- + ** Side Effects:
- + ** none.
- + **
- + ** Author:
- + ** Bruce Israel -- 9/4/84.
- + **
- + */
- +
- + char *getequiv(class,s)
- + char class;
- + STAB *s;
- + {
- + EQUIV *eq;
- +
- + eq = s -> s_equiv;
- + while (eq != NULL) {
- + if (eq -> class == class) return (eq -> equivname);
- + eq = eq -> next;
- + }
- + return(s -> s_name);
- + }
- +
- + #endif ROUTING /* ******************************** */
- diff -c sendmail.h.old sendmail.h
- *** /usr/4.2/src/usr.lib/sendmail/src/sendmail.h Sun Sep 25 21:06:12 1983
- --- /usr/israel/sendmail/src/sendmail.h Fri Feb 1 17:00:42 1985
- ***************
- *** 2,9 ****
- ** SENDMAIL.H -- Global definitions for sendmail.
- */
-
-
- -
- # ifdef _DEFINE
- # define EXTERN
- # ifndef lint
- --- 2,9 ----
- ** SENDMAIL.H -- Global definitions for sendmail.
- */
-
- + # define ROUTING /* Mods for equivalence name classes - BNI 9/5/84 */
-
- # ifdef _DEFINE
- # define EXTERN
- # ifndef lint
- ***************
- *** 290,299 ****
- --- 290,319 ----
- # define CONDIF '\031' /* conditional if-then */
- # define CONDELSE '\032' /* conditional else */
- # define CONDFI '\033' /* conditional fi */
- +
- + #ifdef ROUTING /* ******************************** */
- +
- + # define EQUIVREPL '\034' /* equivalence class replacement */
- +
- + #endif ROUTING /* ******************************** */
- +
- /*
- ** Symbol table definitions
- */
-
- + #ifdef ROUTING /* ******************************** */
- +
- + struct equivstr
- + {
- + char class; /* class the name belongs in */
- + char *equivname; /* translated version of name */
- + struct equivstr *next; /* next item on equivalence list */
- + };
- +
- + typedef struct equivstr EQUIV;
- +
- + #endif ROUTING /* ******************************** */
- +
- struct symtab
- {
- char *s_name; /* name to be entered */
- ***************
- *** 306,311 ****
- --- 326,334 ----
- MAILER *sv_mailer; /* pointer to mailer */
- char *sv_alias; /* alias */
- } s_value;
- + #ifdef ROUTING /* ******************************** */
- + EQUIV *s_equiv; /* pointer to equivalence names list */
- + #endif ROUTING /* ******************************** */
- };
-
- typedef struct symtab STAB;
- ***************
- *** 323,328 ****
- --- 346,358 ----
- # define s_alias s_value.sv_alias
-
- extern STAB *stab();
- +
- + #ifdef ROUTING /* ******************************** */
- +
- + STAB *setclass();
- + char *getequiv();
- +
- + #endif ROUTING /* ******************************** */
-
- /* opcodes to stab */
- # define ST_FIND 0 /* find entry */
- //go.sysin dd *
- if [ `wc -c < 4.2diffs` != 17321 ]; then
- made=FALSE
- /bin/echo 'error transmitting "4.2diffs" --'
- /bin/echo 'length should be 17321, not' `wc -c < 4.2diffs`
- else
- made=TRUE
- fi
- if [ $made = TRUE ]; then
- /bin/chmod 644 4.2diffs
- /bin/echo -n ' '; /bin/ls -ld 4.2diffs
- fi
- /bin/echo 'Extracting 4.3diffs'
- sed 's/^X//' <<'//go.sysin dd *' >4.3diffs
- RCS file: RCS/main.c,v
- retrieving revision 1.1
- diff -c -r1.1 main.c
- *** /tmp/,RCSt1001795 Thu Oct 31 18:03:04 1985
- --- main.c Fri Oct 18 19:39:15 1985
- ***************
- *** 778,783 ****
- --- 778,784 ----
-
- /* these are RHS metasymbols */
- '#', CANONNET, '@', CANONHOST, ':', CANONUSER, '>', CALLSUBR,
- + '&', EQUIVREPL,
-
- /* the conditional operations */
- '?', CONDIF, '|', CONDELSE, '.', CONDFI,
- ===================================================================
- RCS file: RCS/parseaddr.c,v
- retrieving revision 1.1
- diff -c -r1.1 parseaddr.c
- *** /tmp/,RCSt1001795 Thu Oct 31 18:03:12 1985
- --- parseaddr.c Fri Oct 18 19:39:19 1985
- ***************
- *** 213,218 ****
- --- 213,222 ----
- **
- ** Side Effects:
- ** none.
- + **
- + ** N.B.: prescan's work is all done by the internal routine
- + ** _prescan, which merely has one additional parameter:
- + ** av -- place to put the pointers.
- */
-
- /* states and character types */
- ***************
- *** 250,255 ****
- --- 254,272 ----
- char delim;
- char pvpbuf[];
- {
- + static char *av[MAXATOM+1];
- + char **_prescan();
- +
- + return (_prescan(addr, delim, pvpbuf, av));
- + }
- +
- + static char **
- + _prescan(addr, delim, pvpbuf, av)
- + char *addr;
- + char delim;
- + char pvpbuf[];
- + char *av[];
- + {
- register char *p;
- register char *q;
- register int c;
- ***************
- *** 260,266 ****
- char *tok;
- int state;
- int newstate;
- - static char *av[MAXATOM+1];
- extern int errno;
-
- /* make sure error messages don't have garbage on them */
- --- 277,282 ----
- ***************
- *** 443,449 ****
- expand("\001o", buf, &buf[sizeof buf - 1], CurEnv);
- (void) strcat(buf, DELIMCHARS);
- }
- ! if (c == MATCHCLASS || c == MATCHREPL || c == MATCHNCLASS)
- return (ONE);
- if (c == '"')
- return (QST);
- --- 459,466 ----
- expand("\001o", buf, &buf[sizeof buf - 1], CurEnv);
- (void) strcat(buf, DELIMCHARS);
- }
- ! if (c == MATCHCLASS || c == MATCHREPL || c == MATCHNCLASS ||
- ! c == EQUIVREPL)
- return (ONE);
- if (c == '"')
- return (QST);
- ***************
- *** 491,496 ****
- --- 508,514 ----
- {
- char **first; /* first token matched */
- char **last; /* last token matched */
- + char *equiv; /* equivalence name for match */ /* XXX */
- };
-
- # define MAXMATCH 9 /* max params per rewrite */
- ***************
- *** 576,582 ****
- }
- else if (*rp == MATCHNCLASS)
- goto backup;
- !
- /* explicit fall-through */
-
- case MATCHONE:
- --- 594,604 ----
- }
- else if (*rp == MATCHNCLASS)
- goto backup;
- ! /*
- ! * XXX Should only note equiv parameters
- ! * here, and do translation later.
- ! */
- ! mlp->equiv = getequiv(rp[1], s);
- /* explicit fall-through */
-
- case MATCHONE:
- ***************
- *** 585,590 ****
- --- 607,613 ----
- mlp->first = avp;
- mlp->last = avp++;
- mlp++;
- + mlp->equiv = NULL;
- break;
-
- case MATCHZANY:
- ***************
- *** 592,597 ****
- --- 615,621 ----
- mlp->first = avp;
- mlp->last = avp - 1;
- mlp++;
- + mlp->equiv = NULL;
- break;
-
- default:
- ***************
- *** 625,630 ****
- --- 649,655 ----
- {
- /* back out binding */
- mlp--;
- + mlp->equiv = NULL;
- }
- }
-
- ***************
- *** 679,689 ****
- register char **pp;
-
- rp = *rvp;
- ! if (*rp == MATCHREPL)
- {
- /* substitute from LHS */
- m = &mlist[rp[1] - '1'];
- ! if (m >= mlp)
- {
- syserr("rewrite: ruleset %d: replacement out of bounds", ruleset);
- return;
- --- 704,714 ----
- register char **pp;
-
- rp = *rvp;
- ! if (*rp == MATCHREPL || *rp == EQUIVREPL)
- {
- /* substitute from LHS */
- m = &mlist[rp[1] - '1'];
- ! if (rp[1] < '1' || rp[1] > '9' || m >= mlp)
- {
- syserr("rewrite: ruleset %d: replacement out of bounds", ruleset);
- return;
- ***************
- *** 691,697 ****
- # ifdef DEBUG
- if (tTd(21, 15))
- {
- ! printf("$%c:", rp[1]);
- pp = m->first;
- while (pp <= m->last)
- {
- --- 716,725 ----
- # ifdef DEBUG
- if (tTd(21, 15))
- {
- ! if (*rp == EQUIVREPL)
- ! printf("$&%c:", rp[1]);
- ! else
- ! printf("$%c:", rp[1]);
- pp = m->first;
- while (pp <= m->last)
- {
- ***************
- *** 699,716 ****
- (void) fflush(stdout);
- printf("%s\"", *pp++);
- }
- printf("\n");
- }
- # endif DEBUG
- ! pp = m->first;
- ! while (pp <= m->last)
- {
- ! if (avp >= &npvp[MAXATOM])
- {
- ! syserr("rewrite: expansion too long");
- ! return;
- }
- ! *avp++ = *pp++;
- }
- }
- else
- --- 727,770 ----
- (void) fflush(stdout);
- printf("%s\"", *pp++);
- }
- + if (*rp == EQUIVREPL)
- + printf(" => \"%s\"",
- + m->equiv);
- printf("\n");
- }
- # endif DEBUG
- ! if (*rp == EQUIVREPL)
- {
- ! char equivbuf[PSBUFSIZE];
- ! char *equivav[MAXATOM+1];
- ! char *saveDelim = DelimChar;
- ! extern char **copyplist();
- !
- ! /*
- ! * XXX waste of memory!
- ! */
- ! pp = copyplist(_prescan(m->equiv,
- ! '\0',
- ! equivbuf,
- ! equivav),
- ! TRUE);
- ! DelimChar = saveDelim;
- ! while (*pp)
- {
- ! if (avp >= &npvp[MAXATOM])
- ! goto toolong;
- ! *avp++ = *pp++;
- }
- ! }
- ! else
- ! {
- ! pp = m->first;
- ! while (pp <= m->last)
- ! {
- ! if (avp >= &npvp[MAXATOM])
- ! goto toolong;
- ! *avp++ = *pp++;
- ! }
- }
- }
- else
- ===================================================================
- RCS file: RCS/readcf.c,v
- retrieving revision 1.1
- diff -c -r1.1 readcf.c
- *** /tmp/,RCSt1001795 Thu Oct 31 18:03:23 1985
- --- readcf.c Fri Oct 18 19:39:22 1985
- ***************
- *** 164,189 ****
- (void) chompheader(&buf[1], TRUE);
- break;
-
- - case 'C': /* word class */
- case 'F': /* word class from file */
- /* read list of words from argument or file */
- ! if (buf[0] == 'F')
- {
- ! /* read from file */
- ! for (p = &buf[2]; *p != '\0' && !isspace(*p); p++)
- continue;
- - if (*p == '\0')
- - p = "%s";
- - else
- - {
- - *p = '\0';
- - while (isspace(*++p))
- - continue;
- - }
- - fileclass(buf[1], &buf[2], p);
- - break;
- }
-
- /* scan the list of words and set class for all */
- for (p = &buf[2]; *p != '\0'; )
- {
- --- 164,186 ----
- (void) chompheader(&buf[1], TRUE);
- break;
-
- case 'F': /* word class from file */
- /* read list of words from argument or file */
- ! /* read from file */
- ! for (p = &buf[2]; *p != '\0' && !isspace(*p); p++)
- ! continue;
- ! if (*p == '\0')
- ! p = "%s";
- ! else
- {
- ! *p = '\0';
- ! while (isspace(*++p))
- continue;
- }
- + fileclass(buf[1], &buf[2], p);
- + break;
-
- + case 'C': /* word class */
- /* scan the list of words and set class for all */
- for (p = &buf[2]; *p != '\0'; )
- {
- ***************
- *** 203,208 ****
- --- 200,247 ----
- }
- break;
-
- + /* BEGIN STRANGE */
- + /* Do we actually use this??? */
- + case 'E': /* word equivalence class */
- + for (p = &buf[2]; *p != '\0'; )
- + {
- + register char *wd;
- + register char *eqwd;
- + char delim;
- + register STAB *s;
- +
- + while (*p != '\0' && isspace(*p))
- + p++;
- + wd = p;
- + while (*p != '\0' && !isspace(*p))
- + p++;
- + delim = *p;
- + *p = '\0';
- + if (wd[0] == 0)
- + {
- + *p = delim;
- + break;
- + }
- + /*
- + * Cannot use setclass here as we
- + * need the sym entry
- + */
- + s = stab(wd, ST_CLASS, ST_ENTER);
- + setbitn(buf[1], s->s_class);
- + *p = delim;
- + while (*p != '\0' && isspace(*p))
- + p++;
- + eqwd = p;
- + while (*p != '\0' && !isspace(*p))
- + p++;
- + delim = *p;
- + *p = 0;
- + makeequiv(buf[1], eqwd, s);
- + *p = delim;
- + }
- + break;
- + /* END STRANGE */
- +
- case 'M': /* define mailer */
- makemailer(&buf[1]);
- break;
- ***************
- *** 314,324 ****
- {
- register STAB *s;
- char wordbuf[MAXNAME+1];
- !
- ! if (sscanf(buf, fmt, wordbuf) != 1)
- continue;
- s = stab(wordbuf, ST_CLASS, ST_ENTER);
- setbitn(class, s->s_class);
- }
-
- (void) fclose(f);
- --- 353,382 ----
- {
- register STAB *s;
- char wordbuf[MAXNAME+1];
- ! char equivbuf[MAXNAME+1];
- ! int nscanned;
- !
- ! if ((nscanned = sscanf(buf, fmt, wordbuf, equivbuf)) < 1)
- ! {
- ! #ifdef DEBUG
- ! if (tTd(86, 8))
- ! printf("fileclass: found nothing on line.\n");
- ! #endif DEBUG
- continue;
- + }
- + #ifdef DEBUG
- + if (tTd(86, 8))
- + {
- + printf("fileclass: found word \"%s\"", wordbuf);
- + if (nscanned > 1)
- + printf(" => \"%s\"", equivbuf);
- + printf(".\n");
- + }
- + #endif DEBUG
- s = stab(wordbuf, ST_CLASS, ST_ENTER);
- setbitn(class, s->s_class);
- + if (nscanned > 1)
- + makeequiv(class, equivbuf, s);
- }
-
- (void) fclose(f);
- ===================================================================
- RCS file: RCS/sendmail.h,v
- retrieving revision 1.1
- diff -c -r1.1 sendmail.h
- *** /tmp/,RCSt1001795 Thu Oct 31 18:03:32 1985
- --- sendmail.h Sat Oct 19 03:03:24 1985
- ***************
- *** 57,64 ****
- --- 57,69 ----
- #define BYTEBITS 8 /* number of bits in a byte */
-
- /* internal macros */
- + #if BYTEBITS == 8 && (defined(vax) || defined(mc68000) || defined(ns32000))
- + #define _BITWORD(bit) ((bit) >> 5)
- + #define _BITBIT(bit) (1 << ((bit) & (BYTEBITS * sizeof (int) - 1)))
- + #else BYTEBITS == 8
- #define _BITWORD(bit) (bit / (BYTEBITS * sizeof (int)))
- #define _BITBIT(bit) (1 << (bit % (BYTEBITS * sizeof (int))))
- + #endif BYTEBITS == 8
-
- typedef int BITMAP[BITMAPBYTES / sizeof (int)];
-
- ***************
- *** 321,326 ****
- --- 326,334 ----
- # define HOSTBEGIN '\035' /* hostname lookup begin */
- # define HOSTEND '\036' /* hostname lookup end */
-
- + /* canonicalization */
- + # define EQUIVREPL '\037' /* equivalence class replacement */
- +
- /* \001 is also reserved as the macro expansion character */
- /*
- ** Information about hosts that we have looked up recently.
- ***************
- *** 352,357 ****
- --- 360,379 ----
- ** Symbol table definitions
- */
-
- + /*
- + * The canonicalizing operator $&n looks up names and replacements.
- + * The replacment name(s) for a name are stored in the following
- + * linked list, which is then attached to the symbol table entry.
- + */
- + struct equivstr
- + {
- + char class; /* class the replacement is in */
- + char *equivname; /* the replacement name */
- + struct equivstr *next; /* linked list */
- + };
- +
- + typedef struct equivstr EQUIV;
- +
- struct symtab
- {
- char *s_name; /* name to be entered */
- ***************
- *** 367,372 ****
- --- 389,395 ----
- HOSTINFO sv_host; /* host information */
- # endif HOSTINFO
- } s_value;
- + EQUIV *s_equiv; /* list of replacements */
- };
-
- typedef struct symtab STAB;
- ***************
- *** 386,391 ****
- --- 409,415 ----
- # define s_host s_value.sv_host
-
- extern STAB *stab();
- + extern char *getequiv();
-
- /* opcodes to stab */
- # define ST_FIND 0 /* find entry */
- ===================================================================
- RCS file: RCS/stab.c,v
- retrieving revision 1.1
- diff -c -r1.1 stab.c
- *** /tmp/,RCSt1001795 Thu Oct 31 18:03:39 1985
- --- stab.c Fri Oct 18 19:39:27 1985
- ***************
- *** 118,120 ****
- --- 118,221 ----
-
- return (s);
- }
- +
- + /*
- + ** MAKEEQUIV -- make a name equivalence entry
- + **
- + ** Parameters:
- + ** class -- the class the equivalence is in.
- + ** name -- the replacement (new) name.
- + ** s -- the symbol table entry of the source (old) name.
- + **
- + ** Returns:
- + ** none.
- + **
- + ** Side Effects:
- + ** Updates the equivalences attached to `s'.
- + **
- + ** Author:
- + ** Bruce Israel -- 9/4/84.
- + ** Fixes 17 Oct 1985, Chris Torek
- + */
- +
- + makeequiv(class, name, s)
- + register int class;
- + char *name;
- + register STAB *s;
- + {
- + register EQUIV *eq;
- +
- + for (eq = s->s_equiv; eq != NULL; eq = eq->next)
- + {
- + if (eq->class != class)
- + continue;
- +
- + /*
- + * To replace, or to reject: that is the question.
- + * Whether 'tis nobler to suffer the slings and
- + * arrows of outrageous remappings, or, by opposing,
- + * to end them. ...Chris
- + */
- + #ifdef DEBUG
- + if (tTd(87, 5))
- + printf("makeequiv: attempt to replace \"%s\" => \"%s\" (class %c)\n\twith => \"%s\" (ignored).\n",
- + s->s_name, eq->equivname, class, name);
- + #endif DEBUG
- + #ifdef notdef
- + free(eq->equivname);
- + eq->equivname = newstr(name);
- + #endif notdef
- + return;
- + }
- + eq = (EQUIV *)xalloc(sizeof *eq);
- + eq->class = class;
- + eq->equivname = newstr(name);
- + eq->next = s->s_equiv;
- + s->s_equiv = eq;
- + }
- +
- + /*
- + ** GETEQUIV -- get the replacement name for a stab entry given a
- + ** class.
- + **
- + ** Parameters:
- + ** class -- the replacement class.
- + ** s -- the old name.
- + **
- + ** Returns:
- + ** a pointer to a string containing the new name.
- + ** If the symbol table entry has no translation
- + ** name, the original name will be returned.
- + **
- + ** Side Effects:
- + ** none.
- + **
- + ** Author:
- + ** Bruce Israel -- 9/4/84.
- + */
- +
- + char *
- + getequiv(class, s)
- + register int class;
- + register STAB *s;
- + {
- + register EQUIV *eq;
- +
- + for (eq = s->s_equiv; eq != NULL; eq = eq->next)
- + {
- + if (eq->class != class)
- + continue;
- + #ifdef DEBUG
- + if (tTd(87, 5))
- + printf("getequiv: \"%s\" => \"%s\" (class %c).\n",
- + s->s_name, eq->equivname, class);
- + #endif DEBUG
- + return (eq->equivname);
- + }
- + #ifdef DEBUG
- + if (tTd(87, 5))
- + printf("getequiv: \"%s\" not mapped in class %c; unchanged.\n",
- + s->s_name);
- + #endif DEBUG
- + return (s->s_name);
- + }
- //go.sysin dd *
- if [ `wc -c < 4.3diffs` != 13636 ]; then
- made=FALSE
- /bin/echo 'error transmitting "4.3diffs" --'
- /bin/echo 'length should be 13636, not' `wc -c < 4.3diffs`
- else
- made=TRUE
- fi
- if [ $made = TRUE ]; then
- /bin/chmod 644 4.3diffs
- /bin/echo -n ' '; /bin/ls -ld 4.3diffs
- fi
- /bin/echo 'Extracting README'
- sed 's/^X//' <<'//go.sysin dd *' >README
- This documents the University of Maryland modifications to sendmail to
- allow translation tables to be used in sendmail.cf.
-
- There are 5 files here. They are:
-
- 4.2diffs
- 4.3diffs - these are diff -c listings for the changes to the sendmail
- source. The changes exist in 5 files, parseaddr.c (the meat
- of the changes), readcf.c, stab.c main.c and sendmail.h.
-
- mimsy.cf - The standard University of Maryland .cf file. This file is
- almost completely host independent, with only the real name, UUCP
- name, and valid local domain definitions hardcoded into Define's.
- Any other system information has been moved to files in the
- directory /usr/lib/hostnames/.
-
- host-doc - This documents the various files in /usr/lib/hostnames/
- that are used by the sendmail.cf file. It is intended to be a
- README for that directory.
-
- names - this is a shell script that makes a translation table for all
- local network users. It has hard-coded into it all machines on
- the local network, and when run on a machine, builds a file of
- accounts and aliases on the local network but NOT on the current
- host. This file is used by the .cf file to route mail to users on
- the local net. In this fashion, if JOE has an account on one
- local machine, mail to JOE@<any-local-machine> will get to him.
- If JOE has an account on multiple machines, it will route his
- mail to one of them and assume that he has a .forward. Note
- that this requires that names on local network machines be unique
- (i.e. two different people would not be given the same account).
-
- - How to use these mods -
-
- After installing the source mods, you will have a sendmail executable
- that has this extra feature of translation tables. In normal
- sendmails, you use the 'C' and 'F' commands in the .cf file to define
- classes (C for classes define in the .cf file, and F for classes
- defined in an external file). Translation tables are defined with
- the 'E' and 'F' commands. A class is a list of items. A translation
- class is a list of pairs, items and the translated version of the
- item. i.e. a translation file for some uucp sites to be routed (i.e.
- pathalias stuff) could look like:
-
- seismo umcp-cs!seismo
- chimera gymble!harvard!chimera
- godot gymble!harvard!think
- elsie elsie
- ihnp4 umcp-cs!seismo!ihnp4
-
- To read in a translation table from a file, use 'F' like always but
- give a format string with two %s's in it, i.e.
-
- FU/usr/lib/hostnames/uucp-routing %s%s
-
- and both the name and its translation would be read in. The 'E'
- command is like 'C'. It reads pairs of items on the current line (and
- continuation lines) and groups them together. i.e. a list of people
- and the machine that they use might be:
-
- EPjoe site1 bill site2 john site1 ed site3
-
- E was added for orthogonality with C, and is unused in the sample
- sendmail.cf file enclosed.
-
- Accessing Translations
-
- Normally in sendmail you use $<number> in a RHS to access items
- matched on the LHS. If you want the translation instead, follow the $
- with an &, i.e. $&3. For example, rules using the above classes might
- look like:
-
- R$=U!$+ $:$&1!$2 Expand UUCP paths from file
- R$=P $1@$&1 Route mail for users to their machine
-
- Notice that both $num and $&num can be used together. If a
- class was not specified as a translation table, then the translation
- of any item in that class is equivalent to the item itself.
-
- For more information, see the examples in mimsy.cf or send mail to
- israel@mimsy.umd.edu (Arpanet) or seismo!umcp-cs!israel (Usenet).
-
- Enjoy.
- //go.sysin dd *
- if [ `wc -c < README` != 3527 ]; then
- made=FALSE
- /bin/echo 'error transmitting "README" --'
- /bin/echo 'length should be 3527, not' `wc -c < README`
- else
- made=TRUE
- fi
- if [ $made = TRUE ]; then
- /bin/chmod 644 README
- /bin/echo -n ' '; /bin/ls -ld README
- fi
- /bin/echo 'Extracting host-doc'
- sed 's/^X//' <<'//go.sysin dd *' >host-doc
- This file documents the directory /usr/lib/hostnames that is
- frequently used in sendmail.cf. It is intended to be a README for
- that directory.
-
- This directory contains all routing tables for sendmail. The different files
- are used to route mail to different hosts on various nets. The files are:
-
- combined-hosts This file contains sites that are known to be on both the
- arpanet and USEnet. For such sites, mail is routed via
- the ARPAnet if a specific delivery method (i.e. .UUCP) is
- not specified.
-
- csnet This file contains the list of CSNet Phonenet sites. It is
- in the form '<alias> <real-name>'.
-
- cur-site Aliases for the local site.
-
- locals Aliases for all local area network sites. Lines are of
- the form '<site-alias> <real-site-name>'.
-
- mailhosts list of users and mailing lists on the other machines of
- the local network. Lines are of the form:
- <name> <name>@<site>
- This file is created by the 'names' executable nightly.
-
- relays list of domains and an accessible host that knows how
- to relay all mail intended for that domain. For
- example, 'csnet csnet-relay.arpa'.
-
- specials list of hosts that need to be specially processed, and
- the real way to get to that host. This can be used for
- defining special, non-arpanet hosts or hosts who need
- a special path (like if a connection is broken). Each
- line is '<site> <real-site-with-routing>'. For example:
- if ARPASITE's arpanet connection is down indefinitely, you
- might put in: 'ARPASITE ARPASITE.uucp@ARPANEIGHBOR.uucp' and
- then mail will be routed to ARPANEIGHBOR via UUCP and then
- to ARPASITE. Because of the purpose of this file, any
- path in here overrides all other paths (including user
- specified paths).
-
- uucp-direct List of sites that this site talks to directly via UUCP.
-
- uucp-routing List of UUCPnet sites that we know how to route to.
- Lines are of the form '<name> <route>!<name>'.
- //go.sysin dd *
- if [ `wc -c < host-doc` != 1903 ]; then
- made=FALSE
- /bin/echo 'error transmitting "host-doc" --'
- /bin/echo 'length should be 1903, not' `wc -c < host-doc`
- else
- made=TRUE
- fi
- if [ $made = TRUE ]; then
- /bin/chmod 644 host-doc
- /bin/echo -n ' '; /bin/ls -ld host-doc
- fi
- /bin/echo 'Extracting mimsy.cf'
- sed 's/^X//' <<'//go.sysin dd *' >mimsy.cf
- ############################################################
- ############################################################
- #####
- ##### SENDMAIL CONFIGURATION FILE
- #####
- ##### @(#) U of Maryland, October 1985
- ##### - Bruce Israel israel@mimsy.umd.edu,
- ##### umcp-cs!israel
- #####
- ############################################################
- ############################################################
-
-
-
- ############################################################
- ### local info
- ############################################################
-
- # load to start queuing. (busted--never queue. MDW 8/3/84)
- Ox50
-
- # UUCP name
- DUumcp-cs
- CU$U
-
- Dwmimsy
-
- # internet hostname for current host - put into a file for portability
- Fw/usr/lib/hostnames/cur-site
- DA$w
-
- # domain
- DDumd.edu
- CDumd.edu arpa csnet uucp
-
- # official hostname
- Dj$w.$D
-
- # csnet names
- FC/usr/lib/hostnames/csnet %s%s
-
- # domain relays, (domain relay-site)
- FR/usr/lib/hostnames/relays %s%s
-
- # UUCP hosts that we talk directly to
- FW/usr/lib/hostnames/uucp-direct
-
- # users mailhosts, local network people (user user@real-host)
- FH/usr/lib/hostnames/mailhosts %s%s
-
- # local network sites (site-alias real-site-name)
- FL/usr/lib/hostnames/locals %s%s
-
- # uucp routing table (site uucp-path!site)
- FP/usr/lib/hostnames/uucp-routing %s%s
- FP/usr/lib/hostnames/uucp-direct
-
- # combination uucp/arpanet hosts, all local hosts are networked
- FX/usr/lib/hostnames/combined-hosts
- FX/usr/lib/hostnames/locals %s
-
- # Hosts to handle specially (site override-path)
- FS/usr/lib/hostnames/specials %s%s
-
- ############################################################
- #
- # General configuration information
- #
- # This information is basically just "boiler-plate"; it must be
- # there, but is essentially constant.
- #
- # Information in this file should be independent of location --
- # i.e., although there are some policy decisions made, they are
- # not specific to Berkeley per se.
- #
- # @(#)base.m4 4.3 8/30/83
- #
- ############################################################
-
- # @(#)version.m4 4.7 8/31/83
-
- DV4.7
-
- ##########################
- ### Special macros ###
- ##########################
-
- # my name
- DnMAILER-DAEMON
- # UNIX header format
- DlFrom $g $d $y
- # delimiter (operator) characters
- Do.:%@!^=/[]
- # format of a total name
- # yucky style... Dq$g$?x ($x)$.
- Dq$?x$x $.<$g>
- # SMTP login message
- De$j Sendmail $v/$V (with U of MD hacks) ready at $b
-
- # forwarding host -- redefine this if you can't talk to the relay directly
- DF$R
-
- ###################
- ### Options ###
- ###################
-
- # location of alias file
- OA/usr/lib/aliases
- # default delivery mode (deliver in background)
- Odbackground
- # (don't) connect to "expensive" mailers
- #Oc
- # temporary file mode
- OF0644
- # default GID
- Og1
- # location of help file
- OH/usr/lib/sendmail.hf
- # log level
- OL9
- # default messages to old style
- Oo
- # queue directory
- OQ/usr/spool/mqueue
- # read timeout -- violates protocols
- Or2h
- # status file
- OS/usr/lib/sendmail.st
- # queue up everything before starting transmission
- Os
- # default timeout interval
- OT9d
- # time zone names (V6 only)
- OtEST,EDT
- # default UID
- Ou1
-
- ###############################
- ### Message precedences ###
- ###############################
-
- Pfirst-class=0
- Pspecial-delivery=100
- Pjunk=-100
-
- #########################
- ### Trusted users ###
- #########################
-
- Troot
- Tdaemon
- Tuucp
- Tmark
- Tisrael
- Tnetwork
- Ttewok
-
- #############################
- ### Format of headers ###
- #############################
-
- H?P?Return-Path: <$g>
- HReceived: $?sfrom $s $.by $j ($v/$V)
- id $i; $b
- H?D?Resent-Date: $a
- H?D?Date: $a
- H?F?Resent-From: $q
- H?F?From: $q
- H?x?Full-Name: $x
- HSubject:
- # HPosted-Date: $a
- # H?l?Received-Date: $b
- H?M?Resent-Message-Id: <$t.$i@$j>
- H?M?Message-Id: <$t.$i@$j>
-
- ###########################
- ### Rewriting rules ###
- ###########################
-
-
- ################################
- # Sender Field Pre-rewriting #
- ################################
- S1
- #R$*<$*>$* $1$2$3 defocus
-
- ###################################
- # Recipient Field Pre-rewriting #
- ###################################
- S2
- #R$*<$*>$* $1$2$3 defocus
-
- #################################
- # Final Output Post-rewriting #
- #################################
- S4
-
- R@ $@ handle <> error addr
-
- # externalize local domain info
- R$*<$*LOCAL>$* $1<$2$D>$3 change local info
- R$*<$+>$* $1$2$3 defocus
- R@$+:$+:$+ $@@$1,$2:$3 <route-addr> canonical
-
- # UUCP must always be presented in old form
- R$+@$-.UUCP $2!$1 u@h.UUCP => h!u
-
- # delete duplicate local names -- mostly for arpaproto.mc
- R$+%$=w@$=w $1@$3 u%UCB@UCB => u@UCB
- R$+%$=w@$=w.$=D $1@$3.ARPA u%UCB@UCB => u@UCB
-
- ###########################
- # Name Canonicalization #
- ###########################
- S3
-
- # handle "from:<>" special case
- R<> $@@ turn into magic token
-
- # basic textual canonicalization
- R$*<$+>$* $2 basic RFC821/822 parsing
- R$+ at $+ $1@$2 "at" -> "@" for RFC 822
- R$*<$*>$* $1$2$3 in case recursive
-
- # make sure <@a,@b,@c:user@d> syntax is easy to parse -- undone later
- R@$+,$+ @$1:$2 change all "," to ":"
-
- # localize and dispose of domain-based addresses
- R@$+:$+ $@$>6<@$1>:$2 handle <route-addr>
-
- # more miscellaneous cleanup
- R$+:$*;@$+ $@$>6$1:$2;@$3 list syntax
- R$+@$+ $:$1<@$2> focus on domain
- R$+<$+@$+> $1$2<@$3> move gaze right
- R$+<@$+> $@$>6$1<@$2> already canonical
-
- # convert old-style addresses to a domain-based address
- R$+%$+ $@$>6$1<@$2> user%host
- R$-:$+ $@$>6$2<@$1> host:user
- R$-.$+ $@$>6$2<@$1> host.user
- R$+^$+ $1!$2 convert ^ to !
- R$-!$+ $@$>6$2<@$1.UUCP> resolve uucp names
- R$-=$+ $@$>6$2<@$1.BITNET> resolve bitnet names
- R$* $@$>6$1 process everything else
-
- ############################################################
- ############################################################
- #####
- ##### RULESET ZERO PREAMBLE
- #####
- ##### The beginning of ruleset zero is constant through all
- ##### configurations.
- #####
- ##### @(#)zerobase.m4 4.1 7/25/83
- #####
- ############################################################
- ############################################################
-
- S0
-
- # first make canonical
- R$*<$*>$* $1$2$3 defocus
- R$+ $:$>3$1 make canonical
-
- # handle special cases.....
- R@ $#local$:MAILER-DAEMON handle <> form
- R$*<@[$+]>$* $#tcp$@[$2]$:$1@[$2]$3 numeric internet spec
-
- # arrange for local names to be fully qualified
- R$*<$+.ARPA.LOCAL>$* $1<$2.ARPA>$3 because ARPA is a host
-
- # now delete the local info
- R$*<$*$=w.LOCAL>$* $1<$2>$4 thishost.LOCAL
- R$*<$*$=w.ARPA>$* $1<$2>$4 thishost.ARPA
- R$*<$*$=w.UUCP>$* $1<$2>$4 thishost.UUCP
- R$*<$*$=w>$* $1<$2>$4 thishost
- R$*<$*.>$* $1<$2>$3 drop trailing dot
- R<@>:$* $@$>0$1 retry after route strip
- R$*<@> $@$>0$1 strip null trash & retry
-
- ##################################
- # End of ruleset zero preamble #
- ##################################
-
-
- ################################################
- ### Machine dependent part of ruleset zero ###
- ################################################
-
- # Do host routing
-
- R$+<@$=w.$=D> $#local$:$1 If local host, deliver
- R$+<@$=w.$D> $#local$:$1 If local host, deliver
- R$+<@$=w> $#local$:$1 If local host, deliver
-
- # Do UUCP delivery for known UUCP sites
- R<@$=W.UUCP>$+ $#uucp$@$1$:$2 @host.UUCP: ...
- R$+<@$=W.UUCP> $#uucp$@$2$:$1 user@host.UUCP
- R$+<@$-.UUCP> $:$1<@$2.ARPA> if not uucp, try net
-
- # resolve ARPA names we can handle locally
- R$*<@$-.ARPA>$* $#tcp$@$2$:$1<@$2.ARPA>$3 remove ARPA domain
- R$*<@$+>$* $#tcp$@$2$:$1<@$2>$3 deliver w/ domain
-
- # catch whatever may have fallen thru the cracks.
- R$+%$+ $:$>28$1%$2 if it still has @ or %,
- R$+@$+ $:$>28$1@$2 then retry after doing
- R$+<@$+> $@$>0$1<@$2> simple re-canon.
-
- # remaining names must be local
- R$+ $#local$:$1 everything else
-
- ############################################################
- ############################################################
- #####
- ##### Local and Program Mailer specification
- #####
- ##### @(#)localm.m4 4.1 7/25/83
- #####
- ############################################################
- ############################################################
-
- Mlocal, P=/bin/mail, F=lsDFMmn, S=10, R=20, A=mail -d $u
-
- # 4.3 should be:
- #Mlocal, P=/bin/mail, F=rlsDFMmn, S=10, R=20, A=mail -d $u
-
- Mprog, P=/bin/sh, F=lsDFMe, S=10, R=20, A=sh -c $u
-
- S10
- R@ MAILER-DAEMON errors to mailer-daemon
-
- ############################################################
- ############################################################
- #####
- ##### Arpanet TCP Mailer specification
- #####
- ##### @(#)tcpm.m4 4.1 7/25/83
- #####
- ############################################################
- ############################################################
-
- Mtcp, P=[IPC], F=msDFMueXL, S=14, R=14, A=IPC $h, E=\r\n
-
- # 4.3 version is:
- #Mtcp, P=[IPC], F=mDFMueXL, S=14, R=14, A=IPC $h, E=\r\n
-
- S14
-
- # pass <route-addr>'s through
- R<@$+>$* $@<@$1>$2 resolve <route-addr>
-
- # map colons to dots everywhere.....
- R$*:$* $1.$2 map colons to dots
-
- # handle the simple case....
- R$+<@$-.ARPA> $@$1<@$2.ARPA> user@host.ARPA
-
- # output local hosts in user%host@mimsy syntax
- R$+<@LOCAL> $@$1<@$A> local names
- R$+<@$+.LOCAL> $@$1%$2<@$A> local hosts
-
- # handle other external cases
- R$+<@$-> $@$1<@$2> no .ARPA on simple names
- R$+<@$+.$-.ARPA> $@$1%$2<@$3.ARPA> approximate something
- R$+<@[$+]> $@$1<@[$2]> already ok
-
- # convert remaining addresses to old format and externalize appropriately
- R$+ $:$>5$1 => old format
- R$-:$+ $@$1.$2<@$A> convert berk hosts
- R$+<@$+> $@$1<@$2> don't pessmize
- R$+ $:$1<@$w.$D> tack on our hostname
-
-
- #####################################################
- # General code to convert back to old style names #
- #####################################################
- S5
-
- R$+<@$-.LOCAL> $2:$1 u@h.LOCAL => h:u
- R$+<@$-.UUCP> $2!$1 u@host.UUCP => host!u
- R$+@$+.ARPA $1@$2 u@host.ARPA => u@host
-
-
- Muucp, P=/usr/bin/uux, F=sDFMhuU, S=13, R=23, M=100000,
- A=uux - -r $h!rmail ($u)
-
- # 4.3 version is:
- #Muucp, P=/usr/bin/uux, F=sDFMmhuU, S=13, R=23, M=100000,
- # A=uux - -r -z -a$g $h!rmail ($u)
-
- S13
- R$+ $:$>5$1 convert to old style
- R$=w!$+ $2 strip local name
- R$*<@$->$* $1<@$2.ARPA>$3 resolve abbreviations
- R$+ $:$U!$1 stick on our host name
- # R$=w!$=R:$+ $:$1!$3 ucbvax!ucbvax:xxx
-
- S23
- R$+ $:$>5$1 convert to old style
- R$*<@$->$* $1<@$2.ARPA>$3 resolve abbreviations
-
- #
- # S6 - Fully qualify all addresses.
- #
- # This ruleset is the last thing that Ruleset 3 calls before returning.
- # it fully qualifies all addresses by making sure that the proper host
- # and domain names are present. It handles domainifying, mail host
- # routing, and UUCP, csnet, and bitnet routing in the following way:
- #
- # 1) if the address is for an account on another machine on the local
- # network, it appends the appropriate host of the account.
- # 2) local accounts have the local hostname added, and all local
- # network machines have the network domain appended.
- # 3) destinations that are handled by relays, i.e. csnet and bitnet
- # domains, are forwarded to the correct relay machine.
- # 4) addresses destined for a UUCP host have the explicit route
- # to that host added.
- # 5) any remaining addresses without domains are assumed to be
- # ARPAnet hosts.
-
- S6
-
- # source routing - don't process address at all
-
- R<@$-.$+>:$* $@<@$1.$2>:$3
- R<@$*>:$* $@<@$1.arpa>:$2
-
- # Handle special hosts. (i.e. Hosts that need special handling,
- # such as broken connections, or overriding paths.
-
- R$*<@$=S$*> $>28$1%$&2 match on hostname only, ignoring domain
-
- # local
-
- R$+<@$=w.$=D> $:$>29$1 remove all local hosts,
- R$+<@$=w.$D> $:$>29$1 with any real local
- R$+<@$=w> $:$>29$1 domain.
-
- R$* $:$>28$1 put back in canonical
-
- # expand mailhosts
- R$=H $:$>28$&1 modify to mailhost address
-
- R$- $@$1<@$w.$D> if no host, then local (fully qual)
-
- # add local domain if needed
- R$+<@$=L> $@$1<@$&2.$D> if local net host, use local domain
- R$+<@$=L.$=D> $@$1<@$&2.$D> if local net host, use local domain
-
- # do relayed domain
- R$*<@$=C> $:$1<@$&2.CSNET> add domain to csnet sites
- R$*<@$+.$=R> $@$1%$2.$3<@$&3> if relayed domain, use relay
-
- # ARPAize appropriate hosts
- R$+<@$=X> $@$1<@$2.ARPA> if uucp and arpa, use arpa
-
- # route known UUCP hosts
- R$+<@$=P> $:$>29$&2!$1 if unknown but UUCP, use route
- R$+<@$=P.UUCP> $:$>29$&2!$1 if known but UUCP, use route
-
- # add ARPA domain to domainless hosts
-
- R$*<@$-> $@$1<@$2.ARPA> If still domainless, then ARPA
- R$*<$*> $@$1<$2> Return if canonical
-
- R$*!!$* $1!$2 Eliminate all double-bangs
- R$-!$+ $@$2<@$1.UUCP> convert non-can. UUCP to canon.
-
- # S29 - recursively remove all local host names with either the proper
- # domain, an ARPA domain, or no domain.
-
- S29
-
- R$+@$=w.$=D $@$>29$1
- R$+@$=w.$D $@$>29$1
- R$+@$=w $@$>29$1
-
- R$+%$=w.$=D $@$>29$1
- R$+%$=w.$D $@$>29$1
- R$+%$=w $@$>29$1
-
- R$=w!$+ $@$>29$2
-
- # convert any non-canonical to canonical
-
- S28
- R$*<@$*> $@$1<@$2> Already canonical, accept
-
- R$*%$* $1@$2 Convert all %'s to @'s
- R$*@$*@$* $1%$2@$3 Convert all but last back
-
- R$*@$* $@$1<@$2> make into canonical
- //go.sysin dd *
- if [ `wc -c < mimsy.cf` != 13094 ]; then
- made=FALSE
- /bin/echo 'error transmitting "mimsy.cf" --'
- /bin/echo 'length should be 13094, not' `wc -c < mimsy.cf`
- else
- made=TRUE
- fi
- if [ $made = TRUE ]; then
- /bin/chmod 644 mimsy.cf
- /bin/echo -n ' '; /bin/ls -ld mimsy.cf
- fi
- /bin/echo 'Extracting names'
- sed 's/^X//' <<'//go.sysin dd *' >names
- #! /bin/csh -f
- #
- # names - generate a list of aliases on the current host for addresses
- # that are on the local network but NOT on the current host.
- # these will be used by the mail system so that any addresses on
- # the local network appear to be addresses local to the current
- # host.
- #
- # method: all addresses on the local net are processed thru
- # getting their aliases and passwd files.
- # aliases on any machine take priority over accounts anywhere.
- # current machine takes priority over other machines.
- #
- # temp files: uniq - unique names in list (for eliminating repeats)
- # list - generated list
- # tmp1,2 - intermediate processing files
- #
- # set the machines on the local network here (in order of priority).
- set locals = (mimsy tove gymble gyre brilig)
- #
- set uniq = /tmp/names.u.$$ list = /tmp/names.l.$$
- set tmp1 = /tmp/names.1.$$ tmp2 = /tmp/names.2.$$
- cp /dev/null $list
- cp /dev/null $uniq
- foreach file ( /usr/lib/aliases /etc/passwd )
- # process current host addresses from $file first
- awk -F: '{print $1}' < $file | grep -v "#" | grep -v '^$' | \
- sort | uniq> $tmp1
- # put current host addresses into uniq file ONLY. That way they won't be
- # generated from another machine, and the mail system will get them itself
- # from local files.
- cat $tmp1 $uniq | sort -o $uniq
- foreach host ( $locals )
- set work = tmp/$host.$file:t
- rcp ${host}:${file} $work
- # get name from file, ignoring comments and blank lines
- awk -F: '{print $1}' <$work | grep -v "#" | \
- grep -v '^$' | sort | uniq > $tmp1
- # get only names that haven't already been used (i.e. $tmp1 - $uniq)
- comm -13 $uniq $tmp1 > $tmp2
- # add new names to list with host, and to unique names list
- awk '{print $1 " " $1 "@'$host'" }' < $tmp2 >> $list
- cat $tmp2 $uniq | sort -o $uniq
- end
- end
- sort $list
- rm -f $uniq $list $tmp1 $tmp2
- //go.sysin dd *
- if [ `wc -c < names` != 1834 ]; then
- made=FALSE
- /bin/echo 'error transmitting "names" --'
- /bin/echo 'length should be 1834, not' `wc -c < names`
- else
- made=TRUE
- fi
- if [ $made = TRUE ]; then
- /bin/chmod 755 names
- /bin/echo -n ' '; /bin/ls -ld names
- fi
-
-