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