b105854401264394f2e437ed3ff752b2d18e3ef1
[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* tstr=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 FORWARD_TCP     forward_tcp
45 DROP    "drop"|"break"
46 SEND    send
47 SEND_TCP        send_tcp
48 LOG             log
49 ERROR   error
50 ROUTE   route
51 REPLY_ROUTE reply_route
52 EXEC    exec
53 SETFLAG         setflag
54 RESETFLAG       resetflag
55 ISFLAGSET       isflagset
56 LEN_GT          len_gt
57 SET_HOST                "rewritehost"|"sethost"|"seth"
58 SET_HOSTPORT    "rewritehostport"|"sethostport"|"sethp"
59 SET_USER                "rewriteuser"|"setuser"|"setu"
60 SET_USERPASS    "rewriteuserpass"|"setuserpass"|"setup"
61 SET_PORT                "rewriteport"|"setport"|"setp"
62 SET_URI                 "rewriteuri"|"seturi"
63 REVERT_URI              "revert_uri"
64 PREFIX                  "prefix"
65 STRIP                   "strip"
66 APPEND_BRANCH   "append_branch"
67 IF                              "if"
68 ELSE                    "else"
69
70 /*ACTION LVALUES*/
71 URIHOST                 "uri:host"
72 URIPORT                 "uri:port"
73
74 MAX_LEN                 "max_len"
75
76
77 /* condition keywords */
78 METHOD  method
79 URI             uri
80 SRCIP   src_ip
81 DSTIP   dst_ip
82 MYSELF  myself
83 /* operators */
84 EQUAL   =
85 EQUAL_T ==
86 MATCH   =~
87 NOT             !|"not"
88 AND             "and"|"&&"|"&"
89 OR              "or"|"||"|"|"
90
91 /* config vars. */
92 DEBUG   debug
93 FORK    fork
94 LOGSTDERROR     log_stderror
95 LISTEN          listen
96 ALIAS           alias
97 DNS              dns
98 REV_DNS  rev_dns
99 PORT    port
100 STAT    statistics
101 MAXBUFFER maxbuffer
102 CHILDREN children
103 CHECK_VIA       check_via
104 SYN_BRANCH syn_branch
105 MEMLOG  memlog
106 SIP_WARNING sip_warning
107 FIFO fifo
108 FIFO_MODE fifo_mode
109 SERVER_SIGNATURE server_signature
110 REPLY_TO_VIA reply_to_via
111 USER            "user"|"uid"
112 GROUP           "group"|"gid"
113
114 LOADMODULE      loadmodule
115 MODPARAM        modparam
116
117 /* values */
118 YES                     "yes"|"true"|"on"|"enable"
119 NO                      "no"|"false"|"off"|"disable"
120
121 LETTER          [a-zA-Z]
122 DIGIT           [0-9]
123 ALPHANUM        {LETTER}|{DIGIT}|[_]
124 NUMBER          {DIGIT}+
125 ID                      {LETTER}{ALPHANUM}*
126 HEX                     [0-9a-fA-F]
127 HEX4            {HEX}{1,4}
128 IPV6ADDR        ({HEX4}":"){7}{HEX4}|({HEX4}":"){1,7}(":"{HEX4}){1,7}|":"(":"{HEX4}){1,7}|({HEX4}":"){1,7}":"|"::"
129 QUOTES          \"
130 TICK            \'
131 SLASH           "/"
132 SEMICOLON       ;
133 RPAREN          \)
134 LPAREN          \(
135 LBRACE          \{
136 RBRACE          \}
137 LBRACK          \[
138 RBRACK          \]
139 COMMA           ","
140 DOT                     \.
141 CR                      \n
142
143
144
145 COM_LINE        #
146 COM_START       "/\*"
147 COM_END         "\*/"
148
149 EAT_ABLE        [\ \t\b\r]
150
151 %%
152
153
154 <INITIAL>{EAT_ABLE}     { count(); }
155
156 <INITIAL>{FORWARD}      {count(); yylval.strval=yytext; return FORWARD; }
157 <INITIAL>{FORWARD_TCP}  {count(); yylval.strval=yytext; return FORWARD_TCP; }
158 <INITIAL>{DROP} { count(); yylval.strval=yytext; return DROP; }
159 <INITIAL>{SEND} { count(); yylval.strval=yytext; return SEND; }
160 <INITIAL>{SEND_TCP}     { count(); yylval.strval=yytext; return SEND_TCP; }
161 <INITIAL>{LOG}  { count(); yylval.strval=yytext; return LOG_TOK; }
162 <INITIAL>{ERROR}        { count(); yylval.strval=yytext; return ERROR; }
163 <INITIAL>{SETFLAG}      { count(); yylval.strval=yytext; return SETFLAG; }
164 <INITIAL>{RESETFLAG}    { count(); yylval.strval=yytext; return RESETFLAG; }
165 <INITIAL>{ISFLAGSET}    { count(); yylval.strval=yytext; return ISFLAGSET; }
166 <INITIAL>{LEN_GT}       { count(); yylval.strval=yytext; return LEN_GT; }
167 <INITIAL>{ROUTE}        { count(); yylval.strval=yytext; return ROUTE; }
168 <INITIAL>{REPLY_ROUTE}  { count(); yylval.strval=yytext; return REPLY_ROUTE; }
169 <INITIAL>{EXEC} { count(); yylval.strval=yytext; return EXEC; }
170 <INITIAL>{SET_HOST}     { count(); yylval.strval=yytext; return SET_HOST; }
171 <INITIAL>{SET_HOSTPORT} { count(); yylval.strval=yytext; return SET_HOSTPORT; }
172 <INITIAL>{SET_USER}     { count(); yylval.strval=yytext; return SET_USER; }
173 <INITIAL>{SET_USERPASS} { count(); yylval.strval=yytext; return SET_USERPASS; }
174 <INITIAL>{SET_PORT}     { count(); yylval.strval=yytext; return SET_PORT; }
175 <INITIAL>{SET_URI}      { count(); yylval.strval=yytext; return SET_URI; }
176 <INITIAL>{REVERT_URI}   { count(); yylval.strval=yytext; return REVERT_URI; }
177 <INITIAL>{PREFIX}       { count(); yylval.strval=yytext; return PREFIX; }
178 <INITIAL>{STRIP}        { count(); yylval.strval=yytext; return STRIP; }
179 <INITIAL>{APPEND_BRANCH}        { count(); yylval.strval=yytext; return APPEND_BRANCH; }
180 <INITIAL>{IF}   { count(); yylval.strval=yytext; return IF; }
181 <INITIAL>{ELSE} { count(); yylval.strval=yytext; return ELSE; }
182
183 <INITIAL>{URIHOST}      { count(); yylval.strval=yytext; return URIHOST; }
184 <INITIAL>{URIPORT}      { count(); yylval.strval=yytext; return URIPORT; }
185
186 <INITIAL>{MAX_LEN}      { count(); yylval.strval=yytext; return MAX_LEN; }
187
188 <INITIAL>{METHOD}       { count(); yylval.strval=yytext; return METHOD; }
189 <INITIAL>{URI}  { count(); yylval.strval=yytext; return URI; }
190 <INITIAL>{SRCIP}        { count(); yylval.strval=yytext; return SRCIP; }
191 <INITIAL>{DSTIP}        { count(); yylval.strval=yytext; return DSTIP; }
192 <INITIAL>{MYSELF}       { count(); yylval.strval=yytext; return MYSELF; }
193
194 <INITIAL>{DEBUG}        { count(); yylval.strval=yytext; return DEBUG; }
195 <INITIAL>{FORK}         { count(); yylval.strval=yytext; return FORK; }
196 <INITIAL>{LOGSTDERROR}  { yylval.strval=yytext; return LOGSTDERROR; }
197 <INITIAL>{LISTEN}       { count(); yylval.strval=yytext; return LISTEN; }
198 <INITIAL>{ALIAS}        { count(); yylval.strval=yytext; return ALIAS; }
199 <INITIAL>{DNS}  { count(); yylval.strval=yytext; return DNS; }
200 <INITIAL>{REV_DNS}      { count(); yylval.strval=yytext; return REV_DNS; }
201 <INITIAL>{PORT} { count(); yylval.strval=yytext; return PORT; }
202 <INITIAL>{STAT} { count(); yylval.strval=yytext; return STAT; }
203 <INITIAL>{MAXBUFFER}    { count(); yylval.strval=yytext; return MAXBUFFER; }
204 <INITIAL>{CHILDREN}     { count(); yylval.strval=yytext; return CHILDREN; }
205 <INITIAL>{CHECK_VIA}    { count(); yylval.strval=yytext; return CHECK_VIA; }
206 <INITIAL>{SYN_BRANCH}   { count(); yylval.strval=yytext; return SYN_BRANCH; }
207 <INITIAL>{MEMLOG}       { count(); yylval.strval=yytext; return MEMLOG; }
208 <INITIAL>{SIP_WARNING}  { count(); yylval.strval=yytext; return SIP_WARNING; }
209 <INITIAL>{USER}         { count(); yylval.strval=yytext; return USER; }
210 <INITIAL>{GROUP}        { count(); yylval.strval=yytext; return GROUP; }
211 <INITIAL>{FIFO} { count(); yylval.strval=yytext; return FIFO; }
212 <INITIAL>{FIFO_MODE}    { count(); yylval.strval=yytext; return FIFO_MODE; }
213 <INITIAL>{SERVER_SIGNATURE}     { count(); yylval.strval=yytext; return SERVER_SIGNATURE; }
214 <INITIAL>{REPLY_TO_VIA} { count(); yylval.strval=yytext; return REPLY_TO_VIA; }
215 <INITIAL>{LOADMODULE}   { count(); yylval.strval=yytext; return LOADMODULE; }
216 <INITIAL>{MODPARAM}     { count(); yylval.strval=yytext; return MODPARAM; }
217
218 <INITIAL>{EQUAL}        { count(); return EQUAL; }
219 <INITIAL>{EQUAL_T}      { count(); return EQUAL_T; }
220 <INITIAL>{MATCH}        { count(); return MATCH; }
221 <INITIAL>{NOT}          { count(); return NOT; }
222 <INITIAL>{AND}          { count(); return AND; }
223 <INITIAL>{OR}           { count(); return OR;  }
224
225
226
227 <INITIAL>{IPV6ADDR}             { count(); yylval.strval=yytext; return IPV6ADDR; }
228 <INITIAL>{NUMBER}               { count(); yylval.intval=atoi(yytext);return NUMBER; }
229 <INITIAL>{YES}                  { count(); yylval.intval=1; return NUMBER; }
230 <INITIAL>{NO}                   { count(); yylval.intval=0; return NUMBER; }
231
232 <INITIAL>{COMMA}                { count(); return COMMA; }
233 <INITIAL>{SEMICOLON}    { count(); return SEMICOLON; }
234 <INITIAL>{RPAREN}       { count(); return RPAREN; }
235 <INITIAL>{LPAREN}       { count(); return LPAREN; }
236 <INITIAL>{LBRACE}       { count(); return LBRACE; }
237 <INITIAL>{RBRACE}       { count(); return RBRACE; }
238 <INITIAL>{LBRACK}       { count(); return LBRACK; }
239 <INITIAL>{RBRACK}       { count(); return RBRACK; }
240 <INITIAL>{SLASH}        { count(); return SLASH; }
241 <INITIAL>{DOT}          { count(); return DOT; }
242 <INITIAL>\\{CR}         {count(); } /* eat the escaped CR */
243 <INITIAL>{CR}           { count();/* return CR;*/ }
244
245
246 <INITIAL>{QUOTES} { count(); state=STRING_S; BEGIN(STRING1); }
247 <INITIAL>{TICK} { count(); state=STRING_S; BEGIN(STRING2); }
248
249
250 <STRING1>{QUOTES} { count(); state=INITIAL_S; BEGIN(INITIAL); 
251                                                 yytext[yyleng-1]=0; yyleng--;
252                                                 addstr(yytext, &tstr);
253                                                 yylval.strval=tstr; tstr=0;
254                                                 return STRING;
255                                         }
256 <STRING2>{TICK}  { count(); state=INITIAL_S; BEGIN(INITIAL); 
257                                                 yytext[yyleng-1]=0; yyleng--;
258                                                 addstr(yytext, &tstr);
259                                                 yylval.strval=tstr;
260                                                 tstr=0;
261                                                 return STRING;
262                                         }
263 <STRING2>.|{EAT_ABLE}|{CR}      { yymore(); }
264
265 <STRING1>\\n            { count(); yytext[yyleng-2]='\n';yytext[yyleng-1]=0; 
266                                                 yyleng--; addstr(yytext, &tstr); }
267 <STRING1>\\r            { count(); yytext[yyleng-2]='\r';yytext[yyleng-1]=0; 
268                                                 yyleng--; addstr(yytext, &tstr); }
269 <STRING1>\\a            { count(); yytext[yyleng-2]='\a';yytext[yyleng-1]=0; 
270                                                 yyleng--; addstr(yytext, &tstr); }
271 <STRING1>\\t            { count(); yytext[yyleng-2]='\t';yytext[yyleng-1]=0; 
272                                                 yyleng--; addstr(yytext, &tstr); }
273 <STRING1>\\\\           { count(); yytext[yyleng-2]='\\';yytext[yyleng-1]=0; 
274                                                 yyleng--; addstr(yytext, &tstr); } 
275 <STRING1>.|{EAT_ABLE}|{CR}      { yymore(); }
276
277
278 <INITIAL,COMMENT>{COM_START}    { count(); comment_nest++; state=COMMENT_S;
279                                                                                 BEGIN(COMMENT); }
280 <COMMENT>{COM_END}                              { count(); comment_nest--;
281                                                                                 if (comment_nest==0){
282                                                                                         state=INITIAL_S;
283                                                                                         BEGIN(INITIAL);
284                                                                                 }
285                                                                 }
286 <COMMENT>.|{EAT_ABLE}|{CR}                              { count(); };
287
288 <INITIAL>{COM_LINE}.*{CR}       { count(); } 
289
290 <INITIAL>{ID}                   { count(); addstr(yytext, &tstr);
291                                                   yylval.strval=tstr; tstr=0; return ID; }
292
293
294 <<EOF>>                                                 {
295                                                                         switch(state){
296                                                                                 case STRING_S: 
297                                                                                         LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF in"
298                                                                                                                 " unclosed string\n");
299                                                                                         if (tstr) {free(tstr); tstr=0;}
300                                                                                         break;
301                                                                                 case COMMENT_S:
302                                                                                         LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF:"
303                                                                                                                 " %d comments open\n", comment_nest);
304                                                                                         break;
305                                                                                 case COMMENT_LN_S:
306                                                                                         LOG(L_CRIT, "ERROR: unexpected EOF:"
307                                                                                                                 "comment line open\n");
308                                                                                         break;
309                                                                         }
310                                                                         return 0;
311                                                                 }
312                         
313 %%
314
315 static char* addstr(char * src, char ** dest)
316 {
317         char *tmp;
318         unsigned len1, len2;
319         
320         if (*dest==0){
321                 *dest=strdup(src);
322         }else{
323                 len1=strlen(*dest);
324                 len2=strlen(src);
325                 tmp=malloc(len1+len2+1);
326                 if (tmp==0) goto error;
327                 memcpy(tmp, *dest, len1);
328                 memcpy(tmp+len1, src, len2);
329                 tmp[len1+len2]=0;
330                 free(*dest);
331                 *dest=tmp;
332         }
333         return *dest;
334 error:
335         LOG(L_CRIT, "ERROR:lex:addstr: memory allocation error\n");
336         return 0;
337 }
338
339
340
341 static void count()
342 {
343         int i;
344         
345         startcolumn=column;
346         for (i=0; i<yyleng;i++){
347                 if (yytext[i]=='\n'){
348                         line++;
349                         column=startcolumn=1;
350                 }else if (yytext[i]=='\t'){
351                         column++;
352                         /*column+=8 -(column%8);*/
353                 }else{
354                         column++;
355                 }
356         }
357 }
358
359