60153938e9b580fcc006dce3eef876d595270e78
[sip-router] / cfg.y
1 /*
2  * $Id$
3  *
4  *  cfg grammar
5  *
6  * Copyright (C) 2001-2003 Fhg Fokus
7  *
8  * This file is part of ser, a free SIP server.
9  *
10  * ser is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version
14  *
15  * For a license to use the ser software under conditions
16  * other than those described here, or to purchase support for this
17  * software, please contact iptel.org by e-mail at the following addresses:
18  *    info@iptel.org
19  *
20  * ser is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License 
26  * along with this program; if not, write to the Free Software 
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  */
29  /*
30  * History:
31  * ---------
32  * 2003-01-29  src_port added (jiri)
33  * 2003-01-23  mhomed added (jiri)
34  * 2003-03-19  replaced all mallocs/frees with pkg_malloc/pkg_free (andrei)
35  * 2003-03-19  Added support for route type in find_export (janakj)
36  * 2003-03-20  Regex support in modparam (janakj)
37  * 2003-04-01  added dst_port, proto , af (andrei)
38  * 2003-04-05  s/reply_route/failure_route, onreply_route introduced (jiri)
39  * 2003-04-12  added force_rport, chroot and wdir (andrei)
40  * 2003-04-15  added tcp_children, disable_tcp (andrei)
41  */
42
43
44 %{
45
46 #include <stdlib.h>
47 #include <stdio.h>
48 #include <sys/types.h>
49 #include <sys/socket.h>
50 #include <netinet/in.h>
51 #include <arpa/inet.h>
52 #include <string.h>
53 #include <errno.h>
54 #include "route_struct.h"
55 #include "globals.h"
56 #include "route.h"
57 #include "dprint.h"
58 #include "sr_module.h"
59 #include "modparam.h"
60 #include "ip_addr.h"
61 #include "name_alias.h"
62
63 #include "config.h"
64
65 #ifdef DEBUG_DMALLOC
66 #include <dmalloc.h>
67 #endif
68
69 /* hack to avoid alloca usage in the generated C file (needed for compiler
70  with no built in alloca, like icc*/
71 #undef _ALLOCA_H
72
73 struct id_list{
74         char* s;
75         struct id_list* next;
76 };
77
78 extern int yylex();
79 void yyerror(char* s);
80 char* tmp;
81 void* f_tmp;
82 struct id_list* lst_tmp;
83 int rt;  /* Type of route block for find_export */
84  
85
86 %}
87
88 %union {
89         long intval;
90         unsigned long uval;
91         char* strval;
92         struct expr* expr;
93         struct action* action;
94         struct net* ipnet;
95         struct ip_addr* ipaddr;
96         struct id_list* idlst;
97 }
98
99 /* terminals */
100
101
102 /* keywords */
103 %token FORWARD
104 %token FORWARD_TCP
105 %token FORWARD_UDP
106 %token SEND
107 %token SEND_TCP
108 %token DROP
109 %token LOG_TOK
110 %token ERROR
111 %token ROUTE
112 %token ROUTE_FAILURE
113 %token ROUTE_ONREPLY
114 %token EXEC
115 %token SET_HOST
116 %token SET_HOSTPORT
117 %token PREFIX
118 %token STRIP
119 %token APPEND_BRANCH
120 %token SET_USER
121 %token SET_USERPASS
122 %token SET_PORT
123 %token SET_URI
124 %token REVERT_URI
125 %token FORCE_RPORT
126 %token IF
127 %token ELSE
128 %token URIHOST
129 %token URIPORT
130 %token MAX_LEN
131 %token SETFLAG
132 %token RESETFLAG
133 %token ISFLAGSET
134 %token LEN_GT
135 %token METHOD
136 %token URI
137 %token SRCIP
138 %token SRCPORT
139 %token DSTIP
140 %token DSTPORT
141 %token PROTO
142 %token AF
143 %token MYSELF
144
145 /* config vars. */
146 %token DEBUG
147 %token FORK
148 %token LOGSTDERROR
149 %token LISTEN
150 %token ALIAS
151 %token DNS
152 %token REV_DNS
153 %token PORT
154 %token STAT
155 %token CHILDREN
156 %token CHECK_VIA
157 %token SYN_BRANCH
158 %token MEMLOG
159 %token SIP_WARNING
160 %token FIFO
161 %token FIFO_MODE
162 %token SERVER_SIGNATURE
163 %token REPLY_TO_VIA
164 %token LOADMODULE
165 %token MODPARAM
166 %token MAXBUFFER
167 %token USER
168 %token GROUP
169 %token CHROOT
170 %token WDIR
171 %token MHOMED
172 %token DISABLE_TCP
173 %token TCP_CHILDREN
174
175
176
177
178 /* operators */
179 %nonassoc EQUAL
180 %nonassoc EQUAL_T
181 %nonassoc MATCH
182 %left OR
183 %left AND
184 %left NOT
185
186 /* values */
187 %token <intval> NUMBER
188 %token <strval> ID
189 %token <strval> STRING
190 %token <strval> IPV6ADDR
191
192 /* other */
193 %token COMMA
194 %token SEMICOLON
195 %token RPAREN
196 %token LPAREN
197 %token LBRACE
198 %token RBRACE
199 %token LBRACK
200 %token RBRACK
201 %token SLASH
202 %token DOT
203 %token CR
204
205
206 /*non-terminals */
207 %type <expr> exp exp_elem /*, condition*/
208 %type <action> action actions cmd if_cmd stm
209 %type <ipaddr> ipv4 ipv6 ip
210 %type <ipnet> ipnet
211 %type <strval> host
212 %type <strval> listen_id
213 %type <idlst>  id_lst
214 /*%type <route_el> rules;
215   %type <route_el> rule;
216 */
217
218
219
220 %%
221
222
223 cfg:    statements
224         ;
225
226 statements:     statements statement {}
227                 | statement {}
228                 | statements error { yyerror(""); YYABORT;}
229         ;
230
231 statement:      assign_stm 
232                 | module_stm
233                 | {rt=REQUEST_ROUTE;} route_stm 
234                 | {rt=FAILURE_ROUTE;} failure_route_stm
235                 | {rt=ONREPLY_ROUTE;} onreply_route_stm
236
237                 | CR    /* null statement*/
238         ;
239
240 listen_id:      ip                      {       tmp=ip_addr2a($1);
241                                                         if(tmp==0){
242                                                                 LOG(L_CRIT, "ERROR: cfg. parser: bad ip "
243                                                                                 "addresss.\n");
244                                                                 $$=0;
245                                                         }else{
246                                                                 $$=pkg_malloc(strlen(tmp)+1);
247                                                                 if ($$==0){
248                                                                         LOG(L_CRIT, "ERROR: cfg. parser: out of "
249                                                                                         "memory.\n");
250                                                                 }else{
251                                                                         strncpy($$, tmp, strlen(tmp)+1);
252                                                                 }
253                                                         }
254                                                 }
255                  |      ID                      {       $$=pkg_malloc(strlen($1)+1);
256                                                         if ($$==0){
257                                                                         LOG(L_CRIT, "ERROR: cfg. parser: out of "
258                                                                                         "memory.\n");
259                                                         }else{
260                                                                         strncpy($$, $1, strlen($1)+1);
261                                                         }
262                                                 }
263                  |      STRING                  {       $$=pkg_malloc(strlen($1)+1);
264                                                         if ($$==0){
265                                                                         LOG(L_CRIT, "ERROR: cfg. parser: out of "
266                                                                                         "memory.\n");
267                                                         }else{
268                                                                         strncpy($$, $1, strlen($1)+1);
269                                                         }
270                                                 }
271                  |      host            {       $$=pkg_malloc(strlen($1)+1);
272                                                         if ($$==0){
273                                                                         LOG(L_CRIT, "ERROR: cfg. parser: out of "
274                                                                                         "memory.\n");
275                                                         }else{
276                                                                         strncpy($$, $1, strlen($1)+1);
277                                                         }
278                                                 }
279         ;
280
281 id_lst:   listen_id     {       $$=pkg_malloc(sizeof(struct id_list));
282                                                 if ($$==0){
283                                                         LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
284                                                 }else{
285                                                         $$->s=$1;
286                                                         $$->next=0;
287                                                 }
288                                         }
289                 | listen_id id_lst      {
290                                                 $$=pkg_malloc(sizeof(struct id_list));
291                                                 if ($$==0){
292                                                         LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
293                                                 }else{
294                                                         $$->s=$1;
295                                                         $$->next=$2;
296                                                 }
297                                                         }
298                 ;
299
300
301 assign_stm:     DEBUG EQUAL NUMBER { debug=$3; }
302                 | DEBUG EQUAL error  { yyerror("number  expected"); }
303                 | FORK  EQUAL NUMBER { dont_fork= ! $3; }
304                 | FORK  EQUAL error  { yyerror("boolean value expected"); }
305                 | LOGSTDERROR EQUAL NUMBER { log_stderr=$3; }
306                 | LOGSTDERROR EQUAL error { yyerror("boolean value expected"); }
307                 | DNS EQUAL NUMBER   { received_dns|= ($3)?DO_DNS:0; }
308                 | DNS EQUAL error { yyerror("boolean value expected"); }
309                 | REV_DNS EQUAL NUMBER { received_dns|= ($3)?DO_REV_DNS:0; }
310                 | REV_DNS EQUAL error { yyerror("boolean value expected"); }
311                 | PORT EQUAL NUMBER   { port_no=$3; 
312                                                                 if (sock_no>0) 
313                                                                         sock_info[sock_no-1].port_no=port_no;
314                                                           }
315                 | STAT EQUAL STRING {
316                                         #ifdef STATS
317                                                         stat_file=$3;
318                                         #endif
319                                                         }
320                 | MAXBUFFER EQUAL NUMBER { maxbuffer=$3; }
321                 | MAXBUFFER EQUAL error { yyerror("number expected"); }
322                 | PORT EQUAL error    { yyerror("number expected"); } 
323                 | CHILDREN EQUAL NUMBER { children_no=$3; }
324                 | CHILDREN EQUAL error { yyerror("number expected"); } 
325                 | CHECK_VIA EQUAL NUMBER { check_via=$3; }
326                 | CHECK_VIA EQUAL error { yyerror("boolean value expected"); }
327                 | SYN_BRANCH EQUAL NUMBER { syn_branch=$3; }
328                 | SYN_BRANCH EQUAL error { yyerror("boolean value expected"); }
329                 | MEMLOG EQUAL NUMBER { memlog=$3; }
330                 | MEMLOG EQUAL error { yyerror("int value expected"); }
331                 | SIP_WARNING EQUAL NUMBER { sip_warning=$3; }
332                 | SIP_WARNING EQUAL error { yyerror("boolean value expected"); }
333                 | FIFO EQUAL STRING { fifo=$3; }
334                 | FIFO EQUAL error { yyerror("string value expected"); }
335                 | FIFO_MODE EQUAL NUMBER { fifo_mode=$3; }
336                 | FIFO_MODE EQUAL error { yyerror("int value expected"); }
337                 | USER EQUAL STRING     { user=$3; }
338                 | USER EQUAL ID         { user=$3; }
339                 | USER EQUAL error      { yyerror("string value expected"); }
340                 | GROUP EQUAL STRING     { group=$3; }
341                 | GROUP EQUAL ID         { group=$3; }
342                 | GROUP EQUAL error      { yyerror("string value expected"); }
343                 | CHROOT EQUAL STRING     { chroot_dir=$3; }
344                 | CHROOT EQUAL ID         { chroot_dir=$3; }
345                 | CHROOT EQUAL error      { yyerror("string value expected"); }
346                 | WDIR EQUAL STRING     { working_dir=$3; }
347                 | WDIR EQUAL ID         { working_dir=$3; }
348                 | WDIR EQUAL error      { yyerror("string value expected"); }
349                 | MHOMED EQUAL NUMBER { mhomed=$3; }
350                 | MHOMED EQUAL error { yyerror("boolean value expected"); }
351                 | DISABLE_TCP EQUAL NUMBER {
352                                                                         #ifdef USE_TCP
353                                                                                 tcp_disable=$3;
354                                                                         #else
355                                                                                 fprintf(stderr, "WARNING: tcp support"
356                                                                                                 "not compiled in\n");
357                                                                         #endif
358                                                                         }
359                 | DISABLE_TCP EQUAL error { yyerror("boolean value expected"); }
360                 | TCP_CHILDREN EQUAL NUMBER {
361                                                                         #ifdef USE_TCP
362                                                                                 tcp_children_no=$3;
363                                                                         #else
364                                                                                 fprintf(stderr, "WARNING: tcp support"
365                                                                                                 "not compiled in\n");
366                                                                         #endif
367                                                                         }
368                 | TCP_CHILDREN EQUAL error { yyerror("number expected"); }
369                 | SERVER_SIGNATURE EQUAL NUMBER { server_signature=$3; }
370                 | SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); }
371                 | REPLY_TO_VIA EQUAL NUMBER { reply_to_via=$3; }
372                 | REPLY_TO_VIA EQUAL error { yyerror("boolean value expected"); }
373                 | LISTEN EQUAL id_lst {
374                                                         for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next){
375                                                                 if (sock_no < MAX_LISTEN){
376                                                                         sock_info[sock_no].name.s=(char*)
377                                                                                         pkg_malloc(strlen(lst_tmp->s)+1);
378                                                                         if (sock_info[sock_no].name.s==0){
379                                                                                 LOG(L_CRIT, "ERROR: cfg. parser:"
380                                                                                                         " out of memory.\n");
381                                                                                 break;
382                                                                         }else{
383                                                                                 strncpy(sock_info[sock_no].name.s,
384                                                                                                 lst_tmp->s,
385                                                                                                 strlen(lst_tmp->s)+1);
386                                                                                 sock_info[sock_no].name.len=
387                                                                                                         strlen(lst_tmp->s);
388                                                                                 sock_info[sock_no].port_no=port_no;
389                                                                                 sock_no++;
390                                                                         }
391                                                                 }else{
392                                                                         LOG(L_CRIT, "ERROR: cfg. parser: "
393                                                                                                 "too many listen addresses"
394                                                                                                 "(max. %d).\n", MAX_LISTEN);
395                                                                         break;
396                                                                 }
397                                                         }
398                                                          }
399                 | LISTEN EQUAL  error { yyerror("ip address or hostname"
400                                                 "expected"); }
401                 | ALIAS EQUAL  id_lst { 
402                                                         for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next)
403                                                                 add_alias(lst_tmp->s, strlen(lst_tmp->s), 0);
404                                                           }
405                 | ALIAS  EQUAL error  { yyerror(" hostname expected"); }
406                 | error EQUAL { yyerror("unknown config variable"); }
407         ;
408
409 module_stm:     LOADMODULE STRING       { DBG("loading module %s\n", $2);
410                                                                   if (load_module($2)!=0){
411                                                                                 yyerror("failed to load module");
412                                                                   }
413                                                                 }
414                  | LOADMODULE error     { yyerror("string expected");  }
415                  | MODPARAM LPAREN STRING COMMA STRING COMMA STRING RPAREN {
416                          if (set_mod_param_regex($3, $5, STR_PARAM, $7) != 0) {
417                                  yyerror("Can't set module parameter");
418                          }
419                    }
420                  | MODPARAM LPAREN STRING COMMA STRING COMMA NUMBER RPAREN {
421                          if (set_mod_param_regex($3, $5, INT_PARAM, (void*)$7) != 0) {
422                                  yyerror("Can't set module parameter");
423                          }
424                    }
425                  | MODPARAM error { yyerror("Invalid arguments"); }
426                  ;
427
428
429 ip:              ipv4  { $$=$1; }
430                 |ipv6  { $$=$1; }
431                 ;
432
433 ipv4:   NUMBER DOT NUMBER DOT NUMBER DOT NUMBER { 
434                                                                                         $$=pkg_malloc(
435                                                                                                         sizeof(struct ip_addr));
436                                                                                         if ($$==0){
437                                                                                                 LOG(L_CRIT, "ERROR: cfg. "
438                                                                                                         "parser: out of memory.\n"
439                                                                                                         );
440                                                                                         }else{
441                                                                                                 memset($$, 0, 
442                                                                                                         sizeof(struct ip_addr));
443                                                                                                 $$->af=AF_INET;
444                                                                                                 $$->len=4;
445                                                                                                 if (($1>255) || ($1<0) ||
446                                                                                                         ($3>255) || ($3<0) ||
447                                                                                                         ($5>255) || ($5<0) ||
448                                                                                                         ($7>255) || ($7<0)){
449                                                                                                         yyerror("invalid ipv4"
450                                                                                                                         "address");
451                                                                                                         $$->u.addr32[0]=0;
452                                                                                                         /* $$=0; */
453                                                                                                 }else{
454                                                                                                         $$->u.addr[0]=$1;
455                                                                                                         $$->u.addr[1]=$3;
456                                                                                                         $$->u.addr[2]=$5;
457                                                                                                         $$->u.addr[3]=$7;
458                                                                                                         /*
459                                                                                                         $$=htonl( ($1<<24)|
460                                                                                                         ($3<<16)| ($5<<8)|$7 );
461                                                                                                         */
462                                                                                                 }
463                                                                                         }
464                                                                                                 }
465         ;
466
467 ipv6:   IPV6ADDR {
468                                         $$=pkg_malloc(sizeof(struct ip_addr));
469                                         if ($$==0){
470                                                 LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
471                                         }else{
472                                                 memset($$, 0, sizeof(struct ip_addr));
473                                                 $$->af=AF_INET6;
474                                                 $$->len=16;
475                                         #ifdef USE_IPV6
476                                                 if (inet_pton(AF_INET6, $1, $$->u.addr)<=0){
477                                                         yyerror("bad ipv6 address");
478                                                 }
479                                         #else
480                                                 yyerror("ipv6 address & no ipv6 support compiled in");
481                                                 YYABORT;
482                                         #endif
483                                         }
484                                 }
485         ;
486
487
488 route_stm:  ROUTE LBRACE actions RBRACE { push($3, &rlist[DEFAULT_RT]); }
489
490             | ROUTE LBRACK NUMBER RBRACK LBRACE actions RBRACE { 
491                                                                                 if (($3<RT_NO) && ($3>=0)){
492                                                                                         push($6, &rlist[$3]);
493                                                                                 }else{
494                                                                                         yyerror("invalid routing"
495                                                                                                         "table number");
496                                                                                         YYABORT; }
497                                                                                 }
498                 | ROUTE error { yyerror("invalid  route  statement"); }
499         ;
500
501 failure_route_stm: ROUTE_FAILURE LBRACK NUMBER RBRACK LBRACE actions RBRACE {
502                                                                                 if (($3<FAILURE_RT_NO)&&($3>=1)){
503                                                                                         push($6, &failure_rlist[$3]);
504                                                                                 } else {
505                                                                                         yyerror("invalid reply routing"
506                                                                                                 "table number");
507                                                                                         YYABORT; }
508                                                                                 }
509                 | ROUTE_FAILURE error { yyerror("invalid failure_route statement"); }
510         ;
511
512 onreply_route_stm: ROUTE_ONREPLY LBRACK NUMBER RBRACK LBRACE actions RBRACE {
513                                                                                 if (($3<ONREPLY_RT_NO)&&($3>=1)){
514                                                                                         push($6, &onreply_rlist[$3]);
515                                                                                 } else {
516                                                                                         yyerror("invalid reply routing"
517                                                                                                 "table number");
518                                                                                         YYABORT; }
519                                                                                 }
520                 | ROUTE_ONREPLY error { yyerror("invalid failure_route statement"); }
521         ;
522 /*
523 rules:  rules rule { push($2, &$1); $$=$1; }
524         | rule {$$=$1; }
525         | rules error { $$=0; yyerror("invalid rule"); }
526          ;
527
528 rule:   condition       actions CR {
529                                                                 $$=0;
530                                                                 if (add_rule($1, $2, &$$)<0) {
531                                                                         yyerror("error calling add_rule");
532                                                                         YYABORT;
533                                                                 }
534                                                           }
535         | CR            { $$=0;}
536         | condition error { $$=0; yyerror("bad actions in rule"); }
537         ;
538
539 condition:      exp {$$=$1;}
540 */
541
542 exp:    exp AND exp     { $$=mk_exp(AND_OP, $1, $3); }
543         | exp OR  exp           { $$=mk_exp(OR_OP, $1, $3);  }
544         | NOT exp                       { $$=mk_exp(NOT_OP, $2, 0);  }
545         | LPAREN exp RPAREN     { $$=$2; }
546         | exp_elem                      { $$=$1; }
547         ;
548
549 exp_elem:       METHOD EQUAL_T STRING   {$$= mk_elem(   EQUAL_OP, STRING_ST, 
550                                                                                                         METHOD_O, $3);
551                                                                         }
552                 | METHOD EQUAL_T ID     {$$ = mk_elem(  EQUAL_OP, STRING_ST,
553                                                                                         METHOD_O, $3); 
554                                                         }
555                 | METHOD EQUAL_T error { $$=0; yyerror("string expected"); }
556                 | METHOD MATCH STRING   {$$ = mk_elem(  MATCH_OP, STRING_ST,
557                                                                                                 METHOD_O, $3); 
558                                                                 }
559                 | METHOD MATCH ID       {$$ = mk_elem(  MATCH_OP, STRING_ST,
560                                                                                         METHOD_O, $3); 
561                                                         }
562                 | METHOD MATCH error { $$=0; yyerror("string expected"); }
563                 | METHOD error  { $$=0; yyerror("invalid operator,"
564                                                                                 "== or =~ expected");
565                                                 }
566                 | URI EQUAL_T STRING    {$$ = mk_elem(  EQUAL_OP, STRING_ST,
567                                                                                                 URI_O, $3); 
568                                                                 }
569                 | URI EQUAL_T ID        {$$ = mk_elem(  EQUAL_OP, STRING_ST,
570                                                                                         URI_O, $3); 
571                                                         }
572                 | URI EQUAL_T MYSELF    { $$=mk_elem(   EQUAL_OP, MYSELF_ST,
573                                                                                                 URI_O, 0);
574                                                                 }
575                 | URI EQUAL_T error { $$=0; yyerror("string expected"); }
576                 | URI MATCH STRING      { $$=mk_elem(   MATCH_OP, STRING_ST,
577                                                                                         URI_O, $3);
578                                                         }
579                 | URI MATCH ID          { $$=mk_elem(   MATCH_OP, STRING_ST,
580                                                                                         URI_O, $3);
581                                                         }
582                 | URI MATCH error {  $$=0; yyerror("string expected"); }
583                 | URI error     { $$=0; yyerror("invalid operator,"
584                                                                         " == or =~ expected");
585                                         }
586                 | SRCPORT EQUAL_T NUMBER        { $$=mk_elem(   EQUAL_OP, NUMBER_ST,
587                                                                                                 SRCPORT_O, (void *) $3 ); }
588                 | SRCPORT EQUAL_T error { $$=0; yyerror("number expected"); }
589                 | SRCPORT error { $$=0; yyerror("equal operator expected"); }
590                 | DSTPORT EQUAL_T NUMBER        { $$=mk_elem(   EQUAL_OP, NUMBER_ST,
591                                                                                                 DSTPORT_O, (void *) $3 ); }
592                 | DSTPORT EQUAL_T error { $$=0; yyerror("number expected"); }
593                 | DSTPORT error { $$=0; yyerror("equal operator expected"); }
594                 | PROTO EQUAL_T NUMBER  { $$=mk_elem(   EQUAL_OP, NUMBER_ST,
595                                                                                                 PROTO_O, (void *) $3 ); }
596                 | PROTO EQUAL_T error { $$=0; yyerror("number expected"); }
597                 | PROTO error { $$=0; yyerror("equal operator expected"); }
598                 | AF EQUAL_T NUMBER     { $$=mk_elem(   EQUAL_OP, NUMBER_ST,
599                                                                                                 AF_O, (void *) $3 ); }
600                 | AF EQUAL_T error { $$=0; yyerror("number expected"); }
601                 | AF error { $$=0; yyerror("equal operator expected"); }
602                 | SRCIP EQUAL_T ipnet   { $$=mk_elem(   EQUAL_OP, NET_ST,
603                                                                                                 SRCIP_O, $3);
604                                                                 }
605                 | SRCIP EQUAL_T STRING  { $$=mk_elem(   EQUAL_OP, STRING_ST,
606                                                                                                 SRCIP_O, $3);
607                                                                 }
608                 | SRCIP EQUAL_T host    { $$=mk_elem(   EQUAL_OP, STRING_ST,
609                                                                                                 SRCIP_O, $3);
610                                                                 }
611                 | SRCIP EQUAL_T MYSELF  { $$=mk_elem(   EQUAL_OP, MYSELF_ST,
612                                                                                                 SRCIP_O, 0);
613                                                                 }
614                 | SRCIP EQUAL_T error { $$=0; yyerror( "ip address or hostname"
615                                                  "expected" ); }
616                 | SRCIP MATCH STRING    { $$=mk_elem(   MATCH_OP, STRING_ST,
617                                                                                                 SRCIP_O, $3);
618                                                                 }
619                 | SRCIP MATCH ID                { $$=mk_elem(   MATCH_OP, STRING_ST,
620                                                                                                 SRCIP_O, $3);
621                                                                 }
622                 | SRCIP MATCH error  { $$=0; yyerror( "hostname expected"); }
623                 | SRCIP error  { $$=0; 
624                                                  yyerror("invalid operator, == or =~ expected");}
625                 | DSTIP EQUAL_T ipnet   { $$=mk_elem(   EQUAL_OP, NET_ST,
626                                                                                                 DSTIP_O, $3);
627                                                                 }
628                 | DSTIP EQUAL_T STRING  { $$=mk_elem(   EQUAL_OP, STRING_ST,
629                                                                                                 DSTIP_O, $3);
630                                                                 }
631                 | DSTIP EQUAL_T host    { $$=mk_elem(   EQUAL_OP, STRING_ST,
632                                                                                                 DSTIP_O, $3);
633                                                                 }
634                 | DSTIP EQUAL_T MYSELF  { $$=mk_elem(   EQUAL_OP, MYSELF_ST,
635                                                                                                 DSTIP_O, 0);
636                                                                 }
637                 | DSTIP EQUAL_T error { $$=0; yyerror( "ip address or hostname"
638                                                                         "expected" ); }
639                 | DSTIP MATCH STRING    { $$=mk_elem(   MATCH_OP, STRING_ST,
640                                                                                                 DSTIP_O, $3);
641                                                                 }
642                 | DSTIP MATCH ID        { $$=mk_elem(   MATCH_OP, STRING_ST,
643                                                                                         DSTIP_O, $3);
644                                                         }
645                 | DSTIP MATCH error  { $$=0; yyerror ( "hostname  expected" ); }
646                 | DSTIP error { $$=0; 
647                                                 yyerror("invalid operator, == or =~ expected");}
648                 | MYSELF EQUAL_T URI    { $$=mk_elem(   EQUAL_OP, MYSELF_ST,
649                                                                                                 URI_O, 0);
650                                                                 }
651                 | MYSELF EQUAL_T SRCIP  { $$=mk_elem(   EQUAL_OP, MYSELF_ST,
652                                                                                                 SRCIP_O, 0);
653                                                                 }
654                 | MYSELF EQUAL_T DSTIP  { $$=mk_elem(   EQUAL_OP, MYSELF_ST,
655                                                                                                 DSTIP_O, 0);
656                                                                 }
657                 | MYSELF EQUAL_T error {        $$=0; 
658                                                                         yyerror(" URI, SRCIP or DSTIP expected"); }
659                 | MYSELF error  { $$=0; yyerror ("invalid operator, == expected"); }
660                 | stm                           { $$=mk_elem( NO_OP, ACTIONS_ST, ACTION_O, $1 ); }
661                 | NUMBER                {$$=mk_elem( NO_OP, NUMBER_ST, NUMBER_O, (void*)$1 ); }
662         ;
663
664 ipnet:  ip SLASH ip     { $$=mk_net($1, $3); } 
665         | ip SLASH NUMBER       {       if (($3<0) || ($3>$1->len*8)){
666                                                                 yyerror("invalid bit number in netmask");
667                                                                 $$=0;
668                                                         }else{
669                                                                 $$=mk_net_bitlen($1, $3);
670                                                         /*
671                                                                 $$=mk_net($1, 
672                                                                                 htonl( ($3)?~( (1<<(32-$3))-1 ):0 ) );
673                                                         */
674                                                         }
675                                                 }
676         | ip                            { $$=mk_net_bitlen($1, $1->len*8); }
677         | ip SLASH error        { $$=0;
678                                                  yyerror("netmask (eg:255.0.0.0 or 8) expected");
679                                                 }
680         ;
681
682 host:   ID                              { $$=$1; }
683         | host DOT ID           { $$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
684                                                   if ($$==0){
685                                                         LOG(L_CRIT, "ERROR: cfg. parser: memory allocation"
686                                                                                 " failure while parsing host\n");
687                                                   }else{
688                                                         memcpy($$, $1, strlen($1));
689                                                         $$[strlen($1)]='.';
690                                                         memcpy($$+strlen($1)+1, $3, strlen($3));
691                                                         $$[strlen($1)+1+strlen($3)]=0;
692                                                   }
693                                                   pkg_free($1); pkg_free($3);
694                                                 }
695         | host DOT error { $$=0; pkg_free($1); yyerror("invalid hostname"); }
696         ;
697
698
699 stm:            cmd                                             { $$=$1; }
700                 |       LBRACE actions RBRACE   { $$=$2; }
701         ;
702
703 actions:        actions action  {$$=append_action($1, $2); }
704                 | action                        {$$=$1;}
705                 | actions error { $$=0; yyerror("bad command"); }
706         ;
707
708 action:         cmd SEMICOLON {$$=$1;}
709                 | SEMICOLON /* null action */ {$$=0;}
710                 | cmd error { $$=0; yyerror("bad command: missing ';'?"); }
711         ;
712
713 if_cmd:         IF exp stm                              { $$=mk_action3( IF_T,
714                                                                                                          EXPR_ST,
715                                                                                                          ACTIONS_ST,
716                                                                                                          NOSUBTYPE,
717                                                                                                          $2,
718                                                                                                          $3,
719                                                                                                          0);
720                                                                         }
721                 |       IF exp stm ELSE stm             { $$=mk_action3( IF_T,
722                                                                                                          EXPR_ST,
723                                                                                                          ACTIONS_ST,
724                                                                                                          ACTIONS_ST,
725                                                                                                          $2,
726                                                                                                          $3,
727                                                                                                          $5);
728                                                                         }
729         ;
730
731 cmd:            FORWARD LPAREN host RPAREN      { $$=mk_action( FORWARD_T,
732                                                                                                                 STRING_ST,
733                                                                                                                 NUMBER_ST,
734                                                                                                                 $3,
735                                                                                                                 0);
736                                                                                 }
737                 | FORWARD LPAREN STRING RPAREN  { $$=mk_action( FORWARD_T,
738                                                                                                                 STRING_ST,
739                                                                                                                 NUMBER_ST,
740                                                                                                                 $3,
741                                                                                                                 0);
742                                                                                 }
743                 | FORWARD LPAREN ip RPAREN      { $$=mk_action( FORWARD_T,
744                                                                                                                 IP_ST,
745                                                                                                                 NUMBER_ST,
746                                                                                                                 (void*)$3,
747                                                                                                                 0);
748                                                                                 }
749                 | FORWARD LPAREN host COMMA NUMBER RPAREN { $$=mk_action(FORWARD_T,
750                                                                                                                                  STRING_ST,
751                                                                                                                                  NUMBER_ST,
752                                                                                                                                 $3,
753                                                                                                                                 (void*)$5);
754                                                                                                  }
755                 | FORWARD LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(FORWARD_T,
756                                                                                                                                  STRING_ST,
757                                                                                                                                  NUMBER_ST,
758                                                                                                                                 $3,
759                                                                                                                                 (void*)$5);
760                                                                                                         }
761                 | FORWARD LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_T,
762                                                                                                                                  IP_ST,
763                                                                                                                                  NUMBER_ST,
764                                                                                                                                  (void*)$3,
765                                                                                                                                 (void*)$5);
766                                                                                                   }
767                 | FORWARD LPAREN URIHOST COMMA URIPORT RPAREN {
768                                                                                                         $$=mk_action(FORWARD_T,
769                                                                                                                                  URIHOST_ST,
770                                                                                                                                  URIPORT_ST,
771                                                                                                                                 0,
772                                                                                                                                 0);
773                                                                                                         }
774                                                                                                         
775                                                                         
776                 | FORWARD LPAREN URIHOST COMMA NUMBER RPAREN {
777                                                                                                         $$=mk_action(FORWARD_T,
778                                                                                                                                  URIHOST_ST,
779                                                                                                                                  NUMBER_ST,
780                                                                                                                                 0,
781                                                                                                                                 (void*)$5);
782                                                                                                         }
783                 | FORWARD LPAREN URIHOST RPAREN {
784                                                                                                         $$=mk_action(FORWARD_T,
785                                                                                                                                  URIHOST_ST,
786                                                                                                                                  NUMBER_ST,
787                                                                                                                                 0,
788                                                                                                                                 0);
789                                                                                 }
790                 | FORWARD error { $$=0; yyerror("missing '(' or ')' ?"); }
791                 | FORWARD LPAREN error RPAREN { $$=0; yyerror("bad forward"
792                                                                                 "argument"); }
793                 | FORWARD_UDP LPAREN host RPAREN        { $$=mk_action( FORWARD_UDP_T,
794                                                                                                                 STRING_ST,
795                                                                                                                 NUMBER_ST,
796                                                                                                                 $3,
797                                                                                                                 0);
798                                                                                 }
799                 | FORWARD_UDP LPAREN STRING RPAREN      { $$=mk_action( FORWARD_UDP_T,
800                                                                                                                 STRING_ST,
801                                                                                                                 NUMBER_ST,
802                                                                                                                 $3,
803                                                                                                                 0);
804                                                                                 }
805                 | FORWARD_UDP LPAREN ip RPAREN  { $$=mk_action( FORWARD_UDP_T,
806                                                                                                                 IP_ST,
807                                                                                                                 NUMBER_ST,
808                                                                                                                 (void*)$3,
809                                                                                                                 0);
810                                                                                 }
811                 | FORWARD_UDP LPAREN host COMMA NUMBER RPAREN { $$=mk_action(
812                                                                                                                                 FORWARD_UDP_T,
813                                                                                                                                  STRING_ST,
814                                                                                                                                  NUMBER_ST,
815                                                                                                                                 $3,
816                                                                                                                                 (void*)$5);
817                                                                                                  }
818                 | FORWARD_UDP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(
819                                                                                                                                 FORWARD_UDP_T,
820                                                                                                                                  STRING_ST,
821                                                                                                                                  NUMBER_ST,
822                                                                                                                                 $3,
823                                                                                                                                 (void*)$5);
824                                                                                                         }
825                 | FORWARD_UDP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(
826                                                                                                                                 FORWARD_UDP_T,
827                                                                                                                                  IP_ST,
828                                                                                                                                  NUMBER_ST,
829                                                                                                                                  (void*)$3,
830                                                                                                                                 (void*)$5);
831                                                                                                   }
832                 | FORWARD_UDP LPAREN URIHOST COMMA URIPORT RPAREN {
833                                                                                                         $$=mk_action(FORWARD_UDP_T,
834                                                                                                                                  URIHOST_ST,
835                                                                                                                                  URIPORT_ST,
836                                                                                                                                 0,
837                                                                                                                                 0);
838                                                                                                         }
839                                                                                                         
840                                                                         
841                 | FORWARD_UDP LPAREN URIHOST COMMA NUMBER RPAREN {
842                                                                                                         $$=mk_action(FORWARD_UDP_T,
843                                                                                                                                  URIHOST_ST,
844                                                                                                                                  NUMBER_ST,
845                                                                                                                                 0,
846                                                                                                                                 (void*)$5);
847                                                                                                         }
848                 | FORWARD_UDP LPAREN URIHOST RPAREN {
849                                                                                                         $$=mk_action(FORWARD_UDP_T,
850                                                                                                                                  URIHOST_ST,
851                                                                                                                                  NUMBER_ST,
852                                                                                                                                 0,
853                                                                                                                                 0);
854                                                                                 }
855                 | FORWARD_UDP error { $$=0; yyerror("missing '(' or ')' ?"); }
856                 | FORWARD_UDP LPAREN error RPAREN { $$=0; yyerror("bad forward_udp"
857                                                                                 "argument"); }
858                 | FORWARD_TCP LPAREN host RPAREN        { $$=mk_action( FORWARD_TCP_T,
859                                                                                                                 STRING_ST,
860                                                                                                                 NUMBER_ST,
861                                                                                                                 $3,
862                                                                                                                 0);
863                                                                                 }
864                 | FORWARD_TCP LPAREN STRING RPAREN      { $$=mk_action( FORWARD_TCP_T,
865                                                                                                                 STRING_ST,
866                                                                                                                 NUMBER_ST,
867                                                                                                                 $3,
868                                                                                                                 0);
869                                                                                 }
870                 | FORWARD_TCP LPAREN ip RPAREN  { $$=mk_action( FORWARD_TCP_T,
871                                                                                                                 IP_ST,
872                                                                                                                 NUMBER_ST,
873                                                                                                                 (void*)$3,
874                                                                                                                 0);
875                                                                                 }
876                 | FORWARD_TCP LPAREN host COMMA NUMBER RPAREN { $$=mk_action(
877                                                                                                                                 FORWARD_TCP_T,
878                                                                                                                                  STRING_ST,
879                                                                                                                                  NUMBER_ST,
880                                                                                                                                 $3,
881                                                                                                                                 (void*)$5);
882                                                                                                  }
883                 | FORWARD_TCP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(
884                                                                                                                                 FORWARD_TCP_T,
885                                                                                                                                  STRING_ST,
886                                                                                                                                  NUMBER_ST,
887                                                                                                                                 $3,
888                                                                                                                                 (void*)$5);
889                                                                                                         }
890                 | FORWARD_TCP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_TCP_T,
891                                                                                                                                  IP_ST,
892                                                                                                                                  NUMBER_ST,
893                                                                                                                                  (void*)$3,
894                                                                                                                                 (void*)$5);
895                                                                                                   }
896                 | FORWARD_TCP LPAREN URIHOST COMMA URIPORT RPAREN {
897                                                                                                         $$=mk_action(FORWARD_TCP_T,
898                                                                                                                                  URIHOST_ST,
899                                                                                                                                  URIPORT_ST,
900                                                                                                                                 0,
901                                                                                                                                 0);
902                                                                                                         }
903                                                                                                         
904                                                                         
905                 | FORWARD_TCP LPAREN URIHOST COMMA NUMBER RPAREN {
906                                                                                                         $$=mk_action(FORWARD_TCP_T,
907                                                                                                                                  URIHOST_ST,
908                                                                                                                                  NUMBER_ST,
909                                                                                                                                 0,
910                                                                                                                                 (void*)$5);
911                                                                                                         }
912                 | FORWARD_TCP LPAREN URIHOST RPAREN {
913                                                                                                         $$=mk_action(FORWARD_TCP_T,
914                                                                                                                                  URIHOST_ST,
915                                                                                                                                  NUMBER_ST,
916                                                                                                                                 0,
917                                                                                                                                 0);
918                                                                                 }
919                 | FORWARD_TCP error { $$=0; yyerror("missing '(' or ')' ?"); }
920                 | FORWARD_TCP LPAREN error RPAREN { $$=0; yyerror("bad forward_tcp"
921                                                                                 "argument"); }
922                 | SEND LPAREN host RPAREN       { $$=mk_action( SEND_T,
923                                                                                                         STRING_ST,
924                                                                                                         NUMBER_ST,
925                                                                                                         $3,
926                                                                                                         0);
927                                                                         }
928                 | SEND LPAREN STRING RPAREN { $$=mk_action(     SEND_T,
929                                                                                                         STRING_ST,
930                                                                                                         NUMBER_ST,
931                                                                                                         $3,
932                                                                                                         0);
933                                                                         }
934                 | SEND LPAREN ip RPAREN         { $$=mk_action( SEND_T,
935                                                                                                         IP_ST,
936                                                                                                         NUMBER_ST,
937                                                                                                         (void*)$3,
938                                                                                                         0);
939                                                                         }
940                 | SEND LPAREN host COMMA NUMBER RPAREN  { $$=mk_action( SEND_T,
941                                                                                                                                 STRING_ST,
942                                                                                                                                 NUMBER_ST,
943                                                                                                                                 $3,
944                                                                                                                                 (void*)$5);
945                                                                                                 }
946                 | SEND LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action( SEND_T,
947                                                                                                                                 STRING_ST,
948                                                                                                                                 NUMBER_ST,
949                                                                                                                                 $3,
950                                                                                                                                 (void*)$5);
951                                                                                                 }
952                 | SEND LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(    SEND_T,
953                                                                                                                                 IP_ST,
954                                                                                                                                 NUMBER_ST,
955                                                                                                                                 (void*)$3,
956                                                                                                                                 (void*)$5);
957                                                                                            }
958                 | SEND error { $$=0; yyerror("missing '(' or ')' ?"); }
959                 | SEND LPAREN error RPAREN { $$=0; yyerror("bad send"
960                                                                                                         "argument"); }
961                 | SEND_TCP LPAREN host RPAREN   { $$=mk_action( SEND_TCP_T,
962                                                                                                         STRING_ST,
963                                                                                                         NUMBER_ST,
964                                                                                                         $3,
965                                                                                                         0);
966                                                                         }
967                 | SEND_TCP LPAREN STRING RPAREN { $$=mk_action( SEND_TCP_T,
968                                                                                                         STRING_ST,
969                                                                                                         NUMBER_ST,
970                                                                                                         $3,
971                                                                                                         0);
972                                                                         }
973                 | SEND_TCP LPAREN ip RPAREN             { $$=mk_action( SEND_TCP_T,
974                                                                                                         IP_ST,
975                                                                                                         NUMBER_ST,
976                                                                                                         (void*)$3,
977                                                                                                         0);
978                                                                         }
979                 | SEND_TCP LPAREN host COMMA NUMBER RPAREN      { $$=mk_action( SEND_TCP_T,
980                                                                                                                                 STRING_ST,
981                                                                                                                                 NUMBER_ST,
982                                                                                                                                 $3,
983                                                                                                                                 (void*)$5);
984                                                                                                 }
985                 | SEND_TCP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(     SEND_TCP_T,
986                                                                                                                                 STRING_ST,
987                                                                                                                                 NUMBER_ST,
988                                                                                                                                 $3,
989                                                                                                                                 (void*)$5);
990                                                                                                 }
991                 | SEND_TCP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(        SEND_TCP_T,
992                                                                                                                                 IP_ST,
993                                                                                                                                 NUMBER_ST,
994                                                                                                                                 (void*)$3,
995                                                                                                                                 (void*)$5);
996                                                                                            }
997                 | SEND_TCP error { $$=0; yyerror("missing '(' or ')' ?"); }
998                 | SEND_TCP LPAREN error RPAREN { $$=0; yyerror("bad send_tcp"
999                                                                                                         "argument"); }
1000                 | DROP LPAREN RPAREN    {$$=mk_action(DROP_T,0, 0, 0, 0); }
1001                 | DROP                                  {$$=mk_action(DROP_T,0, 0, 0, 0); }
1002                 | LOG_TOK LPAREN STRING RPAREN  {$$=mk_action(  LOG_T, NUMBER_ST, 
1003                                                                                                         STRING_ST,(void*)4,$3);
1004                                                                         }
1005                 | LOG_TOK LPAREN NUMBER COMMA STRING RPAREN     {$$=mk_action(  LOG_T,
1006                                                                                                                                 NUMBER_ST, 
1007                                                                                                                                 STRING_ST,
1008                                                                                                                                 (void*)$3,
1009                                                                                                                                 $5);
1010                                                                                                 }
1011                 | LOG_TOK error { $$=0; yyerror("missing '(' or ')' ?"); }
1012                 | LOG_TOK LPAREN error RPAREN { $$=0; yyerror("bad log"
1013                                                                         "argument"); }
1014                 | SETFLAG LPAREN NUMBER RPAREN {$$=mk_action( SETFLAG_T, NUMBER_ST, 0,
1015                                                                                                         (void *)$3, 0 ); }
1016                 | SETFLAG error { $$=0; yyerror("missing '(' or ')'?"); }
1017
1018                 | LEN_GT LPAREN NUMBER RPAREN {$$=mk_action( LEN_GT_T, NUMBER_ST, 0,
1019                                                                                                         (void *)$3, 0 ); }
1020                 | LEN_GT LPAREN MAX_LEN RPAREN {$$=mk_action( LEN_GT_T, NUMBER_ST, 0,
1021                                                                                                         (void *) BUF_SIZE, 0 ); }
1022                 | LEN_GT error { $$=0; yyerror("missing '(' or ')'?"); }
1023
1024                 | RESETFLAG LPAREN NUMBER RPAREN {$$=mk_action( RESETFLAG_T, NUMBER_ST, 0,
1025                                                                                                         (void *)$3, 0 ); }
1026                 | RESETFLAG error { $$=0; yyerror("missing '(' or ')'?"); }
1027                 | ISFLAGSET LPAREN NUMBER RPAREN {$$=mk_action( ISFLAGSET_T, NUMBER_ST, 0,
1028                                                                                                         (void *)$3, 0 ); }
1029                 | ISFLAGSET error { $$=0; yyerror("missing '(' or ')'?"); }
1030                 | ERROR LPAREN STRING COMMA STRING RPAREN {$$=mk_action(ERROR_T,
1031                                                                                                                                 STRING_ST, 
1032                                                                                                                                 STRING_ST,
1033                                                                                                                                 $3,
1034                                                                                                                                 $5);
1035                                                                                                   }
1036                 | ERROR error { $$=0; yyerror("missing '(' or ')' ?"); }
1037                 | ERROR LPAREN error RPAREN { $$=0; yyerror("bad error"
1038                                                                                                                 "argument"); }
1039                 | ROUTE LPAREN NUMBER RPAREN    { $$=mk_action(ROUTE_T, NUMBER_ST,
1040                                                                                                                 0, (void*)$3, 0);
1041                                                                                 }
1042                 | ROUTE error { $$=0; yyerror("missing '(' or ')' ?"); }
1043                 | ROUTE LPAREN error RPAREN { $$=0; yyerror("bad route"
1044                                                 "argument"); }
1045                 | EXEC LPAREN STRING RPAREN     { $$=mk_action( EXEC_T, STRING_ST, 0,
1046                                                                                                         $3, 0);
1047                                                                         }
1048                 | SET_HOST LPAREN STRING RPAREN { $$=mk_action(SET_HOST_T, STRING_ST,
1049                                                                                                                 0, $3, 0); }
1050                 | SET_HOST error { $$=0; yyerror("missing '(' or ')' ?"); }
1051                 | SET_HOST LPAREN error RPAREN { $$=0; yyerror("bad argument, "
1052                                                                                                                 "string expected"); }
1053
1054                 | PREFIX LPAREN STRING RPAREN { $$=mk_action(PREFIX_T, STRING_ST,
1055                                                                                                                 0, $3, 0); }
1056                 | PREFIX error { $$=0; yyerror("missing '(' or ')' ?"); }
1057                 | PREFIX LPAREN error RPAREN { $$=0; yyerror("bad argument, "
1058                                                                                                                 "string expected"); }
1059                 | STRIP LPAREN NUMBER RPAREN { $$=mk_action(STRIP_T, NUMBER_ST,
1060                                                                                                                 0, (void *) $3, 0); }
1061                 | STRIP error { $$=0; yyerror("missing '(' or ')' ?"); }
1062                 | STRIP LPAREN error RPAREN { $$=0; yyerror("bad argument, "
1063                                                                                                                 "number expected"); }
1064
1065                 | APPEND_BRANCH LPAREN STRING RPAREN { $$=mk_action( APPEND_BRANCH_T,
1066                                                                                                         STRING_ST, 0, $3, 0) ; }
1067                 | APPEND_BRANCH LPAREN RPAREN { $$=mk_action( APPEND_BRANCH_T,
1068                                                                                                         STRING_ST, 0, 0, 0 ) ; }
1069                 | APPEND_BRANCH {  $$=mk_action( APPEND_BRANCH_T, STRING_ST, 0, 0, 0 ) ; }
1070
1071                 | SET_HOSTPORT LPAREN STRING RPAREN { $$=mk_action( SET_HOSTPORT_T, 
1072                                                                                                                 STRING_ST, 0, $3, 0); }
1073                 | SET_HOSTPORT error { $$=0; yyerror("missing '(' or ')' ?"); }
1074                 | SET_HOSTPORT LPAREN error RPAREN { $$=0; yyerror("bad argument,"
1075                                                                                                 " string expected"); }
1076                 | SET_PORT LPAREN STRING RPAREN { $$=mk_action( SET_PORT_T, STRING_ST,
1077                                                                                                                 0, $3, 0); }
1078                 | SET_PORT error { $$=0; yyerror("missing '(' or ')' ?"); }
1079                 | SET_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, "
1080                                                                                                                 "string expected"); }
1081                 | SET_USER LPAREN STRING RPAREN { $$=mk_action( SET_USER_T, STRING_ST,
1082                                                                                                                 0, $3, 0); }
1083                 | SET_USER error { $$=0; yyerror("missing '(' or ')' ?"); }
1084                 | SET_USER LPAREN error RPAREN { $$=0; yyerror("bad argument, "
1085                                                                                                                 "string expected"); }
1086                 | SET_USERPASS LPAREN STRING RPAREN { $$=mk_action( SET_USERPASS_T, 
1087                                                                                                                 STRING_ST, 0, $3, 0); }
1088                 | SET_USERPASS error { $$=0; yyerror("missing '(' or ')' ?"); }
1089                 | SET_USERPASS LPAREN error RPAREN { $$=0; yyerror("bad argument, "
1090                                                                                                                 "string expected"); }
1091                 | SET_URI LPAREN STRING RPAREN { $$=mk_action( SET_URI_T, STRING_ST, 
1092                                                                                                                 0, $3, 0); }
1093                 | SET_URI error { $$=0; yyerror("missing '(' or ')' ?"); }
1094                 | SET_URI LPAREN error RPAREN { $$=0; yyerror("bad argument, "
1095                                                                                 "string expected"); }
1096                 | REVERT_URI LPAREN RPAREN { $$=mk_action( REVERT_URI_T, 0,0,0,0); }
1097                 | REVERT_URI { $$=mk_action( REVERT_URI_T, 0,0,0,0); }
1098                 | FORCE_RPORT LPAREN RPAREN     {$$=mk_action(FORCE_RPORT_T,0, 0, 0, 0); }
1099                 | FORCE_RPORT                           {$$=mk_action(FORCE_RPORT_T,0, 0, 0, 0); }
1100                 | ID LPAREN RPAREN                      { f_tmp=(void*)find_export($1, 0, rt);
1101                                                                            if (f_tmp==0){
1102                                                                                    if (find_export($1, 0, 0)) {
1103                                                                                            yyerror("Command cannot be used in the block\n");
1104                                                                                    } else {
1105                                                                                            yyerror("unknown command, missing"
1106                                                                                                    " loadmodule?\n");
1107                                                                                    }
1108                                                                                 $$=0;
1109                                                                            }else{
1110                                                                                 $$=mk_action(   MODULE_T,
1111                                                                                                                 CMDF_ST,
1112                                                                                                                 0,
1113                                                                                                                 f_tmp,
1114                                                                                                                 0
1115                                                                                                         );
1116                                                                            }
1117                                                                         }
1118                 | ID LPAREN STRING RPAREN { f_tmp=(void*)find_export($1, 1, rt);
1119                                                                         if (f_tmp==0){
1120                                                                                 if (find_export($1, 1, 0)) {
1121                                                                                         yyerror("Command cannot be used in the block\n");
1122                                                                                 } else {
1123                                                                                         yyerror("unknown command, missing"
1124                                                                                                 " loadmodule?\n");
1125                                                                                 }
1126                                                                                 $$=0;
1127                                                                         }else{
1128                                                                                 $$=mk_action(   MODULE_T,
1129                                                                                                                 CMDF_ST,
1130                                                                                                                 STRING_ST,
1131                                                                                                                 f_tmp,
1132                                                                                                                 $3
1133                                                                                                         );
1134                                                                         }
1135                                                                   }
1136                 | ID LPAREN STRING  COMMA STRING RPAREN 
1137                                                                   { f_tmp=(void*)find_export($1, 2, rt);
1138                                                                         if (f_tmp==0){
1139                                                                                 if (find_export($1, 2, 0)) {
1140                                                                                         yyerror("Command cannot be used in the block\n");
1141                                                                                 } else {
1142                                                                                         yyerror("unknown command, missing"
1143                                                                                                 " loadmodule?\n");
1144                                                                                 }
1145                                                                                 $$=0;
1146                                                                         }else{
1147                                                                                 $$=mk_action3(  MODULE_T,
1148                                                                                                                 CMDF_ST,
1149                                                                                                                 STRING_ST,
1150                                                                                                                 STRING_ST,
1151                                                                                                                 f_tmp,
1152                                                                                                                 $3,
1153                                                                                                                 $5
1154                                                                                                         );
1155                                                                         }
1156                                                                   }
1157                 | ID LPAREN error RPAREN { $$=0; yyerror("bad arguments"); }
1158                 | if_cmd                { $$=$1; }
1159         ;
1160
1161
1162 %%
1163
1164 extern int line;
1165 extern int column;
1166 extern int startcolumn;
1167 void yyerror(char* s)
1168 {
1169         LOG(L_CRIT, "parse error (%d,%d-%d): %s\n", line, startcolumn, 
1170                         column, s);
1171         cfg_errors++;
1172 }
1173
1174 /*
1175 int main(int argc, char ** argv)
1176 {
1177         if (yyparse()!=0)
1178                 fprintf(stderr, "parsing error\n");
1179 }
1180 */