- ipv6 support (-DUSE_IPV6)
[sip-router] / cfg.lex
1 /*
2  * $Id$
3  *
4  * scanner for cfg files
5  */
6
7
8 %{
9         #include "cfg.tab.h"
10         #include "dprint.h"
11         #include "globals.h"
12         #include <string.h>
13         #include <stdlib.h>
14
15 #ifdef DEBUG_DMALLOC
16 #include <dmalloc.h>
17 #endif
18
19         /* states */
20         #define INITIAL_S               0
21         #define COMMENT_S               1
22         #define COMMENT_LN_S    2
23         #define STRING_S                3
24
25         
26         static int comment_nest=0;
27         static int state=0;
28         static char* str=0;
29         int line=1;
30         int column=1;
31         int startcolumn=1;
32
33         static char* addstr(char*, char**);
34         static void count();
35
36
37 %}
38
39 /* start conditions */
40 %x STRING1 STRING2 COMMENT COMMENT_LN
41
42 /* action keywords */
43 FORWARD forward
44 DROP    "drop"|"break"
45 SEND    send
46 LOG             log
47 ERROR   error
48 ROUTE   route
49 EXEC    exec
50 SETFLAG         setflag
51 RESETFLAG       resetflag
52 ISFLAGSET       isflagset
53 LEN_GT          len_gt
54 SET_HOST                "rewritehost"|"sethost"|"seth"
55 SET_HOSTPORT    "rewritehostport"|"sethostport"|"sethp"
56 SET_USER                "rewriteuser"|"setuser"|"setu"
57 SET_USERPASS    "rewriteuserpass"|"setuserpass"|"setup"
58 SET_PORT                "rewriteport"|"setport"|"setp"
59 SET_URI                 "rewriteuri"|"seturi"
60 PREFIX                  "prefix"
61 STRIP                   "strip"
62 IF                              "if"
63 ELSE                    "else"
64
65 /*ACTION LVALUES*/
66 URIHOST                 "uri:host"
67 URIPORT                 "uri:port"
68
69 MAX_LEN                 "max_len"
70
71
72 /* condition keywords */
73 METHOD  method
74 URI             uri
75 SRCIP   src_ip
76 DSTIP   dst_ip
77 /* operators */
78 EQUAL   =
79 EQUAL_T ==
80 MATCH   =~
81 NOT             !|"not"
82 AND             "and"|"&&"|"&"
83 OR              "or"|"||"|"|"
84
85 /* config vars. */
86 DEBUG   debug
87 FORK    fork
88 LOGSTDERROR     log_stderror
89 LISTEN          listen
90 DNS              dns
91 REV_DNS  rev_dns
92 PORT    port
93 STAT    statistics
94 MAXBUFFER maxbuffer
95 CHILDREN children
96 CHECK_VIA       check_via
97 LOOP_CHECKS     loop_checks
98
99 LOADMODULE      loadmodule
100 MODPARAM        modparam
101
102 /* values */
103 YES                     "yes"|"true"|"on"|"enable"
104 NO                      "no"|"false"|"off"|"disable"
105
106 LETTER          [a-zA-Z]
107 DIGIT           [0-9]
108 ALPHANUM        {LETTER}|{DIGIT}|[_]
109 NUMBER          {DIGIT}+
110 ID                      {LETTER}{ALPHANUM}*
111 HEX                     [0-9a-fA-F]
112 HEX4            {HEX}{1,4}
113 IPV6ADDR        ({HEX4}":"){7}{HEX4}|({HEX4}":"){1,7}(":"{HEX4}){1,7}|":"(":"{HEX4}){1,7}|({HEX4}":"){1,7}":"|"::"
114 QUOTES          \"
115 TICK            \'
116 SLASH           "/"
117 SEMICOLON       ;
118 RPAREN          \)
119 LPAREN          \(
120 LBRACE          \{
121 RBRACE          \}
122 LBRACK          \[
123 RBRACK          \]
124 COMMA           ","
125 DOT                     \.
126 CR                      \n
127
128
129
130 COM_LINE        #
131 COM_START       "/\*"
132 COM_END         "\*/"
133
134 EAT_ABLE        [\ \t\b\r]
135
136 %%
137
138
139 <INITIAL>{EAT_ABLE}     { count(); }
140
141 <INITIAL>{FORWARD}      {count(); yylval.strval=yytext; return FORWARD; }
142 <INITIAL>{DROP} { count(); yylval.strval=yytext; return DROP; }
143 <INITIAL>{SEND} { count(); yylval.strval=yytext; return SEND; }
144 <INITIAL>{LOG}  { count(); yylval.strval=yytext; return LOG_TOK; }
145 <INITIAL>{ERROR}        { count(); yylval.strval=yytext; return ERROR; }
146 <INITIAL>{SETFLAG}      { count(); yylval.strval=yytext; return SETFLAG; }
147 <INITIAL>{RESETFLAG}    { count(); yylval.strval=yytext; return RESETFLAG; }
148 <INITIAL>{ISFLAGSET}    { count(); yylval.strval=yytext; return ISFLAGSET; }
149 <INITIAL>{LEN_GT}       { count(); yylval.strval=yytext; return LEN_GT; }
150 <INITIAL>{ROUTE}        { count(); yylval.strval=yytext; return ROUTE; }
151 <INITIAL>{EXEC} { count(); yylval.strval=yytext; return EXEC; }
152 <INITIAL>{SET_HOST}     { count(); yylval.strval=yytext; return SET_HOST; }
153 <INITIAL>{SET_HOSTPORT} { count(); yylval.strval=yytext; return SET_HOSTPORT; }
154 <INITIAL>{SET_USER}     { count(); yylval.strval=yytext; return SET_USER; }
155 <INITIAL>{SET_USERPASS} { count(); yylval.strval=yytext; return SET_USERPASS; }
156 <INITIAL>{SET_PORT}     { count(); yylval.strval=yytext; return SET_PORT; }
157 <INITIAL>{SET_URI}      { count(); yylval.strval=yytext; return SET_URI; }
158 <INITIAL>{PREFIX}       { count(); yylval.strval=yytext; return PREFIX; }
159 <INITIAL>{STRIP}        { count(); yylval.strval=yytext; return STRIP; }
160 <INITIAL>{IF}   { count(); yylval.strval=yytext; return IF; }
161 <INITIAL>{ELSE} { count(); yylval.strval=yytext; return ELSE; }
162
163 <INITIAL>{URIHOST}      { count(); yylval.strval=yytext; return URIHOST; }
164 <INITIAL>{URIPORT}      { count(); yylval.strval=yytext; return URIPORT; }
165
166 <INITIAL>{MAX_LEN}      { count(); yylval.strval=yytext; return MAX_LEN; }
167
168 <INITIAL>{METHOD}       { count(); yylval.strval=yytext; return METHOD; }
169 <INITIAL>{URI}  { count(); yylval.strval=yytext; return URI; }
170 <INITIAL>{SRCIP}        { count(); yylval.strval=yytext; return SRCIP; }
171 <INITIAL>{DSTIP}        { count(); yylval.strval=yytext; return DSTIP; }
172
173 <INITIAL>{DEBUG}        { count(); yylval.strval=yytext; return DEBUG; }
174 <INITIAL>{FORK}         { count(); yylval.strval=yytext; return FORK; }
175 <INITIAL>{LOGSTDERROR}  { yylval.strval=yytext; return LOGSTDERROR; }
176 <INITIAL>{LISTEN}       { count(); yylval.strval=yytext; return LISTEN; }
177 <INITIAL>{DNS}  { count(); yylval.strval=yytext; return DNS; }
178 <INITIAL>{REV_DNS}      { count(); yylval.strval=yytext; return REV_DNS; }
179 <INITIAL>{PORT} { count(); yylval.strval=yytext; return PORT; }
180 <INITIAL>{STAT} { count(); yylval.strval=yytext; return STAT; }
181 <INITIAL>{MAXBUFFER}    { count(); yylval.strval=yytext; return MAXBUFFER; }
182 <INITIAL>{CHILDREN}     { count(); yylval.strval=yytext; return CHILDREN; }
183 <INITIAL>{CHECK_VIA}    { count(); yylval.strval=yytext; return CHECK_VIA; }
184 <INITIAL>{LOOP_CHECKS}  { count(); yylval.strval=yytext; return LOOP_CHECKS; }
185 <INITIAL>{LOADMODULE}   { count(); yylval.strval=yytext; return LOADMODULE; }
186 <INITIAL>{MODPARAM}     { count(); yylval.strval=yytext; return MODPARAM; }
187
188 <INITIAL>{EQUAL}        { count(); return EQUAL; }
189 <INITIAL>{EQUAL_T}      { count(); return EQUAL_T; }
190 <INITIAL>{MATCH}        { count(); return MATCH; }
191 <INITIAL>{NOT}          { count(); return NOT; }
192 <INITIAL>{AND}          { count(); return AND; }
193 <INITIAL>{OR}           { count(); return OR;  }
194
195
196
197 <INITIAL>{IPV6ADDR}             { count(); yylval.strval=yytext; return IPV6ADDR; }
198 <INITIAL>{NUMBER}               { count(); yylval.intval=atoi(yytext);return NUMBER; }
199 <INITIAL>{YES}                  { count(); yylval.intval=1; return NUMBER; }
200 <INITIAL>{NO}                   { count(); yylval.intval=0; return NUMBER; }
201
202 <INITIAL>{COMMA}                { count(); return COMMA; }
203 <INITIAL>{SEMICOLON}    { count(); return SEMICOLON; }
204 <INITIAL>{RPAREN}       { count(); return RPAREN; }
205 <INITIAL>{LPAREN}       { count(); return LPAREN; }
206 <INITIAL>{LBRACE}       { count(); return LBRACE; }
207 <INITIAL>{RBRACE}       { count(); return RBRACE; }
208 <INITIAL>{LBRACK}       { count(); return LBRACK; }
209 <INITIAL>{RBRACK}       { count(); return RBRACK; }
210 <INITIAL>{SLASH}        { count(); return SLASH; }
211 <INITIAL>{DOT}          { count(); return DOT; }
212 <INITIAL>\\{CR}         {count(); } /* eat the escaped CR */
213 <INITIAL>{CR}           { count();/* return CR;*/ }
214
215
216 <INITIAL>{QUOTES} { count(); state=STRING_S; BEGIN(STRING1); }
217 <INITIAL>{TICK} { count(); state=STRING_S; BEGIN(STRING2); }
218
219
220 <STRING1>{QUOTES} { count(); state=INITIAL_S; BEGIN(INITIAL); 
221                                                 yytext[yyleng-1]=0; yyleng--;
222                                                 addstr(yytext, &str);
223                                                 yylval.strval=str; str=0;
224                                                 return STRING;
225                                         }
226 <STRING2>{TICK}  { count(); state=INITIAL_S; BEGIN(INITIAL); 
227                                                 yytext[yyleng-1]=0; yyleng--;
228                                                 addstr(yytext, &str);
229                                                 yylval.strval=str;
230                                                 str=0;
231                                                 return STRING;
232                                         }
233 <STRING2>.|{EAT_ABLE}|{CR}      { yymore(); }
234
235 <STRING1>\\n            { count(); yytext[yyleng-2]='\n';yytext[yyleng-1]=0; 
236                                                 yyleng--; addstr(yytext, &str); }
237 <STRING1>\\r            { count(); yytext[yyleng-2]='\r';yytext[yyleng-1]=0; 
238                                                 yyleng--; addstr(yytext, &str); }
239 <STRING1>\\a            { count(); yytext[yyleng-2]='\a';yytext[yyleng-1]=0; 
240                                                 yyleng--; addstr(yytext, &str); }
241 <STRING1>\\t            { count(); yytext[yyleng-2]='\t';yytext[yyleng-1]=0; 
242                                                 yyleng--; addstr(yytext, &str); }
243 <STRING1>\\\\           { count(); yytext[yyleng-2]='\\';yytext[yyleng-1]=0; 
244                                                 yyleng--; addstr(yytext, &str); } 
245 <STRING1>.|{EAT_ABLE}|{CR}      { yymore(); }
246
247
248 <INITIAL,COMMENT>{COM_START}    { count(); comment_nest++; state=COMMENT_S;
249                                                                                 BEGIN(COMMENT); }
250 <COMMENT>{COM_END}                              { count(); comment_nest--;
251                                                                                 if (comment_nest==0){
252                                                                                         state=INITIAL_S;
253                                                                                         BEGIN(INITIAL);
254                                                                                 }
255                                                                 }
256 <COMMENT>.|{EAT_ABLE}|{CR}                              { count(); };
257
258 <INITIAL>{COM_LINE}.*{CR}       { count(); } 
259
260 <INITIAL>{ID}                   { count(); addstr(yytext, &str);
261                                                   yylval.strval=str; str=0; return ID; }
262
263
264 <<EOF>>                                                 {
265                                                                         switch(state){
266                                                                                 case STRING_S: 
267                                                                                         LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF in"
268                                                                                                                 " unclosed string\n");
269                                                                                         if (str) {free(str); str=0;}
270                                                                                         break;
271                                                                                 case COMMENT_S:
272                                                                                         LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF:"
273                                                                                                                 " %d comments open\n", comment_nest);
274                                                                                         break;
275                                                                                 case COMMENT_LN_S:
276                                                                                         LOG(L_CRIT, "ERROR: unexpected EOF:"
277                                                                                                                 "comment line open\n");
278                                                                                         break;
279                                                                         }
280                                                                         return 0;
281                                                                 }
282                         
283 %%
284
285 static char* addstr(char * src, char ** dest)
286 {
287         char *tmp;
288         unsigned len1, len2;
289         
290         if (*dest==0){
291                 *dest=strdup(src);
292         }else{
293                 len1=strlen(*dest);
294                 len2=strlen(src);
295                 tmp=malloc(len1+len2+1);
296                 if (tmp==0) goto error;
297                 memcpy(tmp, *dest, len1);
298                 memcpy(tmp+len1, src, len2);
299                 tmp[len1+len2]=0;
300                 free(*dest);
301                 *dest=tmp;
302         }
303         return *dest;
304 error:
305         LOG(L_CRIT, "ERROR:lex:addstr: memory allocation error\n");
306         return 0;
307 }
308
309
310
311 static void count()
312 {
313         int i;
314         
315         startcolumn=column;
316         for (i=0; i<yyleng;i++){
317                 if (yytext[i]=='\n'){
318                         line++;
319                         column=startcolumn=1;
320                 }else if (yytext[i]=='\t'){
321                         column++;
322                         /*column+=8 -(column%8);*/
323                 }else{
324                         column++;
325                 }
326         }
327 }
328
329