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