static char rcsid[] = "@(#)$Id: rfc822tlen.c,v 1.7 2006/04/09 07:37:05 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.7 $ $State: Exp $
*
* Modified by: Kari Hurtta <hurtta+elm@posti.FMI.FI>
* (was hurtta+elm@ozone.FMI.FI)
******************************************************************************
* The Elm Mail System
*
* Copyright (c) 1993 USENET Community Trust
*****************************************************************************/
#include <headers.h>
/*
* rfc822_toklen(str) - Returns length of RFC-822 token that starts at "str".
*
* We understand the following tokens:
*
* linear-white-space
* specials
* "quoted string"
* [domain.literal]
* (comment)
* CTL (control chars)
* atom
*/
#define charlen(s) ((s)[0] == '\\' && (s)[1] != '\0' ? 2 : 1)
#define IS822_SPECIAL(c) ( \
((c) == '(') || ((c) == ')') || ((c) == '<') || ((c) == '>') \
|| ((c) == '@') || ((c) == ',') || ((c) == ';') || ((c) == ':') \
|| ((c) == '\\') || ((c) == '"') || ((c) == '.') || ((c) == '[') \
|| ((c) == ']') \
)
/*
* RFC-822 defines SPACE to be just < > and HTAB, but after LWSP folding
* CR and NL should be equivalent.
*/
#define IS822_SPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n')
#define IS822_CTL(c) ((unsigned char)(c) <= 037 || (unsigned char)(c) == 0177)
#define IS822_ATOMCH(c) (!IS822_SPECIAL(c) && !IS822_SPACE(c) && !IS822_CTL(c))
int rfc822_toklen(str)
CONST char *str;
{
CONST char *str0;
int depth;
str0 = str;
if (*str == '"') { /* quoted-string */
++str;
while (*str != '\0' && *str != '"')
str += charlen(str);
if (*str != '\0')
++str;
return (str-str0);
}
if (*str == '(' ) { /* comment */
++str;
depth = 0;
while (*str != '\0' && (*str != ')' || depth > 0)) {
switch (*str) {
case '(':
++str;
++depth;
break;
case ')':
++str;
--depth;
break;
default:
str += charlen(str);
break;
}
}
if (*str != '\0')
++str;
return (str-str0);
}
if (*str == '[') { /* domain-literal */
++str;
while (*str != '\0' && *str != ']')
str += charlen(str);
if (*str != '\0')
++str;
return (str-str0);
}
if (IS822_SPACE(*str)) { /* linear-white-space */
while (++str, IS822_SPACE(*str))
;
return (str-str0);
}
if (IS822_SPECIAL(*str) || IS822_CTL(*str))
return charlen(str); /* specials and CTL */
/*
* Treat as an "atom".
*/
while (IS822_ATOMCH(*str))
++str;
return (str-str0);
}
#ifdef _TEST
main()
{
char buf[1024], *bp;
int len;
for (;;) {
fputs("\nstr> ", stdout);
fflush(stdout);
if (gets(buf) == NULL) {
putchar('\n');
break;
}
bp = buf;
while (*bp != '\0') {
len = rfc822_toklen(bp);
printf("len %4d |%.*s|\n", len, len, bp);
bp += len;
}
}
exit(0);
}
#endif
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1