X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=sbr%2Fmf.c;h=8130fbfb6b0aa2877ab9a5ea2fe6539f80055b54;hp=fdad91e42d8585a8918d83ccf49e9d5590005cf1;hb=5cb46b33551f28e4168989e752e09bd927e993f9;hpb=b067ff5c465a5d243ce5a19e562085a9a1a97215 diff --git a/sbr/mf.c b/sbr/mf.c index fdad91e..8130fbf 100644 --- a/sbr/mf.c +++ b/sbr/mf.c @@ -1,123 +1,109 @@ /* - * mf.c -- mail filter subroutines - * - * This code is Copyright (c) 2002, by the authors of nmh. See the - * COPYRIGHT file in the root directory of the nmh distribution for - * complete copyright information. - */ +** mf.c -- mail filter subroutines +** +** This code is Copyright (c) 2002, by the authors of nmh. See the +** COPYRIGHT file in the root directory of the nmh distribution for +** complete copyright information. +*/ #include #include #include #include +#include +#include +#include /* - * static prototypes - */ -static char *getcpy (char *); -static int isat (char *); -static int parse_address (void); -static int phrase (char *); -static int route_addr (char *); -static int local_part (char *); -static int domain (char *); -static int route (char *); -static int my_lex (char *); +** static prototypes +*/ +static char *getcpy(char *); +static int parse_address(void); +static int phrase(char *); +static int route_addr(char *); +static int local_part(char *); +static int domain(char *); +static int route(char *); +static int my_lex(char *); static char * -getcpy (char *s) +getcpy(char *s) { - register char *p; + char *p; if (!s) { /* - * causes compiles to blow up because the symbol _cleanup - * is undefined where did this ever come from? - */ + ** causes compiles to blow up because the symbol _cleanup + ** is undefined where did this ever come from? + */ /* _cleanup(); */ abort(); for(;;) pause(); } - p = mh_xmalloc ((size_t) (strlen (s) + 2)); - strcpy (p, s); + p = mh_xcalloc(strlen(s) + 2, sizeof(char)); + strcpy(p, s); return p; } -#define CHKADR 0 /* undertermined address style */ -#define UNIXDR 1 /* UNIX-style address */ -#define ARPADR 2 /* ARPAnet-style address */ - - -static int -isat (char *p) -{ - return (strncmp (p, " AT ", 4) - && strncmp (p, " At ", 4) - && strncmp (p, " aT ", 4) - && strncmp (p, " at ", 4) ? FALSE : TRUE); -} - - /* - * - * getadrx() implements a partial 822-style address parser. The parser - * is neither complete nor correct. It does however recognize nearly all - * of the 822 address syntax. In addition it handles the majority of the - * 733 syntax as well. Most problems arise from trying to accomodate both. - * - * In terms of 822, the route-specification in - * - * "<" [route] local-part "@" domain ">" - * - * is parsed and returned unchanged. Multiple at-signs are compressed - * via source-routing. Recursive groups are not allowed as per the - * standard. - * - * In terms of 733, " at " is recognized as equivalent to "@". - * - * In terms of both the parser will not complain about missing hosts. - * - * ----- - * - * We should not allow addresses like - * - * Marshall T. Rose - * - * but should insist on - * - * "Marshall T. Rose" - * - * Unfortunately, a lot of mailers stupidly let people get away with this. - * - * ----- - * - * We should not allow addresses like - * - * - * - * but should insist on - * - * MRose@UCI - * - * Unfortunately, a lot of mailers stupidly let people's UAs get away with - * this. - * - * ----- - * - * We should not allow addresses like - * - * @UCI:MRose@UCI-750a - * - * but should insist on - * - * Marshall Rose <@UCI:MRose@UCI-750a> - * - * Unfortunately, a lot of mailers stupidly do this. - * - */ +** +** getadrx() implements a partial 822-style address parser. The parser +** is neither complete nor correct. It does however recognize nearly all +** of the 822 address syntax. +** Historically, it handled the majority (and still handles parts) of the +** 733 syntax as well. Most problems arise from trying to accommodate both. +** +** In terms of 822, the route-specification in +** +** "<" [route] local-part "@" domain ">" +** +** is parsed and returned unchanged. Multiple at-signs are compressed +** via source-routing. Recursive groups are not allowed as per the +** standard. +** +** In terms of both the parser will not complain about missing hosts. +** +** ----- +** +** We should not allow addresses like +** +** Marshall T. Rose +** +** but should insist on +** +** "Marshall T. Rose" +** +** Unfortunately, a lot of mailers stupidly let people get away with this. +** +** ----- +** +** We should not allow addresses like +** +** +** +** but should insist on +** +** MRose@UCI +** +** Unfortunately, a lot of mailers stupidly let people's UAs get away with +** this. +** +** ----- +** +** We should not allow addresses like +** +** @UCI:MRose@UCI-750a +** +** but should insist on +** +** Marshall Rose <@UCI:MRose@UCI-750a> +** +** Unfortunately, a lot of mailers stupidly do this. +** +*/ #define QUOTE '\\' @@ -176,79 +162,77 @@ static struct adrx adrxs2; struct adrx * -getadrx (char *addrs) +getadrx(char *addrs) { - register char *bp; - register struct adrx *adrxp = &adrxs2; + char *bp; + struct adrx *adrxp = &adrxs2; if (pers) - free (pers); + mh_free0(&pers); if (mbox) - free (mbox); + mh_free0(&mbox); if (host) - free (host); + mh_free0(&host); if (path) - free (path); + mh_free0(&path); if (grp) - free (grp); + mh_free0(&grp); if (note) - free (note); - pers = mbox = host = path = grp = note = NULL; + mh_free0(¬e); err[0] = 0; if (dp == NULL) { - dp = cp = getcpy (addrs ? addrs : ""); + dp = cp = getcpy(addrs ? addrs : ""); glevel = 0; } else if (cp == NULL) { - free (dp); - dp = NULL; + mh_free0(&dp); return NULL; } - switch (parse_address ()) { - case DONE: - free (dp); - dp = cp = NULL; - return NULL; - - case OK: - switch (last_lex) { - case LX_COMA: - case LX_END: - break; + switch (parse_address()) { + case DONE: + mh_free0(&dp); + cp = NULL; + return NULL; - default: /* catch trailing comments */ - bp = cp; - my_lex (adr); - cp = bp; - break; - } + case OK: + switch (last_lex) { + case LX_COMA: + case LX_END: break; - default: + default: /* catch trailing comments */ + bp = cp; + my_lex(adr); + cp = bp; break; } + break; + + default: + break; + } if (err[0]) for (;;) { switch (last_lex) { - case LX_COMA: - case LX_END: - break; + case LX_COMA: + case LX_END: + break; - default: - my_lex (adr); - continue; + default: + my_lex(adr); + continue; } break; } - while (isspace (*ap)) + while (isspace(*ap)) ap++; if (cp) - sprintf (adr, "%.*s", (int)(cp - ap), ap); + sprintf(adr, "%.*s", (int)(cp - ap), ap); else - strcpy (adr, ap); - bp = adr + strlen (adr) - 1; + strcpy(adr, ap); + bp = adr + strlen(adr) - 1; if (*bp == ',' || *bp == ';' || *bp == '\n') *bp = 0; @@ -267,330 +251,328 @@ getadrx (char *addrs) static int -parse_address (void) +parse_address(void) { char buffer[BUFSIZ]; again: ; ap = cp; - switch (my_lex (buffer)) { - case LX_ATOM: - case LX_QSTR: - pers = getcpy (buffer); - break; + switch (my_lex(buffer)) { + case LX_ATOM: + case LX_QSTR: + pers = getcpy(buffer); + break; + + case LX_SEMI: + if (glevel-- <= 0) { + strcpy(err, "extraneous semi-colon"); + return NOTOK; + } + case LX_COMA: + if (note) { + mh_free0(¬e); + } + goto again; - case LX_SEMI: - if (glevel-- <= 0) { - strcpy (err, "extraneous semi-colon"); - return NOTOK; - } - case LX_COMA: - if (note) { - free (note); - note = NULL; - } - goto again; + case LX_END: + return DONE; - case LX_END: - return DONE; + case LX_LBRK: /* sigh (2) */ + goto get_addr; - case LX_LBRK: /* sigh (2) */ - goto get_addr; + case LX_AT: /* sigh (3) */ + cp = ap; + if (route_addr(buffer) == NOTOK) + return NOTOK; + return OK; /* why be choosy? */ - case LX_AT: /* sigh (3) */ - cp = ap; - if (route_addr (buffer) == NOTOK) - return NOTOK; - return OK; /* why be choosy? */ + default: + sprintf(err, "illegal address construct (%s)", buffer); + return NOTOK; + } - default: - sprintf (err, "illegal address construct (%s)", buffer); + switch (my_lex(buffer)) { + case LX_ATOM: + case LX_QSTR: + pers = add(buffer, add(" ", pers)); +more_phrase: ; /* sigh (1) */ + if (phrase(buffer) == NOTOK) return NOTOK; - } - switch (my_lex (buffer)) { - case LX_ATOM: - case LX_QSTR: - pers = add (buffer, add (" ", pers)); - more_phrase: ; /* sigh (1) */ - if (phrase (buffer) == NOTOK) + switch (last_lex) { + case LX_LBRK: +get_addr: ; + if (route_addr(buffer) == NOTOK) return NOTOK; + if (last_lex == LX_RBRK) + return OK; + sprintf(err, "missing right-bracket (%s)", buffer); + return NOTOK; - switch (last_lex) { - case LX_LBRK: - get_addr: ; - if (route_addr (buffer) == NOTOK) - return NOTOK; - if (last_lex == LX_RBRK) + case LX_COLN: +get_group: ; + if (glevel++ > 0) { + sprintf(err, "nested groups not allowed (%s)", pers); + return NOTOK; + } + grp = add(": ", pers); + pers = NULL; + { + char *pp = cp; + + for (;;) + switch (my_lex(buffer)) { + case LX_SEMI: + case LX_END: /* tsk, tsk */ + glevel--; return OK; - sprintf (err, "missing right-bracket (%s)", buffer); - return NOTOK; - - case LX_COLN: - get_group: ; - if (glevel++ > 0) { - sprintf (err, "nested groups not allowed (%s)", pers); - return NOTOK; - } - grp = add (": ", pers); - pers = NULL; - { - char *pp = cp; - - for (;;) - switch (my_lex (buffer)) { - case LX_SEMI: - case LX_END: /* tsk, tsk */ - glevel--; - return OK; - - case LX_COMA: - continue; - - default: - cp = pp; - return parse_address (); - } - } - case LX_DOT: /* sigh (1) */ - pers = add (".", pers); - goto more_phrase; + case LX_COMA: + continue; - default: - sprintf (err, "no mailbox in address, only a phrase (%s%s)", pers, buffer); - return NOTOK; + default: + cp = pp; + return parse_address(); + } } - case LX_LBRK: - goto get_addr; + case LX_DOT: /* sigh (1) */ + pers = add(".", pers); + goto more_phrase; - case LX_COLN: - goto get_group; + default: + sprintf(err, "no mailbox in address, only a phrase (%s%s)", pers, buffer); + return NOTOK; + } - case LX_DOT: - mbox = add (buffer, pers); - pers = NULL; - if (route_addr (buffer) == NOTOK) - return NOTOK; - goto check_end; + case LX_LBRK: + goto get_addr; - case LX_AT: - ingrp = glevel; - mbox = pers; - pers = NULL; - if (domain (buffer) == NOTOK) - return NOTOK; - check_end: ; - switch (last_lex) { - case LX_SEMI: - if (glevel-- <= 0) { - strcpy (err, "extraneous semi-colon"); - return NOTOK; - } - case LX_COMA: - case LX_END: - return OK; + case LX_COLN: + goto get_group; - default: - sprintf (err, "junk after local@domain (%s)", buffer); - return NOTOK; - } + case LX_DOT: + mbox = add(buffer, pers); + pers = NULL; + if (route_addr(buffer) == NOTOK) + return NOTOK; + goto check_end; - case LX_SEMI: /* no host */ - case LX_COMA: - case LX_END: - ingrp = glevel; - if (last_lex == LX_SEMI && glevel-- <= 0) { - strcpy (err, "extraneous semi-colon"); + case LX_AT: + ingrp = glevel; + mbox = pers; + pers = NULL; + if (domain(buffer) == NOTOK) + return NOTOK; +check_end: ; + switch (last_lex) { + case LX_SEMI: + if (glevel-- <= 0) { + strcpy(err, "extraneous semi-colon"); return NOTOK; } - mbox = pers; - pers = NULL; + case LX_COMA: + case LX_END: return OK; default: - sprintf (err, "missing mailbox (%s)", buffer); + sprintf(err, "junk after local@domain (%s)", buffer); + return NOTOK; + } + + case LX_SEMI: /* no host */ + case LX_COMA: + case LX_END: + ingrp = glevel; + if (last_lex == LX_SEMI && glevel-- <= 0) { + strcpy(err, "extraneous semi-colon"); return NOTOK; + } + mbox = pers; + pers = NULL; + return OK; + + default: + sprintf(err, "missing mailbox (%s)", buffer); + return NOTOK; } } static int -phrase (char *buffer) +phrase(char *buffer) { for (;;) - switch (my_lex (buffer)) { - case LX_ATOM: - case LX_QSTR: - pers = add (buffer, add (" ", pers)); - continue; + switch (my_lex(buffer)) { + case LX_ATOM: + case LX_QSTR: + pers = add(buffer, add(" ", pers)); + continue; - default: - return OK; + default: + return OK; } } static int -route_addr (char *buffer) +route_addr(char *buffer) { - register char *pp = cp; + char *pp = cp; - if (my_lex (buffer) == LX_AT) { - if (route (buffer) == NOTOK) + if (my_lex(buffer) == LX_AT) { + if (route(buffer) == NOTOK) return NOTOK; } else cp = pp; - if (local_part (buffer) == NOTOK) + if (local_part(buffer) == NOTOK) return NOTOK; switch (last_lex) { - case LX_AT: - return domain (buffer); + case LX_AT: + return domain(buffer); - case LX_SEMI: /* if in group */ - case LX_RBRK: /* no host */ - case LX_COMA: - case LX_END: - return OK; + case LX_SEMI: /* if in group */ + case LX_RBRK: /* no host */ + case LX_COMA: + case LX_END: + return OK; - default: - sprintf (err, "no at-sign after local-part (%s)", buffer); - return NOTOK; + default: + sprintf(err, "no at-sign after local-part (%s)", buffer); + return NOTOK; } } static int -local_part (char *buffer) +local_part(char *buffer) { ingrp = glevel; for (;;) { - switch (my_lex (buffer)) { - case LX_ATOM: - case LX_QSTR: - mbox = add (buffer, mbox); - break; + switch (my_lex(buffer)) { + case LX_ATOM: + case LX_QSTR: + mbox = add(buffer, mbox); + break; - default: - sprintf (err, "no mailbox in local-part (%s)", buffer); - return NOTOK; + default: + sprintf(err, "no mailbox in local-part (%s)", buffer); + return NOTOK; } - switch (my_lex (buffer)) { - case LX_DOT: - mbox = add (buffer, mbox); - continue; + switch (my_lex(buffer)) { + case LX_DOT: + mbox = add(buffer, mbox); + continue; - default: - return OK; + default: + return OK; } } } static int -domain (char *buffer) +domain(char *buffer) { for (;;) { - switch (my_lex (buffer)) { - case LX_ATOM: - case LX_DLIT: - host = add (buffer, host); - break; + switch (my_lex(buffer)) { + case LX_ATOM: + case LX_DLIT: + host = add(buffer, host); + break; - default: - sprintf (err, "no sub-domain in domain-part of address (%s)", buffer); - return NOTOK; + default: + sprintf(err, "no sub-domain in domain-part of address (%s)", buffer); + return NOTOK; } - switch (my_lex (buffer)) { - case LX_DOT: - host = add (buffer, host); - continue; + switch (my_lex(buffer)) { + case LX_DOT: + host = add(buffer, host); + continue; - case LX_AT: /* sigh (0) */ - mbox = add (host, add ("%", mbox)); - free (host); - host = NULL; - continue; + case LX_AT: /* sigh (0) */ + mbox = add(host, add("%", mbox)); + mh_free0(&host); + continue; - default: - return OK; + default: + return OK; } } } static int -route (char *buffer) +route(char *buffer) { - path = getcpy ("@"); + path = getcpy("@"); for (;;) { - switch (my_lex (buffer)) { - case LX_ATOM: - case LX_DLIT: - path = add (buffer, path); - break; + switch (my_lex(buffer)) { + case LX_ATOM: + case LX_DLIT: + path = add(buffer, path); + break; - default: - sprintf (err, "no sub-domain in domain-part of address (%s)", buffer); - return NOTOK; + default: + sprintf(err, "no sub-domain in domain-part of address (%s)", buffer); + return NOTOK; } - switch (my_lex (buffer)) { - case LX_COMA: - path = add (buffer, path); - for (;;) { - switch (my_lex (buffer)) { - case LX_COMA: - continue; - - case LX_AT: - path = add (buffer, path); - break; - - default: - sprintf (err, "no at-sign found for next domain in route (%s)", - buffer); - } + switch (my_lex(buffer)) { + case LX_COMA: + path = add(buffer, path); + for (;;) { + switch (my_lex(buffer)) { + case LX_COMA: + continue; + + case LX_AT: + path = add(buffer, path); break; + + default: + sprintf(err, "no at-sign found for next domain in route (%s)", + buffer); } - continue; + break; + } + continue; - case LX_AT: /* XXX */ - case LX_DOT: - path = add (buffer, path); - continue; + case LX_AT: /* XXX */ + case LX_DOT: + path = add(buffer, path); + continue; - case LX_COLN: - path = add (buffer, path); - return OK; + case LX_COLN: + path = add(buffer, path); + return OK; - default: - sprintf (err, "no colon found to terminate route (%s)", buffer); - return NOTOK; + default: + sprintf(err, "no colon found to terminate route (%s)", buffer); + return NOTOK; } } } static int -my_lex (char *buffer) +my_lex(char *buffer) { /* buffer should be at least BUFSIZ bytes long */ - int i, gotat = 0; - register unsigned char c; - register char *bp; + int i; + unsigned char c; + char *bp; /* - * Add C to the buffer bp. After use of this macro *bp is guaranteed - * to be within the buffer. - */ + ** Add C to the buffer bp. After use of this macro *bp is guaranteed + ** to be within the buffer. + */ #define ADDCHR(C) \ do { \ *bp++ = (C); \ @@ -603,9 +585,8 @@ my_lex (char *buffer) if (!cp) return (last_lex = LX_END); - gotat = isat (cp); c = *cp++; - while (isspace (c)) + while (isspace(c)) c = *cp++; if (c == 0) { cp = NULL; @@ -616,30 +597,29 @@ my_lex (char *buffer) ADDCHR(c); for (i = 0;;) switch (c = *cp++) { - case 0: + case 0: + cp = NULL; + return (last_lex = LX_ERR); + case QUOTE: + ADDCHR(c); + if ((c = *cp++) == 0) { cp = NULL; return (last_lex = LX_ERR); - case QUOTE: - ADDCHR(c); - if ((c = *cp++) == 0) { - cp = NULL; - return (last_lex = LX_ERR); - } - ADDCHR(c); - continue; - case '(': - i++; - default: - ADDCHR(c); - continue; - case ')': - ADDCHR(c); - if (--i < 0) { - *bp = 0; - note = note ? add (buffer, add (" ", note)) - : getcpy (buffer); - return my_lex (buffer); - } + } + ADDCHR(c); + continue; + case '(': + i++; + default: + ADDCHR(c); + continue; + case ')': + ADDCHR(c); + if (--i < 0) { + *bp = 0; + note = note ? add(buffer, add(" ", note)) : getcpy(buffer); + return my_lex(buffer); + } } } @@ -647,22 +627,22 @@ my_lex (char *buffer) ADDCHR(c); for (;;) switch (c = *cp++) { - case 0: + case 0: + cp = NULL; + return (last_lex = LX_ERR); + case QUOTE: + ADDCHR(c); + if ((c = *cp++) == 0) { cp = NULL; return (last_lex = LX_ERR); - case QUOTE: - ADDCHR(c); - if ((c = *cp++) == 0) { - cp = NULL; - return (last_lex = LX_ERR); - } - default: - ADDCHR(c); - continue; - case '"': - ADDCHR(c); - *bp = 0; - return (last_lex = LX_QSTR); + } + default: + ADDCHR(c); + continue; + case '"': + ADDCHR(c); + *bp = 0; + return (last_lex = LX_QSTR); } } @@ -670,22 +650,22 @@ my_lex (char *buffer) ADDCHR(c); for (;;) switch (c = *cp++) { - case 0: + case 0: + cp = NULL; + return (last_lex = LX_ERR); + case QUOTE: + ADDCHR(c); + if ((c = *cp++) == 0) { cp = NULL; return (last_lex = LX_ERR); - case QUOTE: - ADDCHR(c); - if ((c = *cp++) == 0) { - cp = NULL; - return (last_lex = LX_ERR); - } - default: - ADDCHR(c); - continue; - case ']': - ADDCHR(c); - *bp = 0; - return (last_lex = LX_DLIT); + } + default: + ADDCHR(c); + continue; + case ']': + ADDCHR(c); + *bp = 0; + return (last_lex = LX_DLIT); } } @@ -695,7 +675,7 @@ my_lex (char *buffer) if (c == special[i].lx_chr) return (last_lex = special[i].lx_val); - if (iscntrl (c)) + if (iscntrl(c)) return (last_lex = LX_ERR); for (;;) { @@ -704,7 +684,7 @@ my_lex (char *buffer) for (i = 0; special[i].lx_chr != 0; i++) if (c == special[i].lx_chr) goto got_atom; - if (iscntrl (c) || isspace (c)) + if (iscntrl(c) || isspace(c)) break; ADDCHR(c); } @@ -714,9 +694,7 @@ got_atom: ; else cp--; *bp = 0; - last_lex = !gotat || cp == NULL || strchr(cp, '<') != NULL - ? LX_ATOM : LX_AT; - return last_lex; + return LX_ATOM; my_lex_buffull: /* Out of buffer space. *bp is the last byte in the buffer */ @@ -726,10 +704,10 @@ got_atom: ; char * -legal_person (char *p) +legal_person(char *p) { int i; - register char *cp; + char *cp; static char buffer[BUFSIZ]; if (*p == '"') @@ -737,7 +715,7 @@ legal_person (char *p) for (cp = p; *cp; cp++) for (i = 0; special[i].lx_chr; i++) if (*cp == special[i].lx_chr) { - sprintf (buffer, "\"%s\"", p); + sprintf(buffer, "\"%s\"", p); return buffer; }