Merge commit 'origin/andrei/type_conversion'
[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  * 2003-04-22  strip_tail added (jiri)
42  * 2003-07-03  tls* (disable, certificate, private_key, ca_list, verify,
43  *              require_certificate added (andrei)
44  * 2003-07-06  more tls config. vars added: tls_method, tls_port_no (andrei)
45  * 2003-10-02  added {,set_}advertised_{address,port} (andrei)
46  * 2003-10-10  added <,>,<=,>=, != operators support
47  *             added msg:len (andrei)
48  * 2003-10-11  if(){} doesn't require a ';' after it anymore (andrei)
49  * 2003-10-13  added FIFO_DIR & proto:host:port listen/alias support (andrei)
50  * 2003-10-24  converted to the new socket_info lists (andrei)
51  * 2003-10-28  added tcp_accept_aliases (andrei)
52  * 2003-11-20  added {tcp_connect, tcp_send, tls_*}_timeout (andrei)
53  * 2004-03-30  added DISABLE_CORE and OPEN_FD_LIMIT (andrei)
54  * 2004-04-29  added SOCK_MODE, SOCK_USER & SOCK_GROUP (andrei)
55  * 2004-05-03  applied multicast support patch (MCAST_LOOPBACK) from janakj
56  *             added MCAST_TTL (andrei)
57  * 2004-07-05  src_ip & dst_ip will detect ip addresses between quotes
58  *              (andrei)
59  * 2004-10-19  added FROM_URI, TO_URI (andrei)
60  * 2004-11-30  added force_send_socket (andrei)
61  * 2005-07-08  added TCP_CON_LIFETIME, TCP_POLL_METHOD, TCP_MAX_CONNECTIONS
62  *              (andrei)
63  * 2005-07-11 added DNS_RETR_TIME, DNS_RETR_NO, DNS_SERVERS_NO, DNS_USE_SEARCH,
64  *             DNS_TRY_IPV6 (andrei)
65  * 2005-07-12  default onreply route added (andrei)
66  * 2005-11-16  fixed if (cond) cmd; (andrei)
67  * 2005-12-11  added onsend_route support, fcmd (filtered cmd),
68  *             snd_{ip,port,proto,af}, to_{ip,proto} (andrei)
69  * 2005-12-19  select framework (mma)
70  * 2006-01-06  AVP index support (mma)
71  * 2005-01-07  optional semicolon in statement, PARAM_STR&PARAM_STRING
72  * 2006-02-02  named flags support (andrei)
73  * 2006-02-06  named routes support (andrei)
74  * 2006-05-30  avp flags (tma)
75  * 2006-09-11  added dns cache (use, flags, ttls, mem ,gc) & dst blacklist
76  *              options (andrei)
77  * 2006-10-13  added STUN_ALLOW_STUN, STUN_ALLOW_FP, STUN_REFRESH_INTERVAL
78  *              (vlada)
79  * 2007-02-09  separated command needed for tls-in-core and for tls in general
80  *              (andrei)
81  * 2007-06-07  added SHM_FORCE_ALLOC, MLOCK_PAGES, REAL_TIME, RT_PRIO,
82  *              RT_POLICY, RT_TIMER1_PRIO, RT_TIMER1_POLICY, RT_TIMER2_PRIO,
83  *              RT_TIMER2_POLICY (andrei)
84  * 2007-06-16  added DDNS_SRV_LB, DNS_TRY_NAPTR (andrei)
85  * 2007-09-10  introduced phone2tel option which allows NOT to consider
86  *             user=phone URIs as TEL URIs (jiri)
87  * 2007-10-10  added DNS_SEARCH_FMATCH (mma)
88  * 2007-11-28  added TCP_OPT_{FD_CACHE, DEFER_ACCEPT, DELAYED_ACK, SYNCNT,
89  *              LINGER2, KEEPALIVE, KEEPIDLE, KEEPINTVL, KEEPCNT} (andrei)
90  * 2008-01-24  added cfg_var definition (Miklos)
91  * 2008-11-18  support for variable parameter module functions (andrei)
92  * 2007-12-03  support for generalised lvalues and rvalues:
93  *               lval=rval_expr, where lval=avp|pvar  (andrei)
94  * 2007-12-06  expression are now evaluated in terms of rvalues;
95  *             NUMBER is now always positive; cleanup (andrei)
96  * 2009-01-26  case/switch() support (andrei)
97  * 2009-03-10  added SET_USERPHONE action (Miklos)
98 */
99
100 %{
101
102 #include <stdlib.h>
103 #include <stdio.h>
104 #include <stdarg.h>
105 #include <sys/types.h>
106 #include <sys/socket.h>
107 #include <netinet/in.h>
108 #include <arpa/inet.h>
109 #include <string.h>
110 #include <errno.h>
111 #include "route_struct.h"
112 #include "globals.h"
113 #include "route.h"
114 #include "switch.h"
115 #include "dprint.h"
116 #include "sr_module.h"
117 #include "modparam.h"
118 #include "ip_addr.h"
119 #include "resolve.h"
120 #include "socket_info.h"
121 #include "name_alias.h"
122 #include "ut.h"
123 #include "dset.h"
124 #include "select.h"
125 #include "flags.h"
126 #include "tcp_init.h"
127 #include "tcp_options.h"
128 #include "sctp_options.h"
129 #include "pvar.h"
130 #include "lvalue.h"
131 #include "rvalue.h"
132 #include "sr_compat.h"
133 #include "msg_translator.h"
134
135 #include "config.h"
136 #include "cfg_core.h"
137 #include "cfg/cfg.h"
138 #ifdef CORE_TLS
139 #include "tls/tls_config.h"
140 #endif
141 #include "timer_ticks.h"
142
143 #ifdef DEBUG_DMALLOC
144 #include <dmalloc.h>
145 #endif
146
147 /* hack to avoid alloca usage in the generated C file (needed for compiler
148  with no built in alloca, like icc*/
149 #undef _ALLOCA_H
150
151 #define onsend_check(s) \
152         do{\
153                 if (rt!=ONSEND_ROUTE) yyerror( s " allowed only in onsend_routes");\
154         }while(0)
155
156
157 #ifdef USE_DNS_CACHE
158         #define IF_DNS_CACHE(x) x
159 #else
160         #define IF_DNS_CACHE(x) warn("dns cache support not compiled in")
161 #endif
162
163 #ifdef USE_DNS_FAILOVER
164         #define IF_DNS_FAILOVER(x) x
165 #else
166         #define IF_DNS_FAILOVER(x) warn("dns failover support not compiled in")
167 #endif
168
169 #ifdef USE_NAPTR
170         #define IF_NAPTR(x) x
171 #else
172         #define IF_NAPTR(x) warn("dns naptr support not compiled in")
173 #endif
174
175 #ifdef USE_DST_BLACKLIST
176         #define IF_DST_BLACKLIST(x) x
177 #else
178         #define IF_DST_BLACKLIST(x) warn("dst blacklist support not compiled in")
179 #endif
180
181 #ifdef USE_STUN
182         #define IF_STUN(x) x
183 #else 
184         #define IF_STUN(x) warn("stun support not compiled in")
185 #endif
186
187
188 extern int yylex();
189 static void yyerror(char* s, ...);
190 static void yyerror_at(struct cfg_pos* pos, char* s, ...);
191 static char* tmp;
192 static int i_tmp;
193 static unsigned u_tmp;
194 static struct socket_id* lst_tmp;
195 static struct name_lst*  nl_tmp;
196 static int rt;  /* Type of route block for find_export */
197 static str* str_tmp;
198 static str s_tmp;
199 static struct ip_addr* ip_tmp;
200 static struct avp_spec* s_attr;
201 static select_t sel;
202 static select_t* sel_ptr;
203 static pv_spec_t* pv_spec;
204 static struct action *mod_func_action;
205 static struct lvalue* lval_tmp;
206 static struct rvalue* rval_tmp;
207
208 static void warn(char* s, ...);
209 static void warn_at(struct cfg_pos* pos, char* s, ...);
210 static void get_cpos(struct cfg_pos* pos);
211 static struct rval_expr* mk_rve_rval(enum rval_type, void* v);
212 static struct rval_expr* mk_rve1(enum rval_expr_op op, struct rval_expr* rve1);
213 static struct rval_expr* mk_rve2(enum rval_expr_op op, struct rval_expr* rve1,
214                                                                         struct rval_expr* rve2);
215 static struct socket_id* mk_listen_id(char*, int, int);
216 static struct name_lst* mk_name_lst(char* name, int flags);
217 static struct socket_id* mk_listen_id2(struct name_lst*, int, int);
218 static void free_name_lst(struct name_lst* lst);
219 static void free_socket_id_lst(struct socket_id* i);
220
221 static struct case_stms* mk_case_stm(struct rval_expr* ct, int is_re, 
222                                                                         struct action* a, int* err);
223 static int case_check_type(struct case_stms* stms);
224 static int case_check_default(struct case_stms* stms);
225
226
227 %}
228
229 %union {
230         long intval;
231         unsigned long uval;
232         char* strval;
233         struct expr* expr;
234         struct action* action;
235         struct case_stms* case_stms;
236         struct net* ipnet;
237         struct ip_addr* ipaddr;
238         struct socket_id* sockid;
239         struct name_lst* name_l;
240         struct avp_spec* attr;
241         struct _pv_spec* pvar;
242         struct lvalue* lval;
243         struct rvalue* rval;
244         struct rval_expr* rv_expr;
245         select_t* select;
246 }
247
248 /* terminals */
249
250
251 /* keywords */
252 %token FORWARD
253 %token FORWARD_TCP
254 %token FORWARD_TLS
255 %token FORWARD_SCTP
256 %token FORWARD_UDP
257 %token SEND
258 %token SEND_TCP
259 %token DROP
260 %token RETURN
261 %token BREAK
262 %token LOG_TOK
263 %token ERROR
264 %token ROUTE
265 %token ROUTE_FAILURE
266 %token ROUTE_ONREPLY
267 %token ROUTE_BRANCH
268 %token ROUTE_SEND
269 %token EXEC
270 %token SET_HOST
271 %token SET_HOSTPORT
272 %token SET_HOSTPORTTRANS
273 %token PREFIX
274 %token STRIP
275 %token STRIP_TAIL
276 %token SET_USERPHONE
277 %token APPEND_BRANCH
278 %token SET_USER
279 %token SET_USERPASS
280 %token SET_PORT
281 %token SET_URI
282 %token REVERT_URI
283 %token FORCE_RPORT
284 %token FORCE_TCP_ALIAS
285 %token UDP_MTU
286 %token UDP_MTU_TRY_PROTO
287 %token IF
288 %token ELSE
289 %token SET_ADV_ADDRESS
290 %token SET_ADV_PORT
291 %token FORCE_SEND_SOCKET
292 %token SWITCH
293 %token CASE
294 %token DEFAULT
295 %token WHILE
296 %token URIHOST
297 %token URIPORT
298 %token MAX_LEN
299 %token SETFLAG
300 %token RESETFLAG
301 %token ISFLAGSET
302 %token SETAVPFLAG
303 %token RESETAVPFLAG
304 %token ISAVPFLAGSET
305 %token METHOD
306 %token URI
307 %token FROM_URI
308 %token TO_URI
309 %token SRCIP
310 %token SRCPORT
311 %token DSTIP
312 %token DSTPORT
313 %token TOIP
314 %token TOPORT
315 %token SNDIP
316 %token SNDPORT
317 %token SNDPROTO
318 %token SNDAF
319 %token PROTO
320 %token AF
321 %token MYSELF
322 %token MSGLEN
323 %token RETCODE
324 %token UDP
325 %token TCP
326 %token TLS
327 %token SCTP
328
329 /* config vars. */
330 %token DEBUG_V
331 %token FORK
332 %token LOGSTDERROR
333 %token LOGFACILITY
334 %token LISTEN
335 %token ALIAS
336 %token SR_AUTO_ALIASES
337 %token DNS
338 %token REV_DNS
339 %token DNS_TRY_IPV6
340 %token DNS_TRY_NAPTR
341 %token DNS_SRV_LB
342 %token DNS_UDP_PREF
343 %token DNS_TCP_PREF
344 %token DNS_TLS_PREF
345 %token DNS_SCTP_PREF
346 %token DNS_RETR_TIME
347 %token DNS_RETR_NO
348 %token DNS_SERVERS_NO
349 %token DNS_USE_SEARCH
350 %token DNS_SEARCH_FMATCH
351 %token DNS_CACHE_INIT
352 %token DNS_USE_CACHE
353 %token DNS_USE_FAILOVER
354 %token DNS_CACHE_FLAGS
355 %token DNS_CACHE_NEG_TTL
356 %token DNS_CACHE_MIN_TTL
357 %token DNS_CACHE_MAX_TTL
358 %token DNS_CACHE_MEM
359 %token DNS_CACHE_GC_INT
360 %token DNS_CACHE_DEL_NONEXP
361 /*blacklist*/
362 %token DST_BLST_INIT
363 %token USE_DST_BLST
364 %token DST_BLST_MEM
365 %token DST_BLST_TTL
366 %token DST_BLST_GC_INT
367
368 %token PORT
369 %token STAT
370 %token CHILDREN
371 %token CHECK_VIA
372 %token PHONE2TEL
373 %token SYN_BRANCH
374 %token MEMLOG
375 %token MEMDBG
376 %token SIP_WARNING
377 %token SERVER_SIGNATURE
378 %token REPLY_TO_VIA
379 %token LOADMODULE
380 %token LOADPATH
381 %token MODPARAM
382 %token MAXBUFFER
383 %token USER
384 %token GROUP
385 %token CHROOT
386 %token WDIR
387 %token MHOMED
388 %token DISABLE_TCP
389 %token TCP_ACCEPT_ALIASES
390 %token TCP_CHILDREN
391 %token TCP_CONNECT_TIMEOUT
392 %token TCP_SEND_TIMEOUT
393 %token TCP_CON_LIFETIME
394 %token TCP_POLL_METHOD
395 %token TCP_MAX_CONNECTIONS
396 %token TCP_NO_CONNECT
397 %token TCP_SOURCE_IPV4
398 %token TCP_SOURCE_IPV6
399 %token TCP_OPT_FD_CACHE
400 %token TCP_OPT_BUF_WRITE
401 %token TCP_OPT_CONN_WQ_MAX
402 %token TCP_OPT_WQ_MAX
403 %token TCP_OPT_RD_BUF
404 %token TCP_OPT_WQ_BLK
405 %token TCP_OPT_DEFER_ACCEPT
406 %token TCP_OPT_DELAYED_ACK
407 %token TCP_OPT_SYNCNT
408 %token TCP_OPT_LINGER2
409 %token TCP_OPT_KEEPALIVE
410 %token TCP_OPT_KEEPIDLE
411 %token TCP_OPT_KEEPINTVL
412 %token TCP_OPT_KEEPCNT
413 %token TCP_OPT_CRLF_PING
414 %token DISABLE_TLS
415 %token ENABLE_TLS
416 %token TLSLOG
417 %token TLS_PORT_NO
418 %token TLS_METHOD
419 %token TLS_HANDSHAKE_TIMEOUT
420 %token TLS_SEND_TIMEOUT
421 %token SSLv23
422 %token SSLv2
423 %token SSLv3
424 %token TLSv1
425 %token TLS_VERIFY
426 %token TLS_REQUIRE_CERTIFICATE
427 %token TLS_CERTIFICATE
428 %token TLS_PRIVATE_KEY
429 %token TLS_CA_LIST
430 %token DISABLE_SCTP
431 %token ENABLE_SCTP
432 %token SCTP_CHILDREN
433 %token SCTP_SOCKET_RCVBUF
434 %token SCTP_SOCKET_SNDBUF
435 %token SCTP_AUTOCLOSE
436 %token SCTP_SEND_TTL
437 %token SCTP_SEND_RETRIES
438 %token ADVERTISED_ADDRESS
439 %token ADVERTISED_PORT
440 %token DISABLE_CORE
441 %token OPEN_FD_LIMIT
442 %token SHM_FORCE_ALLOC
443 %token MLOCK_PAGES
444 %token REAL_TIME
445 %token RT_PRIO
446 %token RT_POLICY
447 %token RT_TIMER1_PRIO
448 %token RT_TIMER1_POLICY
449 %token RT_TIMER2_PRIO
450 %token RT_TIMER2_POLICY
451 %token MCAST_LOOPBACK
452 %token MCAST_TTL
453 %token TOS
454 %token PMTU_DISCOVERY
455 %token KILL_TIMEOUT
456 %token MAX_WLOOPS
457 %token CFG_DESCRIPTION
458 %token SERVER_ID
459
460 %token FLAGS_DECL
461 %token AVPFLAGS_DECL
462
463 %token ATTR_MARK
464 %token SELECT_MARK
465 %token ATTR_FROM
466 %token ATTR_TO
467 %token ATTR_FROMURI
468 %token ATTR_TOURI
469 %token ATTR_FROMUSER
470 %token ATTR_TOUSER
471 %token ATTR_FROMDOMAIN
472 %token ATTR_TODOMAIN
473 %token ATTR_GLOBAL
474 %token ADDEQ
475
476
477 %token STUN_REFRESH_INTERVAL
478 %token STUN_ALLOW_STUN
479 %token STUN_ALLOW_FP
480
481
482 /* operators, C like precedence */
483 %right EQUAL
484 %left LOG_OR
485 %left LOG_AND
486 %left BIN_OR
487 %left BIN_AND
488 %left EQUAL_T DIFF MATCH INTEQ INTDIFF STREQ STRDIFF
489 %left GT LT GTE LTE
490 %left PLUS MINUS
491 %left STAR SLASH
492 %right NOT
493 %right DEFINED
494 %left DOT
495
496 /* no precedence, they use () */
497 %token STRLEN
498 %token STREMPTY
499
500 /* values */
501 %token <intval> NUMBER
502 %token <strval> ID
503 %token <strval> STRING
504 %token <strval> IPV6ADDR
505 %token <strval> PVAR
506 /* not clear yet if this is an avp or pvar */
507 %token <strval> AVP_OR_PVAR
508
509 /* other */
510 %token COMMA
511 %token SEMICOLON
512 %token RPAREN
513 %token LPAREN
514 %token LBRACE
515 %token RBRACE
516 %token LBRACK
517 %token RBRACK
518 %token CR
519 %token COLON
520
521
522 /*non-terminals */
523 %type <expr> exp exp_elem
524 %type <intval> intno eint_op eint_op_onsend
525 %type <intval> eip_op eip_op_onsend
526 %type <action> action actions cmd fcmd if_cmd stm /*exp_stm*/ assign_action
527 %type <action> switch_cmd while_cmd
528 %type <case_stms> single_case case_stms
529 %type <ipaddr> ipv4 ipv6 ipv6addr ip
530 %type <ipnet> ipnet
531 %type <strval> host
532 %type <strval> listen_id
533 %type <name_l> listen_id_lst
534 %type <name_l> listen_id2
535 %type <sockid>  id_lst
536 %type <sockid>  phostport
537 %type <sockid>  listen_phostport
538 %type <intval> proto port
539 %type <intval> equalop strop cmpop rve_cmpop rve_equalop
540 %type <intval> uri_type
541 %type <attr> attr_id
542 %type <attr> attr_id_num_idx
543 %type <attr> attr_id_no_idx
544 %type <attr> attr_id_ass
545 /*%type <attr> attr_id_val*/
546 %type <attr> attr_id_any
547 %type <attr> attr_id_any_str
548 %type <pvar> pvar
549 %type <lval> lval
550 %type <rv_expr> rval rval_expr ct_rval
551 %type <lval> avp_pvar
552 /* %type <intval> class_id */
553 %type <intval> assign_op
554 %type <select> select_id
555 %type <strval>  flag_name;
556 %type <strval>  route_name;
557 %type <intval> avpflag_oper
558 %type <intval> rve_un_op
559 /* %type <intval> rve_op */
560
561 /*%type <route_el> rules;
562   %type <route_el> rule;
563 */
564
565 %%
566
567
568 cfg:
569         statements
570         ;
571 statements:
572         statements statement {}
573         | statement {}
574         | statements error { yyerror(""); YYABORT;}
575         ;
576 statement:
577         assign_stm
578         | flags_decl
579         | avpflags_decl
580         | module_stm
581         | {rt=REQUEST_ROUTE;} route_stm
582         | {rt=FAILURE_ROUTE;} failure_route_stm
583         | {rt=ONREPLY_ROUTE;} onreply_route_stm
584         | {rt=BRANCH_ROUTE;} branch_route_stm
585         | {rt=ONSEND_ROUTE;}   send_route_stm
586         | SEMICOLON     /* null statement */
587         | CR    /* null statement*/
588         ;
589 listen_id:
590         ip {
591                 tmp=ip_addr2a($1);
592                 if (tmp==0) {
593                         LOG(L_CRIT, "ERROR: cfg. parser: bad ip "
594                                         "address.\n");
595                         $$=0;
596                 } else {
597                         $$=pkg_malloc(strlen(tmp)+1);
598                         if ($$==0) {
599                                 LOG(L_CRIT, "ERROR: cfg. parser: out of "
600                                                 "memory.\n");
601                         } else {
602                                 strncpy($$, tmp, strlen(tmp)+1);
603                         }
604                 }
605         }
606         | STRING {
607                 $$=pkg_malloc(strlen($1)+1);
608                 if ($$==0) {
609                                 LOG(L_CRIT, "ERROR: cfg. parser: out of "
610                                                 "memory.\n");
611                 } else {
612                                 strncpy($$, $1, strlen($1)+1);
613                 }
614         }
615         | host {
616                 $$=pkg_malloc(strlen($1)+1);
617                 if ($$==0) {
618                                 LOG(L_CRIT, "ERROR: cfg. parser: out of "
619                                                 "memory.\n");
620                 } else {
621                                 strncpy($$, $1, strlen($1)+1);
622                 }
623         }
624         ;
625
626
627 listen_id_lst:
628         listen_id       { $$=mk_name_lst($1, SI_IS_MHOMED); }
629         | listen_id COMMA listen_id_lst { $$=mk_name_lst($1, SI_IS_MHOMED); 
630                                                                                 if ($$) $$->next=$3;
631                                                                         }
632         ;
633
634 listen_id2:
635         LPAREN listen_id_lst RPAREN { $$=$2; }
636         | listen_id     { $$=mk_name_lst($1, 0); }
637         ;
638
639 proto:
640         UDP     { $$=PROTO_UDP; }
641         | TCP   { $$=PROTO_TCP; }
642         | TLS   { $$=PROTO_TLS; }
643         | SCTP  { $$=PROTO_SCTP; }
644         | STAR  { $$=0; }
645         ;
646 port:
647         NUMBER  { $$=$1; }
648         | STAR  { $$=0; }
649 ;
650 phostport:
651         listen_id               { $$=mk_listen_id($1, 0, 0); }
652         | listen_id COLON port  { $$=mk_listen_id($1, 0, $3); }
653         | proto COLON listen_id { $$=mk_listen_id($3, $1, 0); }
654         | proto COLON listen_id COLON port      { $$=mk_listen_id($3, $1, $5);}
655         | listen_id COLON error { $$=0; yyerror(" port number expected"); }
656         ;
657
658 listen_phostport:
659         listen_id2              { $$=mk_listen_id2($1, 0, 0); }
660         | listen_id2 COLON port { $$=mk_listen_id2($1, 0, $3); }
661         | proto COLON listen_id2        { $$=mk_listen_id2($3, $1, 0); }
662         | proto COLON listen_id2 COLON port     { $$=mk_listen_id2($3, $1, $5);}
663         | listen_id2 COLON error { $$=0; yyerror(" port number expected"); }
664         ;
665
666 id_lst:
667         listen_phostport                {  $$=$1 ; }
668         | listen_phostport id_lst       { $$=$1; $$->next=$2; }
669         ;
670
671 intno: NUMBER
672         |  MINUS %prec NOT NUMBER { $$=-$2; }
673         ;
674
675 flags_decl:             FLAGS_DECL      flag_list
676                         |       FLAGS_DECL error { yyerror("flag list expected\n"); }
677 ;
678 flag_list:              flag_spec
679                         |       flag_spec COMMA flag_list
680 ;
681
682 flag_spec:              flag_name       { if (register_flag($1,-1)<0)
683                                                                 yyerror("register flag failed");
684                                                 }
685                         |       flag_name COLON NUMBER {
686                                                 if (register_flag($1, $3)<0)
687                                                                 yyerror("register flag failed");
688                                                                                 }
689 ;
690
691 flag_name:              STRING  { $$=$1; }
692                         |       ID              { $$=$1; }
693 ;
694
695 avpflags_decl:
696         AVPFLAGS_DECL avpflag_list
697         | AVPFLAGS_DECL error { yyerror("avpflag list expected\n"); }
698         ;
699 avpflag_list:
700         avpflag_spec
701         | avpflag_spec COMMA avpflag_list
702         ;
703 avpflag_spec:
704         flag_name {
705                 if (register_avpflag($1)==0)
706                         yyerror("cannot declare avpflag");
707         }
708         ;
709 assign_stm:
710         DEBUG_V EQUAL intno { default_core_cfg.debug=$3; }
711         | DEBUG_V EQUAL error  { yyerror("number  expected"); }
712         | FORK  EQUAL NUMBER { dont_fork= ! $3; }
713         | FORK  EQUAL error  { yyerror("boolean value expected"); }
714         | LOGSTDERROR EQUAL NUMBER { if (!config_check) log_stderr=$3; }
715         | LOGSTDERROR EQUAL error { yyerror("boolean value expected"); }
716         | LOGFACILITY EQUAL ID {
717                 if ( (i_tmp=str2facility($3))==-1)
718                         yyerror("bad facility (see syslog(3) man page)");
719                 if (!config_check)
720                         default_core_cfg.log_facility=i_tmp;
721         }
722         | LOGFACILITY EQUAL error { yyerror("ID expected"); }
723         | DNS EQUAL NUMBER   { received_dns|= ($3)?DO_DNS:0; }
724         | DNS EQUAL error { yyerror("boolean value expected"); }
725         | REV_DNS EQUAL NUMBER { received_dns|= ($3)?DO_REV_DNS:0; }
726         | REV_DNS EQUAL error { yyerror("boolean value expected"); }
727         | DNS_TRY_IPV6 EQUAL NUMBER   { default_core_cfg.dns_try_ipv6=$3; }
728         | DNS_TRY_IPV6 error { yyerror("boolean value expected"); }
729         | DNS_TRY_NAPTR EQUAL NUMBER   { IF_NAPTR(default_core_cfg.dns_try_naptr=$3); }
730         | DNS_TRY_NAPTR error { yyerror("boolean value expected"); }
731         | DNS_SRV_LB EQUAL NUMBER   { IF_DNS_FAILOVER(default_core_cfg.dns_srv_lb=$3); }
732         | DNS_SRV_LB error { yyerror("boolean value expected"); }
733         | DNS_UDP_PREF EQUAL intno { IF_NAPTR(default_core_cfg.dns_udp_pref=$3);}
734         | DNS_UDP_PREF error { yyerror("number expected"); }
735         | DNS_TCP_PREF EQUAL intno { IF_NAPTR(default_core_cfg.dns_tcp_pref=$3);}
736         | DNS_TCP_PREF error { yyerror("number expected"); }
737         | DNS_TLS_PREF EQUAL intno { IF_NAPTR(default_core_cfg.dns_tls_pref=$3);}
738         | DNS_TLS_PREF error { yyerror("number expected"); }
739         | DNS_SCTP_PREF EQUAL intno { 
740                                                                 IF_NAPTR(default_core_cfg.dns_sctp_pref=$3); }
741         | DNS_SCTP_PREF error { yyerror("number expected"); }
742         | DNS_RETR_TIME EQUAL NUMBER   { default_core_cfg.dns_retr_time=$3; }
743         | DNS_RETR_TIME error { yyerror("number expected"); }
744         | DNS_RETR_NO EQUAL NUMBER   { default_core_cfg.dns_retr_no=$3; }
745         | DNS_RETR_NO error { yyerror("number expected"); }
746         | DNS_SERVERS_NO EQUAL NUMBER   { default_core_cfg.dns_servers_no=$3; }
747         | DNS_SERVERS_NO error { yyerror("number expected"); }
748         | DNS_USE_SEARCH EQUAL NUMBER   { default_core_cfg.dns_search_list=$3; }
749         | DNS_USE_SEARCH error { yyerror("boolean value expected"); }
750         | DNS_SEARCH_FMATCH EQUAL NUMBER   { default_core_cfg.dns_search_fmatch=$3; }
751         | DNS_SEARCH_FMATCH error { yyerror("boolean value expected"); }
752         | DNS_CACHE_INIT EQUAL NUMBER   { IF_DNS_CACHE(dns_cache_init=$3); }
753         | DNS_CACHE_INIT error { yyerror("boolean value expected"); }
754         | DNS_USE_CACHE EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.use_dns_cache=$3); }
755         | DNS_USE_CACHE error { yyerror("boolean value expected"); }
756         | DNS_USE_FAILOVER EQUAL NUMBER   { IF_DNS_FAILOVER(default_core_cfg.use_dns_failover=$3);}
757         | DNS_USE_FAILOVER error { yyerror("boolean value expected"); }
758         | DNS_CACHE_FLAGS EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_cache_flags=$3); }
759         | DNS_CACHE_FLAGS error { yyerror("boolean value expected"); }
760         | DNS_CACHE_NEG_TTL EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_neg_cache_ttl=$3); }
761         | DNS_CACHE_NEG_TTL error { yyerror("boolean value expected"); }
762         | DNS_CACHE_MAX_TTL EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_cache_max_ttl=$3); }
763         | DNS_CACHE_MAX_TTL error { yyerror("boolean value expected"); }
764         | DNS_CACHE_MIN_TTL EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_cache_min_ttl=$3); }
765         | DNS_CACHE_MIN_TTL error { yyerror("boolean value expected"); }
766         | DNS_CACHE_MEM EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_cache_max_mem=$3); }
767         | DNS_CACHE_MEM error { yyerror("boolean value expected"); }
768         | DNS_CACHE_GC_INT EQUAL NUMBER   { IF_DNS_CACHE(dns_timer_interval=$3); }
769         | DNS_CACHE_GC_INT error { yyerror("boolean value expected"); }
770         | DNS_CACHE_DEL_NONEXP EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_cache_del_nonexp=$3); }
771         | DNS_CACHE_DEL_NONEXP error { yyerror("boolean value expected"); }
772         | DST_BLST_INIT EQUAL NUMBER   { IF_DST_BLACKLIST(dst_blacklist_init=$3); }
773         | DST_BLST_INIT error { yyerror("boolean value expected"); }
774         | USE_DST_BLST EQUAL NUMBER   { IF_DST_BLACKLIST(default_core_cfg.use_dst_blacklist=$3); }
775         | USE_DST_BLST error { yyerror("boolean value expected"); }
776         | DST_BLST_MEM EQUAL NUMBER   { IF_DST_BLACKLIST(default_core_cfg.blst_max_mem=$3); }
777         | DST_BLST_MEM error { yyerror("boolean value expected"); }
778         | DST_BLST_TTL EQUAL NUMBER   { IF_DST_BLACKLIST(default_core_cfg.blst_timeout=$3); }
779         | DST_BLST_TTL error { yyerror("boolean value expected"); }
780         | DST_BLST_GC_INT EQUAL NUMBER { IF_DST_BLACKLIST(blst_timer_interval=$3);}
781         | DST_BLST_GC_INT error { yyerror("boolean value expected"); }
782         | PORT EQUAL NUMBER   { port_no=$3; }
783         | STAT EQUAL STRING {
784                 #ifdef STATS
785                                 stat_file=$3;
786                 #endif
787         }
788         | MAXBUFFER EQUAL NUMBER { maxbuffer=$3; }
789         | MAXBUFFER EQUAL error { yyerror("number expected"); }
790         | PORT EQUAL error    { yyerror("number expected"); }
791         | CHILDREN EQUAL NUMBER { children_no=$3; }
792         | CHILDREN EQUAL error { yyerror("number expected"); }
793         | CHECK_VIA EQUAL NUMBER { check_via=$3; }
794         | CHECK_VIA EQUAL error { yyerror("boolean value expected"); }
795         | PHONE2TEL EQUAL NUMBER { phone2tel=$3; }
796         | PHONE2TEL EQUAL error { yyerror("boolean value expected"); }
797         | SYN_BRANCH EQUAL NUMBER { syn_branch=$3; }
798         | SYN_BRANCH EQUAL error { yyerror("boolean value expected"); }
799         | MEMLOG EQUAL intno { memlog=$3; }
800         | MEMLOG EQUAL error { yyerror("int value expected"); }
801         | MEMDBG EQUAL intno { memdbg=$3; }
802         | MEMDBG EQUAL error { yyerror("int value expected"); }
803         | SIP_WARNING EQUAL NUMBER { sip_warning=$3; }
804         | SIP_WARNING EQUAL error { yyerror("boolean value expected"); }
805         | USER EQUAL STRING     { user=$3; }
806         | USER EQUAL ID         { user=$3; }
807         | USER EQUAL error      { yyerror("string value expected"); }
808         | GROUP EQUAL STRING     { group=$3; }
809         | GROUP EQUAL ID         { group=$3; }
810         | GROUP EQUAL error      { yyerror("string value expected"); }
811         | CHROOT EQUAL STRING     { chroot_dir=$3; }
812         | CHROOT EQUAL ID         { chroot_dir=$3; }
813         | CHROOT EQUAL error      { yyerror("string value expected"); }
814         | WDIR EQUAL STRING     { working_dir=$3; }
815         | WDIR EQUAL ID         { working_dir=$3; }
816         | WDIR EQUAL error      { yyerror("string value expected"); }
817         | MHOMED EQUAL NUMBER { mhomed=$3; }
818         | MHOMED EQUAL error { yyerror("boolean value expected"); }
819         | DISABLE_TCP EQUAL NUMBER {
820                 #ifdef USE_TCP
821                         tcp_disable=$3;
822                 #else
823                         warn("tcp support not compiled in");
824                 #endif
825         }
826         | DISABLE_TCP EQUAL error { yyerror("boolean value expected"); }
827         | TCP_ACCEPT_ALIASES EQUAL NUMBER {
828                 #ifdef USE_TCP
829                         tcp_default_cfg.accept_aliases=$3;
830                 #else
831                         warn("tcp support not compiled in");
832                 #endif
833         }
834         | TCP_ACCEPT_ALIASES EQUAL error { yyerror("boolean value expected"); }
835         | TCP_CHILDREN EQUAL NUMBER {
836                 #ifdef USE_TCP
837                         tcp_children_no=$3;
838                 #else
839                         warn("tcp support not compiled in");
840                 #endif
841         }
842         | TCP_CHILDREN EQUAL error { yyerror("number expected"); }
843         | TCP_CONNECT_TIMEOUT EQUAL intno {
844                 #ifdef USE_TCP
845                         tcp_default_cfg.connect_timeout_s=$3;
846                 #else
847                         warn("tcp support not compiled in");
848                 #endif
849         }
850         | TCP_CONNECT_TIMEOUT EQUAL error { yyerror("number expected"); }
851         | TCP_SEND_TIMEOUT EQUAL intno {
852                 #ifdef USE_TCP
853                         tcp_default_cfg.send_timeout=S_TO_TICKS($3);
854                 #else
855                         warn("tcp support not compiled in");
856                 #endif
857         }
858         | TCP_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
859         | TCP_CON_LIFETIME EQUAL intno {
860                 #ifdef USE_TCP
861                         if ($3<0)
862                                 tcp_default_cfg.con_lifetime=-1;
863                         else
864                                 tcp_default_cfg.con_lifetime=S_TO_TICKS($3);
865                 #else
866                         warn("tcp support not compiled in");
867                 #endif
868         }
869         | TCP_CON_LIFETIME EQUAL error { yyerror("number expected"); }
870         | TCP_POLL_METHOD EQUAL ID {
871                 #ifdef USE_TCP
872                         tcp_poll_method=get_poll_type($3);
873                         if (tcp_poll_method==POLL_NONE) {
874                                 LOG(L_CRIT, "bad poll method name:"
875                                                 " %s\n, try one of %s.\n",
876                                                 $3, poll_support);
877                                 yyerror("bad tcp_poll_method "
878                                                 "value");
879                         }
880                 #else
881                         warn("tcp support not compiled in");
882                 #endif
883         }
884         | TCP_POLL_METHOD EQUAL STRING {
885                 #ifdef USE_TCP
886                         tcp_poll_method=get_poll_type($3);
887                         if (tcp_poll_method==POLL_NONE) {
888                                 LOG(L_CRIT, "bad poll method name:"
889                                                 " %s\n, try one of %s.\n",
890                                                 $3, poll_support);
891                                 yyerror("bad tcp_poll_method "
892                                                 "value");
893                         }
894                 #else
895                         warn("tcp support not compiled in");
896                 #endif
897         }
898         | TCP_POLL_METHOD EQUAL error { yyerror("poll method name expected"); }
899         | TCP_MAX_CONNECTIONS EQUAL NUMBER {
900                 #ifdef USE_TCP
901                         tcp_max_connections=$3;
902                 #else
903                         warn("tcp support not compiled in");
904                 #endif
905         }
906         | TCP_MAX_CONNECTIONS EQUAL error { yyerror("number expected"); }
907         | TCP_NO_CONNECT EQUAL NUMBER {
908                 #ifdef USE_TCP
909                         tcp_default_cfg.no_connect=$3;
910                 #else
911                         warn("tcp support not compiled in");
912                 #endif
913         }
914         | TCP_NO_CONNECT EQUAL error { yyerror("boolean value expected"); }
915         | TCP_SOURCE_IPV4 EQUAL ipv4 {
916                 #ifdef USE_TCP
917                         if (tcp_set_src_addr($3)<0)
918                                 warn("tcp_source_ipv4 failed");
919                 #else
920                         warn("tcp support not compiled in");
921                 #endif
922                 pkg_free($3);
923         }
924         | TCP_SOURCE_IPV4 EQUAL error { yyerror("IPv4 address expected"); }
925         | TCP_SOURCE_IPV6 EQUAL ipv6 {
926                 #ifdef USE_TCP
927                         #ifdef USE_IPV6
928                                 if (tcp_set_src_addr($3)<0)
929                                         warn("tcp_source_ipv6 failed");
930                         #else
931                                 warn("IPv6 support not compiled in");
932                         #endif
933                 #else
934                         warn("tcp support not compiled in");
935                 #endif
936                 pkg_free($3);
937         }
938         | TCP_SOURCE_IPV6 EQUAL error { yyerror("IPv6 address expected"); }
939         | TCP_OPT_FD_CACHE EQUAL NUMBER {
940                 #ifdef USE_TCP
941                         tcp_default_cfg.fd_cache=$3;
942                 #else
943                         warn("tcp support not compiled in");
944                 #endif
945         }
946         | TCP_OPT_FD_CACHE EQUAL error { yyerror("boolean value expected"); }
947         | TCP_OPT_BUF_WRITE EQUAL NUMBER {
948                 #ifdef USE_TCP
949                         tcp_default_cfg.async=$3;
950                 #else
951                         warn("tcp support not compiled in");
952                 #endif
953         }
954         | TCP_OPT_BUF_WRITE EQUAL error { yyerror("boolean value expected"); }
955         | TCP_OPT_CONN_WQ_MAX EQUAL NUMBER {
956                 #ifdef USE_TCP
957                         tcp_default_cfg.tcpconn_wq_max=$3;
958                 #else
959                         warn("tcp support not compiled in");
960                 #endif
961         }
962         | TCP_OPT_CONN_WQ_MAX error { yyerror("boolean value expected"); }
963         | TCP_OPT_WQ_MAX EQUAL NUMBER {
964                 #ifdef USE_TCP
965                         tcp_default_cfg.tcp_wq_max=$3;
966                 #else
967                         warn("tcp support not compiled in");
968                 #endif
969         }
970         | TCP_OPT_WQ_MAX error { yyerror("number expected"); }
971         | TCP_OPT_RD_BUF EQUAL NUMBER {
972                 #ifdef USE_TCP
973                         tcp_default_cfg.rd_buf_size=$3;
974                 #else
975                         warn("tcp support not compiled in");
976                 #endif
977         }
978         | TCP_OPT_RD_BUF error { yyerror("number expected"); }
979         | TCP_OPT_WQ_BLK EQUAL NUMBER {
980                 #ifdef USE_TCP
981                         tcp_default_cfg.wq_blk_size=$3;
982                 #else
983                         warn("tcp support not compiled in");
984                 #endif
985         }
986         | TCP_OPT_WQ_BLK error { yyerror("number expected"); }
987         | TCP_OPT_DEFER_ACCEPT EQUAL NUMBER {
988                 #ifdef USE_TCP
989                         tcp_default_cfg.defer_accept=$3;
990                 #else
991                         warn("tcp support not compiled in");
992                 #endif
993         }
994         | TCP_OPT_DEFER_ACCEPT EQUAL error { yyerror("boolean value expected"); }
995         | TCP_OPT_DELAYED_ACK EQUAL NUMBER {
996                 #ifdef USE_TCP
997                         tcp_default_cfg.delayed_ack=$3;
998                 #else
999                         warn("tcp support not compiled in");
1000                 #endif
1001         }
1002         | TCP_OPT_DELAYED_ACK EQUAL error { yyerror("boolean value expected"); }
1003         | TCP_OPT_SYNCNT EQUAL NUMBER {
1004                 #ifdef USE_TCP
1005                         tcp_default_cfg.syncnt=$3;
1006                 #else
1007                         warn("tcp support not compiled in");
1008                 #endif
1009         }
1010         | TCP_OPT_SYNCNT EQUAL error { yyerror("number expected"); }
1011         | TCP_OPT_LINGER2 EQUAL NUMBER {
1012                 #ifdef USE_TCP
1013                         tcp_default_cfg.linger2=$3;
1014                 #else
1015                         warn("tcp support not compiled in");
1016                 #endif
1017         }
1018         | TCP_OPT_LINGER2 EQUAL error { yyerror("number expected"); }
1019         | TCP_OPT_KEEPALIVE EQUAL NUMBER {
1020                 #ifdef USE_TCP
1021                         tcp_default_cfg.keepalive=$3;
1022                 #else
1023                         warn("tcp support not compiled in");
1024                 #endif
1025         }
1026         | TCP_OPT_KEEPALIVE EQUAL error { yyerror("boolean value expected");}
1027         | TCP_OPT_KEEPIDLE EQUAL NUMBER {
1028                 #ifdef USE_TCP
1029                         tcp_default_cfg.keepidle=$3;
1030                 #else
1031                         warn("tcp support not compiled in");
1032                 #endif
1033         }
1034         | TCP_OPT_KEEPIDLE EQUAL error { yyerror("number expected"); }
1035         | TCP_OPT_KEEPINTVL EQUAL NUMBER {
1036                 #ifdef USE_TCP
1037                         tcp_default_cfg.keepintvl=$3;
1038                 #else
1039                         warn("tcp support not compiled in");
1040                 #endif
1041         }
1042         | TCP_OPT_KEEPINTVL EQUAL error { yyerror("number expected"); }
1043         | TCP_OPT_KEEPCNT EQUAL NUMBER {
1044                 #ifdef USE_TCP
1045                         tcp_default_cfg.keepcnt=$3;
1046                 #else
1047                         warn("tcp support not compiled in");
1048                 #endif
1049         }
1050         | TCP_OPT_KEEPCNT EQUAL error { yyerror("number expected"); }
1051         | TCP_OPT_CRLF_PING EQUAL NUMBER {
1052                 #ifdef USE_TCP
1053                         tcp_default_cfg.crlf_ping=$3;
1054                 #else
1055                         warn("tcp support not compiled in");
1056                 #endif
1057         }
1058         | TCP_OPT_CRLF_PING EQUAL error { yyerror("boolean value expected"); }
1059         | DISABLE_TLS EQUAL NUMBER {
1060                 #ifdef USE_TLS
1061                         tls_disable=$3;
1062                 #else
1063                         warn("tls support not compiled in");
1064                 #endif
1065         }
1066         | DISABLE_TLS EQUAL error { yyerror("boolean value expected"); }
1067         | ENABLE_TLS EQUAL NUMBER {
1068                 #ifdef USE_TLS
1069                         tls_disable=!($3);
1070                 #else
1071                         warn("tls support not compiled in");
1072                 #endif
1073         }
1074         | ENABLE_TLS EQUAL error { yyerror("boolean value expected"); }
1075         | TLSLOG EQUAL NUMBER {
1076                 #ifdef CORE_TLS
1077                         tls_log=$3;
1078                 #else
1079                         warn("tls-in-core support not compiled in");
1080                 #endif
1081         }
1082         | TLSLOG EQUAL error { yyerror("int value expected"); }
1083         | TLS_PORT_NO EQUAL NUMBER {
1084                 #ifdef USE_TLS
1085                         tls_port_no=$3;
1086                 #else
1087                         warn("tls support not compiled in");
1088                 #endif
1089         }
1090         | TLS_PORT_NO EQUAL error { yyerror("number expected"); }
1091         | TLS_METHOD EQUAL SSLv23 {
1092                 #ifdef CORE_TLS
1093                         tls_method=TLS_USE_SSLv23;
1094                 #else
1095                         warn("tls-in-core support not compiled in");
1096                 #endif
1097         }
1098         | TLS_METHOD EQUAL SSLv2 {
1099                 #ifdef CORE_TLS
1100                         tls_method=TLS_USE_SSLv2;
1101                 #else
1102                         warn("tls-in-core support not compiled in");
1103                 #endif
1104         }
1105         | TLS_METHOD EQUAL SSLv3 {
1106                 #ifdef CORE_TLS
1107                         tls_method=TLS_USE_SSLv3;
1108                 #else
1109                         warn("tls-in-core support not compiled in");
1110                 #endif
1111         }
1112         | TLS_METHOD EQUAL TLSv1 {
1113                 #ifdef CORE_TLS
1114                         tls_method=TLS_USE_TLSv1;
1115                 #else
1116                         warn("tls-in-core support not compiled in");
1117                 #endif
1118         }
1119         | TLS_METHOD EQUAL error {
1120                 #ifdef CORE_TLS
1121                         yyerror("SSLv23, SSLv2, SSLv3 or TLSv1 expected");
1122                 #else
1123                         warn("tls-in-core support not compiled in");
1124                 #endif
1125         }
1126         | TLS_VERIFY EQUAL NUMBER {
1127                 #ifdef CORE_TLS
1128                         tls_verify_cert=$3;
1129                 #else
1130                         warn("tls-in-core support not compiled in");
1131                 #endif
1132         }
1133         | TLS_VERIFY EQUAL error { yyerror("boolean value expected"); }
1134         | TLS_REQUIRE_CERTIFICATE EQUAL NUMBER {
1135                 #ifdef CORE_TLS
1136                         tls_require_cert=$3;
1137                 #else
1138                         warn( "tls-in-core support not compiled in");
1139                 #endif
1140         }
1141         | TLS_REQUIRE_CERTIFICATE EQUAL error { yyerror("boolean value expected"); }
1142         | TLS_CERTIFICATE EQUAL STRING {
1143                 #ifdef CORE_TLS
1144                         tls_cert_file=$3;
1145                 #else
1146                         warn("tls-in-core support not compiled in");
1147                 #endif
1148         }
1149         | TLS_CERTIFICATE EQUAL error { yyerror("string value expected"); }
1150         | TLS_PRIVATE_KEY EQUAL STRING {
1151                 #ifdef CORE_TLS
1152                         tls_pkey_file=$3;
1153                 #else
1154                         warn("tls-in-core support not compiled in");
1155                 #endif
1156         }
1157         | TLS_PRIVATE_KEY EQUAL error { yyerror("string value expected"); }
1158         | TLS_CA_LIST EQUAL STRING {
1159                 #ifdef CORE_TLS
1160                         tls_ca_file=$3;
1161                 #else
1162                         warn("tls-in-core support not compiled in");
1163                 #endif
1164         }
1165         | TLS_CA_LIST EQUAL error { yyerror("string value expected"); }
1166         | TLS_HANDSHAKE_TIMEOUT EQUAL NUMBER {
1167                 #ifdef CORE_TLS
1168                         tls_handshake_timeout=$3;
1169                 #else
1170                         warn("tls-in-core support not compiled in");
1171                 #endif
1172         }
1173         | TLS_HANDSHAKE_TIMEOUT EQUAL error { yyerror("number expected"); }
1174         | TLS_SEND_TIMEOUT EQUAL NUMBER {
1175                 #ifdef CORE_TLS
1176                         tls_send_timeout=$3;
1177                 #else
1178                         warn("tls-in-core support not compiled in");
1179                 #endif
1180         }
1181         | TLS_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
1182         | DISABLE_SCTP EQUAL NUMBER {
1183                 #ifdef USE_SCTP
1184                         sctp_disable=$3;
1185                 #else
1186                         warn("sctp support not compiled in");
1187                 #endif
1188         }
1189         | DISABLE_SCTP EQUAL error { yyerror("boolean value expected"); }
1190         | ENABLE_SCTP EQUAL NUMBER {
1191                 #ifdef USE_SCTP
1192                         sctp_disable=($3<=1)?!$3:$3;
1193                 #else
1194                         warn("sctp support not compiled in");
1195                 #endif
1196         }
1197         | ENABLE_SCTP EQUAL error { yyerror("boolean or number expected"); }
1198         | SCTP_CHILDREN EQUAL NUMBER {
1199                 #ifdef USE_SCTP
1200                         sctp_children_no=$3;
1201                 #else
1202                         warn("sctp support not compiled in");
1203                 #endif
1204         }
1205         | SCTP_CHILDREN EQUAL error { yyerror("number expected"); }
1206         | SCTP_SOCKET_RCVBUF EQUAL NUMBER {
1207                 #ifdef USE_SCTP
1208                         sctp_options.sctp_so_rcvbuf=$3;
1209                 #else
1210                         warn("sctp support not compiled in");
1211                 #endif
1212         }
1213         | SCTP_SOCKET_RCVBUF EQUAL error { yyerror("number expected"); }
1214         | SCTP_SOCKET_SNDBUF EQUAL NUMBER {
1215                 #ifdef USE_SCTP
1216                         sctp_options.sctp_so_sndbuf=$3;
1217                 #else
1218                         warn("sctp support not compiled in");
1219                 #endif
1220         }
1221         | SCTP_SOCKET_SNDBUF EQUAL error { yyerror("number expected"); }
1222         | SCTP_AUTOCLOSE EQUAL NUMBER {
1223                 #ifdef USE_SCTP
1224                         sctp_options.sctp_autoclose=$3;
1225                 #else
1226                         warn("sctp support not compiled in");
1227                 #endif
1228         }
1229         | SCTP_AUTOCLOSE EQUAL error { yyerror("number expected"); }
1230         | SCTP_SEND_TTL EQUAL NUMBER {
1231                 #ifdef USE_SCTP
1232                         sctp_options.sctp_send_ttl=$3;
1233                 #else
1234                         warn("sctp support not compiled in");
1235                 #endif
1236         }
1237         | SCTP_SEND_TTL EQUAL error { yyerror("number expected"); }
1238         | SCTP_SEND_RETRIES EQUAL NUMBER {
1239                 #ifdef USE_SCTP
1240                         sctp_options.sctp_send_retries=$3;
1241                 #else
1242                         warn("sctp support not compiled in");
1243                 #endif
1244         }
1245         | SCTP_SEND_RETRIES EQUAL error { yyerror("number expected"); }
1246         | SERVER_SIGNATURE EQUAL NUMBER { server_signature=$3; }
1247         | SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); }
1248         | REPLY_TO_VIA EQUAL NUMBER { reply_to_via=$3; }
1249         | REPLY_TO_VIA EQUAL error { yyerror("boolean value expected"); }
1250         | LISTEN EQUAL id_lst {
1251                 for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
1252                         if (add_listen_iface(   lst_tmp->addr_lst->name,
1253                                                                         lst_tmp->addr_lst->next,
1254                                                                         lst_tmp->port, lst_tmp->proto,
1255                                                                         lst_tmp->flags)!=0) {
1256                                 LOG(L_CRIT,  "ERROR: cfg. parser: failed to add listen"
1257                                                                 " address\n");
1258                                 break;
1259                         }
1260                 }
1261                 free_socket_id_lst($3);
1262         }
1263         | LISTEN EQUAL  error { yyerror("ip address or hostname expected"); }
1264         | ALIAS EQUAL  id_lst {
1265                 for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next){
1266                         add_alias(      lst_tmp->addr_lst->name,
1267                                                 strlen(lst_tmp->addr_lst->name),
1268                                                 lst_tmp->port, lst_tmp->proto);
1269                         for (nl_tmp=lst_tmp->addr_lst->next; nl_tmp; nl_tmp=nl_tmp->next)
1270                                 add_alias(nl_tmp->name, strlen(nl_tmp->name),
1271                                                         lst_tmp->port, lst_tmp->proto);
1272                 }
1273                 free_socket_id_lst($3);
1274         }
1275         | ALIAS  EQUAL error  { yyerror(" hostname expected"); }
1276         | SR_AUTO_ALIASES EQUAL NUMBER { sr_auto_aliases=$3; }
1277         | SR_AUTO_ALIASES EQUAL error  { yyerror("boolean value expected"); }
1278         | ADVERTISED_ADDRESS EQUAL listen_id {
1279                 default_global_address.s=$3;
1280                 default_global_address.len=strlen($3);
1281         }
1282         | ADVERTISED_ADDRESS EQUAL error {yyerror("ip address or hostname expected"); }
1283         | ADVERTISED_PORT EQUAL NUMBER {
1284                 tmp=int2str($3, &i_tmp);
1285                 if ((default_global_port.s=pkg_malloc(i_tmp))==0) {
1286                         LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
1287                         default_global_port.len=0;
1288                 } else {
1289                         default_global_port.len=i_tmp;
1290                         memcpy(default_global_port.s, tmp, default_global_port.len);
1291                 };
1292         }
1293         |ADVERTISED_PORT EQUAL error {yyerror("ip address or hostname expected"); }
1294         | DISABLE_CORE EQUAL NUMBER { disable_core_dump=$3; }
1295         | DISABLE_CORE EQUAL error { yyerror("boolean value expected"); }
1296         | OPEN_FD_LIMIT EQUAL NUMBER { open_files_limit=$3; }
1297         | OPEN_FD_LIMIT EQUAL error { yyerror("number expected"); }
1298         | SHM_FORCE_ALLOC EQUAL NUMBER { shm_force_alloc=$3; }
1299         | SHM_FORCE_ALLOC EQUAL error { yyerror("boolean value expected"); }
1300         | MLOCK_PAGES EQUAL NUMBER { mlock_pages=$3; }
1301         | MLOCK_PAGES EQUAL error { yyerror("boolean value expected"); }
1302         | REAL_TIME EQUAL NUMBER { real_time=$3; }
1303         | REAL_TIME EQUAL error { yyerror("boolean value expected"); }
1304         | RT_PRIO EQUAL NUMBER { rt_prio=$3; }
1305         | RT_PRIO EQUAL error { yyerror("boolean value expected"); }
1306         | RT_POLICY EQUAL NUMBER { rt_policy=$3; }
1307         | RT_POLICY EQUAL error { yyerror("boolean value expected"); }
1308         | RT_TIMER1_PRIO EQUAL NUMBER { rt_timer1_prio=$3; }
1309         | RT_TIMER1_PRIO EQUAL error { yyerror("boolean value expected"); }
1310         | RT_TIMER1_POLICY EQUAL NUMBER { rt_timer1_policy=$3; }
1311         | RT_TIMER1_POLICY EQUAL error { yyerror("boolean value expected"); }
1312         | RT_TIMER2_PRIO EQUAL NUMBER { rt_timer2_prio=$3; }
1313         | RT_TIMER2_PRIO EQUAL error { yyerror("boolean value expected"); }
1314         | RT_TIMER2_POLICY EQUAL NUMBER { rt_timer2_policy=$3; }
1315         | RT_TIMER2_POLICY EQUAL error { yyerror("boolean value expected"); }
1316         | MCAST_LOOPBACK EQUAL NUMBER {
1317                 #ifdef USE_MCAST
1318                         mcast_loopback=$3;
1319                 #else
1320                         warn("no multicast support compiled in");
1321                 #endif
1322         }
1323         | MCAST_LOOPBACK EQUAL error { yyerror("boolean value expected"); }
1324         | MCAST_TTL EQUAL NUMBER {
1325                 #ifdef USE_MCAST
1326                         mcast_ttl=$3;
1327                 #else
1328                         warn("no multicast support compiled in");
1329                 #endif
1330         }
1331         | MCAST_TTL EQUAL error { yyerror("number expected"); }
1332         | TOS EQUAL NUMBER { tos=$3; }
1333         | TOS EQUAL error { yyerror("number expected"); }
1334         | PMTU_DISCOVERY EQUAL NUMBER { pmtu_discovery=$3; }
1335         | PMTU_DISCOVERY error { yyerror("number expected"); }
1336         | KILL_TIMEOUT EQUAL NUMBER { ser_kill_timeout=$3; }
1337         | KILL_TIMEOUT EQUAL error { yyerror("number expected"); }
1338         | MAX_WLOOPS EQUAL NUMBER { default_core_cfg.max_while_loops=$3; }
1339         | MAX_WLOOPS EQUAL error { yyerror("number expected"); }
1340         | STUN_REFRESH_INTERVAL EQUAL NUMBER { IF_STUN(stun_refresh_interval=$3); }
1341         | STUN_REFRESH_INTERVAL EQUAL error{ yyerror("number expected"); }
1342         | STUN_ALLOW_STUN EQUAL NUMBER { IF_STUN(stun_allow_stun=$3); }
1343         | STUN_ALLOW_STUN EQUAL error{ yyerror("number expected"); }
1344         | STUN_ALLOW_FP EQUAL NUMBER { IF_STUN(stun_allow_fp=$3) ; }
1345         | STUN_ALLOW_FP EQUAL error{ yyerror("number expected"); }
1346     | SERVER_ID EQUAL NUMBER { server_id=$3; }
1347         | UDP_MTU EQUAL NUMBER { default_core_cfg.udp_mtu=$3; }
1348         | UDP_MTU EQUAL error { yyerror("number expected"); }
1349         | FORCE_RPORT EQUAL NUMBER 
1350                 { default_core_cfg.force_rport=$3; fix_global_req_flags(0, 0); }
1351         | FORCE_RPORT EQUAL error { yyerror("boolean value expected"); }
1352         | UDP_MTU_TRY_PROTO EQUAL proto
1353                 { default_core_cfg.udp_mtu_try_proto=$3; fix_global_req_flags(0, 0); }
1354         | UDP_MTU_TRY_PROTO EQUAL error
1355                 { yyerror("TCP, TLS, SCTP or UDP expected"); }
1356         | cfg_var
1357         | error EQUAL { yyerror("unknown config variable"); }
1358         ;
1359 cfg_var:
1360         ID DOT ID EQUAL NUMBER {
1361                 if (cfg_declare_int($1, $3, $5, 0, 0, NULL)) {
1362                         yyerror("variable cannot be declared");
1363                 }
1364         }
1365         | ID DOT ID EQUAL STRING {
1366                 if (cfg_declare_str($1, $3, $5, NULL)) {
1367                         yyerror("variable cannot be declared");
1368                 }
1369         }
1370         | ID DOT ID EQUAL NUMBER CFG_DESCRIPTION STRING {
1371                 if (cfg_declare_int($1, $3, $5, 0, 0, $7)) {
1372                         yyerror("variable cannot be declared");
1373                 }
1374         }
1375         | ID DOT ID EQUAL STRING CFG_DESCRIPTION STRING {
1376                 if (cfg_declare_str($1, $3, $5, $7)) {
1377                         yyerror("variable cannot be declared");
1378                 }
1379         }
1380         | ID DOT ID EQUAL error { yyerror("number or string expected"); }
1381         ;
1382 module_stm:
1383         LOADMODULE STRING {
1384                 DBG("loading module %s\n", $2);
1385                         if (load_module($2)!=0) {
1386                                 yyerror("failed to load module");
1387                         }
1388         }
1389         | LOADMODULE error      { yyerror("string expected"); }
1390         | LOADPATH STRING {
1391                 DBG("loading modules under %s\n", $2);
1392                 printf("loading modules under %s\n", $2);
1393                 mods_dir = $2;
1394         }
1395         | LOADPATH error        { yyerror("string expected"); }
1396         | MODPARAM LPAREN STRING COMMA STRING COMMA STRING RPAREN {
1397                 if (set_mod_param_regex($3, $5, PARAM_STRING, $7) != 0) {
1398                          yyerror("Can't set module parameter");
1399                 }
1400         }
1401         | MODPARAM LPAREN STRING COMMA STRING COMMA NUMBER RPAREN {
1402                 if (set_mod_param_regex($3, $5, PARAM_INT, (void*)$7) != 0) {
1403                          yyerror("Can't set module parameter");
1404                 }
1405         }
1406         | MODPARAM error { yyerror("Invalid arguments"); }
1407         ;
1408 ip:
1409         ipv4  { $$=$1; }
1410         | ipv6  { $$=$1; }
1411         ;
1412 ipv4:
1413         NUMBER DOT NUMBER DOT NUMBER DOT NUMBER {
1414                 $$=pkg_malloc(sizeof(struct ip_addr));
1415                 if ($$==0) {
1416                         LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
1417                 } else {
1418                         memset($$, 0, sizeof(struct ip_addr));
1419                         $$->af=AF_INET;
1420                         $$->len=4;
1421                         if (($1>255) || ($1<0) ||
1422                                 ($3>255) || ($3<0) ||
1423                                 ($5>255) || ($5<0) ||
1424                                 ($7>255) || ($7<0)) {
1425                                 yyerror("invalid ipv4 address");
1426                                 $$->u.addr32[0]=0;
1427                                 /* $$=0; */
1428                         } else {
1429                                 $$->u.addr[0]=$1;
1430                                 $$->u.addr[1]=$3;
1431                                 $$->u.addr[2]=$5;
1432                                 $$->u.addr[3]=$7;
1433                                 /*
1434                                 $$=htonl( ($1<<24)|
1435                                 ($3<<16)| ($5<<8)|$7 );
1436                                 */
1437                         }
1438                 }
1439         }
1440         ;
1441 ipv6addr:
1442         IPV6ADDR {
1443                 $$=pkg_malloc(sizeof(struct ip_addr));
1444                 if ($$==0) {
1445                         LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
1446                 } else {
1447                 #ifdef USE_IPV6
1448                         memset($$, 0, sizeof(struct ip_addr));
1449                         $$->af=AF_INET6;
1450                         $$->len=16;
1451                         if (inet_pton(AF_INET6, $1, $$->u.addr)<=0) {
1452                                 yyerror("bad ipv6 address");
1453                         }
1454                 #else
1455                         yyerror("ipv6 address & no ipv6 support compiled in");
1456                         YYABORT;
1457                 #endif
1458                 }
1459         }
1460         ;
1461 ipv6:
1462         ipv6addr { $$=$1; }
1463         | LBRACK ipv6addr RBRACK {$$=$2; }
1464 ;
1465
1466
1467 route_name:             NUMBER  {
1468                                         tmp=int2str($1, &i_tmp);
1469                                         if (($$=pkg_malloc(i_tmp+1))==0) {
1470                                                 yyerror("out of  memory");
1471                                                 YYABORT;
1472                                         } else {
1473                                                 memcpy($$, tmp, i_tmp);
1474                                                 $$[i_tmp]=0;
1475                                         }
1476                                                 }
1477                         |       ID              { $$=$1; }
1478                         |       STRING  { $$=$1; }
1479 ;
1480
1481 route_stm:
1482         ROUTE LBRACE actions RBRACE { push($3, &main_rt.rlist[DEFAULT_RT]); }
1483         | ROUTE LBRACK route_name RBRACK LBRACE actions RBRACE {
1484                 i_tmp=route_get(&main_rt, $3);
1485                 if (i_tmp==-1){
1486                         yyerror("internal error");
1487                         YYABORT;
1488                 }
1489                 if (main_rt.rlist[i_tmp]){
1490                         yyerror("duplicate route");
1491                         YYABORT;
1492                 }
1493                 push($6, &main_rt.rlist[i_tmp]);
1494         }
1495         | ROUTE error { yyerror("invalid  route  statement"); }
1496         ;
1497 failure_route_stm:
1498         ROUTE_FAILURE LBRACE actions RBRACE {
1499                                                                         push($3, &failure_rt.rlist[DEFAULT_RT]);
1500                                                                                 }
1501         | ROUTE_FAILURE LBRACK route_name RBRACK LBRACE actions RBRACE {
1502                 i_tmp=route_get(&failure_rt, $3);
1503                 if (i_tmp==-1){
1504                         yyerror("internal error");
1505                         YYABORT;
1506                 }
1507                 if (failure_rt.rlist[i_tmp]){
1508                         yyerror("duplicate route");
1509                         YYABORT;
1510                 }
1511                 push($6, &failure_rt.rlist[i_tmp]);
1512         }
1513         | ROUTE_FAILURE error { yyerror("invalid failure_route statement"); }
1514         ;
1515 onreply_route_stm:
1516         ROUTE_ONREPLY LBRACE actions RBRACE {
1517                                                                         push($3, &onreply_rt.rlist[DEFAULT_RT]);
1518                                                                                 }
1519         | ROUTE_ONREPLY LBRACK route_name RBRACK LBRACE actions RBRACE {
1520                 i_tmp=route_get(&onreply_rt, $3);
1521                 if (i_tmp==-1){
1522                         yyerror("internal error");
1523                         YYABORT;
1524                 }
1525                 if (onreply_rt.rlist[i_tmp]){
1526                         yyerror("duplicate route");
1527                         YYABORT;
1528                 }
1529                 push($6, &onreply_rt.rlist[i_tmp]);
1530         }
1531         | ROUTE_ONREPLY error { yyerror("invalid onreply_route statement"); }
1532         ;
1533 branch_route_stm:
1534         ROUTE_BRANCH LBRACE actions RBRACE {
1535                                                                         push($3, &branch_rt.rlist[DEFAULT_RT]);
1536                                                                                 }
1537         | ROUTE_BRANCH LBRACK route_name RBRACK LBRACE actions RBRACE {
1538                 i_tmp=route_get(&branch_rt, $3);
1539                 if (i_tmp==-1){
1540                         yyerror("internal error");
1541                         YYABORT;
1542                 }
1543                 if (branch_rt.rlist[i_tmp]){
1544                         yyerror("duplicate route");
1545                         YYABORT;
1546                 }
1547                 push($6, &branch_rt.rlist[i_tmp]);
1548         }
1549         | ROUTE_BRANCH error { yyerror("invalid branch_route statement"); }
1550         ;
1551 send_route_stm: ROUTE_SEND LBRACE actions RBRACE {
1552                                                                         push($3, &onsend_rt.rlist[DEFAULT_RT]);
1553                                                                                                 }
1554         | ROUTE_SEND LBRACK route_name RBRACK LBRACE actions RBRACE {
1555                 i_tmp=route_get(&onsend_rt, $3);
1556                 if (i_tmp==-1){
1557                         yyerror("internal error");
1558                         YYABORT;
1559                 }
1560                 if (onsend_rt.rlist[i_tmp]){
1561                         yyerror("duplicate route");
1562                         YYABORT;
1563                 }
1564                 push($6, &onsend_rt.rlist[i_tmp]);
1565         }
1566         | ROUTE_SEND error { yyerror("invalid onsend_route statement"); }
1567         ;
1568
1569 exp:    rval_expr
1570                 {
1571                         if ($1==0){
1572                                 yyerror("invalid expression");
1573                                 $$=0;
1574                         }else if (!rve_check_type((enum rval_type*)&i_tmp, $1, 0, 0 ,0)){
1575                                 yyerror("invalid expression");
1576                                 $$=0;
1577                         }else if (i_tmp!=RV_INT && i_tmp!=RV_NONE){
1578                                 yyerror("invalid expression type, int expected\n");
1579                                 $$=0;
1580                         }else
1581                                 $$=mk_elem(NO_OP, RVEXP_O, $1, 0, 0);
1582                 }
1583         ;
1584
1585 /* exp elem operators */
1586 equalop:
1587         EQUAL_T {$$=EQUAL_OP; }
1588         | DIFF  {$$=DIFF_OP; }
1589         | STREQ {$$=EQUAL_OP; }  /* for expr. elems equiv. to EQUAL_T*/
1590         | STRDIFF {$$=DIFF_OP; } /* for expr. elems. equiv. to DIFF */
1591         ;
1592 cmpop:
1593           GT    {$$=GT_OP; }
1594         | LT    {$$=LT_OP; }
1595         | GTE   {$$=GTE_OP; }
1596         | LTE   {$$=LTE_OP; }
1597         ;
1598 strop:
1599         equalop {$$=$1; }
1600         | MATCH {$$=MATCH_OP; }
1601         ;
1602
1603
1604 /* rve expr. operators */
1605 rve_equalop:
1606         EQUAL_T {$$=RVE_EQ_OP; }
1607         | DIFF  {$$=RVE_DIFF_OP; }
1608         | INTEQ {$$=RVE_IEQ_OP; }
1609         | INTDIFF {$$=RVE_IDIFF_OP; }
1610         | STREQ {$$=RVE_STREQ_OP; }
1611         | STRDIFF {$$=RVE_STRDIFF_OP; }
1612         ;
1613 rve_cmpop:
1614           GT    {$$=RVE_GT_OP; }
1615         | LT    {$$=RVE_LT_OP; }
1616         | GTE   {$$=RVE_GTE_OP; }
1617         | LTE   {$$=RVE_LTE_OP; }
1618         ;
1619
1620
1621
1622 /* boolean expression uri operands */
1623 uri_type:
1624         URI             {$$=URI_O;}
1625         | FROM_URI      {$$=FROM_URI_O;}
1626         | TO_URI        {$$=TO_URI_O;}
1627         ;
1628
1629
1630 /* boolean expression integer operands, available only in the
1631   onsend route */
1632 eint_op_onsend:
1633                         SNDPORT         { $$=SNDPORT_O; }
1634                 |       TOPORT          { $$=TOPORT_O; }
1635                 |       SNDPROTO        { $$=SNDPROTO_O; }
1636                 |       SNDAF           { $$=SNDAF_O; }
1637                 ;
1638
1639 /* boolean expression integer operands */
1640 eint_op:        SRCPORT         { $$=SRCPORT_O; }
1641                 |       DSTPORT         { $$=DSTPORT_O; }
1642                 |       PROTO           { $$=PROTO_O; }
1643                 |       AF                      { $$=AF_O; }
1644                 |       MSGLEN          { $$=MSGLEN_O; }
1645                 |       RETCODE         { $$=RETCODE_O; }
1646                 | eint_op_onsend
1647         ;
1648
1649 /* boolean expression ip/ipnet operands */
1650 eip_op_onsend:
1651                         SNDIP           { onsend_check("snd_ip"); $$=SNDIP_O; }
1652                 |       TOIP            { onsend_check("to_ip");  $$=TOIP_O; }
1653                 ;
1654
1655 eip_op:         SRCIP           { $$=SRCIP_O; }
1656                 |       DSTIP           { $$=DSTIP_O; }
1657                 | eip_op_onsend
1658                 ;
1659
1660
1661
1662 exp_elem:
1663         METHOD strop %prec EQUAL_T rval_expr
1664                 {$$= mk_elem($2, METHOD_O, 0, RVE_ST, $3);}
1665         | METHOD strop %prec EQUAL_T ID
1666                 {$$ = mk_elem($2, METHOD_O, 0, STRING_ST,$3); }
1667         | METHOD strop error { $$=0; yyerror("string expected"); }
1668         | METHOD error  
1669                 { $$=0; yyerror("invalid operator,== , !=, or =~ expected"); }
1670         | uri_type strop %prec EQUAL_T rval_expr
1671                 {$$ = mk_elem($2, $1, 0, RVE_ST, $3); }
1672         | uri_type strop %prec EQUAL_T MYSELF
1673                 {$$=mk_elem($2, $1, 0, MYSELF_ST, 0); }
1674         | uri_type strop %prec EQUAL_T error
1675                 { $$=0; yyerror("string or MYSELF expected"); }
1676         | uri_type error
1677                 { $$=0; yyerror("invalid operator, == , != or =~ expected"); }
1678         | eint_op cmpop %prec GT rval_expr { $$=mk_elem($2, $1, 0, RVE_ST, $3 ); }
1679         | eint_op equalop %prec EQUAL_T rval_expr 
1680                 { $$=mk_elem($2, $1, 0, RVE_ST, $3 ); }
1681         | eint_op cmpop error   { $$=0; yyerror("number expected"); }
1682         | eint_op equalop error { $$=0; yyerror("number expected"); }
1683         | eint_op error { $$=0; yyerror("==, !=, <,>, >= or <=  expected"); }
1684         | eip_op strop %prec EQUAL_T ipnet { $$=mk_elem($2, $1, 0, NET_ST, $3); }
1685         | eip_op strop %prec EQUAL_T rval_expr {
1686                         s_tmp.s=0;
1687                         $$=0;
1688                         if (rve_is_constant($3)){
1689                                 i_tmp=rve_guess_type($3);
1690                                 if (i_tmp==RV_INT)
1691                                         yyerror("string expected");
1692                                 else if (i_tmp==RV_STR){
1693                                         if (((rval_tmp=rval_expr_eval(0, 0, $3))==0) ||
1694                                                                 (rval_get_str(0, 0, &s_tmp, rval_tmp, 0)<0)){
1695                                                 rval_destroy(rval_tmp);
1696                                                 yyerror("bad rvalue expression");
1697                                         }else{
1698                                                 rval_destroy(rval_tmp);
1699                                         }
1700                                 }else{
1701                                         yyerror("BUG: unexpected dynamic type");
1702                                 }
1703                         }else{
1704                                         warn("non constant rvalue in ip comparison");
1705                         }
1706                         if (s_tmp.s){
1707                                 ip_tmp=str2ip(&s_tmp);
1708                         #ifdef USE_IPV6
1709                                 if (ip_tmp==0)
1710                                         ip_tmp=str2ip6(&s_tmp);
1711                         #endif
1712                                 pkg_free(s_tmp.s);
1713                                 if (ip_tmp) {
1714                                         $$=mk_elem($2, $1, 0, NET_ST, 
1715                                                                 mk_net_bitlen(ip_tmp, ip_tmp->len*8) );
1716                                 } else {
1717                                         $$=mk_elem($2, $1, 0, RVE_ST, $3);
1718                                 }
1719                         }else{
1720                                 $$=mk_elem($2, $1, 0, RVE_ST, $3);
1721                         }
1722                 }
1723         | eip_op strop %prec EQUAL_T host
1724                 { $$=mk_elem($2, $1, 0, STRING_ST, $3); }
1725         | eip_op strop %prec EQUAL_T MYSELF
1726                 { $$=mk_elem($2, $1, 0, MYSELF_ST, 0); }
1727         | eip_op strop %prec EQUAL_T error
1728                 { $$=0; yyerror( "ip address or hostname expected" ); }
1729         | eip_op error
1730                 { $$=0; yyerror("invalid operator, ==, != or =~ expected");}
1731         
1732         | MYSELF equalop %prec EQUAL_T uri_type
1733                 { $$=mk_elem($2, $3, 0, MYSELF_ST, 0); }
1734         | MYSELF equalop %prec EQUAL_T eip_op
1735                 { $$=mk_elem($2, $3, 0, MYSELF_ST, 0); }
1736         | MYSELF equalop %prec EQUAL_T error
1737                 { $$=0; yyerror(" URI, SRCIP or DSTIP expected"); }
1738         | MYSELF error  { $$=0; yyerror ("invalid operator, == or != expected"); }
1739         ;
1740 /*
1741 exp_elem2:
1742         rval_expr cmpop %prec GT rval_expr
1743                 { $$=mk_elem( $2, RVE_ST, $1, RVE_ST, $3);}
1744         |
1745         rval_expr equalop %prec EQUAL_T rval_expr
1746                 { $$=mk_elem( $2, RVE_ST, $1, RVE_ST, $3);}
1747         | rval_expr LOG_AND rval_expr
1748                 { $$=mk_exp_rve(LOGAND_OP, $1, $3);}
1749         | rval_expr LOG_OR rval_expr
1750                 { $$=mk_exp_rve(LOGOR_OP, $1, $3);}
1751 ;
1752 */
1753
1754 ipnet:
1755         ip SLASH ip     { $$=mk_net($1, $3); }
1756         | ip SLASH NUMBER {
1757                 if (($3<0) || ($3>$1->len*8)) {
1758                         yyerror("invalid bit number in netmask");
1759                         $$=0;
1760                 } else {
1761                         $$=mk_net_bitlen($1, $3);
1762                 /*
1763                         $$=mk_net($1, htonl( ($3)?~( (1<<(32-$3))-1 ):0 ) );
1764                 */
1765                 }
1766         }
1767         | ip    { $$=mk_net_bitlen($1, $1->len*8); }
1768         | ip SLASH error { $$=0; yyerror("netmask (eg:255.0.0.0 or 8) expected"); }
1769         ;
1770
1771 host:
1772         ID { $$=$1; }
1773         | host DOT ID {
1774                 $$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
1775                 if ($$==0) {
1776                         LOG(L_CRIT, "ERROR: cfg. parser: memory allocation failure while parsing host\n");
1777                 } else {
1778                         memcpy($$, $1, strlen($1));
1779                         $$[strlen($1)]='.';
1780                         memcpy($$+strlen($1)+1, $3, strlen($3));
1781                         $$[strlen($1)+1+strlen($3)]=0;
1782                 }
1783                 pkg_free($1);
1784                 pkg_free($3);
1785         }
1786         | host MINUS ID {
1787                 $$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
1788                 if ($$==0) {
1789                         LOG(L_CRIT, "ERROR: cfg. parser: memory allocation failure while parsing host\n");
1790                 } else {
1791                         memcpy($$, $1, strlen($1));
1792                         $$[strlen($1)]='-';
1793                         memcpy($$+strlen($1)+1, $3, strlen($3));
1794                         $$[strlen($1)+1+strlen($3)]=0;
1795                 }
1796                 pkg_free($1);
1797                 pkg_free($3);
1798         }
1799         | host DOT error { $$=0; pkg_free($1); yyerror("invalid hostname"); }
1800         ;
1801 /* filtered cmd */
1802 fcmd:
1803         cmd {
1804                 /* check if allowed */
1805                 if ($1 && rt==ONSEND_ROUTE) {
1806                         switch($1->type) {
1807                                 case DROP_T:
1808                                 case SEND_T:
1809                                 case SEND_TCP_T:
1810                                 case LOG_T:
1811                                 case SETFLAG_T:
1812                                 case RESETFLAG_T:
1813                                 case ISFLAGSET_T:
1814                                 case IF_T:
1815                                 case MODULE_T:
1816                                         $$=$1;
1817                                         break;
1818                                 default:
1819                                         $$=0;
1820                                         yyerror("command not allowed in onsend_route\n");
1821                         }
1822                 } else {
1823                         $$=$1;
1824                 }
1825         }
1826         ;
1827 /*
1828 exp_stm:
1829         fcmd    { $$=$1; }
1830         | if_cmd        { $$=$1; }
1831         | assign_action { $$ = $1; }
1832         | LBRACE actions RBRACE { $$=$2; }
1833         ;
1834 */
1835 stm:
1836         action  { $$=$1; }
1837         | LBRACE actions RBRACE { $$=$2; }
1838         ;
1839 actions:
1840         actions action  {$$=append_action($1, $2); }
1841         | action        {$$=$1;}
1842         | actions error { $$=0; yyerror("bad command"); }
1843         ;
1844 action:
1845         fcmd SEMICOLON {$$=$1;}
1846         | if_cmd {$$=$1;}
1847         | switch_cmd {$$=$1;}
1848         | while_cmd { $$=$1; }
1849         | assign_action SEMICOLON {$$=$1;}
1850         | SEMICOLON /* null action */ {$$=0;}
1851         | fcmd error { $$=0; yyerror("bad command: missing ';'?"); }
1852         ;
1853 if_cmd:
1854         IF exp stm              { $$=mk_action( IF_T, 3, EXPR_ST, $2, ACTIONS_ST, $3, NOSUBTYPE, 0); }
1855         | IF exp stm ELSE stm   { $$=mk_action( IF_T, 3, EXPR_ST, $2, ACTIONS_ST, $3, ACTIONS_ST, $5); }
1856         ;
1857
1858 ct_rval: rval_expr {
1859                         $$=0;
1860                         if (!rve_is_constant($1)){
1861                                 yyerror("constant expected");
1862                         /*
1863                         } else if (!rve_check_type((enum rval_type*)&i_tmp, $1, 0, 0 ,0)){
1864                                 yyerror("invalid expression (bad type)");
1865                         }else if (i_tmp!=RV_INT){
1866                                 yyerror("invalid expression type, int expected\n");
1867                         */
1868                         }else
1869                                 $$=$1;
1870                 }
1871 ;
1872 single_case:
1873         CASE ct_rval COLON actions {
1874                 $$=0;
1875                 if ($2==0) yyerror ("bad case label");
1876                 else if ((($$=mk_case_stm($2, 0, $4, &i_tmp))==0) && (i_tmp==-10)){
1877                                 YYABORT;
1878                 }
1879         }
1880 | CASE SLASH ct_rval COLON actions {
1881                 $$=0;
1882                 if ($3==0) yyerror ("bad case label");
1883                 else if ((($$=mk_case_stm($3, 1, $5, &i_tmp))==0) && (i_tmp==-10)){
1884                                 YYABORT;
1885                 }
1886         }
1887         | CASE ct_rval COLON {
1888                 $$=0;
1889                 if ($2==0) yyerror ("bad case label");
1890                 else if ((($$=mk_case_stm($2, 0, 0, &i_tmp))==0) && (i_tmp==-10)){
1891                                 YYABORT;
1892                 }
1893         }
1894         | CASE SLASH ct_rval COLON {
1895                 $$=0;
1896                 if ($3==0) yyerror ("bad case label");
1897                 else if ((($$=mk_case_stm($3, 1, 0, &i_tmp))==0) && (i_tmp==-10)){
1898                                 YYABORT;
1899                 }
1900         }
1901         | DEFAULT COLON actions {
1902                 if ((($$=mk_case_stm(0, 0, $3, &i_tmp))==0) && (i_tmp=-10)){
1903                                 YYABORT;
1904                 }
1905         }
1906         | DEFAULT COLON {
1907                 if ((($$=mk_case_stm(0, 0, 0, &i_tmp))==0) && (i_tmp==-10)){
1908                                 YYABORT;
1909                 }
1910         }
1911         | CASE error { $$=0; yyerror("bad case label"); }
1912         | CASE ct_rval COLON error { $$=0; yyerror ("bad case body"); }
1913 ;
1914 case_stms:
1915         case_stms single_case {
1916                 $$=$1;
1917                 if ($2==0) yyerror ("bad case");
1918                 if ($$){
1919                         *($$->append)=$2;
1920                         if (*($$->append)!=0)
1921                                 $$->append=&((*($$->append))->next);
1922                 }
1923         }
1924         | single_case {
1925                 $$=$1;
1926                 if ($1==0) yyerror ("bad case");
1927                 else $$->append=&($$->next);
1928         }
1929 ;
1930 switch_cmd:
1931           SWITCH rval_expr LBRACE case_stms RBRACE { 
1932                 $$=0;
1933                 if ($2==0) yyerror("bad expression in switch(...)");
1934                 else if ($4==0) yyerror ("bad switch body");
1935                 else if (case_check_default($4)!=0)
1936                         yyerror_at(&$2->fpos, "bad switch(): too many "
1937                                                         "\"default:\" labels\n");
1938                 else if (case_check_type($4)!=0)
1939                         yyerror_at(&$2->fpos, "bad switch(): mixed integer and"
1940                                                         " string/RE cases not allowed\n");
1941                 else{
1942                         $$=mk_action(SWITCH_T, 2, RVE_ST, $2, CASE_ST, $4);
1943                         if ($$==0) {
1944                                 yyerror("internal error");
1945                                 YYABORT;
1946                         }
1947                 }
1948         }
1949         | SWITCH rval_expr LBRACE RBRACE {
1950                 $$=0;
1951                 warn("empty switch()");
1952                 if ($2==0) yyerror("bad expression in switch(...)");
1953                 else{
1954                         /* it might have sideffects, so leave it for the optimizer */
1955                         $$=mk_action(SWITCH_T, 2, RVE_ST, $2, CASE_ST, 0);
1956                         if ($$==0) {
1957                                 yyerror("internal error");
1958                                 YYABORT;
1959                         }
1960                 }
1961         }
1962         | SWITCH error { $$=0; yyerror ("bad expression in switch(...)"); }
1963         | SWITCH rval_expr LBRACE error RBRACE 
1964                 {$$=0; yyerror ("bad switch body"); }
1965 ;
1966
1967 while_cmd:
1968         WHILE rval_expr stm {
1969                 if ($2){
1970                         if (rve_is_constant($2))
1971                                 warn_at(&$2->fpos, "constant value in while(...)");
1972                 }else
1973                         yyerror_at(&$2->fpos, "bad while(...) expression");
1974                 $$=mk_action( WHILE_T, 2, RVE_ST, $2, ACTIONS_ST, $3);
1975         }
1976 ;
1977
1978 /* class_id:
1979         LBRACK ATTR_USER RBRACK { $$ = AVP_CLASS_USER; }
1980         | LBRACK ATTR_DOMAIN RBRACK { $$ = AVP_CLASS_DOMAIN; }
1981         | LBRACK ATTR_GLOBAL RBRACK { $$ = AVP_CLASS_GLOBAL; }
1982         ;
1983 */
1984 select_param:
1985         ID {
1986                 if (sel.n >= MAX_SELECT_PARAMS-1) {
1987                         yyerror("Select identifier too long\n");
1988                 }
1989                 sel.params[sel.n].type = SEL_PARAM_STR;
1990                 sel.params[sel.n].v.s.s = $1;
1991                 sel.params[sel.n].v.s.len = strlen($1);
1992                 sel.n++;
1993         }
1994         | ID LBRACK NUMBER RBRACK {
1995                 if (sel.n >= MAX_SELECT_PARAMS-2) {
1996                         yyerror("Select identifier too long\n");
1997                 }
1998                 sel.params[sel.n].type = SEL_PARAM_STR;
1999                 sel.params[sel.n].v.s.s = $1;
2000                 sel.params[sel.n].v.s.len = strlen($1);
2001                 sel.n++;
2002                 sel.params[sel.n].type = SEL_PARAM_INT;
2003                 sel.params[sel.n].v.i = $3;
2004                 sel.n++;
2005         }
2006         | ID LBRACK STRING RBRACK {
2007                 if (sel.n >= MAX_SELECT_PARAMS-2) {
2008                         yyerror("Select identifier too long\n");
2009                 }
2010                 sel.params[sel.n].type = SEL_PARAM_STR;
2011                 sel.params[sel.n].v.s.s = $1;
2012                 sel.params[sel.n].v.s.len = strlen($1);
2013                 sel.n++;
2014                 sel.params[sel.n].type = SEL_PARAM_STR;
2015                 sel.params[sel.n].v.s.s = $3;
2016                 sel.params[sel.n].v.s.len = strlen($3);
2017                 sel.n++;
2018         }
2019         ;
2020 select_params:
2021         select_params DOT select_param
2022         | select_param
2023         ;
2024 select_id:
2025         SELECT_MARK { sel.n = 0; sel.f[0] = 0; } select_params {
2026                 sel_ptr = (select_t*)pkg_malloc(sizeof(select_t));
2027                 if (!sel_ptr) {
2028                         yyerror("No memory left to allocate select structure\n");
2029                 }
2030                 memcpy(sel_ptr, &sel, sizeof(select_t));
2031                 $$ = sel_ptr;
2032         }
2033         ;
2034 attr_class_spec:
2035         ATTR_FROM { s_attr->type |= AVP_TRACK_FROM; }
2036         | ATTR_TO { s_attr->type |= AVP_TRACK_TO; }
2037         | ATTR_FROMURI { s_attr->type |= AVP_TRACK_FROM | AVP_CLASS_URI; }
2038         | ATTR_TOURI { s_attr->type |= AVP_TRACK_TO | AVP_CLASS_URI; }
2039         | ATTR_FROMUSER { s_attr->type |= AVP_TRACK_FROM | AVP_CLASS_USER; }
2040         | ATTR_TOUSER { s_attr->type |= AVP_TRACK_TO | AVP_CLASS_USER; }
2041         | ATTR_FROMDOMAIN { s_attr->type |= AVP_TRACK_FROM | AVP_CLASS_DOMAIN; }
2042         | ATTR_TODOMAIN { s_attr->type |= AVP_TRACK_TO | AVP_CLASS_DOMAIN; }
2043         | ATTR_GLOBAL { s_attr->type |= AVP_TRACK_ALL | AVP_CLASS_GLOBAL; }
2044         ;
2045 attr_name_spec:
2046         ID { s_attr->type |= AVP_NAME_STR; s_attr->name.s.s = $1; s_attr->name.s.len = strlen ($1); }
2047         ;
2048 attr_spec:
2049         attr_name_spec
2050         | attr_class_spec DOT attr_name_spec
2051         ;
2052 attr_mark:
2053         ATTR_MARK {
2054                 s_attr = (struct avp_spec*)pkg_malloc(sizeof(struct avp_spec));
2055                 if (!s_attr) { yyerror("No memory left"); }
2056                 s_attr->type = 0;
2057         }
2058         ;
2059 attr_id:
2060         attr_mark attr_spec { $$ = s_attr; }
2061         ;
2062 attr_id_num_idx:
2063         attr_mark attr_spec LBRACK intno RBRACK {
2064                 s_attr->type|= (AVP_NAME_STR | ($4<0?AVP_INDEX_BACKWARD:AVP_INDEX_FORWARD));
2065                 s_attr->index = ($4<0?-$4:$4);
2066                 $$ = s_attr;
2067         }
2068         ;
2069 attr_id_no_idx:
2070         attr_mark attr_spec LBRACK RBRACK {
2071                 s_attr->type|= AVP_INDEX_ALL;
2072                 $$ = s_attr;
2073         }
2074         ;
2075 attr_id_ass:
2076         attr_id
2077         | attr_id_no_idx
2078         ;
2079 /*
2080 attr_id_val:
2081         attr_id
2082         | attr_id_num_idx
2083         ;
2084 */
2085 attr_id_any:
2086         attr_id
2087         | attr_id_no_idx
2088         | attr_id_num_idx
2089 ;
2090 attr_id_any_str:
2091         attr_id
2092         | STRING {
2093                 avp_spec_t *avp_spec;
2094                 str s;
2095                 int type, idx;
2096                 avp_spec = pkg_malloc(sizeof(*avp_spec));
2097                 if (!avp_spec) {
2098                         yyerror("Not enough memory");
2099                         YYABORT;
2100                 }
2101                 s.s = $1;
2102                 if (s.s[0] == '$')
2103                         s.s++;
2104                 s.len = strlen(s.s);
2105                 if (parse_avp_name(&s, &type, &avp_spec->name, &idx)) {
2106                         yyerror("error when parsing AVP");
2107                         pkg_free(avp_spec);
2108                         YYABORT;
2109                 }
2110                 avp_spec->type = type;
2111                 avp_spec->index = idx;
2112                 $$ = avp_spec;
2113         }
2114         ;
2115
2116 pvar:   PVAR {
2117                         pv_spec=pkg_malloc(sizeof(*pv_spec));
2118                         if (!pv_spec) {
2119                                 yyerror("Not enough memory");
2120                                 YYABORT;
2121                         }
2122                         memset(pv_spec, 0, sizeof(*pv_spec));
2123                         s_tmp.s=$1; s_tmp.len=strlen($1);
2124                         if (pv_parse_spec(&s_tmp, pv_spec)==0){
2125                                 yyerror("unknown script pseudo variable");
2126                                 pkg_free(pv_spec);
2127                                 pv_spec=0;
2128                                 YYABORT;
2129                         }
2130                         $$=pv_spec;
2131                 }
2132         ;
2133
2134 avp_pvar:       AVP_OR_PVAR {
2135                                 lval_tmp=pkg_malloc(sizeof(*lval_tmp));
2136                                 if (!lval_tmp) {
2137                                         yyerror("Not enough memory");
2138                                         YYABORT;
2139                                 }
2140                                 memset(lval_tmp, 0, sizeof(*lval_tmp));
2141                                 s_tmp.s=$1; s_tmp.len=strlen(s_tmp.s);
2142                                 if (pv_parse_spec2(&s_tmp, &lval_tmp->lv.pvs, 1)==0){
2143                                         /* not a pvar, try avps */
2144                                         lval_tmp->lv.avps.type|= AVP_NAME_STR;
2145                                         lval_tmp->lv.avps.name.s.s = s_tmp.s+1;
2146                                         lval_tmp->lv.avps.name.s.len = s_tmp.len-1;
2147                                         lval_tmp->type=LV_AVP;
2148                                 }else{
2149                                         lval_tmp->type=LV_PVAR;
2150                                 }
2151                                 $$ = lval_tmp;
2152                                 DBG("parsed ambigous avp/pvar \"%.*s\" to %d\n",
2153                                                         s_tmp.len, s_tmp.s, lval_tmp->type);
2154                         }
2155         ;
2156
2157
2158 /*
2159 assign_op:
2160         ADDEQ { $$ = ADD_T; }
2161         | EQUAL { $$ = ASSIGN_T; }
2162         ;
2163 */
2164 assign_op:
2165         EQUAL { $$ = ASSIGN_T; }
2166         ;
2167
2168
2169 lval: attr_id_ass {
2170                                         lval_tmp=pkg_malloc(sizeof(*lval_tmp));
2171                                         if (!lval_tmp) {
2172                                                 yyerror("Not enough memory");
2173                                                 YYABORT;
2174                                         }
2175                                         lval_tmp->type=LV_AVP; lval_tmp->lv.avps=*$1;
2176                                         pkg_free($1); /* free the avp spec we just copied */
2177                                         $$=lval_tmp;
2178                                 }
2179         | pvar        {
2180                                         if (!pv_is_w($1))
2181                                                 yyerror("read only pvar in assignment left side");
2182                                         if ($1->trans!=0)
2183                                                 yyerror("pvar with transformations in assignment"
2184                                                                 " left side");
2185                                         lval_tmp=pkg_malloc(sizeof(*lval_tmp));
2186                                         if (!lval_tmp) {
2187                                                 yyerror("Not enough memory");
2188                                                 YYABORT;
2189                                         }
2190                                         lval_tmp->type=LV_PVAR; lval_tmp->lv.pvs=*($1);
2191                                         pkg_free($1); /* free the pvar spec we just copied */
2192                                         $$=lval_tmp;
2193                                 }
2194         | avp_pvar    {
2195                                         if (($1)->type==LV_PVAR){
2196                                                 if (!pv_is_w(&($1)->lv.pvs))
2197                                                         yyerror("read only pvar in assignment left side");
2198                                                 if ($1->lv.pvs.trans!=0)
2199                                                         yyerror("pvar with transformations in assignment"
2200                                                                         " left side");
2201                                         }
2202                                         $$=$1;
2203                                 }
2204         ;
2205
2206 rval: intno                     {$$=mk_rve_rval(RV_INT, (void*)$1); }
2207         | STRING                        {       s_tmp.s=$1; s_tmp.len=strlen($1);
2208                                                         $$=mk_rve_rval(RV_STR, &s_tmp); }
2209         | attr_id_any           {$$=mk_rve_rval(RV_AVP, $1); pkg_free($1); }
2210         | pvar                          {$$=mk_rve_rval(RV_PVAR, $1); pkg_free($1); }
2211         | avp_pvar                      {
2212                                                         switch($1->type){
2213                                                                 case LV_AVP:
2214                                                                         $$=mk_rve_rval(RV_AVP, &$1->lv.avps);
2215                                                                         break;
2216                                                                 case LV_PVAR:
2217                                                                         $$=mk_rve_rval(RV_PVAR, &$1->lv.pvs);
2218                                                                         break;
2219                                                                 default:
2220                                                                         yyerror("BUG: invalid lvalue type ");
2221                                                                         YYABORT;
2222                                                         }
2223                                                         pkg_free($1); /* not needed anymore */
2224                                                 }
2225         | select_id                     {$$=mk_rve_rval(RV_SEL, $1); pkg_free($1); }
2226         | fcmd                          {$$=mk_rve_rval(RV_ACTION_ST, $1); }
2227         | exp_elem { $$=mk_rve_rval(RV_BEXPR, $1); }
2228         | LBRACE actions RBRACE {$$=mk_rve_rval(RV_ACTION_ST, $2); }
2229         | LBRACE error RBRACE   { $$=0; yyerror("bad command block"); }
2230         | LPAREN assign_action RPAREN   {$$=mk_rve_rval(RV_ACTION_ST, $2); }
2231         | LPAREN error RPAREN   { $$=0; yyerror("bad expression"); }
2232         ;
2233
2234
2235 rve_un_op: NOT  { $$=RVE_LNOT_OP; }
2236                 |  MINUS %prec NOT      { $$=RVE_UMINUS_OP; } 
2237                 /* TODO: RVE_BOOL_OP, RVE_NOT_OP? */
2238         ;
2239
2240 /*
2241 rve_op:         PLUS            { $$=RVE_PLUS_OP; }
2242                 |       MINUS           { $$=RVE_MINUS_OP; }
2243                 |       STAR            { $$=RVE_MUL_OP; }
2244                 |       SLASH           { $$=RVE_DIV_OP; }
2245         ;
2246 */
2247
2248 rval_expr: rval                                         { $$=$1;
2249                                                                                 /*      if ($$==0){
2250                                                                                                 yyerror("out of memory\n");
2251                                                                                                 YYABORT;
2252                                                                                         }
2253                                                                                         */
2254                                                                         }
2255                 | rve_un_op %prec NOT rval_expr {$$=mk_rve1($1, $2); }
2256                 | rval_expr PLUS rval_expr              {$$=mk_rve2(RVE_PLUS_OP, $1, $3); }
2257                 | rval_expr MINUS rval_expr             {$$=mk_rve2(RVE_MINUS_OP, $1, $3); }
2258                 | rval_expr STAR rval_expr              {$$=mk_rve2(RVE_MUL_OP, $1, $3); }
2259                 | rval_expr SLASH rval_expr             {$$=mk_rve2(RVE_DIV_OP, $1, $3); }
2260                 | rval_expr BIN_OR rval_expr    {$$=mk_rve2(RVE_BOR_OP, $1,  $3); }
2261                 | rval_expr BIN_AND rval_expr   {$$=mk_rve2(RVE_BAND_OP, $1,  $3);}
2262                 | rval_expr rve_cmpop %prec GT rval_expr { $$=mk_rve2( $2, $1, $3);}
2263                 | rval_expr rve_equalop %prec EQUAL_T rval_expr
2264                         { $$=mk_rve2( $2, $1, $3);}
2265                 | rval_expr LOG_AND rval_expr   { $$=mk_rve2(RVE_LAND_OP, $1, $3);}
2266                 | rval_expr LOG_OR rval_expr    { $$=mk_rve2(RVE_LOR_OP, $1, $3);}
2267                 | LPAREN rval_expr RPAREN               { $$=$2;}
2268                 | STRLEN LPAREN rval_expr RPAREN { $$=mk_rve1(RVE_STRLEN_OP, $3);}
2269                 | STREMPTY LPAREN rval_expr RPAREN {$$=mk_rve1(RVE_STREMPTY_OP, $3);}
2270                 | DEFINED rval_expr                             { $$=mk_rve1(RVE_DEFINED_OP, $2);}
2271                 | rve_un_op %prec NOT error             { $$=0; yyerror("bad expression"); }
2272                 | rval_expr PLUS error                  { yyerror("bad expression"); }
2273                 | rval_expr MINUS error                 { yyerror("bad expression"); }
2274                 | rval_expr STAR error                  { yyerror("bad expression"); }
2275                 | rval_expr SLASH error                 { yyerror("bad expression"); }
2276                 | rval_expr BIN_OR error                { yyerror("bad expression"); }
2277                 | rval_expr BIN_AND error               { yyerror("bad expression"); }
2278                 | rval_expr rve_cmpop %prec GT error
2279                         { yyerror("bad expression"); }
2280                 | rval_expr rve_equalop %prec EQUAL_T error
2281                         { yyerror("bad expression"); }
2282                 | rval_expr LOG_AND error               { yyerror("bad expression"); }
2283                 | rval_expr LOG_OR error                { yyerror("bad expression"); }
2284                 | STRLEN LPAREN error RPAREN    { $$=0; yyerror("bad expression"); }
2285                 | STREMPTY LPAREN error RPAREN  { $$=0; yyerror("bad expression"); }
2286                 | DEFINED error                                 { $$=0; yyerror("bad expression"); }
2287                 ;
2288
2289 assign_action: lval assign_op  rval_expr        { $$=mk_action($2, 2, LVAL_ST, $1, 
2290                                                                                                                           RVE_ST, $3);
2291                                                                                 }
2292         ;
2293
2294 /*
2295 assign_action:
2296         attr_id_ass assign_op STRING  { $$=mk_action($2, 2, AVP_ST, $1, STRING_ST, $3); }
2297         | attr_id_ass assign_op NUMBER  { $$=mk_action($2, 2, AVP_ST, $1, NUMBER_ST, (void*)$3); }
2298         | attr_id_ass assign_op fcmd    { $$=mk_action($2, 2, AVP_ST, $1, ACTION_ST, $3); }
2299         | attr_id_ass assign_op attr_id_any { $$=mk_action($2, 2, AVP_ST, $1, AVP_ST, $3); }
2300         | attr_id_ass assign_op select_id { $$=mk_action($2, 2, AVP_ST, (void*)$1, SELECT_ST, (void*)$3); }
2301         | attr_id_ass assign_op LPAREN exp RPAREN { $$ = mk_action($2, 2, AVP_ST, $1, EXPR_ST, $4); }
2302         ;
2303 */
2304
2305 avpflag_oper:
2306         SETAVPFLAG { $$ = 1; }
2307         | RESETAVPFLAG { $$ = 0; }
2308         | ISAVPFLAGSET { $$ = -1; }
2309         ;
2310 cmd:
2311         FORWARD LPAREN host RPAREN      { $$=mk_action( FORWARD_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
2312         | FORWARD LPAREN STRING RPAREN  { $$=mk_action( FORWARD_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
2313         | FORWARD LPAREN ip RPAREN      { $$=mk_action( FORWARD_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); }
2314         | FORWARD LPAREN host COMMA NUMBER RPAREN { $$=mk_action(FORWARD_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); }
2315         | FORWARD LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(FORWARD_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); }
2316         | FORWARD LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); }
2317         | FORWARD LPAREN URIHOST COMMA URIPORT RPAREN { $$=mk_action(FORWARD_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); }
2318         | FORWARD LPAREN URIHOST COMMA NUMBER RPAREN {$$=mk_action(FORWARD_T, 2, URIHOST_ST, 0, NUMBER_ST, (void*)$5); }
2319         | FORWARD LPAREN URIHOST RPAREN { $$=mk_action(FORWARD_T, 2, URIHOST_ST, 0, NUMBER_ST, 0); }
2320         | FORWARD error { $$=0; yyerror("missing '(' or ')' ?"); }
2321         | FORWARD LPAREN error RPAREN { $$=0; yyerror("bad forward argument"); }
2322         | FORWARD_UDP LPAREN host RPAREN        { $$=mk_action(FORWARD_UDP_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
2323         | FORWARD_UDP LPAREN STRING RPAREN      { $$=mk_action(FORWARD_UDP_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
2324         | FORWARD_UDP LPAREN ip RPAREN  { $$=mk_action(FORWARD_UDP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); }
2325         | FORWARD_UDP LPAREN host COMMA NUMBER RPAREN { $$=mk_action(FORWARD_UDP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); }
2326         | FORWARD_UDP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(FORWARD_UDP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); }
2327         | FORWARD_UDP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_UDP_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); }
2328         | FORWARD_UDP LPAREN URIHOST COMMA URIPORT RPAREN {$$=mk_action(FORWARD_UDP_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); }
2329         | FORWARD_UDP LPAREN URIHOST COMMA NUMBER RPAREN { $$=mk_action(FORWARD_UDP_T, 2, URIHOST_ST, 0, NUMBER_ST, (void*)$5); }
2330         | FORWARD_UDP LPAREN URIHOST RPAREN { $$=mk_action(FORWARD_UDP_T, 2, URIHOST_ST, 0, NUMBER_ST, 0); }
2331         | FORWARD_UDP error { $$=0; yyerror("missing '(' or ')' ?"); }
2332         | FORWARD_UDP LPAREN error RPAREN { $$=0; yyerror("bad forward_udp argument"); }
2333         | FORWARD_TCP LPAREN host RPAREN        { $$=mk_action(FORWARD_TCP_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
2334         | FORWARD_TCP LPAREN STRING RPAREN      { $$=mk_action(FORWARD_TCP_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
2335         | FORWARD_TCP LPAREN ip RPAREN  { $$=mk_action(FORWARD_TCP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); }
2336         | FORWARD_TCP LPAREN host COMMA NUMBER RPAREN { $$=mk_action(FORWARD_TCP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); }
2337         | FORWARD_TCP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(FORWARD_TCP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); }
2338         | FORWARD_TCP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_TCP_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); }
2339         | FORWARD_TCP LPAREN URIHOST COMMA URIPORT RPAREN {$$=mk_action(FORWARD_TCP_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); }
2340         | FORWARD_TCP LPAREN URIHOST COMMA NUMBER RPAREN { $$=mk_action(FORWARD_TCP_T, 2, URIHOST_ST, 0, NUMBER_ST, (void*)$5); }
2341         | FORWARD_TCP LPAREN URIHOST RPAREN { $$=mk_action(FORWARD_TCP_T, 2, URIHOST_ST, 0, NUMBER_ST, 0); }
2342         | FORWARD_TCP error { $$=0; yyerror("missing '(' or ')' ?"); }
2343         | FORWARD_TCP LPAREN error RPAREN { $$=0; yyerror("bad forward_tcp argument"); }
2344         | FORWARD_TLS LPAREN host RPAREN {
2345                 #ifdef USE_TLS
2346                         $$=mk_action(FORWARD_TLS_T, 2, STRING_ST, $3, NUMBER_ST, 0);
2347                 #else
2348                         $$=0;
2349                         yyerror("tls support not compiled in");
2350                 #endif
2351         }
2352         | FORWARD_TLS LPAREN STRING RPAREN {
2353                 #ifdef USE_TLS
2354                         $$=mk_action(FORWARD_TLS_T, 2, STRING_ST, $3, NUMBER_ST, 0);
2355                 #else
2356                         $$=0;
2357                         yyerror("tls support not compiled in");
2358                 #endif
2359         }
2360         | FORWARD_TLS LPAREN ip RPAREN  {
2361                 #ifdef USE_TLS
2362                         $$=mk_action(FORWARD_TLS_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0);
2363                 #else
2364                         $$=0;
2365                         yyerror("tls support not compiled in");
2366                 #endif
2367         }
2368         | FORWARD_TLS LPAREN host COMMA NUMBER RPAREN {
2369                 #ifdef USE_TLS
2370                         $$=mk_action(FORWARD_TLS_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5);
2371                 #else
2372                         $$=0;
2373                         yyerror("tls support not compiled in");
2374                 #endif
2375         }
2376         | FORWARD_TLS LPAREN STRING COMMA NUMBER RPAREN {
2377                 #ifdef USE_TLS
2378                         $$=mk_action(FORWARD_TLS_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5);
2379                 #else
2380                         $$=0;
2381                         yyerror("tls support not compiled in");
2382                 #endif
2383         }
2384         | FORWARD_TLS LPAREN ip COMMA NUMBER RPAREN {
2385                 #ifdef USE_TLS
2386                         $$=mk_action(FORWARD_TLS_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5);
2387                 #else
2388                         $$=0;
2389                         yyerror("tls support not compiled in");
2390                 #endif
2391                                         }
2392         | FORWARD_TLS LPAREN URIHOST COMMA URIPORT RPAREN {
2393                 #ifdef USE_TLS
2394                         $$=mk_action(FORWARD_TLS_T, 2, URIHOST_ST, 0, URIPORT_ST, 0);
2395                 #else
2396                         $$=0;
2397                         yyerror("tls support not compiled in");
2398                 #endif
2399         }
2400         | FORWARD_TLS LPAREN URIHOST COMMA NUMBER RPAREN {
2401                 #ifdef USE_TLS
2402                         $$=mk_action(FORWARD_TLS_T, 2, URIHOST_ST, 0, NUMBER_ST, (void*)$5);
2403                 #else
2404                         $$=0;
2405                         yyerror("tls support not compiled in");
2406                 #endif
2407         }
2408         | FORWARD_TLS LPAREN URIHOST RPAREN {
2409                 #ifdef USE_TLS
2410                         $$=mk_action(FORWARD_TLS_T, 2, URIHOST_ST, 0, NUMBER_ST, 0);
2411                 #else
2412                         $$=0;
2413                         yyerror("tls support not compiled in");
2414                 #endif
2415         }
2416         | FORWARD_TLS error { $$=0; yyerror("missing '(' or ')' ?"); }
2417         | FORWARD_TLS LPAREN error RPAREN { $$=0; 
2418                                                                         yyerror("bad forward_tls argument"); }
2419         | FORWARD_SCTP LPAREN host RPAREN {
2420                 #ifdef USE_SCTP
2421                         $$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST, 0);
2422                 #else
2423                         $$=0;
2424                         yyerror("sctp support not compiled in");
2425                 #endif
2426         }
2427         | FORWARD_SCTP LPAREN STRING RPAREN {
2428                 #ifdef USE_SCTP
2429                         $$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST, 0);
2430                 #else
2431                         $$=0;
2432                         yyerror("sctp support not compiled in");
2433                 #endif
2434         }
2435         | FORWARD_SCTP LPAREN ip RPAREN {
2436                 #ifdef USE_SCTP
2437                         $$=mk_action(FORWARD_SCTP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0);
2438                 #else
2439                         $$=0;
2440                         yyerror("sctp support not compiled in");
2441                 #endif
2442         }
2443         | FORWARD_SCTP LPAREN host COMMA NUMBER RPAREN {
2444                 #ifdef USE_SCTP
2445                         $$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST,
2446                                                         (void*)$5);
2447                 #else
2448                         $$=0;
2449                         yyerror("sctp support not compiled in");
2450                 #endif
2451         }
2452         | FORWARD_SCTP LPAREN STRING COMMA NUMBER RPAREN {
2453                 #ifdef USE_SCTP
2454                         $$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST,
2455                                                         (void*)$5);
2456                 #else
2457                         $$=0;
2458                         yyerror("sctp support not compiled in");
2459                 #endif
2460         }
2461         | FORWARD_SCTP LPAREN ip COMMA NUMBER RPAREN {
2462                 #ifdef USE_SCTP
2463                         $$=mk_action(FORWARD_SCTP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 
2464                                                         (void*)$5);
2465                 #else
2466                         $$=0;
2467                         yyerror("sctp support not compiled in");
2468                 #endif
2469                                         }
2470         | FORWARD_SCTP LPAREN URIHOST COMMA URIPORT RPAREN {
2471                 #ifdef USE_SCTP
2472                         $$=mk_action(FORWARD_SCTP_T, 2, URIHOST_ST, 0, URIPORT_ST, 0);
2473                 #else
2474                         $$=0;
2475                         yyerror("sctp support not compiled in");
2476                 #endif
2477         }
2478         | FORWARD_SCTP LPAREN URIHOST COMMA NUMBER RPAREN {
2479                 #ifdef USE_SCTP
2480                         $$=mk_action(FORWARD_SCTP_T, 2, URIHOST_ST, 0, NUMBER_ST,
2481                                                         (void*)$5);
2482                 #else
2483                         $$=0;
2484                         yyerror("sctp support not compiled in");
2485                 #endif
2486         }
2487         | FORWARD_SCTP LPAREN URIHOST RPAREN {
2488                 #ifdef USE_SCTP
2489                         $$=mk_action(FORWARD_SCTP_T, 2, URIHOST_ST, 0, NUMBER_ST, 0);
2490                 #else
2491                         $$=0;
2492                         yyerror("tls support not compiled in");
2493                 #endif
2494         }
2495         | FORWARD_SCTP error { $$=0; yyerror("missing '(' or ')' ?"); }
2496         | FORWARD_SCTP LPAREN error RPAREN { $$=0; 
2497                                                                         yyerror("bad forward_tls argument"); }
2498         | SEND LPAREN host RPAREN       { $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
2499         | SEND LPAREN STRING RPAREN { $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
2500         | SEND LPAREN ip RPAREN         { $$=mk_action(SEND_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); }
2501         | SEND LPAREN host COMMA NUMBER RPAREN  { $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); }
2502         | SEND LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); }
2503         | SEND LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(SEND_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); }
2504         | SEND error { $$=0; yyerror("missing '(' or ')' ?"); }
2505         | SEND LPAREN error RPAREN { $$=0; yyerror("bad send argument"); }
2506         | SEND_TCP LPAREN host RPAREN   { $$=mk_action(SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
2507         | SEND_TCP LPAREN STRING RPAREN { $$=mk_action(SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
2508         | SEND_TCP LPAREN ip RPAREN     { $$=mk_action(SEND_TCP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); }
2509         | SEND_TCP LPAREN host COMMA NUMBER RPAREN      { $$=mk_action( SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5);}
2510         | SEND_TCP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); }
2511         | SEND_TCP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(SEND_TCP_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); }
2512         | SEND_TCP error { $$=0; yyerror("missing '(' or ')' ?"); }
2513         | SEND_TCP LPAREN error RPAREN { $$=0; yyerror("bad send_tcp argument"); }
2514         | DROP LPAREN RPAREN            {$$=mk_action(DROP_T, 2, NUMBER_ST, 0, NUMBER_ST, (void*)EXIT_R_F); }
2515         | DROP LPAREN NUMBER RPAREN     {$$=mk_action(DROP_T, 2, NUMBER_ST, (void*)$3, NUMBER_ST, (void*)EXIT_R_F); }
2516         | DROP NUMBER                   {$$=mk_action(DROP_T, 2, NUMBER_ST, (void*)$2, NUMBER_ST, (void*)EXIT_R_F); }
2517         | DROP RETCODE                  {$$=mk_action(DROP_T, 2, RETCODE_ST, 0, NUMBER_ST, (void*)EXIT_R_F); }
2518         | DROP                          {$$=mk_action(DROP_T, 2, NUMBER_ST, 0, NUMBER_ST, (void*)EXIT_R_F); }
2519         | RETURN                        {$$=mk_action(DROP_T, 2, NUMBER_ST, (void*)1, NUMBER_ST, (void*)RETURN_R_F); }
2520         | RETURN NUMBER                 {$$=mk_action(DROP_T, 2, NUMBER_ST, (void*)$2, NUMBER_ST, (void*)RETURN_R_F);}
2521         | RETURN RETCODE                {$$=mk_action(DROP_T, 2, RETCODE_ST, 0, NUMBER_ST, (void*)RETURN_R_F);}
2522         | BREAK                         {$$=mk_action(DROP_T, 2, NUMBER_ST, 0, NUMBER_ST, (void*)BREAK_R_F); }
2523         | LOG_TOK LPAREN STRING RPAREN  {$$=mk_action(LOG_T, 2, NUMBER_ST,
2524                                                                                 (void*)(L_DBG+1), STRING_ST, $3); }
2525         | LOG_TOK LPAREN NUMBER COMMA STRING RPAREN     {$$=mk_action(LOG_T, 2, NUMBER_ST, (void*)$3, STRING_ST, $5); }
2526         | LOG_TOK error                 { $$=0; yyerror("missing '(' or ')' ?"); }
2527         | LOG_TOK LPAREN error RPAREN   { $$=0; yyerror("bad log argument"); }
2528         | SETFLAG LPAREN NUMBER RPAREN  {
2529                                                         if (check_flag($3)==-1)
2530                                                                 yyerror("bad flag value");
2531                                                         $$=mk_action(SETFLAG_T, 1, NUMBER_ST,
2532                                                                                                         (void*)$3);
2533                                                                         }
2534         | SETFLAG LPAREN flag_name RPAREN       {
2535                                                         i_tmp=get_flag_no($3, strlen($3));
2536                                                         if (i_tmp<0) yyerror("flag not declared");
2537                                                         $$=mk_action(SETFLAG_T, 1, NUMBER_ST,
2538                                                                                 (void*)(long)i_tmp);
2539                                                                         }
2540         | SETFLAG error                 { $$=0; yyerror("missing '(' or ')'?"); }
2541         | RESETFLAG LPAREN NUMBER RPAREN {
2542                                                         if (check_flag($3)==-1)
2543                                                                 yyerror("bad flag value");
2544                                                         $$=mk_action(RESETFLAG_T, 1, NUMBER_ST, (void*)$3);
2545                                                                         }
2546         | RESETFLAG LPAREN flag_name RPAREN     {
2547                                                         i_tmp=get_flag_no($3, strlen($3));
2548                                                         if (i_tmp<0) yyerror("flag not declared");
2549                                                         $$=mk_action(RESETFLAG_T, 1, NUMBER_ST,
2550                                                                                 (void*)(long)i_tmp);
2551                                                                         }
2552         | RESETFLAG error               { $$=0; yyerror("missing '(' or ')'?"); }
2553         | ISFLAGSET LPAREN NUMBER RPAREN {
2554                                                         if (check_flag($3)==-1)
2555                                                                 yyerror("bad flag value");
2556                                                         $$=mk_action(ISFLAGSET_T, 1, NUMBER_ST, (void*)$3);
2557                                                                         }
2558         | ISFLAGSET LPAREN flag_name RPAREN     {
2559                                                         i_tmp=get_flag_no($3, strlen($3));
2560                                                         if (i_tmp<0) yyerror("flag not declared");
2561                                                         $$=mk_action(ISFLAGSET_T, 1, NUMBER_ST,
2562                                                                                 (void*)(long)i_tmp);
2563                                                                         }
2564         | ISFLAGSET error { $$=0; yyerror("missing '(' or ')'?"); }
2565         | avpflag_oper LPAREN attr_id_any_str COMMA flag_name RPAREN {
2566                 i_tmp=get_avpflag_no($5);
2567                 if (i_tmp==0) yyerror("avpflag not declared");
2568                 $$=mk_action(AVPFLAG_OPER_T, 3, AVP_ST, $3, NUMBER_ST, (void*)(long)i_tmp, NUMBER_ST, (void*)$1);
2569         }
2570         | avpflag_oper error { $$=0; yyerror("missing '(' or ')'?"); }
2571         | ERROR LPAREN STRING COMMA STRING RPAREN {$$=mk_action(ERROR_T, 2, STRING_ST, $3, STRING_ST, $5); }
2572         | ERROR error { $$=0; yyerror("missing '(' or ')' ?"); }
2573         | ERROR LPAREN error RPAREN { $$=0; yyerror("bad error argument"); }
2574         | ROUTE LPAREN route_name RPAREN        {
2575                                                 i_tmp=route_get(&main_rt, $3);
2576                                                 if (i_tmp==-1){
2577                                                         yyerror("internal error");
2578                                                         YYABORT;
2579                                                 }
2580                                                 $$=mk_action(ROUTE_T, 1, NUMBER_ST,(void*)(long)i_tmp);
2581                                                                                 }
2582         | ROUTE error { $$=0; yyerror("missing '(' or ')' ?"); }
2583         | ROUTE LPAREN error RPAREN { $$=0; yyerror("bad route argument"); }
2584         | EXEC LPAREN STRING RPAREN     { $$=mk_action(EXEC_T, 1, STRING_ST, $3); }
2585         | SET_HOST LPAREN STRING RPAREN { $$=mk_action(SET_HOST_T, 1, STRING_ST, $3); }
2586         | SET_HOST error { $$=0; yyerror("missing '(' or ')' ?"); }
2587         | SET_HOST LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2588         | PREFIX LPAREN STRING RPAREN { $$=mk_action(PREFIX_T, 1, STRING_ST,  $3); }
2589         | PREFIX error { $$=0; yyerror("missing '(' or ')' ?"); }
2590         | PREFIX LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2591         | STRIP_TAIL LPAREN NUMBER RPAREN { $$=mk_action(STRIP_TAIL_T, 1, NUMBER_ST, (void*)$3); }
2592         | STRIP_TAIL error { $$=0; yyerror("missing '(' or ')' ?"); }
2593         | STRIP_TAIL LPAREN error RPAREN { $$=0; yyerror("bad argument, number expected"); }
2594         | STRIP LPAREN NUMBER RPAREN { $$=mk_action(STRIP_T, 1, NUMBER_ST, (void*) $3); }
2595         | STRIP error { $$=0; yyerror("missing '(' or ')' ?"); }
2596         | STRIP LPAREN error RPAREN { $$=0; yyerror("bad argument, number expected"); }
2597         | SET_USERPHONE LPAREN RPAREN { $$=mk_action(SET_USERPHONE_T, 0); }
2598         | SET_USERPHONE error { $$=0; yyerror("missing '(' or ')' ?"); }
2599         | APPEND_BRANCH LPAREN STRING COMMA STRING RPAREN {
2600                 qvalue_t q;
2601                 if (str2q(&q, $5, strlen($5)) < 0) {
2602                         yyerror("bad argument, q value expected");
2603                 }
2604                 $$=mk_action(APPEND_BRANCH_T, 2, STRING_ST, $3, NUMBER_ST, (void *)(long)q);
2605         }
2606         | APPEND_BRANCH LPAREN STRING RPAREN { $$=mk_action(APPEND_BRANCH_T, 2, STRING_ST, $3, NUMBER_ST, (void *)Q_UNSPECIFIED); }
2607         | APPEND_BRANCH LPAREN RPAREN { $$=mk_action(APPEND_BRANCH_T, 2, STRING_ST, 0, NUMBER_ST, (void *)Q_UNSPECIFIED); }
2608         | APPEND_BRANCH {  $$=mk_action( APPEND_BRANCH_T, 1, STRING_ST, 0); }
2609         | SET_HOSTPORT LPAREN STRING RPAREN { $$=mk_action(SET_HOSTPORT_T, 1, STRING_ST, $3); }
2610         | SET_HOSTPORT error { $$=0; yyerror("missing '(' or ')' ?"); }
2611         | SET_HOSTPORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2612         | SET_HOSTPORTTRANS LPAREN STRING RPAREN { $$=mk_action(SET_HOSTPORTTRANS_T, 1, STRING_ST, $3); }
2613         | SET_HOSTPORTTRANS error { $$=0; yyerror("missing '(' or ')' ?"); }
2614         | SET_HOSTPORTTRANS LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2615         | SET_PORT LPAREN STRING RPAREN { $$=mk_action(SET_PORT_T, 1, STRING_ST, $3); }
2616         | SET_PORT error { $$=0; yyerror("missing '(' or ')' ?"); }
2617         | SET_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2618         | SET_USER LPAREN STRING RPAREN { $$=mk_action(SET_USER_T, 1, STRING_ST, $3); }
2619         | SET_USER error { $$=0; yyerror("missing '(' or ')' ?"); }
2620         | SET_USER LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2621         | SET_USERPASS LPAREN STRING RPAREN { $$=mk_action(SET_USERPASS_T, 1, STRING_ST, $3); }
2622         | SET_USERPASS error { $$=0; yyerror("missing '(' or ')' ?"); }
2623         | SET_USERPASS LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2624         | SET_URI LPAREN STRING RPAREN { $$=mk_action(SET_URI_T, 1, STRING_ST,$3); }
2625         | SET_URI error { $$=0; yyerror("missing '(' or ')' ?"); }
2626         | SET_URI LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2627         | REVERT_URI LPAREN RPAREN { $$=mk_action(REVERT_URI_T, 0); }
2628         | REVERT_URI { $$=mk_action(REVERT_URI_T, 0); }
2629         | FORCE_RPORT LPAREN RPAREN     { $$=mk_action(FORCE_RPORT_T, 0); }
2630         | FORCE_RPORT   {$$=mk_action(FORCE_RPORT_T, 0); }
2631         | FORCE_TCP_ALIAS LPAREN NUMBER RPAREN  {
2632                 #ifdef USE_TCP
2633                         $$=mk_action(FORCE_TCP_ALIAS_T, 1, NUMBER_ST, (void*)$3);
2634                 #else
2635                         yyerror("tcp support not compiled in");
2636                 #endif
2637         }
2638         | FORCE_TCP_ALIAS LPAREN RPAREN {
2639                 #ifdef USE_TCP
2640                         $$=mk_action(FORCE_TCP_ALIAS_T, 0);
2641                 #else
2642                         yyerror("tcp support not compiled in");
2643                 #endif
2644         }
2645         | FORCE_TCP_ALIAS                               {
2646                 #ifdef USE_TCP
2647                         $$=mk_action(FORCE_TCP_ALIAS_T, 0);
2648                 #else
2649                         yyerror("tcp support not compiled in");
2650                 #endif
2651         }
2652         | FORCE_TCP_ALIAS LPAREN error RPAREN   {$$=0; yyerror("bad argument, number expected"); }
2653         | UDP_MTU_TRY_PROTO LPAREN proto RPAREN
2654                 { $$=mk_action(UDP_MTU_TRY_PROTO_T, 1, NUMBER_ST, $3); }
2655         | UDP_MTU_TRY_PROTO LPAREN error RPAREN
2656                 { $$=0; yyerror("bad argument, UDP, TCP, TLS or SCTP expected"); }
2657         | SET_ADV_ADDRESS LPAREN listen_id RPAREN {
2658                 $$=0;
2659                 if ((str_tmp=pkg_malloc(sizeof(str)))==0) {
2660                         LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
2661                 } else {
2662                         str_tmp->s=$3;
2663                         str_tmp->len=strlen($3);
2664                         $$=mk_action(SET_ADV_ADDR_T, 1, STR_ST, str_tmp);
2665                 }
2666         }
2667         | SET_ADV_ADDRESS LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2668         | SET_ADV_ADDRESS error {$$=0; yyerror("missing '(' or ')' ?"); }
2669         | SET_ADV_PORT LPAREN NUMBER RPAREN {
2670                 $$=0;
2671                 tmp=int2str($3, &i_tmp);
2672                 if ((str_tmp=pkg_malloc(sizeof(str)))==0) {
2673                         LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
2674                 } else {
2675                         if ((str_tmp->s=pkg_malloc(i_tmp))==0) {
2676                                 LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
2677                         } else {
2678                                 memcpy(str_tmp->s, tmp, i_tmp);
2679                                 str_tmp->len=i_tmp;
2680                                 $$=mk_action(SET_ADV_PORT_T, 1, STR_ST, str_tmp);
2681                         }
2682                 }
2683         }
2684         | SET_ADV_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
2685         | SET_ADV_PORT  error {$$=0; yyerror("missing '(' or ')' ?"); }
2686         | FORCE_SEND_SOCKET LPAREN phostport RPAREN { 
2687                 $$=mk_action(FORCE_SEND_SOCKET_T, 1, SOCKID_ST, $3);
2688         }
2689         | FORCE_SEND_SOCKET LPAREN error RPAREN {
2690                 $$=0; yyerror("bad argument, [proto:]host[:port] expected");
2691         }
2692         | FORCE_SEND_SOCKET error {$$=0; yyerror("missing '(' or ')' ?"); }
2693         | ID {mod_func_action = mk_action(MODULE_T, 2, MODEXP_ST, NULL, NUMBER_ST,
2694                         0); } LPAREN func_params RPAREN {
2695                 mod_func_action->val[0].u.data = 
2696                         find_export_record($1, mod_func_action->val[1].u.number, rt,
2697                                                                 &u_tmp);
2698                 if (mod_func_action->val[0].u.data == 0) {
2699                         if (find_export_record($1, mod_func_action->val[1].u.number, 0,
2700                                                                         &u_tmp) ) {
2701                                         yyerror("Command cannot be used in the block\n");
2702                         } else {
2703                                 yyerror("unknown command, missing loadmodule?\n");
2704                         }
2705                         pkg_free(mod_func_action);
2706                         mod_func_action=0;
2707                 }else{
2708                         switch( ((union cmd_export_u*)
2709                                                 mod_func_action->val[0].u.data)->c.param_no){
2710                                 case 0:
2711                                 case 1:
2712                                 case 2:
2713                                         /* MODULE_T used for 0-2 params */
2714                                         break;
2715                                 case 3:
2716                                         mod_func_action->type=MODULE3_T;
2717                                         break;
2718                                 case 4:
2719                                         mod_func_action->type=MODULE4_T;
2720                                         break;
2721                                 case 5:
2722                                         mod_func_action->type=MODULE5_T;
2723                                         break;
2724                                 case 6:
2725                                         mod_func_action->type=MODULE6_T;
2726                                         break;
2727                                 case VAR_PARAM_NO:
2728                                         mod_func_action->type=MODULEX_T;
2729                                         break;
2730                                 default:
2731                                         yyerror("too many parameters for function\n");
2732                                         break;
2733                         }
2734                 }
2735                 $$ = mod_func_action;
2736         }
2737         | ID error                                      { yyerror("'('')' expected (function call)");}
2738         ;
2739 func_params:
2740         /* empty */
2741         | func_params COMMA func_param { }
2742         | func_param {}
2743         | func_params error { yyerror("call params error\n"); }
2744         ;
2745 func_param:
2746         NUMBER {
2747                 if (mod_func_action->val[1].u.number < MAX_ACTIONS-2) {
2748                         mod_func_action->val[mod_func_action->val[1].u.number+2].type =
2749                                 NUMBER_ST;
2750                         mod_func_action->val[mod_func_action->val[1].u.number+2].u.number =
2751                                 $1;
2752                         mod_func_action->val[1].u.number++;
2753                 } else {
2754                         yyerror("Too many arguments\n");
2755                 }
2756         }
2757         | STRING {
2758                 if (mod_func_action->val[1].u.number < MAX_ACTIONS-2) {
2759                         mod_func_action->val[mod_func_action->val[1].u.number+2].type = STRING_ST;
2760                         mod_func_action->val[mod_func_action->val[1].u.number+2].u.string = $1;
2761                         mod_func_action->val[1].u.number++;
2762                 } else {
2763                         yyerror("Too many arguments\n");
2764                 }
2765         }
2766         ;
2767 %%
2768
2769 extern int line;
2770 extern int column;
2771 extern int startcolumn;
2772 extern int startline;
2773
2774
2775 static void get_cpos(struct cfg_pos* pos)
2776 {
2777         pos->s_line=startline;
2778         pos->e_line=line;
2779         pos->s_col=startcolumn;
2780         pos->e_col=column-1;
2781 }
2782
2783
2784 static void warn_at(struct cfg_pos* p, char* format, ...)
2785 {
2786         va_list ap;
2787         char s[256];
2788         
2789         va_start(ap, format);
2790         vsnprintf(s, sizeof(s), format, ap);
2791         va_end(ap);
2792         if (p->e_line!=p->s_line)
2793                 LOG(L_WARN, "warning in config file, from line %d, column %d to line %d, column %d: %s\n",
2794                                         p->s_line, p->s_col, p->e_line, p->e_col, s);
2795         else if (p->s_col!=p->e_col)
2796                 LOG(L_WARN, "warning in config file, line %d, column %d-%d: %s\n",
2797                                         p->s_line, p->s_col, p->e_col, s);
2798         else
2799                 LOG(L_WARN, "warning in config file, line %d, column %d: %s\n",
2800                                 p->s_line, p->s_col, s);
2801         cfg_warnings++;
2802 }
2803
2804
2805
2806 static void yyerror_at(struct cfg_pos* p, char* format, ...)
2807 {
2808         va_list ap;
2809         char s[256];
2810         
2811         va_start(ap, format);
2812         vsnprintf(s, sizeof(s), format, ap);
2813         va_end(ap);
2814         if (p->e_line!=p->s_line)
2815                 LOG(L_CRIT, "parse error in config file, from line %d, column %d to line %d, column %d: %s\n",
2816                                         p->s_line, p->s_col, p->e_line, p->e_col, s);
2817         else if (p->s_col!=p->e_col)
2818                 LOG(L_CRIT, "parse error in config file, line %d, column %d-%d: %s\n",
2819                                         p->s_line, p->s_col, p->e_col, s);
2820         else
2821                 LOG(L_CRIT, "parse error in config file, line %d, column %d: %s\n",
2822                                         p->s_line, p->s_col, s);
2823         cfg_errors++;
2824 }
2825
2826
2827
2828 static void warn(char* format, ...)
2829 {
2830         va_list ap;
2831         char s[256];
2832         struct cfg_pos pos;
2833         
2834         get_cpos(&pos);
2835         va_start(ap, format);
2836         vsnprintf(s, sizeof(s), format, ap);
2837         va_end(ap);
2838         warn_at(&pos, s);
2839 }
2840
2841
2842
2843 static void yyerror(char* format, ...)
2844 {
2845         va_list ap;
2846         char s[256];
2847         struct cfg_pos pos;
2848         
2849         get_cpos(&pos);
2850         va_start(ap, format);
2851         vsnprintf(s, sizeof(s), format, ap);
2852         va_end(ap);
2853         yyerror_at(&pos, s);
2854 }
2855
2856
2857
2858 /** mk_rval_expr_v wrapper.
2859  *  checks mk_rval_expr_v return value and sets the cfg. pos
2860  *  (line and column numbers)
2861  *  @return rval_expr* on success, 0 on error (@see mk_rval_expr_v)
2862  */
2863 static struct rval_expr* mk_rve_rval(enum rval_type type, void* v)
2864 {
2865         struct rval_expr* ret;
2866         struct cfg_pos pos;
2867
2868         get_cpos(&pos);
2869         ret=mk_rval_expr_v(type, v, &pos);
2870         if (ret==0){
2871                 yyerror("internal error: failed to create rval expr");
2872                 /* YYABORT; */
2873         }
2874         return ret;
2875 }
2876
2877
2878 /** mk_rval_expr1 wrapper.
2879  *  checks mk_rval_expr1 return value (!=0 and type checking)
2880  *  @return rval_expr* on success, 0 on error (@see mk_rval_expr1)
2881  */
2882 static struct rval_expr* mk_rve1(enum rval_expr_op op, struct rval_expr* rve1)
2883 {
2884         struct rval_expr* ret;
2885         struct rval_expr* bad_rve;
2886         enum rval_type type, bad_t, exp_t;
2887         
2888         if (rve1==0)
2889                 return 0;
2890         ret=mk_rval_expr1(op, rve1, &rve1->fpos);
2891         if (ret && (rve_check_type(&type, ret, &bad_rve, &bad_t, &exp_t)!=1)){
2892                 yyerror_at(&rve1->fpos, "bad expression: type mismatch"
2893                                         " (%s instead of %s)", rval_type_name(bad_t),
2894                                         rval_type_name(exp_t));
2895         }
2896         return ret;
2897 }
2898
2899
2900 /** mk_rval_expr2 wrapper.
2901  *  checks mk_rval_expr2 return value (!=0 and type checking)
2902  *  @return rval_expr* on success, 0 on error (@see mk_rval_expr2)
2903  */
2904 static struct rval_expr* mk_rve2(enum rval_expr_op op, struct rval_expr* rve1,
2905                                                                         struct rval_expr* rve2)
2906 {
2907         struct rval_expr* ret;
2908         struct rval_expr* bad_rve;
2909         enum rval_type type, bad_t, exp_t;
2910         struct cfg_pos pos;
2911         
2912         if ((rve1==0) || (rve2==0))
2913                 return 0;
2914         bad_rve=0;
2915         bad_t=0;
2916         exp_t=0;
2917         cfg_pos_join(&pos, &rve1->fpos, &rve2->fpos);
2918         ret=mk_rval_expr2(op, rve1, rve2, &pos);
2919         if (ret && (rve_check_type(&type, ret, &bad_rve, &bad_t, &exp_t)!=1)){
2920                 if (bad_rve)
2921                         yyerror_at(&pos, "bad expression: type mismatch:"
2922                                                 " %s instead of %s at (%d,%d)",
2923                                                 rval_type_name(bad_t), rval_type_name(exp_t),
2924                                                 bad_rve->fpos.s_line, bad_rve->fpos.s_col);
2925                 else
2926                         yyerror("BUG: unexpected null \"bad\" expression\n");
2927         }
2928         return ret;
2929 }
2930
2931
2932 static struct name_lst* mk_name_lst(char* host, int flags)
2933 {
2934         struct name_lst* l;
2935         l=pkg_malloc(sizeof(struct name_lst));
2936         if (l==0) {
2937                 LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
2938         } else {
2939                 l->name=host;
2940                 l->flags=flags;
2941                 l->next=0;
2942         }
2943         return l;
2944 }
2945
2946
2947 static struct socket_id* mk_listen_id(char* host, int proto, int port)
2948 {
2949         struct socket_id* l;
2950         l=pkg_malloc(sizeof(struct socket_id));
2951         if (l==0) {
2952                 LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
2953         } else {
2954                 l->addr_lst=mk_name_lst(host, 0);
2955                 if (l->addr_lst==0){
2956                         pkg_free(l);
2957                         return 0;
2958                 }
2959                 l->flags=0;
2960                 l->port=port;
2961                 l->proto=proto;
2962                 l->next=0;
2963         }
2964         return l;
2965 }
2966
2967
2968 static void free_name_lst(struct name_lst* lst)
2969 {
2970         struct name_lst* tmp;
2971         
2972         while(lst){
2973                 tmp=lst;
2974                 lst=lst->next;
2975                 pkg_free(tmp);
2976         }
2977 }
2978
2979
2980 static struct socket_id* mk_listen_id2(struct name_lst* addr_l, int proto,
2981                                                                                 int port)
2982 {
2983         struct socket_id* l;
2984         l=pkg_malloc(sizeof(struct socket_id));
2985         if (l==0) {
2986                 LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
2987         } else {
2988                 l->flags=addr_l->flags;
2989                 l->port=port;
2990                 l->proto=proto;
2991                 l->addr_lst=addr_l;
2992                 l->next=0;
2993         }
2994         return l;
2995 }
2996
2997
2998 static void free_socket_id(struct socket_id* i)
2999 {
3000         free_name_lst(i->addr_lst);
3001         pkg_free(i);
3002 }
3003
3004
3005 static void free_socket_id_lst(struct socket_id* lst)
3006 {
3007         struct socket_id* tmp;
3008         
3009         while(lst){
3010                 tmp=lst;
3011                 lst=lst->next;
3012                 free_socket_id(tmp);
3013         }
3014 }
3015
3016
3017 /** create a temporary case statmenet structure.
3018  *  *err will be filled in case of error (return == 0):
3019  *   -1 - non constant expression
3020  *   -2 - expression error (bad type)
3021  *   -10 - memory allocation error
3022  */
3023 static struct case_stms* mk_case_stm(struct rval_expr* ct, int is_re,
3024                                                                                         struct action* a, int* err)
3025 {
3026         struct case_stms* s;
3027         struct rval_expr* bad_rve;
3028         enum rval_type type, bad_t, exp_t;
3029         enum match_str_type t;
3030         
3031         t=MATCH_UNKNOWN;
3032         if (ct){
3033                 /* if ct!=0 => case, else if ct==0 is a default */
3034                 if (!rve_is_constant(ct)){
3035                         yyerror_at(&ct->fpos, "non constant expression in case");
3036                         *err=-1;
3037                         return 0;
3038                 }
3039                 if (rve_check_type(&type, ct, &bad_rve, &bad_t, &exp_t)!=1){
3040                         yyerror_at(&ct->fpos, "bad expression: type mismatch:"
3041                                                         " %s instead of %s at (%d,%d)",
3042                                                         rval_type_name(bad_t), rval_type_name(exp_t),
3043                                                         bad_rve->fpos.s_line, bad_rve->fpos.s_col);
3044                         *err=-2;
3045                         return 0;
3046                 }
3047                 if (is_re)
3048                         t=MATCH_RE;
3049                 else if (type==RV_STR)
3050                         t=MATCH_STR;
3051                 else
3052                         t=MATCH_INT;
3053         }
3054
3055         s=pkg_malloc(sizeof(*s));
3056         if (s==0) {
3057                 yyerror("internal error: memory allocation failure");
3058                 *err=-10;
3059         } else {
3060                 memset(s, 0, sizeof(*s));
3061                 s->ct_rve=ct;
3062                 s->type=t;
3063                 s->actions=a;
3064                 s->next=0;
3065                 s->append=0;
3066         }
3067         return s;
3068 }
3069
3070
3071 /*
3072  * @return 0 on success, -1 on error.
3073  */
3074 static int case_check_type(struct case_stms* stms)
3075 {
3076         struct case_stms* c;
3077         struct case_stms* s;
3078         
3079         for(c=stms; c ; c=c->next){
3080                 if (!c->ct_rve) continue;
3081                 for (s=c->next; s; s=s->next){
3082                         if (!s->ct_rve) continue;
3083                         if ((s->type!=c->type) &&
3084                                 !(      (c->type==MATCH_STR || c->type==MATCH_RE) &&
3085                                         (s->type==MATCH_STR || s->type==MATCH_RE) ) ){
3086                                         yyerror_at(&s->ct_rve->fpos, "type mismatch in case");
3087                                         return -1;
3088                         }
3089                 }
3090         }
3091         return 0;
3092 }
3093
3094
3095 /*
3096  * @return 0 on success, -1 on error.
3097  */
3098 static int case_check_default(struct case_stms* stms)
3099 {
3100         struct case_stms* c;
3101         int default_no;
3102         
3103         default_no=0;
3104         for(c=stms; c ; c=c->next)
3105                 if (c->ct_rve==0) default_no++;
3106         return (default_no<=1)?0:-1;
3107 }
3108
3109
3110
3111 /*
3112 int main(int argc, char ** argv)
3113 {
3114         if (yyparse()!=0)
3115                 fprintf(stderr, "parsing error\n");
3116 }
3117 */