tsmtpd.y - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       tsmtpd.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 }