1261 lines
30 KiB
C
1261 lines
30 KiB
C
|
|
#line 2 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
#include "common.h"
|
|
#include "smtp.h"
|
|
#include <ctype.h>
|
|
|
|
char *yylp; /* next character to be lex'd */
|
|
int yydone; /* tell yylex to give up */
|
|
char *yybuffer; /* first parsed character */
|
|
char *yyend; /* end of buffer to be parsed */
|
|
Node *root;
|
|
Field *firstfield;
|
|
Field *lastfield;
|
|
Node *usender;
|
|
Node *usys;
|
|
Node *udate;
|
|
char *startfield, *endfield;
|
|
int originator;
|
|
int destination;
|
|
int date;
|
|
int received;
|
|
int messageid;
|
|
extern int yyerrflag;
|
|
#ifndef YYMAXDEPTH
|
|
#define YYMAXDEPTH 150
|
|
#endif
|
|
#ifndef YYSTYPE
|
|
#define YYSTYPE int
|
|
#endif
|
|
YYSTYPE yylval;
|
|
YYSTYPE yyval;
|
|
#define WORD 57346
|
|
#define DATE 57347
|
|
#define RESENT_DATE 57348
|
|
#define RETURN_PATH 57349
|
|
#define FROM 57350
|
|
#define SENDER 57351
|
|
#define REPLY_TO 57352
|
|
#define RESENT_FROM 57353
|
|
#define RESENT_SENDER 57354
|
|
#define RESENT_REPLY_TO 57355
|
|
#define SUBJECT 57356
|
|
#define TO 57357
|
|
#define CC 57358
|
|
#define BCC 57359
|
|
#define RESENT_TO 57360
|
|
#define RESENT_CC 57361
|
|
#define RESENT_BCC 57362
|
|
#define REMOTE 57363
|
|
#define PRECEDENCE 57364
|
|
#define MIMEVERSION 57365
|
|
#define CONTENTTYPE 57366
|
|
#define MESSAGEID 57367
|
|
#define RECEIVED 57368
|
|
#define MAILER 57369
|
|
#define BADTOKEN 57370
|
|
#define YYEOFCODE 1
|
|
#define YYERRCODE 2
|
|
|
|
#line 246 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
|
|
|
|
/*
|
|
* Initialize the parsing. Done once for each header field.
|
|
*/
|
|
void
|
|
yyinit(char *p, int len)
|
|
{
|
|
yybuffer = p;
|
|
yylp = p;
|
|
yyend = p + len;
|
|
firstfield = lastfield = 0;
|
|
received = 0;
|
|
}
|
|
|
|
/*
|
|
* keywords identifying header fields we care about
|
|
*/
|
|
typedef struct Keyword Keyword;
|
|
struct Keyword {
|
|
char *rep;
|
|
int val;
|
|
};
|
|
|
|
/* field names that we need to recognize */
|
|
Keyword key[] = {
|
|
{ "date", DATE },
|
|
{ "resent-date", RESENT_DATE },
|
|
{ "return_path", RETURN_PATH },
|
|
{ "from", FROM },
|
|
{ "sender", SENDER },
|
|
{ "reply-to", REPLY_TO },
|
|
{ "resent-from", RESENT_FROM },
|
|
{ "resent-sender", RESENT_SENDER },
|
|
{ "resent-reply-to", RESENT_REPLY_TO },
|
|
{ "to", TO },
|
|
{ "cc", CC },
|
|
{ "bcc", BCC },
|
|
{ "resent-to", RESENT_TO },
|
|
{ "resent-cc", RESENT_CC },
|
|
{ "resent-bcc", RESENT_BCC },
|
|
{ "remote", REMOTE },
|
|
{ "subject", SUBJECT },
|
|
{ "precedence", PRECEDENCE },
|
|
{ "mime-version", MIMEVERSION },
|
|
{ "content-type", CONTENTTYPE },
|
|
{ "message-id", MESSAGEID },
|
|
{ "received", RECEIVED },
|
|
{ "mailer", MAILER },
|
|
{ "who-the-hell-cares", WORD }
|
|
};
|
|
|
|
/*
|
|
* Lexical analysis for an rfc822 header field. Continuation lines
|
|
* are handled in yywhite() when skipping over white space.
|
|
*
|
|
*/
|
|
int
|
|
yylex(void)
|
|
{
|
|
String *t;
|
|
int quoting;
|
|
int escaping;
|
|
char *start;
|
|
Keyword *kp;
|
|
int c, d;
|
|
|
|
/* print("lexing\n"); /**/
|
|
if(yylp >= yyend)
|
|
return 0;
|
|
if(yydone)
|
|
return 0;
|
|
|
|
quoting = escaping = 0;
|
|
start = yylp;
|
|
yylval = malloc(sizeof(Node));
|
|
yylval->white = yylval->s = 0;
|
|
yylval->next = 0;
|
|
yylval->addr = 0;
|
|
yylval->start = yylp;
|
|
for(t = 0; yylp < yyend; yylp++){
|
|
c = *yylp & 0xff;
|
|
|
|
/* dump nulls, they can't be in header */
|
|
if(c == 0)
|
|
continue;
|
|
|
|
if(escaping) {
|
|
escaping = 0;
|
|
} else if(quoting) {
|
|
switch(c){
|
|
case '\\':
|
|
escaping = 1;
|
|
break;
|
|
case '\n':
|
|
d = (*(yylp+1))&0xff;
|
|
if(d != ' ' && d != '\t'){
|
|
quoting = 0;
|
|
yylp--;
|
|
continue;
|
|
}
|
|
break;
|
|
case '"':
|
|
quoting = 0;
|
|
break;
|
|
}
|
|
} else {
|
|
switch(c){
|
|
case '\\':
|
|
escaping = 1;
|
|
break;
|
|
case '(':
|
|
case ' ':
|
|
case '\t':
|
|
case '\r':
|
|
goto out;
|
|
case '\n':
|
|
if(yylp == start){
|
|
yylp++;
|
|
/* print("lex(c %c)\n", c); /**/
|
|
yylval->end = yylp;
|
|
return yylval->c = c;
|
|
}
|
|
goto out;
|
|
case '@':
|
|
case '>':
|
|
case '<':
|
|
case ':':
|
|
case ',':
|
|
case ';':
|
|
if(yylp == start){
|
|
yylp++;
|
|
yylval->white = yywhite();
|
|
/* print("lex(c %c)\n", c); /**/
|
|
yylval->end = yylp;
|
|
return yylval->c = c;
|
|
}
|
|
goto out;
|
|
case '"':
|
|
quoting = 1;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
if(t == 0)
|
|
t = s_new();
|
|
s_putc(t, c);
|
|
}
|
|
out:
|
|
yylval->white = yywhite();
|
|
if(t) {
|
|
s_terminate(t);
|
|
} else /* message begins with white-space! */
|
|
return yylval->c = '\n';
|
|
yylval->s = t;
|
|
for(kp = key; kp->val != WORD; kp++)
|
|
if(cistrcmp(s_to_c(t), kp->rep)==0)
|
|
break;
|
|
/* print("lex(%d) %s\n", kp->val-WORD, s_to_c(t)); /**/
|
|
yylval->end = yylp;
|
|
return yylval->c = kp->val;
|
|
}
|
|
|
|
void
|
|
yyerror(char *x)
|
|
{
|
|
USED(x);
|
|
|
|
/*fprint(2, "parse err: %s\n", x);/**/
|
|
}
|
|
|
|
/*
|
|
* parse white space and comments
|
|
*/
|
|
String *
|
|
yywhite(void)
|
|
{
|
|
String *w;
|
|
int clevel;
|
|
int c;
|
|
int escaping;
|
|
|
|
escaping = clevel = 0;
|
|
for(w = 0; yylp < yyend; yylp++){
|
|
c = *yylp & 0xff;
|
|
|
|
/* dump nulls, they can't be in header */
|
|
if(c == 0)
|
|
continue;
|
|
|
|
if(escaping){
|
|
escaping = 0;
|
|
} else if(clevel) {
|
|
switch(c){
|
|
case '\n':
|
|
/*
|
|
* look for multiline fields
|
|
*/
|
|
if(*(yylp+1)==' ' || *(yylp+1)=='\t')
|
|
break;
|
|
else
|
|
goto out;
|
|
case '\\':
|
|
escaping = 1;
|
|
break;
|
|
case '(':
|
|
clevel++;
|
|
break;
|
|
case ')':
|
|
clevel--;
|
|
break;
|
|
}
|
|
} else {
|
|
switch(c){
|
|
case '\\':
|
|
escaping = 1;
|
|
break;
|
|
case '(':
|
|
clevel++;
|
|
break;
|
|
case ' ':
|
|
case '\t':
|
|
case '\r':
|
|
break;
|
|
case '\n':
|
|
/*
|
|
* look for multiline fields
|
|
*/
|
|
if(*(yylp+1)==' ' || *(yylp+1)=='\t')
|
|
break;
|
|
else
|
|
goto out;
|
|
default:
|
|
goto out;
|
|
}
|
|
}
|
|
if(w == 0)
|
|
w = s_new();
|
|
s_putc(w, c);
|
|
}
|
|
out:
|
|
if(w)
|
|
s_terminate(w);
|
|
return w;
|
|
}
|
|
|
|
/*
|
|
* link two parsed entries together
|
|
*/
|
|
Node*
|
|
link2(Node *p1, Node *p2)
|
|
{
|
|
Node *p;
|
|
|
|
for(p = p1; p->next; p = p->next)
|
|
;
|
|
p->next = p2;
|
|
return p1;
|
|
}
|
|
|
|
/*
|
|
* link three parsed entries together
|
|
*/
|
|
Node*
|
|
link3(Node *p1, Node *p2, Node *p3)
|
|
{
|
|
Node *p;
|
|
|
|
for(p = p2; p->next; p = p->next)
|
|
;
|
|
p->next = p3;
|
|
|
|
for(p = p1; p->next; p = p->next)
|
|
;
|
|
p->next = p2;
|
|
|
|
return p1;
|
|
}
|
|
|
|
/*
|
|
* make a:b, move all white space after both
|
|
*/
|
|
Node*
|
|
colon(Node *p1, Node *p2)
|
|
{
|
|
if(p1->white){
|
|
if(p2->white)
|
|
s_append(p1->white, s_to_c(p2->white));
|
|
} else {
|
|
p1->white = p2->white;
|
|
p2->white = 0;
|
|
}
|
|
|
|
s_append(p1->s, ":");
|
|
if(p2->s)
|
|
s_append(p1->s, s_to_c(p2->s));
|
|
|
|
if(p1->end < p2->end)
|
|
p1->end = p2->end;
|
|
freenode(p2);
|
|
return p1;
|
|
}
|
|
|
|
/*
|
|
* concatenate two fields, move all white space after both
|
|
*/
|
|
Node*
|
|
concat(Node *p1, Node *p2)
|
|
{
|
|
char buf[2];
|
|
|
|
if(p1->white){
|
|
if(p2->white)
|
|
s_append(p1->white, s_to_c(p2->white));
|
|
} else {
|
|
p1->white = p2->white;
|
|
p2->white = 0;
|
|
}
|
|
|
|
if(p1->s == nil){
|
|
buf[0] = p1->c;
|
|
buf[1] = 0;
|
|
p1->s = s_new();
|
|
s_append(p1->s, buf);
|
|
}
|
|
|
|
if(p2->s)
|
|
s_append(p1->s, s_to_c(p2->s));
|
|
else {
|
|
buf[0] = p2->c;
|
|
buf[1] = 0;
|
|
s_append(p1->s, buf);
|
|
}
|
|
|
|
if(p1->end < p2->end)
|
|
p1->end = p2->end;
|
|
freenode(p2);
|
|
return p1;
|
|
}
|
|
|
|
/*
|
|
* look for disallowed chars in the field name
|
|
*/
|
|
int
|
|
badfieldname(Node *p)
|
|
{
|
|
for(; p; p = p->next){
|
|
/* field name can't contain white space */
|
|
if(p->white && p->next)
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* mark as an address
|
|
*/
|
|
Node *
|
|
address(Node *p)
|
|
{
|
|
p->addr = 1;
|
|
return p;
|
|
}
|
|
|
|
/*
|
|
* case independent string compare
|
|
*/
|
|
int
|
|
cistrcmp(char *s1, char *s2)
|
|
{
|
|
int c1, c2;
|
|
|
|
for(; *s1; s1++, s2++){
|
|
c1 = isupper(*s1) ? tolower(*s1) : *s1;
|
|
c2 = isupper(*s2) ? tolower(*s2) : *s2;
|
|
if (c1 != c2)
|
|
return -1;
|
|
}
|
|
return *s2;
|
|
}
|
|
|
|
/*
|
|
* free a node
|
|
*/
|
|
void
|
|
freenode(Node *p)
|
|
{
|
|
Node *tp;
|
|
|
|
while(p){
|
|
tp = p->next;
|
|
if(p->s)
|
|
s_free(p->s);
|
|
if(p->white)
|
|
s_free(p->white);
|
|
free(p);
|
|
p = tp;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* an anonymous user
|
|
*/
|
|
Node*
|
|
nobody(Node *p)
|
|
{
|
|
if(p->s)
|
|
s_free(p->s);
|
|
p->s = s_copy("pOsTmAsTeR");
|
|
p->addr = 1;
|
|
return p;
|
|
}
|
|
|
|
/*
|
|
* add anything that was dropped because of a parse error
|
|
*/
|
|
void
|
|
missing(Node *p)
|
|
{
|
|
Node *np;
|
|
char *start, *end;
|
|
Field *f;
|
|
String *s;
|
|
|
|
start = yybuffer;
|
|
if(lastfield != nil){
|
|
for(np = lastfield->node; np; np = np->next)
|
|
start = np->end+1;
|
|
}
|
|
|
|
end = p->start-1;
|
|
|
|
if(end <= start)
|
|
return;
|
|
|
|
if(strncmp(start, "From ", 5) == 0)
|
|
return;
|
|
|
|
np = malloc(sizeof(Node));
|
|
np->start = start;
|
|
np->end = end;
|
|
np->white = nil;
|
|
s = s_copy("BadHeader: ");
|
|
np->s = s_nappend(s, start, end-start);
|
|
np->next = nil;
|
|
|
|
f = malloc(sizeof(Field));
|
|
f->next = 0;
|
|
f->node = np;
|
|
f->source = 0;
|
|
if(firstfield)
|
|
lastfield->next = f;
|
|
else
|
|
firstfield = f;
|
|
lastfield = f;
|
|
}
|
|
|
|
/*
|
|
* create a new field
|
|
*/
|
|
void
|
|
newfield(Node *p, int source)
|
|
{
|
|
Field *f;
|
|
|
|
missing(p);
|
|
|
|
f = malloc(sizeof(Field));
|
|
f->next = 0;
|
|
f->node = p;
|
|
f->source = source;
|
|
if(firstfield)
|
|
lastfield->next = f;
|
|
else
|
|
firstfield = f;
|
|
lastfield = f;
|
|
endfield = startfield;
|
|
startfield = yylp;
|
|
}
|
|
|
|
/*
|
|
* fee a list of fields
|
|
*/
|
|
void
|
|
freefield(Field *f)
|
|
{
|
|
Field *tf;
|
|
|
|
while(f){
|
|
tf = f->next;
|
|
freenode(f->node);
|
|
free(f);
|
|
f = tf;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* add some white space to a node
|
|
*/
|
|
Node*
|
|
whiten(Node *p)
|
|
{
|
|
Node *tp;
|
|
|
|
for(tp = p; tp->next; tp = tp->next)
|
|
;
|
|
if(tp->white == 0)
|
|
tp->white = s_copy(" ");
|
|
return p;
|
|
}
|
|
|
|
void
|
|
yycleanup(void)
|
|
{
|
|
Field *f, *fnext;
|
|
Node *np, *next;
|
|
|
|
for(f = firstfield; f; f = fnext){
|
|
for(np = f->node; np; np = next){
|
|
if(np->s)
|
|
s_free(np->s);
|
|
if(np->white)
|
|
s_free(np->white);
|
|
next = np->next;
|
|
free(np);
|
|
}
|
|
fnext = f->next;
|
|
free(f);
|
|
}
|
|
firstfield = lastfield = 0;
|
|
}
|
|
static const short yyexca[] =
|
|
{-1, 1,
|
|
1, -1,
|
|
-2, 0,
|
|
-1, 47,
|
|
1, 4,
|
|
-2, 0,
|
|
-1, 112,
|
|
29, 72,
|
|
31, 72,
|
|
32, 72,
|
|
35, 72,
|
|
-2, 74
|
|
};
|
|
#define YYNPROD 122
|
|
#define YYPRIVATE 57344
|
|
#define YYLAST 608
|
|
static const short yyact[] =
|
|
{
|
|
112, 133, 136, 53, 121, 111, 134, 55, 109, 118,
|
|
119, 116, 162, 171, 35, 48, 166, 54, 5, 166,
|
|
179, 114, 115, 155, 49, 101, 100, 99, 95, 94,
|
|
93, 92, 98, 91, 132, 90, 123, 89, 122, 88,
|
|
87, 86, 85, 84, 83, 82, 97, 81, 80, 106,
|
|
47, 46, 110, 117, 153, 168, 108, 2, 56, 57,
|
|
58, 59, 60, 61, 62, 63, 64, 65, 73, 66,
|
|
67, 68, 69, 70, 71, 72, 74, 75, 76, 77,
|
|
78, 79, 124, 124, 49, 55, 177, 131, 110, 52,
|
|
110, 110, 138, 137, 140, 141, 124, 124, 51, 120,
|
|
124, 124, 124, 50, 102, 104, 135, 154, 31, 32,
|
|
107, 157, 105, 14, 55, 55, 156, 13, 161, 117,
|
|
117, 139, 158, 124, 142, 143, 144, 145, 146, 147,
|
|
163, 164, 160, 12, 148, 149, 11, 157, 150, 151,
|
|
152, 10, 156, 9, 8, 7, 3, 1, 0, 124,
|
|
124, 124, 124, 124, 0, 169, 0, 0, 110, 165,
|
|
0, 0, 170, 117, 0, 0, 0, 0, 173, 176,
|
|
178, 0, 0, 0, 172, 0, 0, 0, 180, 0,
|
|
0, 182, 183, 0, 0, 165, 165, 165, 165, 165,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 174, 56, 57, 58, 59, 60, 61, 62,
|
|
63, 64, 65, 73, 66, 67, 68, 69, 70, 71,
|
|
72, 74, 75, 76, 77, 78, 79, 0, 0, 128,
|
|
130, 129, 125, 126, 127, 15, 0, 36, 16, 17,
|
|
19, 103, 20, 18, 23, 22, 21, 30, 24, 26,
|
|
28, 25, 27, 29, 0, 34, 37, 38, 39, 33,
|
|
40, 0, 4, 0, 45, 44, 41, 42, 43, 56,
|
|
57, 58, 59, 60, 61, 62, 63, 64, 65, 73,
|
|
66, 67, 68, 69, 70, 71, 72, 74, 75, 76,
|
|
77, 78, 79, 0, 0, 96, 45, 44, 41, 42,
|
|
43, 15, 0, 36, 16, 17, 19, 6, 20, 18,
|
|
23, 22, 21, 30, 24, 26, 28, 25, 27, 29,
|
|
0, 34, 37, 38, 39, 33, 40, 0, 4, 0,
|
|
45, 44, 41, 42, 43, 15, 0, 36, 16, 17,
|
|
19, 103, 20, 18, 23, 22, 21, 30, 24, 26,
|
|
28, 25, 27, 29, 0, 34, 37, 38, 39, 33,
|
|
40, 0, 0, 0, 45, 44, 41, 42, 43, 56,
|
|
57, 58, 59, 60, 61, 62, 63, 64, 65, 73,
|
|
66, 67, 68, 69, 70, 71, 72, 74, 75, 76,
|
|
77, 78, 79, 0, 0, 0, 0, 175, 113, 0,
|
|
52, 56, 57, 58, 59, 60, 61, 62, 63, 64,
|
|
65, 73, 66, 67, 68, 69, 70, 71, 72, 74,
|
|
75, 76, 77, 78, 79, 0, 0, 0, 0, 0,
|
|
113, 0, 52, 56, 57, 58, 59, 60, 61, 62,
|
|
63, 64, 65, 73, 66, 67, 68, 69, 70, 71,
|
|
72, 74, 75, 76, 77, 78, 79, 0, 0, 0,
|
|
0, 0, 0, 159, 52, 56, 57, 58, 59, 60,
|
|
61, 62, 63, 64, 65, 73, 66, 67, 68, 69,
|
|
70, 71, 72, 74, 75, 76, 77, 78, 79, 0,
|
|
0, 0, 0, 0, 0, 0, 52, 56, 57, 58,
|
|
59, 60, 61, 62, 63, 64, 65, 73, 66, 67,
|
|
68, 69, 70, 71, 72, 74, 75, 76, 77, 78,
|
|
79, 0, 0, 167, 0, 0, 113, 56, 57, 58,
|
|
59, 60, 61, 62, 63, 64, 65, 73, 66, 67,
|
|
68, 69, 70, 71, 72, 74, 75, 76, 77, 78,
|
|
79, 0, 0, 0, 0, 0, 113, 56, 57, 58,
|
|
59, 60, 61, 62, 63, 64, 65, 73, 66, 67,
|
|
68, 69, 70, 71, 72, 74, 75, 76, 77, 78,
|
|
79, 0, 0, 181, 56, 57, 58, 59, 60, 61,
|
|
62, 63, 64, 65, 73, 66, 67, 68, 69, 70,
|
|
71, 72, 74, 75, 76, 77, 78, 79
|
|
};
|
|
static const short yypact[] =
|
|
{
|
|
299,-1000,-1000, 22,-1000, 21, 54,-1000,-1000,-1000,
|
|
-1000,-1000,-1000,-1000,-1000, 19, 17, 15, 14, 13,
|
|
12, 11, 10, 9, 7, 5, 3, 1, 0, -1,
|
|
-2, 265, -3, -4, -5,-1000,-1000,-1000,-1000,-1000,
|
|
-1000,-1000,-1000,-1000,-1000,-1000, 233, 233, 580, 397,
|
|
-9,-1000, 580, -26, -25,-1000,-1000,-1000,-1000,-1000,
|
|
-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
|
|
-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
|
|
333, 199, 199, 397, 461, 397, 397, 397, 397, 397,
|
|
397, 397, 397, 397, 397, 199, 199,-1000,-1000, 199,
|
|
199, 199,-1000, -6,-1000, 33, 580, -8,-1000,-1000,
|
|
523,-1000,-1000, 429, 580, -23,-1000,-1000, 580, 580,
|
|
-1000,-1000, 199,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
|
|
-1000,-1000, -15,-1000,-1000,-1000, 493,-1000,-1000, -15,
|
|
-1000,-1000, -15, -15, -15, -15, -15, -15, 199, 199,
|
|
199, 199, 199, 47, 580, 397,-1000,-1000, -21,-1000,
|
|
-25, -26, 580,-1000,-1000,-1000, 397, 365, 580, 580,
|
|
-1000,-1000,-1000,-1000, -12,-1000,-1000, 553,-1000,-1000,
|
|
580, 580,-1000,-1000
|
|
};
|
|
static const short yypgo[] =
|
|
{
|
|
0, 147, 57, 146, 18, 145, 144, 143, 141, 136,
|
|
133, 117, 113, 8, 112, 0, 34, 110, 6, 4,
|
|
38, 109, 108, 1, 106, 2, 5, 103, 17, 98,
|
|
11, 3, 36, 86, 14
|
|
};
|
|
static const short yyr1[] =
|
|
{
|
|
0, 1, 1, 2, 2, 2, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 3, 6, 6, 6, 6,
|
|
6, 6, 6, 5, 5, 7, 7, 7, 7, 7,
|
|
7, 7, 7, 7, 7, 7, 7, 8, 8, 11,
|
|
11, 12, 12, 10, 10, 21, 21, 21, 21, 9,
|
|
9, 16, 16, 23, 23, 24, 24, 17, 17, 18,
|
|
18, 18, 26, 26, 13, 13, 27, 27, 29, 29,
|
|
28, 28, 31, 30, 25, 25, 20, 20, 32, 32,
|
|
32, 32, 32, 32, 32, 19, 14, 33, 33, 15,
|
|
15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
|
15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
|
15, 15, 15, 22, 22, 22, 22, 34, 34, 34,
|
|
34, 34
|
|
};
|
|
static const short yyr2[] =
|
|
{
|
|
0, 1, 3, 1, 2, 3, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 3, 6, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 2, 3, 2, 3, 2,
|
|
3, 2, 3, 2, 3, 2, 3, 3, 2, 3,
|
|
2, 3, 2, 3, 2, 1, 1, 1, 1, 3,
|
|
2, 1, 3, 1, 1, 4, 3, 1, 3, 1,
|
|
2, 1, 3, 2, 3, 1, 2, 4, 1, 1,
|
|
3, 3, 1, 1, 1, 2, 1, 2, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 6, 1, 3, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 2, 2, 1, 1, 1,
|
|
1, 1
|
|
};
|
|
static const short yychk[] =
|
|
{
|
|
-1000, -1, -2, -3, 29, -4, 8, -5, -6, -7,
|
|
-8, -9, -10, -11, -12, 2, 5, 6, 10, 7,
|
|
9, 13, 12, 11, 15, 18, 16, 19, 17, 20,
|
|
14, -22, -21, 26, 22, -34, 4, 23, 24, 25,
|
|
27, 33, 34, 35, 32, 31, 29, 29, -13, 30,
|
|
-27, -29, 35, -31, -28, -15, 4, 5, 6, 7,
|
|
8, 9, 10, 11, 12, 13, 15, 16, 17, 18,
|
|
19, 20, 21, 14, 22, 23, 24, 25, 26, 27,
|
|
29, 30, 30, 30, 30, 30, 30, 30, 30, 30,
|
|
30, 30, 30, 30, 30, 30, 30, -34, -15, 30,
|
|
30, 30, -2, 8, -2, -14, -15, -17, -18, -13,
|
|
-25, -26, -15, 33, 30, 31, -30, -15, 35, 35,
|
|
-4, -19, -20, -32, -15, 33, 34, 35, 30, 32,
|
|
31, -19, -16, -23, -18, -24, -25, -13, -18, -16,
|
|
-18, -18, -16, -16, -16, -16, -16, -16, -20, -20,
|
|
-20, -20, -20, 21, -15, 31, -26, -15, -13, 34,
|
|
-28, -31, 35, -30, -30, -32, 31, 30, 8, -15,
|
|
-18, 34, -30, -23, -16, 32, -15, -33, -15, 32,
|
|
-15, 30, -15, -15
|
|
};
|
|
static const short yydef[] =
|
|
{
|
|
0, -2, 1, 0, 3, 0, 0, 6, 7, 8,
|
|
9, 10, 11, 12, 13, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 113, 114, 45, 46, 47,
|
|
48, 117, 118, 119, 120, 121, 0, -2, 0, 0,
|
|
0, 65, 0, 68, 69, 72, 89, 90, 91, 92,
|
|
93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
|
|
103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 25,
|
|
27, 29, 31, 33, 35, 38, 50, 115, 116, 44,
|
|
40, 42, 2, 0, 5, 0, 0, 18, 57, 59,
|
|
0, 61, -2, 0, 0, 0, 66, 73, 0, 0,
|
|
14, 23, 85, 76, 78, 79, 80, 81, 82, 83,
|
|
84, 24, 16, 51, 53, 54, 0, 17, 19, 20,
|
|
21, 22, 26, 28, 30, 32, 34, 36, 37, 49,
|
|
43, 39, 41, 0, 0, 0, 60, 75, 0, 63,
|
|
64, 0, 0, 70, 71, 77, 0, 0, 0, 0,
|
|
58, 62, 67, 52, 0, 56, 15, 0, 87, 55,
|
|
0, 0, 86, 88
|
|
};
|
|
static const short yytok1[] =
|
|
{
|
|
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
29, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 31, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 30, 32,
|
|
33, 0, 34, 0, 35
|
|
};
|
|
static const short yytok2[] =
|
|
{
|
|
2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
|
|
12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
|
22, 23, 24, 25, 26, 27, 28
|
|
};
|
|
static const long yytok3[] =
|
|
{
|
|
0
|
|
};
|
|
#define YYFLAG -1000
|
|
#define YYERROR goto yyerrlab
|
|
#define YYACCEPT return(0)
|
|
#define YYABORT return(1)
|
|
#define yyclearin yychar = -1
|
|
#define yyerrok yyerrflag = 0
|
|
|
|
#ifdef yydebug
|
|
#include "y.debug"
|
|
#else
|
|
#define yydebug 0
|
|
static const char* yytoknames[1]; /* for debugging */
|
|
static const char* yystates[1]; /* for debugging */
|
|
#endif
|
|
|
|
/* parser for yacc output */
|
|
#ifdef YYARG
|
|
#define yynerrs yyarg->yynerrs
|
|
#define yyerrflag yyarg->yyerrflag
|
|
#define yyval yyarg->yyval
|
|
#define yylval yyarg->yylval
|
|
#else
|
|
int yynerrs = 0; /* number of errors */
|
|
int yyerrflag = 0; /* error recovery flag */
|
|
#endif
|
|
|
|
extern int fprint(int, char*, ...);
|
|
extern int sprint(char*, char*, ...);
|
|
|
|
static const char*
|
|
yytokname(int yyc)
|
|
{
|
|
static char x[10];
|
|
|
|
if(yyc > 0 && yyc <= sizeof(yytoknames)/sizeof(yytoknames[0]))
|
|
if(yytoknames[yyc-1])
|
|
return yytoknames[yyc-1];
|
|
sprint(x, "<%d>", yyc);
|
|
return x;
|
|
}
|
|
|
|
static const char*
|
|
yystatname(int yys)
|
|
{
|
|
static char x[10];
|
|
|
|
if(yys >= 0 && yys < sizeof(yystates)/sizeof(yystates[0]))
|
|
if(yystates[yys])
|
|
return yystates[yys];
|
|
sprint(x, "<%d>\n", yys);
|
|
return x;
|
|
}
|
|
|
|
static long
|
|
#ifdef YYARG
|
|
yylex1(struct Yyarg *yyarg)
|
|
#else
|
|
yylex1(void)
|
|
#endif
|
|
{
|
|
long yychar;
|
|
const long *t3p;
|
|
int c;
|
|
|
|
#ifdef YYARG
|
|
yychar = yylex(yyarg);
|
|
#else
|
|
yychar = yylex();
|
|
#endif
|
|
if(yychar <= 0) {
|
|
c = yytok1[0];
|
|
goto out;
|
|
}
|
|
if(yychar < sizeof(yytok1)/sizeof(yytok1[0])) {
|
|
c = yytok1[yychar];
|
|
goto out;
|
|
}
|
|
if(yychar >= YYPRIVATE)
|
|
if(yychar < YYPRIVATE+sizeof(yytok2)/sizeof(yytok2[0])) {
|
|
c = yytok2[yychar-YYPRIVATE];
|
|
goto out;
|
|
}
|
|
for(t3p=yytok3;; t3p+=2) {
|
|
c = t3p[0];
|
|
if(c == yychar) {
|
|
c = t3p[1];
|
|
goto out;
|
|
}
|
|
if(c == 0)
|
|
break;
|
|
}
|
|
c = 0;
|
|
|
|
out:
|
|
if(c == 0)
|
|
c = yytok2[1]; /* unknown char */
|
|
if(yydebug >= 3)
|
|
fprint(2, "lex %.4lux %s\n", yychar, yytokname(c));
|
|
return c;
|
|
}
|
|
|
|
int
|
|
#ifdef YYARG
|
|
yyparse(struct Yyarg *yyarg)
|
|
#else
|
|
yyparse(void)
|
|
#endif
|
|
{
|
|
struct
|
|
{
|
|
YYSTYPE yyv;
|
|
int yys;
|
|
} yys[YYMAXDEPTH], *yyp, *yypt;
|
|
const short *yyxi;
|
|
int yyj, yym, yystate, yyn, yyg;
|
|
long yychar;
|
|
#ifndef YYARG
|
|
YYSTYPE save1, save2;
|
|
int save3, save4;
|
|
|
|
save1 = yylval;
|
|
save2 = yyval;
|
|
save3 = yynerrs;
|
|
save4 = yyerrflag;
|
|
#endif
|
|
|
|
yystate = 0;
|
|
yychar = -1;
|
|
yynerrs = 0;
|
|
yyerrflag = 0;
|
|
yyp = &yys[-1];
|
|
goto yystack;
|
|
|
|
ret0:
|
|
yyn = 0;
|
|
goto ret;
|
|
|
|
ret1:
|
|
yyn = 1;
|
|
goto ret;
|
|
|
|
ret:
|
|
#ifndef YYARG
|
|
yylval = save1;
|
|
yyval = save2;
|
|
yynerrs = save3;
|
|
yyerrflag = save4;
|
|
#endif
|
|
return yyn;
|
|
|
|
yystack:
|
|
/* put a state and value onto the stack */
|
|
if(yydebug >= 4)
|
|
fprint(2, "char %s in %s", yytokname(yychar), yystatname(yystate));
|
|
|
|
yyp++;
|
|
if(yyp >= &yys[YYMAXDEPTH]) {
|
|
yyerror("yacc stack overflow");
|
|
goto ret1;
|
|
}
|
|
yyp->yys = yystate;
|
|
yyp->yyv = yyval;
|
|
|
|
yynewstate:
|
|
yyn = yypact[yystate];
|
|
if(yyn <= YYFLAG)
|
|
goto yydefault; /* simple state */
|
|
if(yychar < 0)
|
|
#ifdef YYARG
|
|
yychar = yylex1(yyarg);
|
|
#else
|
|
yychar = yylex1();
|
|
#endif
|
|
yyn += yychar;
|
|
if(yyn < 0 || yyn >= YYLAST)
|
|
goto yydefault;
|
|
yyn = yyact[yyn];
|
|
if(yychk[yyn] == yychar) { /* valid shift */
|
|
yychar = -1;
|
|
yyval = yylval;
|
|
yystate = yyn;
|
|
if(yyerrflag > 0)
|
|
yyerrflag--;
|
|
goto yystack;
|
|
}
|
|
|
|
yydefault:
|
|
/* default state action */
|
|
yyn = yydef[yystate];
|
|
if(yyn == -2) {
|
|
if(yychar < 0)
|
|
#ifdef YYARG
|
|
yychar = yylex1(yyarg);
|
|
#else
|
|
yychar = yylex1();
|
|
#endif
|
|
|
|
/* look through exception table */
|
|
for(yyxi=yyexca;; yyxi+=2)
|
|
if(yyxi[0] == -1 && yyxi[1] == yystate)
|
|
break;
|
|
for(yyxi += 2;; yyxi += 2) {
|
|
yyn = yyxi[0];
|
|
if(yyn < 0 || yyn == yychar)
|
|
break;
|
|
}
|
|
yyn = yyxi[1];
|
|
if(yyn < 0)
|
|
goto ret0;
|
|
}
|
|
if(yyn == 0) {
|
|
/* error ... attempt to resume parsing */
|
|
switch(yyerrflag) {
|
|
case 0: /* brand new error */
|
|
yyerror("syntax error");
|
|
if(yydebug >= 1) {
|
|
fprint(2, "%s", yystatname(yystate));
|
|
fprint(2, "saw %s\n", yytokname(yychar));
|
|
}
|
|
goto yyerrlab;
|
|
yyerrlab:
|
|
yynerrs++;
|
|
|
|
case 1:
|
|
case 2: /* incompletely recovered error ... try again */
|
|
yyerrflag = 3;
|
|
|
|
/* find a state where "error" is a legal shift action */
|
|
while(yyp >= yys) {
|
|
yyn = yypact[yyp->yys] + YYERRCODE;
|
|
if(yyn >= 0 && yyn < YYLAST) {
|
|
yystate = yyact[yyn]; /* simulate a shift of "error" */
|
|
if(yychk[yystate] == YYERRCODE)
|
|
goto yystack;
|
|
}
|
|
|
|
/* the current yyp has no shift onn "error", pop stack */
|
|
if(yydebug >= 2)
|
|
fprint(2, "error recovery pops state %d, uncovers %d\n",
|
|
yyp->yys, (yyp-1)->yys );
|
|
yyp--;
|
|
}
|
|
/* there is no state on the stack with an error shift ... abort */
|
|
goto ret1;
|
|
|
|
case 3: /* no shift yet; clobber input char */
|
|
if(yydebug >= 2)
|
|
fprint(2, "error recovery discards %s\n", yytokname(yychar));
|
|
if(yychar == YYEOFCODE)
|
|
goto ret1;
|
|
yychar = -1;
|
|
goto yynewstate; /* try again in the same state */
|
|
}
|
|
}
|
|
|
|
/* reduction by production yyn */
|
|
if(yydebug >= 2)
|
|
fprint(2, "reduce %d in:\n\t%s", yyn, yystatname(yystate));
|
|
|
|
yypt = yyp;
|
|
yyp -= yyr2[yyn];
|
|
yyval = (yyp+1)->yyv;
|
|
yym = yyn;
|
|
|
|
/* consult goto table to find next state */
|
|
yyn = yyr1[yyn];
|
|
yyg = yypgo[yyn];
|
|
yyj = yyg + yyp->yys + 1;
|
|
|
|
if(yyj >= YYLAST || yychk[yystate=yyact[yyj]] != -yyn)
|
|
yystate = yyact[yyg];
|
|
switch(yym) {
|
|
|
|
case 3:
|
|
#line 56 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yydone = 1; } break;
|
|
case 6:
|
|
#line 61 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ date = 1; } break;
|
|
case 7:
|
|
#line 63 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ originator = 1; } break;
|
|
case 8:
|
|
#line 65 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ destination = 1; } break;
|
|
case 15:
|
|
#line 74 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ freenode(yypt[-5].yyv); freenode(yypt[-2].yyv); freenode(yypt[-1].yyv);
|
|
usender = yypt[-4].yyv; udate = yypt[-3].yyv; usys = yypt[-0].yyv;
|
|
} break;
|
|
case 16:
|
|
#line 79 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 1); } break;
|
|
case 17:
|
|
#line 81 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 1); } break;
|
|
case 18:
|
|
#line 83 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 1); } break;
|
|
case 19:
|
|
#line 85 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 1); } break;
|
|
case 20:
|
|
#line 87 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 1); } break;
|
|
case 21:
|
|
#line 89 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 1); } break;
|
|
case 22:
|
|
#line 91 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 1); } break;
|
|
case 23:
|
|
#line 94 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 24:
|
|
#line 96 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 25:
|
|
#line 99 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link2(yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 26:
|
|
#line 101 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 27:
|
|
#line 103 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link2(yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 28:
|
|
#line 105 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 29:
|
|
#line 107 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link2(yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 30:
|
|
#line 109 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 31:
|
|
#line 111 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link2(yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 32:
|
|
#line 113 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 33:
|
|
#line 115 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link2(yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 34:
|
|
#line 117 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 35:
|
|
#line 119 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link2(yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 36:
|
|
#line 121 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 37:
|
|
#line 124 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 38:
|
|
#line 126 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link2(yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 39:
|
|
#line 129 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 0); received++; } break;
|
|
case 40:
|
|
#line 131 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link2(yypt[-1].yyv, yypt[-0].yyv), 0); received++; } break;
|
|
case 41:
|
|
#line 134 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 42:
|
|
#line 136 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link2(yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 43:
|
|
#line 139 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 44:
|
|
#line 141 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ newfield(link2(yypt[-1].yyv, yypt[-0].yyv), 0); } break;
|
|
case 47:
|
|
#line 143 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ messageid = 1; } break;
|
|
case 49:
|
|
#line 146 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ /* hack to allow same lex for field names and the rest */
|
|
if(badfieldname(yypt[-2].yyv)){
|
|
freenode(yypt[-2].yyv);
|
|
freenode(yypt[-1].yyv);
|
|
freenode(yypt[-0].yyv);
|
|
return 1;
|
|
}
|
|
newfield(link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv), 0);
|
|
} break;
|
|
case 50:
|
|
#line 156 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ /* hack to allow same lex for field names and the rest */
|
|
if(badfieldname(yypt[-1].yyv)){
|
|
freenode(yypt[-1].yyv);
|
|
freenode(yypt[-0].yyv);
|
|
return 1;
|
|
}
|
|
newfield(link2(yypt[-1].yyv, yypt[-0].yyv), 0);
|
|
} break;
|
|
case 52:
|
|
#line 167 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv); } break;
|
|
case 55:
|
|
#line 173 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = link2(yypt[-3].yyv, link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv)); } break;
|
|
case 56:
|
|
#line 175 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv); } break;
|
|
case 58:
|
|
#line 179 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv); } break;
|
|
case 60:
|
|
#line 183 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = link2(yypt[-1].yyv, yypt[-0].yyv); } break;
|
|
case 62:
|
|
#line 187 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv); } break;
|
|
case 63:
|
|
#line 189 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = nobody(yypt[-0].yyv); freenode(yypt[-1].yyv); } break;
|
|
case 64:
|
|
#line 192 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = address(concat(yypt[-2].yyv, concat(yypt[-1].yyv, yypt[-0].yyv))); } break;
|
|
case 66:
|
|
#line 196 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = concat(yypt[-1].yyv, yypt[-0].yyv); } break;
|
|
case 67:
|
|
#line 198 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = concat(yypt[-3].yyv, concat(yypt[-2].yyv, concat(yypt[-1].yyv, yypt[-0].yyv))); } break;
|
|
case 68:
|
|
#line 201 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = address(yypt[-0].yyv); } break;
|
|
case 70:
|
|
#line 205 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = address(concat(yypt[-2].yyv, concat(yypt[-1].yyv, yypt[-0].yyv)));} break;
|
|
case 71:
|
|
#line 207 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = address(concat(yypt[-2].yyv, concat(yypt[-1].yyv, yypt[-0].yyv)));} break;
|
|
case 75:
|
|
#line 215 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = link2(yypt[-1].yyv, yypt[-0].yyv); } break;
|
|
case 77:
|
|
#line 219 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = link2(yypt[-1].yyv, yypt[-0].yyv); } break;
|
|
case 86:
|
|
#line 226 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = link3(yypt[-5].yyv, yypt[-3].yyv, link3(yypt[-4].yyv, yypt[-0].yyv, link2(yypt[-2].yyv, yypt[-1].yyv))); } break;
|
|
case 88:
|
|
#line 230 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = link3(yypt[-2].yyv, yypt[-1].yyv, yypt[-0].yyv); } break;
|
|
case 115:
|
|
#line 240 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = link2(yypt[-1].yyv, yypt[-0].yyv); } break;
|
|
case 116:
|
|
#line 242 "/usr/local/plan9/src/cmd/upas/smtp/rfc822.y"
|
|
{ yyval = link2(yypt[-1].yyv, yypt[-0].yyv); } break;
|
|
}
|
|
goto yystack; /* stack new state and value */
|
|
}
|