123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- %{
- #include "common.h"
- #include <ctype.h>
- #include "smtpd.h"
- #define YYSTYPE yystype
- typedef struct quux yystype;
- struct quux {
- String *s;
- int c;
- };
- Biobuf *yyfp;
- YYSTYPE *bang;
- extern Biobuf bin;
- extern int debug;
- YYSTYPE cat(YYSTYPE*, YYSTYPE*, YYSTYPE*, YYSTYPE*, YYSTYPE*, YYSTYPE*, YYSTYPE*);
- int yyparse(void);
- int yylex(void);
- YYSTYPE anonymous(void);
- %}
- %term SPACE
- %term CNTRL
- %term CRLF
- %start conversation
- %%
- conversation : cmd
- | conversation cmd
- ;
- cmd : error
- | 'h' 'e' 'l' 'o' spaces sdomain CRLF
- { hello($6.s, 0); }
- | 'e' 'h' 'l' 'o' spaces sdomain CRLF
- { hello($6.s, 1); }
- | 'm' 'a' 'i' 'l' spaces 'f' 'r' 'o' 'm' ':' spath CRLF
- { sender($11.s); }
- | 'm' 'a' 'i' 'l' spaces 'f' 'r' 'o' 'm' ':' spath spaces 'a' 'u' 't' 'h' '=' sauth CRLF
- { sender($11.s); }
- | 'r' 'c' 'p' 't' spaces 't' 'o' ':' spath CRLF
- { receiver($9.s); }
- | 'd' 'a' 't' 'a' CRLF
- { data(); }
- | 'r' 's' 'e' 't' CRLF
- { reset(); }
- | 's' 'e' 'n' 'd' spaces 'f' 'r' 'o' 'm' ':' spath CRLF
- { sender($11.s); }
- | 's' 'o' 'm' 'l' spaces 'f' 'r' 'o' 'm' ':' spath CRLF
- { sender($11.s); }
- | 's' 'a' 'm' 'l' spaces 'f' 'r' 'o' 'm' ':' spath CRLF
- { sender($11.s); }
- | 'v' 'r' 'f' 'y' spaces string CRLF
- { verify($6.s); }
- | 'e' 'x' 'p' 'n' spaces string CRLF
- { verify($6.s); }
- | 'h' 'e' 'l' 'p' CRLF
- { help(0); }
- | 'h' 'e' 'l' 'p' spaces string CRLF
- { help($6.s); }
- | 'n' 'o' 'o' 'p' CRLF
- { noop(); }
- | 'q' 'u' 'i' 't' CRLF
- { quit(); }
- | 't' 'u' 'r' 'n' CRLF
- { turn(); }
- | 's' 't' 'a' 'r' 't' 't' 'l' 's' CRLF
- { starttls(); }
- | 'a' 'u' 't' 'h' spaces name spaces string CRLF
- { auth($6.s, $8.s); }
- | 'a' 'u' 't' 'h' spaces name CRLF
- { auth($6.s, nil); }
- | CRLF
- { reply("501 illegal command or bad syntax\r\n"); }
- ;
- path : '<' '>' ={ $$ = anonymous(); }
- | '<' mailbox '>' ={ $$ = $2; }
- | '<' a_d_l ':' mailbox '>' ={ $$ = cat(&$2, bang, &$4, 0, 0 ,0, 0); }
- ;
- spath : path ={ $$ = $1; }
- | spaces path ={ $$ = $2; }
- ;
- auth : path ={ $$ = $1; }
- | mailbox ={ $$ = $1; }
- ;
- sauth : auth ={ $$ = $1; }
- | spaces auth ={ $$ = $2; }
- ;
- ;
- a_d_l : at_domain ={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
- | at_domain ',' a_d_l ={ $$ = cat(&$1, bang, &$3, 0, 0, 0, 0); }
- ;
- at_domain : '@' domain ={ $$ = cat(&$2, 0, 0, 0, 0 ,0, 0); }
- ;
- sdomain : domain ={ $$ = $1; }
- | domain spaces ={ $$ = $1; }
- ;
- domain : element ={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
- | element '.' ={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
- | element '.' domain ={ $$ = cat(&$1, &$2, &$3, 0, 0 ,0, 0); }
- ;
- element : name ={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
- | '#' number ={ $$ = cat(&$1, &$2, 0, 0, 0 ,0, 0); }
- | '[' ']' ={ $$ = cat(&$1, &$2, 0, 0, 0 ,0, 0); }
- | '[' dotnum ']' ={ $$ = cat(&$1, &$2, &$3, 0, 0 ,0, 0); }
- ;
- mailbox : local_part ={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
- | local_part '@' domain ={ $$ = cat(&$3, bang, &$1, 0, 0 ,0, 0); }
- ;
- local_part : dot_string ={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
- | quoted_string ={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
- ;
- name : let_dig ={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
- | let_dig ld_str ={ $$ = cat(&$1, &$2, 0, 0, 0 ,0, 0); }
- | let_dig ldh_str ld_str ={ $$ = cat(&$1, &$2, &$3, 0, 0 ,0, 0); }
- ;
- ld_str : let_dig
- | let_dig ld_str ={ $$ = cat(&$1, &$2, 0, 0, 0 ,0, 0); }
- ;
- ldh_str : hunder
- | ld_str hunder ={ $$ = cat(&$1, &$2, 0, 0, 0 ,0, 0); }
- | ldh_str ld_str hunder ={ $$ = cat(&$1, &$2, &$3, 0, 0 ,0, 0); }
- ;
- let_dig : a
- | d
- ;
- dot_string : string ={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
- | string '.' dot_string ={ $$ = cat(&$1, &$2, &$3, 0, 0 ,0, 0); }
- ;
- string : char ={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
- | string char ={ $$ = cat(&$1, &$2, 0, 0, 0 ,0, 0); }
- ;
- quoted_string : '"' qtext '"' ={ $$ = cat(&$1, &$2, &$3, 0, 0 ,0, 0); }
- ;
- qtext : '\\' x ={ $$ = cat(&$2, 0, 0, 0, 0 ,0, 0); }
- | qtext '\\' x ={ $$ = cat(&$1, &$3, 0, 0, 0 ,0, 0); }
- | q
- | qtext q ={ $$ = cat(&$1, &$2, 0, 0, 0 ,0, 0); }
- ;
- char : c
- | '\\' x ={ $$ = $2; }
- ;
- dotnum : snum '.' snum '.' snum '.' snum ={ $$ = cat(&$1, &$2, &$3, &$4, &$5, &$6, &$7); }
- ;
- number : d ={ $$ = cat(&$1, 0, 0, 0, 0 ,0, 0); }
- | number d ={ $$ = cat(&$1, &$2, 0, 0, 0 ,0, 0); }
- ;
- snum : number ={ if(atoi(s_to_c($1.s)) > 255) print("bad snum\n"); }
- ;
- spaces : SPACE ={ $$ = $1; }
- | SPACE spaces ={ $$ = $1; }
- ;
- hunder : '-' | '_'
- ;
- special1 : CNTRL
- | '(' | ')' | ',' | '.'
- | ':' | ';' | '<' | '>' | '@'
- ;
- special : special1 | '\\' | '"'
- ;
- notspecial : '!' | '#' | '$' | '%' | '&' | '\''
- | '*' | '+' | '-' | '/'
- | '=' | '?'
- | '[' | ']' | '^' | '_' | '`' | '{' | '|' | '}' | '~'
- ;
- a : 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i'
- | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r'
- | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z'
- ;
- d : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
- ;
- c : a | d | notspecial
- ;
- q : a | d | special1 | notspecial | SPACE
- ;
- x : a | d | special | notspecial | SPACE
- ;
- %%
- void
- parseinit(void)
- {
- bang = (YYSTYPE*)malloc(sizeof(YYSTYPE));
- bang->c = '!';
- bang->s = 0;
- yyfp = &bin;
- }
- yylex(void)
- {
- int c;
- for(;;){
- c = Bgetc(yyfp);
- if(c == -1)
- return 0;
- if(debug)
- fprint(2, "%c", c);
- yylval.c = c = c & 0x7F;
- if(c == '\n'){
- return CRLF;
- }
- if(c == '\r'){
- c = Bgetc(yyfp);
- if(c != '\n'){
- Bungetc(yyfp);
- c = '\r';
- } else {
- if(debug)
- fprint(2, "%c", c);
- return CRLF;
- }
- }
- if(isalpha(c))
- return tolower(c);
- if(isspace(c))
- return SPACE;
- if(iscntrl(c))
- return CNTRL;
- return c;
- }
- }
- YYSTYPE
- cat(YYSTYPE *y1, YYSTYPE *y2, YYSTYPE *y3, YYSTYPE *y4, YYSTYPE *y5, YYSTYPE *y6, YYSTYPE *y7)
- {
- YYSTYPE rv;
- if(y1->s)
- rv.s = y1->s;
- else {
- rv.s = s_new();
- s_putc(rv.s, y1->c);
- s_terminate(rv.s);
- }
- if(y2){
- if(y2->s){
- s_append(rv.s, s_to_c(y2->s));
- s_free(y2->s);
- } else {
- s_putc(rv.s, y2->c);
- s_terminate(rv.s);
- }
- } else
- return rv;
- if(y3){
- if(y3->s){
- s_append(rv.s, s_to_c(y3->s));
- s_free(y3->s);
- } else {
- s_putc(rv.s, y3->c);
- s_terminate(rv.s);
- }
- } else
- return rv;
- if(y4){
- if(y4->s){
- s_append(rv.s, s_to_c(y4->s));
- s_free(y4->s);
- } else {
- s_putc(rv.s, y4->c);
- s_terminate(rv.s);
- }
- } else
- return rv;
- if(y5){
- if(y5->s){
- s_append(rv.s, s_to_c(y5->s));
- s_free(y5->s);
- } else {
- s_putc(rv.s, y5->c);
- s_terminate(rv.s);
- }
- } else
- return rv;
- if(y6){
- if(y6->s){
- s_append(rv.s, s_to_c(y6->s));
- s_free(y6->s);
- } else {
- s_putc(rv.s, y6->c);
- s_terminate(rv.s);
- }
- } else
- return rv;
- if(y7){
- if(y7->s){
- s_append(rv.s, s_to_c(y7->s));
- s_free(y7->s);
- } else {
- s_putc(rv.s, y7->c);
- s_terminate(rv.s);
- }
- } else
- return rv;
- return rv;
- }
- void
- yyerror(char *x)
- {
- USED(x);
- }
- /*
- * an anonymous user
- */
- YYSTYPE
- anonymous(void)
- {
- YYSTYPE rv;
- rv.s = s_copy("/dev/null");
- return rv;
- }
|