aboutsummaryrefslogtreecommitdiffstats
path: root/rfc822.c
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>1997-01-11 17:33:27 +0000
committerEric S. Raymond <esr@thyrsus.com>1997-01-11 17:33:27 +0000
commitcfcf10f7b0ed01ef10abb87fb172e2a9ce37d9fd (patch)
tree4bf9fbaf93ea3dfc1d66fb1afc94d357bd0ba44e /rfc822.c
parent23aa007d7d4376222e7cf7acf36a6fc49990fac4 (diff)
downloadfetchmail-cfcf10f7b0ed01ef10abb87fb172e2a9ce37d9fd.tar.gz
fetchmail-cfcf10f7b0ed01ef10abb87fb172e2a9ce37d9fd.tar.bz2
fetchmail-cfcf10f7b0ed01ef10abb87fb172e2a9ce37d9fd.zip
Simpler and more effective address parsing.
svn path=/trunk/; revision=741
Diffstat (limited to 'rfc822.c')
-rw-r--r--rfc822.c87
1 files changed, 43 insertions, 44 deletions
diff --git a/rfc822.c b/rfc822.c
index 4cf4333d..8497c54b 100644
--- a/rfc822.c
+++ b/rfc822.c
@@ -154,7 +154,7 @@ const char *hdr; /* header to be parsed, NUL to continue previous hdr */
{
static char *tp, address[POPBUFSIZE+1];
static const char *hp;
- static int state;
+ static int state, oldstate;
int parendepth;
/*
@@ -163,11 +163,11 @@ const char *hdr; /* header to be parsed, NUL to continue previous hdr */
* a marker for RFC822 continuations elsewhere.
*/
#define START_HDR 0 /* before header colon */
-#define BARE_ADDRESS 1 /* collecting address without delimiters */
-#define INSIDE_DQUOTE 2 /* inside double quotes */
-#define INSIDE_PARENS 3 /* inside parentheses */
-#define INSIDE_BRACKETS 4 /* inside bracketed address */
-#define STR_INSIDE_BR 5 /* copying string within bracketed address */
+#define SKIP_JUNK 1 /* skip whitespace, \n, and junk */
+#define BARE_ADDRESS 2 /* collecting address without delimiters */
+#define INSIDE_DQUOTE 3 /* inside double quotes */
+#define INSIDE_PARENS 4 /* inside parentheses */
+#define INSIDE_BRACKETS 5 /* inside bracketed address */
#define ENDIT_ALL 6 /* after last address */
if (hdr)
@@ -188,45 +188,58 @@ const char *hdr; /* header to be parsed, NUL to continue previous hdr */
}
else if (*hp == ':')
{
- state = BARE_ADDRESS;
+ state = SKIP_JUNK;
tp = address;
}
break;
- case BARE_ADDRESS: /* collecting address without delimiters */
- if (*hp == '\n') /* end of address list */
+ case SKIP_JUNK: /* looking for address start */
+ if (*hp == '\n') /* no more addresses */
{
- *tp++ = '\0';
state = ENDIT_ALL;
- return(tp = address);
- }
- else if (*hp == ',') /* end of address */
- {
- if (tp > address)
- {
- *tp++ = '\0';
- ++hp;
- return(tp = address);
- }
+ return(NULL);
}
- else if (*hp == '"') /* quoted string */
+ else if (*hp == '"') /* quoted string */
{
+ oldstate = SKIP_JUNK;
state = INSIDE_DQUOTE;
*tp++ = *hp;
}
- else if (*hp == '(') /* address comment -- ignore */
+ else if (*hp == '(') /* address comment -- ignore */
{
parendepth = 1;
state = INSIDE_PARENS;
}
- else if (*hp == '<') /* begin <address> */
+ else if (*hp == '<') /* begin <address> */
{
state = INSIDE_BRACKETS;
tp = address;
}
- else if (isspace(*hp)) /* ignore space */
+ else if (!isspace(*hp)) /* ignore space */
+ {
+ --hp;
state = BARE_ADDRESS;
- else /* just take it */
+ }
+ break;
+
+ case BARE_ADDRESS: /* collecting address without delimiters */
+ if (*hp == '\n') /* end of bare address */
+ {
+ *tp++ = '\0';
+ state = ENDIT_ALL;
+ return(tp = address);
+ }
+ else if (*hp == ',' || isspace(*hp)) /* end of address */
+ {
+ if (tp > address)
+ {
+ *tp++ = '\0';
+ ++hp;
+ state = SKIP_JUNK;
+ return(tp = address);
+ }
+ }
+ else /* just take it */
{
state = BARE_ADDRESS;
*tp++ = *hp;
@@ -244,7 +257,7 @@ const char *hdr; /* header to be parsed, NUL to continue previous hdr */
else
{
*tp++ = *hp;
- state = BARE_ADDRESS;
+ state = oldstate;
}
break;
@@ -256,14 +269,14 @@ const char *hdr; /* header to be parsed, NUL to continue previous hdr */
else if (*hp == ')')
--parendepth;
if (parendepth == 0)
- state = BARE_ADDRESS;
+ state = SKIP_JUNK;
break;
case INSIDE_BRACKETS: /* possible <>-enclosed address */
if (*hp == '>') /* end of address */
{
*tp++ = '\0';
- state = BARE_ADDRESS;
+ state = SKIP_JUNK;
++hp;
return(tp = address);
}
@@ -272,27 +285,13 @@ const char *hdr; /* header to be parsed, NUL to continue previous hdr */
else if (*hp == '"') /* quoted address */
{
*tp++ = *hp;
- state = STR_INSIDE_BR;
+ oldstate = INSIDE_BRACKETS;
+ state = INSIDE_DQUOTE;
}
else /* just copy address */
*tp++ = *hp;
break;
- case STR_INSIDE_BR: /* we're in a quoted address, copy verbatim */
- if (*hp == '\n') /* mismatched quotes */
- {
- state = ENDIT_ALL;
- return(NULL);
- }
- if (*hp != '"') /* just copy it if it isn't a quote */
- *tp++ = *hp;
- else if (*hp == '"') /* end of quoted string */
- {
- *tp++ = *hp;
- state = INSIDE_BRACKETS;
- }
- break;
-
case ENDIT_ALL: /* after last address */
return(NULL);
break;