#include <ctype.h>
#include <stdio.h>
#include <h/utils.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
/*
** 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 char *
getcpy(char *s)
{
- register char *p;
+ char *p;
if (!s) {
/*
}
-#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
+** 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 accomodate both.
**
** In terms of 822, the route-specification in
** 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.
**
** -----
struct adrx *
getadrx(char *addrs)
{
- register char *bp;
- register struct adrx *adrxp = &adrxs2;
+ char *bp;
+ struct adrx *adrxp = &adrxs2;
if (pers)
free(pers);
}
switch (parse_address()) {
- case DONE:
- free(dp);
- dp = cp = NULL;
- return NULL;
-
- case OK:
- switch (last_lex) {
- case LX_COMA:
- case LX_END:
- break;
+ case DONE:
+ free(dp);
+ 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;
}
again: ;
ap = cp;
switch (my_lex(buffer)) {
- case LX_ATOM:
- case LX_QSTR:
- pers = getcpy(buffer);
- break;
+ 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) {
+ free(note);
+ note = NULL;
+ }
+ 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? */
+
+ default:
+ sprintf(err, "illegal address construct (%s)", buffer);
+ 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)
+ return NOTOK;
- case LX_AT: /* sigh (3) */
- cp = ap;
+ switch (last_lex) {
+ case LX_LBRK:
+get_addr: ;
if (route_addr(buffer) == NOTOK)
return NOTOK;
- return OK; /* why be choosy? */
-
- default:
- sprintf(err, "illegal address construct (%s)", buffer);
+ if (last_lex == LX_RBRK)
+ return OK;
+ sprintf(err, "missing right-bracket (%s)", buffer);
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)
+ 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;
- switch (last_lex) {
- case LX_LBRK:
- get_addr: ;
- if (route_addr(buffer) == NOTOK)
- return NOTOK;
- if (last_lex == LX_RBRK)
+ 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) {
+ 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;
}
}
{
for (;;)
switch (my_lex(buffer)) {
- case LX_ATOM:
- case LX_QSTR:
- pers = add(buffer, add(" ", pers));
- continue;
+ case LX_ATOM:
+ case LX_QSTR:
+ pers = add(buffer, add(" ", pers));
+ continue;
- default:
- return OK;
+ default:
+ return OK;
}
}
static int
route_addr(char *buffer)
{
- register char *pp = cp;
+ char *pp = cp;
if (my_lex(buffer) == LX_AT) {
if (route(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;
}
}
for (;;) {
switch (my_lex(buffer)) {
- case LX_ATOM:
- case LX_QSTR:
- mbox = add(buffer, mbox);
- break;
+ 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;
+ case LX_DOT:
+ mbox = add(buffer, mbox);
+ continue;
- default:
- return OK;
+ default:
+ return OK;
}
}
}
{
for (;;) {
switch (my_lex(buffer)) {
- case LX_ATOM:
- case LX_DLIT:
- host = add(buffer, host);
- break;
+ 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;
+ 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));
+ free(host);
+ host = NULL;
+ continue;
- default:
- return OK;
+ default:
+ return OK;
}
}
}
for (;;) {
switch (my_lex(buffer)) {
- case LX_ATOM:
- case LX_DLIT:
- path = add(buffer, path);
- break;
+ 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;
+ case LX_COMA:
+ path = add(buffer, path);
+ for (;;) {
+ switch (my_lex(buffer)) {
+ case LX_COMA:
+ continue;
- default:
- sprintf(err, "no at-sign found for next domain in route (%s)",
- buffer);
- }
+ 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;
}
}
}
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
if (!cp)
return (last_lex = LX_END);
- gotat = isat(cp);
c = *cp++;
while (isspace(c))
c = *cp++;
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);
+ }
}
}
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);
}
}
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);
}
}
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 */
legal_person(char *p)
{
int i;
- register char *cp;
+ char *cp;
static char buffer[BUFSIZ];
if (*p == '"')