#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 int local_part (char *);
-static int domain (char *);
-static int route (char *);
-static int my_lex (char *);
+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) {
/*
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.
+** 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
**
** 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)
+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;
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
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;
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);
}
}
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 (;;) {
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);
}
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 */
char *
-legal_person (char *p)
+legal_person(char *p)
{
int i;
- register char *cp;
+ char *cp;
static char buffer[BUFSIZ];
if (*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;
}