plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

smtpd.y (7021B)


      1 %{
      2 #include "common.h"
      3 #include <ctype.h>
      4 #include "smtpd.h"
      5 
      6 #define YYSTYPE yystype
      7 typedef struct quux yystype;
      8 struct quux {
      9 	String	*s;
     10 	int	c;
     11 };
     12 Biobuf *yyfp;
     13 YYSTYPE *bang;
     14 extern Biobuf bin;
     15 extern int debug;
     16 
     17 YYSTYPE cat(YYSTYPE*, YYSTYPE*, YYSTYPE*, YYSTYPE*, YYSTYPE*, YYSTYPE*, YYSTYPE*);
     18 int yyparse(void);
     19 int yylex(void);
     20 YYSTYPE anonymous(void);
     21 %}
     22 
     23 %term SPACE
     24 %term CNTRL
     25 %term CRLF
     26 %start conversation
     27 %%
     28 
     29 conversation	: cmd
     30 		| conversation cmd
     31 		;
     32 cmd		: error
     33 		| 'h' 'e' 'l' 'o' spaces sdomain CRLF
     34 			{ hello($6.s, 0); }
     35 		| 'e' 'h' 'l' 'o' spaces sdomain CRLF
     36 			{ hello($6.s, 1); }
     37 		| 'm' 'a' 'i' 'l' spaces 'f' 'r' 'o' 'm' ':' spath CRLF
     38 			{ sender($11.s); }
     39 		| 'm' 'a' 'i' 'l' spaces 'f' 'r' 'o' 'm' ':' spath spaces 'a' 'u' 't' 'h' '=' sauth CRLF
     40 			{ sender($11.s); }
     41 		| 'r' 'c' 'p' 't' spaces 't' 'o' ':' spath CRLF
     42 			{ receiver($9.s); }
     43 		| 'd' 'a' 't' 'a' CRLF
     44 			{ data(); }
     45 		| 'r' 's' 'e' 't' CRLF
     46 			{ reset(); }
     47 		| 's' 'e' 'n' 'd' spaces 'f' 'r' 'o' 'm' ':' spath CRLF
     48 			{ sender($11.s); }
     49 		| 's' 'o' 'm' 'l' spaces 'f' 'r' 'o' 'm'  ':' spath CRLF
     50 			{ sender($11.s); }
     51 		| 's' 'a' 'm' 'l' spaces 'f' 'r' 'o' 'm' ':' spath CRLF
     52 			{ sender($11.s); }
     53 		| 'v' 'r' 'f' 'y' spaces string CRLF
     54 			{ verify($6.s); }
     55 		| 'e' 'x' 'p' 'n' spaces string CRLF
     56 			{ verify($6.s); }
     57 		| 'h' 'e' 'l' 'p' CRLF
     58 			{ help(0); }
     59 		| 'h' 'e' 'l' 'p' spaces string CRLF
     60 			{ help($6.s); }
     61 		| 'n' 'o' 'o' 'p' CRLF
     62 			{ noop(); }
     63 		| 'q' 'u' 'i' 't' CRLF
     64 			{ quit(); }
     65 		| 't' 'u' 'r' 'n' CRLF
     66 			{ turn(); }
     67 		| 's' 't' 'a' 'r' 't' 't' 'l' 's' CRLF
     68 			{ starttls(); }
     69 		| 'a' 'u' 't' 'h' spaces name spaces string CRLF
     70 			{ auth($6.s, $8.s); }
     71 		| 'a' 'u' 't' 'h' spaces name CRLF
     72 			{ auth($6.s, nil); }
     73 		| CRLF
     74 			{ reply("501 illegal command or bad syntax\r\n"); }
     75 		;
     76 path		: '<' '>'			={ $$ = anonymous(); }
     77 		| '<' mailbox '>'		={ $$ = $2; }
     78 		| '<' a_d_l ':' mailbox '>'	={ $$ = cat(&$2, bang, &$4, 0, 0 ,0, 0); }
     79 		;
     80 spath		: path			={ $$ = $1; }
     81 		| spaces path		={ $$ = $2; }
     82 		;
     83 auth		: path			={ $$ = $1; }
     84 		| mailbox		={ $$ = $1; }
     85 		;
     86 sauth		: auth			={ $$ = $1; }
     87 		| spaces auth		={ $$ = $2; }
     88 		;
     89 		;
     90 a_d_l		: at_domain		={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
     91 		| at_domain ',' a_d_l	={ $$ = cat(&$1, bang, &$3, 0, 0, 0, 0); }
     92 		;
     93 at_domain	: '@' domain		={ $$ = cat(&$2, 0, 0, 0, 0 ,0, 0); }
     94 		;
     95 sdomain		: domain		={ $$ = $1; }
     96 		| domain spaces		={ $$ = $1; }
     97 		;
     98 domain		: element		={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
     99 		| element '.'		={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
    100 		| element '.' domain	={ $$ = cat(&$1, &$2, &$3, 0, 0 ,0, 0); }
    101 		;
    102 element		: name			={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
    103 		| '#' number		={ $$ = cat(&$1, &$2, 0, 0, 0 ,0, 0); }
    104 		| '[' ']'		={ $$ = cat(&$1, &$2, 0, 0, 0 ,0, 0); }
    105 		| '[' dotnum ']'	={ $$ = cat(&$1, &$2, &$3, 0, 0 ,0, 0); }
    106 		;
    107 mailbox		: local_part		={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
    108 		| local_part '@' domain	={ $$ = cat(&$3, bang, &$1, 0, 0 ,0, 0); }
    109 		;
    110 local_part	: dot_string		={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
    111 		| quoted_string		={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
    112 		;
    113 name		: let_dig			={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
    114 		| let_dig ld_str		={ $$ = cat(&$1, &$2, 0, 0, 0 ,0, 0); }
    115 		| let_dig ldh_str ld_str	={ $$ = cat(&$1, &$2, &$3, 0, 0 ,0, 0); }
    116 		;
    117 ld_str		: let_dig
    118 		| let_dig ld_str		={ $$ = cat(&$1, &$2, 0, 0, 0 ,0, 0); }
    119 		;
    120 ldh_str		: hunder
    121 		| ld_str hunder		={ $$ = cat(&$1, &$2, 0, 0, 0 ,0, 0); }
    122 		| ldh_str ld_str hunder	={ $$ = cat(&$1, &$2, &$3, 0, 0 ,0, 0); }
    123 		;
    124 let_dig		: a
    125 		| d
    126 		;
    127 dot_string	: string			={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
    128 		| string '.' dot_string		={ $$ = cat(&$1, &$2, &$3, 0, 0 ,0, 0); }
    129 		;
    130 
    131 string		: char	={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
    132 		| string char	={ $$ = cat(&$1, &$2, 0, 0, 0 ,0, 0); }
    133 		;
    134 
    135 quoted_string	: '"' qtext '"'	={ $$ = cat(&$1, &$2, &$3, 0, 0 ,0, 0); }
    136 		;
    137 qtext		: '\\' x		={ $$ = cat(&$2, 0, 0, 0, 0 ,0, 0); }
    138 		| qtext '\\' x		={ $$ = cat(&$1, &$3, 0, 0, 0 ,0, 0); }
    139 		| q
    140 		| qtext q		={ $$ = cat(&$1, &$2, 0, 0, 0 ,0, 0); }
    141 		;
    142 char		: c
    143 		| '\\' x		={ $$ = $2; }
    144 		;
    145 dotnum		: snum '.' snum '.' snum '.' snum ={ $$ = cat(&$1, &$2, &$3, &$4, &$5, &$6, &$7); }
    146 		;
    147 number		: d		={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
    148 		| number d	={ $$ = cat(&$1, &$2, 0, 0, 0 ,0, 0); }
    149 		;
    150 snum		: number		={ if(atoi(s_to_c($1.s)) > 255) print("bad snum\n"); } 
    151 		;
    152 spaces		: SPACE		={ $$ = $1; }
    153 		| SPACE	spaces	={ $$ = $1; }
    154 		;
    155 hunder		: '-' | '_'
    156 		;
    157 special1	: CNTRL
    158 		| '(' | ')' | ',' | '.'
    159 		| ':' | ';' | '<' | '>' | '@'
    160 		;
    161 special		: special1 | '\\' | '"'
    162 		;
    163 notspecial	: '!' | '#' | '$' | '%' | '&' | '\''
    164 		| '*' | '+' | '-' | '/'
    165 		| '=' | '?'
    166 		| '[' | ']' | '^' | '_' | '`' | '{' | '|' | '}' | '~'
    167 		;
    168 
    169 a		: 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i'
    170 		| 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r'
    171 		| 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z'
    172 		;
    173 d		: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
    174 		;
    175 c		: a | d | notspecial
    176 		;		
    177 q		: a | d | special1 | notspecial | SPACE
    178 		;
    179 x		: a | d | special | notspecial | SPACE
    180 		;
    181 %%
    182 
    183 void
    184 parseinit(void)
    185 {
    186 	bang = (YYSTYPE*)malloc(sizeof(YYSTYPE));
    187 	bang->c = '!';
    188 	bang->s = 0;
    189 	yyfp = &bin;
    190 }
    191 
    192 int
    193 yylex(void)
    194 {
    195 	int c;
    196 
    197 	for(;;){
    198 		c = Bgetc(yyfp);
    199 		if(c == -1)
    200 			return 0;
    201 		if(debug)
    202 			fprint(2, "%c", c);
    203 		yylval.c = c = c & 0x7F;
    204 		if(c == '\n'){
    205 			return CRLF;
    206 		}
    207 		if(c == '\r'){
    208 			c = Bgetc(yyfp);
    209 			if(c != '\n'){
    210 				Bungetc(yyfp);
    211 				c = '\r';
    212 			} else {
    213 				if(debug)
    214 					fprint(2, "%c", c);
    215 				return CRLF;
    216 			}
    217 		}
    218 		if(isalpha(c))
    219 			return tolower(c);
    220 		if(isspace(c))
    221 			return SPACE;
    222 		if(iscntrl(c))
    223 			return CNTRL;
    224 		return c;
    225 	}
    226 }
    227 
    228 YYSTYPE
    229 cat(YYSTYPE *y1, YYSTYPE *y2, YYSTYPE *y3, YYSTYPE *y4, YYSTYPE *y5, YYSTYPE *y6, YYSTYPE *y7)
    230 {
    231 	YYSTYPE rv;
    232 
    233 	memset(&rv, 0, sizeof rv);
    234 	if(y1->s)
    235 		rv.s = y1->s;
    236 	else {
    237 		rv.s = s_new();
    238 		s_putc(rv.s, y1->c);
    239 		s_terminate(rv.s);
    240 	}
    241 	if(y2){
    242 		if(y2->s){
    243 			s_append(rv.s, s_to_c(y2->s));
    244 			s_free(y2->s);
    245 		} else {
    246 			s_putc(rv.s, y2->c);
    247 			s_terminate(rv.s);
    248 		}
    249 	} else
    250 		return rv;
    251 	if(y3){
    252 		if(y3->s){
    253 			s_append(rv.s, s_to_c(y3->s));
    254 			s_free(y3->s);
    255 		} else {
    256 			s_putc(rv.s, y3->c);
    257 			s_terminate(rv.s);
    258 		}
    259 	} else
    260 		return rv;
    261 	if(y4){
    262 		if(y4->s){
    263 			s_append(rv.s, s_to_c(y4->s));
    264 			s_free(y4->s);
    265 		} else {
    266 			s_putc(rv.s, y4->c);
    267 			s_terminate(rv.s);
    268 		}
    269 	} else
    270 		return rv;
    271 	if(y5){
    272 		if(y5->s){
    273 			s_append(rv.s, s_to_c(y5->s));
    274 			s_free(y5->s);
    275 		} else {
    276 			s_putc(rv.s, y5->c);
    277 			s_terminate(rv.s);
    278 		}
    279 	} else
    280 		return rv;
    281 	if(y6){
    282 		if(y6->s){
    283 			s_append(rv.s, s_to_c(y6->s));
    284 			s_free(y6->s);
    285 		} else {
    286 			s_putc(rv.s, y6->c);
    287 			s_terminate(rv.s);
    288 		}
    289 	} else
    290 		return rv;
    291 	if(y7){
    292 		if(y7->s){
    293 			s_append(rv.s, s_to_c(y7->s));
    294 			s_free(y7->s);
    295 		} else {
    296 			s_putc(rv.s, y7->c);
    297 			s_terminate(rv.s);
    298 		}
    299 	} else
    300 		return rv;
    301 	return rv;
    302 }
    303 
    304 void
    305 yyerror(char *x)
    306 {
    307 	USED(x);
    308 }
    309 
    310 /*
    311  *  an anonymous user
    312  */
    313 YYSTYPE
    314 anonymous(void)
    315 {
    316 	YYSTYPE rv;
    317 
    318 	memset(&rv, 0, sizeof rv);
    319 	rv.s = s_copy("/dev/null");
    320 	return rv;
    321 }