加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
cfg.y 75.08 KB
一键复制 编辑 原始数据 按行查看 历史
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716
/*
* cfg grammar
*
* Copyright (C) 2001-2003 FhG Fokus
* Copyright (C) 2005-2009 Voice Sistem S.R.L.
* Copyright (C) 2006 enum.at
*
* This file is part of opensips, a free SIP server.
*
* opensips is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version
*
* opensips is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* History:
* ---------
* 2003-01-29 src_port added (jiri)
* 2003-01-23 mhomed added (jiri)
* 2003-03-19 replaced all mallocs/frees with pkg_malloc/pkg_free (andrei)
* 2003-03-19 Added support for route type in find_export (janakj)
* 2003-03-20 Regex support in modparam (janakj)
* 2003-04-01 added dst_port, proto , af (andrei)
* 2003-04-05 s/reply_route/failure_route, onreply_route introduced (jiri)
* 2003-04-12 added force_rport, chroot and wdir (andrei)
* 2003-04-15 added tcp_children, disable_tcp (andrei)
* 2003-04-22 strip_tail added (jiri)
* 2003-07-03 tls* (disable, certificate, private_key, ca_list, verify,
* require_certificate added (andrei)
* 2003-07-06 more tls config. vars added: tls_method, tls_port_no (andrei)
* 2003-10-02 added {,set_}advertised_{address,port} (andrei)
* 2003-10-10 added <,>,<=,>=, != operators support
* added msg:len (andrei)
* 2003-10-11 if(){} doesn't require a ';' after it anymore (andrei)
* 2003-10-13 added FIFO_DIR & proto:host:port listen/alias support (andrei)
* 2003-10-24 converted to the new socket_info lists (andrei)
* 2003-10-28 added tcp_accept_aliases (andrei)
* 2003-11-20 added {tcp_connect, tcp_send, tls_*}_timeout (andrei)
* 2004-03-30 added DISABLE_CORE and OPEN_FD_LIMIT (andrei)
* 2004-04-29 added SOCK_MODE, SOCK_USER & SOCK_GROUP (andrei)
* 2004-05-03 applied multicast support patch (MCAST_LOOPBACK) from janakj
added MCAST_TTL (andrei)
* 2004-07-05 src_ip & dst_ip will detect ip addresses between quotes
* (andrei)
* 2004-10-19 added FROM_URI, TO_URI (andrei)
* 2004-11-30 added force_send_socket (andrei)
* 2005-07-08 added TCP_CON_LIFETIME, TCP_POLL_METHOD, TCP_MAX_CONNECTIONS
* (andrei)
* 2005-07-26 default onreply route added (andrei)
* 2005-11-22 added tos configurability (thanks to Andreas Granig)
* 2005-11-29 added serialize_branches and next_branches (bogdan)
* 2006-03-02 MODULE_T action points to a cmd_export_t struct instead to
* a function address - more info is accessible (bogdan)
* 2006-03-02 store the cfg line into the action struct to be able to
* give more hints if fixups fail (bogdan)
* 2006-05-22 forward(_udp,_tcp,_tls) and send(_tcp) merged in forward() and
* send() (bogdan)
* 2006-12-22 functions for script and branch flags added (bogdan)
* 2007-01-11 auto_aliases option added (bogdan)
* 2007-01-25 disable_dns_failover option added (bogdan)
* 2012-01-19 added TCP keepalive support
* 2012-12-06 added event_route (razvanc)
* 2013-05-23 added NAPTR lookup option (dsandras)
* 2013-09-25 added TLS_CA_DIR option (chris_secusmart)
* 2013-10-06 added TLS_DH_PARAM option (mehmet_secusmart)
* 2013-10-30 added TLS_EC_CURVE option (yrjoe_secusmart)
*/
%{
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>
#include "route_struct.h"
#include "globals.h"
#include "route.h"
#include "dprint.h"
#include "cfg_pp.h"
#include "sr_module.h"
#include "modparam.h"
#include "ip_addr.h"
#include "resolve.h"
#include "socket_info.h"
#include "name_alias.h"
#include "ut.h"
#include "pt_scaling.h"
#include "dset.h"
#include "pvar.h"
#include "blacklists.h"
#include "xlog.h"
#include "db/db_insertq.h"
#include "bin_interface.h"
#include "net/trans.h"
#include "config.h"
#include "mem/rpm_mem.h"
#include "poll_types.h"
#ifdef SHM_EXTRA_STATS
#include "mem/module_info.h"
#endif
#ifdef DEBUG_DMALLOC
#include <dmalloc.h>
#endif
/* hack to avoid alloca usage in the generated C file (needed for compiler
with no built in alloca, like icc*/
#undef _ALLOCA_H
#undef MIN
#undef MAX
extern int yylex();
static void yyerror(char* s);
static void yyerrorf(char* fmt, ...);
static char* tmp;
static int i_tmp, rc;
static struct socket_id* lst_tmp;
static int rt; /* Type of route block for find_export */
static str s_tmp;
static str tstr;
static struct net* net_tmp;
static pv_spec_t *spec;
static pv_elem_t *elem;
static struct bl_rule *bl_head = 0;
static struct bl_rule *bl_tail = 0;
static struct script_route_ref *rt_ref = NULL;
action_elem_t elems[MAX_ACTION_ELEMS];
static action_elem_t route_elems[MAX_ACTION_ELEMS];
action_elem_t *a_tmp;
static inline void warn(char* s);
static struct socket_id* mk_listen_id(char*, enum sip_protos, int);
static struct socket_id* set_listen_id_adv(struct socket_id *, char *, int);
static struct multi_str *new_string(char *s);
static int parse_ipnet(char *in, int len, struct net **ipnet);
extern int line;
extern int column;
extern int startcolumn;
extern char *finame;
struct listen_param {
enum si_flags flags;
int workers;
struct socket_id *socket;
char *tag;
char *auto_scaling_profile;
} p_tmp;
static void fill_socket_id(struct listen_param *param, struct socket_id *s);
union route_name_var {
int iname;
struct _pv_spec *sname;
struct _pv_elem *ename;
void *data;
} rn_tmp;
#ifndef SHM_EXTRA_STATS
struct multi_str{
char *s;
struct multi_str* next;
};
#else
static struct multi_str *tmp_mod;
#endif
#define get_cfg_file_name \
((finame) ? finame : cfg_file ? cfg_file : "default")
#define mk_action_(_res, _type, _no, _elems) \
do { \
_res = mk_action(_type, _no, _elems, line, get_cfg_file_name); \
} while(0)
#define mk_action0(_res, _type) \
do { \
_res = mk_action(_type, 0, 0, line, get_cfg_file_name); \
} while(0)
#define mk_action1(_res, _type, _p1_type, _p1) \
do { \
elems[0].type = _p1_type; \
elems[0].u.data = _p1; \
_res = mk_action(_type, 1, elems, line, get_cfg_file_name); \
} while(0)
#define mk_action2(_res, _type, _p1_type, _p2_type, _p1, _p2) \
do { \
elems[0].type = _p1_type; \
elems[0].u.data = _p1; \
elems[1].type = _p2_type; \
elems[1].u.data = _p2; \
_res = mk_action(_type, 2, elems, line, get_cfg_file_name); \
} while(0)
#define mk_action3(_res, _type, _p1_type, _p2_type, _p3_type, _p1, _p2, _p3) \
do { \
elems[0].type = _p1_type; \
elems[0].u.data = _p1; \
elems[1].type = _p2_type; \
elems[1].u.data = _p2; \
elems[2].type = _p3_type; \
elems[2].u.data = _p3; \
_res = mk_action(_type, 3, elems, line, get_cfg_file_name); \
} while(0)
extern int cfg_parse_only_routes;
#define IFOR(_instr) \
if (cfg_parse_only_routes==1) {_instr;break;}
%}
%union {
long intval;
unsigned long uval;
char* strval;
struct expr* expr;
struct action* action;
struct net* ipnet;
struct ip_addr* ipaddr;
struct socket_id* sockid;
struct listen_param* listen_param;
struct _pv_spec *specval;
struct multi_str* multistr;
}
/* terminals */
/* keywords */
%token DROP
%token ASSERT
%token EXIT
%token RETURN
%token LOG_TOK
%token ERROR
%token ROUTE
%token ROUTE_FAILURE
%token ROUTE_ONREPLY
%token ROUTE_BRANCH
%token ROUTE_ERROR
%token ROUTE_LOCAL
%token ROUTE_STARTUP
%token ROUTE_TIMER
%token ROUTE_EVENT
%token IF
%token ELSE
%token SWITCH
%token CASE
%token DEFAULT
%token BREAK
%token WHILE
%token FOR
%token IN
%token READONLY
%token EXPIRE
%token NULLV
%token XDBG
%token XLOG
%token XLOG_BUF_SIZE
%token XLOG_FORCE_COLOR
%token XLOG_PRINT_LEVEL
%token XLOG_LEVEL
%token PV_PRINT_BUF_SIZE
/* config vars. */
%token DEBUG_MODE
%token ENABLE_ASSERTS
%token ABORT_ON_ASSERT
%token LOGLEVEL
%token LOGPREFIX
%token LOGSTDOUT
%token LOGSTDERROR
%token STDERROR_ENABLED
%token SYSLOG_ENABLED
%token LOG_EVENT_ENABLED
%token STDERROR_LEVEL_FILTER
%token SYSLOG_LEVEL_FILTER
%token LOG_EVENT_LEVEL_FILTER
%token STDERROR_FORMAT
%token SYSLOG_FORMAT
%token LOG_JSON_BUF_SIZE
%token LOG_MSG_BUF_SIZE
%token LOGFACILITY
%token SYSLOG_FACILITY
%token LOGNAME
%token SYSLOG_NAME
%token AVP_ALIASES
%token LISTEN
%token SOCKET
%token MEMGROUP
%token ALIAS
%token AUTO_ALIASES
%token TAG
%token DNS
%token REV_DNS
%token DNS_TRY_IPV6
%token DNS_TRY_NAPTR
%token DNS_RETR_TIME
%token DNS_RETR_NO
%token DNS_SERVERS_NO
%token DNS_USE_SEARCH
%token MAX_WHILE_LOOPS
%token UDP_WORKERS
%token CHECK_VIA
%token SHM_HASH_SPLIT_PERCENTAGE
%token SHM_SECONDARY_HASH_SIZE
%token MEM_WARMING_ENABLED
%token MEM_WARMING_PATTERN_FILE
%token MEM_WARMING_PERCENTAGE
%token RPM_MEM_FILE
%token RPM_MEM_SIZE
%token MEMLOG
%token MEMDUMP
%token SHM_MEMLOG_SIZE
%token EXECMSGTHRESHOLD
%token EXECDNSTHRESHOLD
%token TCPTHRESHOLD
%token EVENT_SHM_THRESHOLD
%token EVENT_PKG_THRESHOLD
%token QUERYBUFFERSIZE
%token QUERYFLUSHTIME
%token SIP_WARNING
%token SERVER_SIGNATURE
%token SERVER_HEADER
%token USER_AGENT_HEADER
%token LOADMODULE
%token MPATH
%token MODPARAM
%token MAXBUFFER
%token CHROOT
%token WDIR
%token MHOMED
%token POLL_METHOD
%token TCP_ACCEPT_ALIASES
%token TCP_WORKERS
%token TCP_CONNECT_TIMEOUT
%token TCP_CON_LIFETIME
%token TCP_SOCKET_BACKLOG
%token TCP_MAX_CONNECTIONS
%token TCP_NO_NEW_CONN_BFLAG
%token TCP_NO_NEW_CONN_RPLFLAG
%token TCP_KEEPALIVE
%token TCP_KEEPCOUNT
%token TCP_KEEPIDLE
%token TCP_KEEPINTERVAL
%token TCP_MAX_MSG_TIME
%token TCP_PARALLEL_READ_ON_WORKERS
%token ADVERTISED_ADDRESS
%token ADVERTISED_PORT
%token DISABLE_CORE
%token OPEN_FD_LIMIT
%token MCAST_LOOPBACK
%token MCAST_TTL
%token TOS
%token DISABLE_DNS_FAILOVER
%token DISABLE_DNS_BLACKLIST
%token DST_BLACKLIST
%token DISABLE_STATELESS_FWD
%token DB_VERSION_TABLE
%token DB_DEFAULT_URL
%token DB_MAX_ASYNC_CONNECTIONS
%token DISABLE_503_TRANSLATION
%token SYNC_TOKEN
%token ASYNC_TOKEN
%token LAUNCH_TOKEN
%token AUTO_SCALING_PROFILE
%token AUTO_SCALING_CYCLE
%token TIMER_WORKERS
/* operators */
%nonassoc EQUAL
%nonassoc EQUAL_T
%nonassoc GT
%nonassoc LT
%nonassoc GTE
%nonassoc LTE
%nonassoc DIFF
%nonassoc MATCH
%nonassoc NOTMATCH
%nonassoc COLONEQ
%nonassoc PLUSEQ
%nonassoc MINUSEQ
%nonassoc SLASHEQ
%nonassoc MULTEQ
%nonassoc MODULOEQ
%nonassoc BANDEQ
%nonassoc BOREQ
%nonassoc BXOREQ
%left OR AND
%left BOR BAND BXOR BLSHIFT BRSHIFT
%left PLUS MINUS SLASH MULT MODULO
%right NOT BNOT
%right RPAREN ELSE /* solves the classic if-if-else ambiguity */
/* values */
%token <intval> NUMBER
%token <intval> ZERO
%token <strval> ID
%token <strval> STRING
%token <strval> SCRIPTVAR
%token <strval> IPV6ADDR
%token <strval> IPV4ADDR
%token <strval> IPNET
/* other */
%token COMMA
%token SEMICOLON
%token RPAREN
%token LPAREN
%token LBRACE
%token RBRACE
%token LBRACK
%token RBRACK
%token SLASH
%token AS
%token USE_WORKERS
%token USE_AUTO_SCALING_PROFILE
%token MAX
%token MIN
%token DOT
%token CR
%token COLON
%token ANY
%token ANYCAST
%token FRAG
%token REUSE_PORT
%token SCRIPTVARERR
%token SCALE_UP_TO
%token SCALE_DOWN_TO
%token ON
%token CYCLES
%token CYCLES_WITHIN
%token PERCENTAGE
/*non-terminals */
%type <expr> exp exp_elem exp_cond assignexp /*, condition*/
%type <action> action actions brk_action brk_actions cmd if_cmd stm brk_stm
%type <action> exp_stm assign_cmd while_cmd foreach_cmd async_func brk_if_cmd
%type <action> switch_cmd switch_stm case_stms case_stm default_stm
%type <intval> func_param
%type <ipaddr> ipv4 ipv6 ipv6addr ip
%type <ipnet> ipnet
%type <specval> script_var
%type <strval> host
%type <strval> listen_id
%type <sockid> socket_def
%type <sockid> id_lst
%type <sockid> alias_def
%type <sockid> listen_id_def
%type <sockid> phostport panyhostport
%type <intval> proto port any_proto
%type <strval> host_sep
%type <intval> equalop compop matchop strop intop
%type <intval> assignop
%type <intval> snumber
%type <strval> route_name
%type <intval> route_name_var
%type <intval> route_param
%type <intval> blst_flag blst_flags
%type <strval> folded_string
%type <multistr> multi_string
/*
* known shift/reduce conflicts (the default action, shift, is correct):
* - RETURN PLUS NUMBER
* - RETURN MINUS NUMBER
* (reason: MINUS has left associativity, but for both "return -1;" and
* "return;" to work, it would need right assoc; same idea for PLUS)
*/
%expect 2
%%
cfg: statements
;
statements: statements statement {}
| statement {}
| statements error { yyerror(""); YYABORT;}
;
statement: assign_stm
| module_stm
| {rt=REQUEST_ROUTE;} route_stm
| {rt=FAILURE_ROUTE;} failure_route_stm
| {rt=ONREPLY_ROUTE;} onreply_route_stm
| {rt=BRANCH_ROUTE;} branch_route_stm
| {rt=ERROR_ROUTE;} error_route_stm
| {rt=LOCAL_ROUTE;} local_route_stm
| {rt=STARTUP_ROUTE;} startup_route_stm
| {rt=TIMER_ROUTE;} timer_route_stm
| {rt=EVENT_ROUTE;} event_route_stm
| CR /* null statement*/
;
listen_id: ip { IFOR();
tmp=ip_addr2a($1);
if(tmp==0){
LM_CRIT("cfg. parser: bad ip address.\n");
$$=0;
}else{
$$=pkg_malloc(strlen(tmp)+1);
if ($$==0){
LM_CRIT("cfg. parser: out of memory.\n");
YYABORT;
}else{
memcpy($$, tmp, strlen(tmp)+1);
}
}
}
| STRING { IFOR();
$$=pkg_malloc(strlen($1)+1);
if ($$==0){
LM_CRIT("cfg. parser: out of memory.\n");
YYABORT;
}else{
memcpy($$, $1, strlen($1)+1);
}
}
| host { IFOR();
if ($1==0) {
$$ = 0;
} else {
$$=pkg_malloc(strlen($1)+1);
if ($$==0){
LM_CRIT("cfg. parser: out of memory.\n");
YYABORT;
}else{
memcpy($$, $1, strlen($1)+1);
}
}
}
;
host_sep: DOT {$$=".";}
| MINUS {$$="-"; }
;
host: ID { $$=$1; }
| host host_sep ID { IFOR();
$$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
if ($$==0){
LM_CRIT("cfg. parser: memory allocation"
" failure while parsing host\n");
YYABORT;
}else{
memcpy($$, $1, strlen($1));
$$[strlen($1)]=*$2;
memcpy($$+strlen($1)+1, $3, strlen($3));
$$[strlen($1)+1+strlen($3)]=0;
}
pkg_free($1); pkg_free($3);
}
| host DOT error { $$=0; pkg_free($1);
yyerror("invalid hostname (use quotes if hostname "
"has config keywords)"); }
;
proto: ID { IFOR();
if (parse_proto((unsigned char *)$1, strlen($1), &i_tmp) < 0) {
yyerrorf("cannot handle protocol <%s>\n", $1);
YYABORT;
}
pkg_free($1);
$$ = i_tmp;
}
;
port: NUMBER { $$=$1; }
| ANY { $$=0; }
;
snumber: NUMBER { $$=$1; }
| PLUS NUMBER { $$=$2; }
| MINUS NUMBER { $$=-$2; }
;
phostport: proto COLON listen_id { IFOR();
$$=mk_listen_id($3, $1, 0); }
| proto COLON listen_id COLON port { IFOR();
$$=mk_listen_id($3, $1, $5);}
| proto COLON listen_id COLON error {
$$=0;
yyerror("port number expected");
YYABORT;
}
| NUMBER error { $$=0;
yyerror("protocol expected");
YYABORT;
}
;
panyhostport: proto COLON MULT { IFOR();
$$=mk_listen_id(0, $1, 0); }
| proto COLON MULT COLON port { IFOR();
$$=mk_listen_id(0, $1, $5); }
;
alias_def: listen_id { IFOR();
$$=mk_listen_id($1, PROTO_NONE, 0); }
| ANY COLON listen_id { IFOR();
$$=mk_listen_id($3, PROTO_NONE, 0); }
| ANY COLON listen_id COLON port { IFOR();
$$=mk_listen_id($3, PROTO_NONE, $5); }
| ANY COLON listen_id COLON error {
$$=0;
yyerror(" port number expected");
}
| phostport
;
id_lst: alias_def { IFOR(); $$=$1 ; }
| alias_def id_lst { IFOR(); $$=$1; $$->next=$2; }
;
listen_id_def: listen_id { IFOR();
$$=mk_listen_id($1, PROTO_NONE, 0); }
| listen_id COLON port { IFOR();
$$=mk_listen_id($1, PROTO_NONE, $3); }
| listen_id COLON error {
$$=0;
yyerror(" port number expected");
}
;
socket_def_param: ANYCAST { IFOR();
p_tmp.flags |= SI_IS_ANYCAST;
}
| FRAG { IFOR();
p_tmp.flags |= SI_FRAG;
}
| REUSE_PORT { IFOR();
p_tmp.flags |= SI_REUSEPORT;
}
| USE_WORKERS NUMBER { IFOR();
p_tmp.workers=$2;
}
| AS listen_id_def { IFOR();
p_tmp.socket = $2;
}
| TAG ID { IFOR();
p_tmp.tag = $2;
}
| USE_AUTO_SCALING_PROFILE ID { IFOR();
p_tmp.auto_scaling_profile=$2;
}
;
socket_def_params: socket_def_param
| socket_def_param socket_def_params
;
socket_def: panyhostport { $$=$1; }
| phostport { $$=$1; }
| panyhostport { IFOR();
memset(&p_tmp, 0, sizeof(p_tmp));
} socket_def_params { IFOR();
$$=$1; fill_socket_id(&p_tmp, $$);
}
| phostport { IFOR();
memset(&p_tmp, 0, sizeof(p_tmp));
} socket_def_params { IFOR();
$$=$1; fill_socket_id(&p_tmp, $$);
}
;
any_proto: ANY { $$=PROTO_NONE; }
| proto { $$=$1; }
multi_string: STRING { IFOR(); $$=new_string($1); }
| STRING multi_string { IFOR(); $$=new_string($1); $$->next=$2; }
;
blst_elem: LPAREN any_proto COMMA ipnet COMMA port COMMA STRING RPAREN {
IFOR(pkg_free($4));
s_tmp.s=$8;
s_tmp.len=strlen($8);
if (add_rule_to_list(&bl_head,&bl_tail,$4,&s_tmp,$6,$2,0)) {
yyerror("failed to add backlist element\n");YYABORT;
}
}
| NOT LPAREN any_proto COMMA ipnet COMMA port COMMA STRING RPAREN {
IFOR(pkg_free($5));
s_tmp.s=$9;
s_tmp.len=strlen($9);
if (add_rule_to_list(&bl_head,&bl_tail,$5,&s_tmp,
$7,$3,BLR_APPLY_CONTRARY)) {
yyerror("failed to add backlist element\n");YYABORT;
}
}
| LPAREN any_proto COMMA ipnet COMMA port RPAREN {
IFOR(pkg_free($4));
if (add_rule_to_list(&bl_head,&bl_tail,$4,NULL,$6,$2,0)) {
yyerror("failed to add backlist element\n");YYABORT;
}
}
| NOT LPAREN any_proto COMMA ipnet COMMA port RPAREN {
IFOR(pkg_free($5));
if (add_rule_to_list(&bl_head,&bl_tail,$5,NULL,
$7,$3,BLR_APPLY_CONTRARY)) {
yyerror("failed to add backlist element\n");YYABORT;
}
}
| LPAREN any_proto COMMA ipnet RPAREN {
IFOR(pkg_free($4));
if (add_rule_to_list(&bl_head,&bl_tail,$4,NULL,0,$2,0)) {
yyerror("failed to add backlist element\n");YYABORT;
}
}
| NOT LPAREN any_proto COMMA ipnet RPAREN {
IFOR(pkg_free($5));
if (add_rule_to_list(&bl_head,&bl_tail,$5,NULL,
0,$3,BLR_APPLY_CONTRARY)) {
yyerror("failed to add backlist element\n");YYABORT;
}
}
| LPAREN ipnet COMMA port RPAREN {
IFOR(pkg_free($2));
if (add_rule_to_list(&bl_head,&bl_tail,$2,NULL,$4,PROTO_NONE,0)) {
yyerror("failed to add backlist element\n");YYABORT;
}
}
| NOT LPAREN ipnet COMMA port RPAREN {
IFOR(pkg_free($3));
if (add_rule_to_list(&bl_head,&bl_tail,$3,NULL,
$5,PROTO_NONE,BLR_APPLY_CONTRARY)) {
yyerror("failed to add backlist element\n");YYABORT;
}
}
| LPAREN ipnet RPAREN {
IFOR(pkg_free($2));
if (add_rule_to_list(&bl_head,&bl_tail,$2,NULL,0,PROTO_NONE,0)) {
yyerror("failed to add backlist element\n"); YYABORT;
}
}
| NOT LPAREN ipnet RPAREN {
IFOR(pkg_free($3));
if (add_rule_to_list(&bl_head,&bl_tail,$3,NULL,
0,PROTO_NONE,BLR_APPLY_CONTRARY)) {
yyerror("failed to add backlist element\n");YYABORT;
}
}
| ipnet {
IFOR(pkg_free($1));
if (add_rule_to_list(&bl_head,&bl_tail,$1,NULL,0,PROTO_NONE,0)) {
yyerror("failed to add backlist element\n"); YYABORT;
}
}
| NOT ipnet {
IFOR(pkg_free($2));
if (add_rule_to_list(&bl_head,&bl_tail,$2,NULL,
0,PROTO_NONE,BLR_APPLY_CONTRARY)) {
yyerror("failed to add backlist element\n");YYABORT;
}
}
;
blst_def: COLON LBRACE blst_elem_list RBRACE
| COLON LBRACE RBRACE
|
;
blst_flag: READONLY { $$ = BL_READONLY_LIST; }
| EXPIRE { $$ = BL_DO_EXPIRE; }
| DEFAULT { $$ = BL_BY_DEFAULT; }
;
blst_flags: blst_flags COMMA blst_flag { $$ = $1 | $3; }
| blst_flag {}
;
blst_elem_list: blst_elem_list COMMA blst_elem {}
| blst_elem {}
| blst_elem_list error { yyerror("bad black list element");}
;
auto_scale_profile_def:
ID SCALE_UP_TO NUMBER ON NUMBER MODULO FOR
NUMBER CYCLES_WITHIN NUMBER
SCALE_DOWN_TO NUMBER ON NUMBER MODULO FOR
NUMBER CYCLES { IFOR();
if (create_auto_scaling_profile($1,$3,$5,$8,$10,
$12, $14, $17,10*$17)<0)
yyerror("failed to create auto scaling profile");
}
| ID SCALE_UP_TO NUMBER ON NUMBER MODULO FOR
NUMBER CYCLES
SCALE_DOWN_TO NUMBER ON NUMBER MODULO FOR
NUMBER CYCLES { IFOR();
if (create_auto_scaling_profile($1,$3,$5,$8,$8,
$11, $13, $16, 10*$16)<0)
yyerror("failed to create auto scaling profile");
}
| ID SCALE_UP_TO NUMBER ON NUMBER MODULO FOR
NUMBER CYCLES_WITHIN NUMBER { IFOR();
if (create_auto_scaling_profile($1,$3,$5,$8,$10,
0, 0, 0, 0)<0)
yyerror("failed to create auto scaling profile");
}
| ID SCALE_UP_TO NUMBER ON NUMBER MODULO FOR
NUMBER CYCLES { IFOR();
if (create_auto_scaling_profile($1,$3,$5,$8,$8,
0, 0, 0, 0)<0)
yyerror("failed to create auto scaling profile");
}
;
assign_stm: LOGLEVEL EQUAL snumber { IFOR();
/* in debug mode, force logging to DEBUG level*/
*log_level = debug_mode?L_DBG:$3;
}
| LOGPREFIX EQUAL STRING { IFOR();
if (*$3) {
int len = strlen($3);
char *buf = pkg_malloc(len + 2);
if (!buf)
yyerror("oom");
sprintf(buf, "%s:", $3);
log_prefix = buf;
} else {
log_prefix = $3;
}
}
| LOGPREFIX EQUAL error { yyerror("string value expected"); }
| ENABLE_ASSERTS EQUAL NUMBER { IFOR(); enable_asserts=$3; }
| ENABLE_ASSERTS EQUAL error { yyerror("boolean value expected"); }
| ABORT_ON_ASSERT EQUAL NUMBER { IFOR(); abort_on_assert=$3; }
| ABORT_ON_ASSERT EQUAL error { yyerror("boolean value expected"); }
| DEBUG_MODE EQUAL NUMBER { IFOR();
debug_mode=$3;
if (debug_mode) {
*log_level = L_DBG;
stderr_enabled=1;
syslog_enabled=0;
s_tmp.s=STDERR_CONSUMER_NAME;
s_tmp.len=strlen(STDERR_CONSUMER_NAME);
set_log_consumer_mute_state(&s_tmp, 0);
s_tmp.s=SYSLOG_CONSUMER_NAME;
s_tmp.len=strlen(SYSLOG_CONSUMER_NAME);
set_log_consumer_mute_state(&s_tmp, 1);
}
}
| DEBUG_MODE EQUAL error
{ yyerror("boolean value expected for debug_mode"); }
| LOGSTDOUT EQUAL NUMBER
/* may be useful when integrating 3rd party libraries */
{ IFOR(); log_stdout=$3; }
| LOGSTDOUT EQUAL error { yyerror("boolean value expected"); }
| LOGSTDERROR EQUAL NUMBER {
IFOR();
warn("'log_stderror' is deprecated, use 'stderror_enabled' and/or"
"'syslog_enabled' instead");
if (!config_check && !debug_mode) {
if ($3) {
stderr_enabled=1;
syslog_enabled=0;
} else {
stderr_enabled=0;
syslog_enabled=1;
}
s_tmp.s=STDERR_CONSUMER_NAME;
s_tmp.len=strlen(STDERR_CONSUMER_NAME);
set_log_consumer_mute_state(&s_tmp, !$3);
s_tmp.s=SYSLOG_CONSUMER_NAME;
s_tmp.len=strlen(SYSLOG_CONSUMER_NAME);
set_log_consumer_mute_state(&s_tmp, $3);
}
}
| LOGSTDERROR EQUAL error { yyerror("boolean value expected"); }
| STDERROR_ENABLED EQUAL NUMBER {
/* in config-check or debug mode we force logging
* to standard error */
IFOR();
if (!config_check && !debug_mode) {
stderr_enabled=$3;
s_tmp.s=STDERR_CONSUMER_NAME;
s_tmp.len=strlen(STDERR_CONSUMER_NAME);
set_log_consumer_mute_state(&s_tmp, !$3);
}
}
| STDERROR_ENABLED EQUAL error { yyerror("boolean value expected"); }
| SYSLOG_ENABLED EQUAL NUMBER {
IFOR();
/* in config-check or debug mode we force logging
* to standard error */
if (!config_check && !debug_mode) {
syslog_enabled=$3;
s_tmp.s=SYSLOG_CONSUMER_NAME;
s_tmp.len=strlen(SYSLOG_CONSUMER_NAME);
set_log_consumer_mute_state(&s_tmp, !$3);
}
}
| SYSLOG_ENABLED EQUAL error { yyerror("boolean value expected"); }
| LOG_EVENT_ENABLED EQUAL NUMBER {
IFOR();
if ($3) {
if (init_log_msg_buf(0) < 0) {
yyerror("failed to allocate msg log buffer");
YYABORT;
}
}
log_event_enabled=$3; }
| LOG_EVENT_ENABLED EQUAL error { yyerror("boolean value expected"); }
| STDERROR_LEVEL_FILTER EQUAL snumber {
IFOR();
s_tmp.s=STDERR_CONSUMER_NAME;
s_tmp.len=strlen(STDERR_CONSUMER_NAME);
set_log_consumer_level_filter(&s_tmp, $3);
}
| STDERROR_LEVEL_FILTER EQUAL error { yyerror("number expected"); }
| SYSLOG_LEVEL_FILTER EQUAL snumber {
IFOR();
s_tmp.s=SYSLOG_CONSUMER_NAME;
s_tmp.len=strlen(SYSLOG_CONSUMER_NAME);
set_log_consumer_level_filter(&s_tmp, $3);
}
| SYSLOG_LEVEL_FILTER EQUAL error { yyerror("number expected"); }
| LOG_EVENT_LEVEL_FILTER EQUAL NUMBER { IFOR();
log_event_level_filter = $3; }
| LOG_EVENT_LEVEL_FILTER EQUAL error { yyerror("number expected"); }
| STDERROR_FORMAT EQUAL STRING { IFOR();
s_tmp.s = $3;
s_tmp.len = strlen($3);
if ((i_tmp = parse_log_format(&s_tmp)) < 0) {
yyerror("unknown log format");
} else {
if (i_tmp != LOG_FORMAT_PLAIN) {
if (init_log_json_buf(0) < 0) {
yyerror("failed to allocate json log buffer");
YYABORT;
}
if (init_log_msg_buf(0) < 0) {
yyerror("failed to allocate msg log buffer");
YYABORT;
}
if (i_tmp == LOG_FORMAT_JSON_CEE && init_log_cee_hostname() < 0) {
yyerror("failed to allocate hostname buffer");
YYABORT;
}
}
stderr_log_format = i_tmp;
}
}
| SYSLOG_FORMAT EQUAL STRING { IFOR();
s_tmp.s = $3;
s_tmp.len = strlen($3);
if ((i_tmp = parse_log_format(&s_tmp)) < 0) {
yyerror("unknown log format");
} else {
if (i_tmp != LOG_FORMAT_PLAIN) {
if (init_log_json_buf(0) < 0) {
yyerror("failed to allocate json log buffer");
YYABORT;
}
if (init_log_msg_buf(0) < 0) {
yyerror("failed to allocate msg log buffer");
YYABORT;
}
if (i_tmp == LOG_FORMAT_JSON_CEE && init_log_cee_hostname() < 0) {
yyerror("failed to allocate hostname buffer");
YYABORT;
}
}
syslog_log_format = i_tmp;
}
}
| LOG_JSON_BUF_SIZE EQUAL NUMBER {
IFOR();
log_json_buf_size = $3;
if (init_log_json_buf(1) < 0) {
yyerror("failed to realloc json log buffer");
YYABORT;
}
}
| LOG_JSON_BUF_SIZE EQUAL error { yyerror("number expected"); }
| LOG_MSG_BUF_SIZE EQUAL NUMBER {
IFOR();
log_msg_buf_size = $3;
if (init_log_msg_buf(1) < 0) {
yyerror("failed to realloc msg log buffer");
YYABORT;
}
}
| LOG_MSG_BUF_SIZE EQUAL error { yyerror("number expected"); }
| LOGFACILITY EQUAL ID { IFOR();
warn("'log_facility' is deprecated, use 'syslog_facility' instead");
if ( (i_tmp=str2facility($3))==-1)
yyerror("bad facility (see syslog(3) man page)");
if (!config_check)
log_facility=i_tmp;
}
| LOGFACILITY EQUAL error { yyerror("ID expected"); }
| SYSLOG_FACILITY EQUAL ID { IFOR();
if ( (i_tmp=str2facility($3))==-1)
yyerror("bad facility (see syslog(3) man page)");
if (!config_check)
log_facility=i_tmp;
}
| SYSLOG_FACILITY EQUAL error { yyerror("ID expected"); }
| LOGNAME EQUAL STRING { IFOR();
warn("'log_name' is deprecated, use 'syslog_name' instead");
log_name=$3; }
| LOGNAME EQUAL error { yyerror("string value expected"); }
| SYSLOG_NAME EQUAL STRING { IFOR(); log_name=$3; }
| SYSLOG_NAME EQUAL error { yyerror("string value expected"); }
| DNS EQUAL NUMBER { IFOR(); received_dns|= ($3)?DO_DNS:0; }
| DNS EQUAL error { yyerror("boolean value expected"); }
| REV_DNS EQUAL NUMBER { IFOR(); received_dns|= ($3)?DO_REV_DNS:0; }
| REV_DNS EQUAL error { yyerror("boolean value expected"); }
| DNS_TRY_IPV6 EQUAL NUMBER { IFOR(); dns_try_ipv6=$3; }
| DNS_TRY_IPV6 error { yyerror("boolean value expected"); }
| DNS_TRY_NAPTR EQUAL NUMBER { IFOR(); dns_try_naptr=$3; }
| DNS_TRY_NAPTR error { yyerror("boolean value expected"); }
| DNS_RETR_TIME EQUAL NUMBER { IFOR(); dns_retr_time=$3; }
| DNS_RETR_TIME error { yyerror("number expected"); }
| DNS_RETR_NO EQUAL NUMBER { IFOR(); dns_retr_no=$3; }
| DNS_RETR_NO error { yyerror("number expected"); }
| DNS_SERVERS_NO EQUAL NUMBER { IFOR(); dns_servers_no=$3; }
| DNS_SERVERS_NO error { yyerror("number expected"); }
| DNS_USE_SEARCH EQUAL NUMBER { IFOR(); dns_search_list=$3; }
| DNS_USE_SEARCH error { yyerror("boolean value expected"); }
| MAX_WHILE_LOOPS EQUAL NUMBER { IFOR(); max_while_loops=$3; }
| MAX_WHILE_LOOPS EQUAL error { yyerror("number expected"); }
| MAXBUFFER EQUAL NUMBER { IFOR(); maxbuffer=$3; }
| MAXBUFFER EQUAL error { yyerror("number expected"); }
| UDP_WORKERS EQUAL NUMBER { IFOR(); udp_workers_no=$3; }
| UDP_WORKERS EQUAL NUMBER USE_AUTO_SCALING_PROFILE ID { IFOR();
udp_workers_no=$3;
udp_auto_scaling_profile=$5;
}
| UDP_WORKERS EQUAL error { yyerror("number expected"); }
| TIMER_WORKERS EQUAL NUMBER { IFOR();
timer_workers_no=$3;
}
| TIMER_WORKERS EQUAL NUMBER USE_AUTO_SCALING_PROFILE ID { IFOR();
timer_workers_no=$3;
timer_auto_scaling_profile=$5;
}
| CHECK_VIA EQUAL NUMBER { check_via=$3; }
| CHECK_VIA EQUAL error { yyerror("boolean value expected"); }
| SHM_HASH_SPLIT_PERCENTAGE EQUAL NUMBER { IFOR();
#ifdef HP_MALLOC
shm_hash_split_percentage=$3;
#else
LM_ERR("Cannot set parameter; Please recompile with support "
"for HP_MALLOC\n");
#endif
}
| SHM_HASH_SPLIT_PERCENTAGE EQUAL error {
#ifdef HP_MALLOC
yyerror("number expected");
#else
LM_ERR("Cannot set parameter; Please recompile with support "
"for HP_MALLOC\n");
#endif
}
| SHM_SECONDARY_HASH_SIZE EQUAL NUMBER { IFOR();
#ifdef HP_MALLOC
shm_secondary_hash_size=$3;
#else
LM_ERR("Cannot set parameter; Please recompile with support"
" for HP_MALLOC\n");
#endif
}
| SHM_SECONDARY_HASH_SIZE EQUAL error {
#ifdef HP_MALLOC
yyerror("number expected");
#else
LM_ERR("Cannot set parameter; Please recompile with support "
"for HP_MALLOC\n");
#endif
}
| MEM_WARMING_ENABLED EQUAL NUMBER { IFOR();
#ifdef HP_MALLOC
mem_warming_enabled = $3;
#else
LM_ERR("Cannot set parameter; Please recompile with support"
" for HP_MALLOC\n");
#endif
}
| MEM_WARMING_ENABLED EQUAL error {
#ifdef HP_MALLOC
yyerror("number expected");
#else
LM_ERR("Cannot set parameter; Please recompile with support "
"for HP_MALLOC\n");
#endif
}
| MEM_WARMING_PATTERN_FILE EQUAL STRING { IFOR();
#ifdef HP_MALLOC
mem_warming_pattern_file = $3;
#else
LM_ERR("Cannot set parameter; Please recompile with "
"support for HP_MALLOC\n");
#endif
}
| MEM_WARMING_PATTERN_FILE EQUAL error {
#ifdef HP_MALLOC
yyerror("string expected");
#else
LM_ERR("Cannot set parameter; Please recompile with support "
"for HP_MALLOC\n");
#endif
}
| MEM_WARMING_PERCENTAGE EQUAL NUMBER { IFOR();
#ifdef HP_MALLOC
mem_warming_percentage = $3;
#else
LM_ERR("Cannot set parameter; Please recompile with "
"support for HP_MALLOC\n");
#endif
}
| MEM_WARMING_PERCENTAGE EQUAL error {
#ifdef HP_MALLOC
yyerror("number expected");
#else
LM_ERR("Cannot set parameter; Please recompile with support "
"for HP_MALLOC\n");
#endif
}
| RPM_MEM_FILE EQUAL STRING { IFOR();
rpm_mem_file = $3;
}
| RPM_MEM_FILE EQUAL error { yyerror("string value expected"); }
| RPM_MEM_SIZE EQUAL NUMBER { IFOR();
rpm_mem_size = $3 * 1024 * 1024;
}
| RPM_MEM_SIZE EQUAL error { yyerror("int value expected"); }
| MEMLOG EQUAL snumber { IFOR(); memlog=$3; memdump=$3; }
| MEMLOG EQUAL error { yyerror("int value expected"); }
| SHM_MEMLOG_SIZE EQUAL snumber { IFOR(); shm_memlog_size=$3;}
| SHM_MEMLOG_SIZE EQUAL error { yyerror("int value expected"); }
| MEMDUMP EQUAL snumber { IFOR(); memdump=$3; }
| MEMDUMP EQUAL error { yyerror("int value expected"); }
| EXECMSGTHRESHOLD EQUAL NUMBER { IFOR();execmsgthreshold=$3; }
| EXECMSGTHRESHOLD EQUAL error { yyerror("int value expected"); }
| EXECDNSTHRESHOLD EQUAL NUMBER { IFOR(); execdnsthreshold=$3; }
| EXECDNSTHRESHOLD EQUAL error { yyerror("int value expected"); }
| TCPTHRESHOLD EQUAL NUMBER { IFOR(); tcpthreshold=$3; }
| TCPTHRESHOLD EQUAL error { yyerror("int value expected"); }
| EVENT_SHM_THRESHOLD EQUAL NUMBER { IFOR();
#ifdef STATISTICS
if ($3 < 0 || $3 > 100)
yyerror("SHM threshold has to be a percentage between"
" 0 and 100");
event_shm_threshold=$3;
#else
yyerror("statistics support not compiled in");
#endif /* STATISTICS */
}
| EVENT_SHM_THRESHOLD EQUAL error { yyerror("int value expected"); }
| EVENT_PKG_THRESHOLD EQUAL NUMBER { IFOR();
#ifdef PKG_MALLOC
#ifdef STATISTICS
if ($3 < 0 || $3 > 100)
yyerror("PKG threshold has to be a percentage between "
"0 and 100");
event_pkg_threshold=$3;
#else
yyerror("statistics support not compiled in");
#endif
#else
yyerror("pkg_malloc support not compiled in");
#endif
}
| EVENT_PKG_THRESHOLD EQUAL error { yyerror("int value expected"); }
| QUERYBUFFERSIZE EQUAL NUMBER { IFOR(); query_buffer_size=$3; }
| QUERYBUFFERSIZE EQUAL error { yyerror("int value expected"); }
| QUERYFLUSHTIME EQUAL NUMBER { IFOR(); query_flush_time=$3; }
| QUERYFLUSHTIME EQUAL error { yyerror("int value expected"); }
| SIP_WARNING EQUAL NUMBER { IFOR(); sip_warning=$3; }
| SIP_WARNING EQUAL error { yyerror("boolean value expected"); }
| CHROOT EQUAL STRING { IFOR(); chroot_dir=$3; }
| CHROOT EQUAL ID { IFOR(); chroot_dir=$3; }
| CHROOT EQUAL error { yyerror("string value expected"); }
| WDIR EQUAL STRING { IFOR(); working_dir=$3; }
| WDIR EQUAL ID { IFOR(); working_dir=$3; }
| WDIR EQUAL error { yyerror("string value expected"); }
| MHOMED EQUAL NUMBER { IFOR(); mhomed=$3; }
| MHOMED EQUAL error { yyerror("boolean value expected"); }
| POLL_METHOD EQUAL ID { IFOR();
io_poll_method=get_poll_type($3);
if (io_poll_method==POLL_NONE){
LM_CRIT("bad poll method name:"
" %s\n, try one of %s.\n",
$3, poll_support);
yyerror("bad poll_method "
"value");
}
}
| POLL_METHOD EQUAL STRING { IFOR();
io_poll_method=get_poll_type($3);
if (io_poll_method==POLL_NONE){
LM_CRIT("bad poll method name:"
" %s\n, try one of %s.\n",
$3, poll_support);
yyerror("bad poll_method "
"value");
}
}
| POLL_METHOD EQUAL error { yyerror("poll method name expected"); }
| TCP_ACCEPT_ALIASES EQUAL NUMBER { IFOR();
if ($3 < TCP_ALIAS_NEVER || $3 > TCP_ALIAS_ALWAYS)
yyerror("invalid 'tcp_accept_aliases' value");
tcp_accept_aliases=$3;
}
| TCP_ACCEPT_ALIASES EQUAL error { yyerror("boolean value expected"); }
| TCP_WORKERS EQUAL NUMBER { IFOR();
tcp_workers_no=$3;
}
| TCP_WORKERS EQUAL NUMBER USE_AUTO_SCALING_PROFILE ID{ IFOR();
tcp_workers_no=$3;
tcp_auto_scaling_profile=$5;
}
| TCP_WORKERS EQUAL error { yyerror("number expected"); }
| TCP_CONNECT_TIMEOUT EQUAL NUMBER { IFOR();
if ($3 <= 0)
yyerror("invalid 'tcp_connect_timeout' (value too low!)");
tcp_connect_timeout=$3;
}
| TCP_CONNECT_TIMEOUT EQUAL error { yyerror("number expected"); }
| TCP_CON_LIFETIME EQUAL NUMBER { IFOR();
tcp_con_lifetime=$3;
}
| TCP_CON_LIFETIME EQUAL error { yyerror("number expected"); }
| TCP_SOCKET_BACKLOG EQUAL NUMBER { IFOR();
tcp_socket_backlog=$3;
}
| TCP_SOCKET_BACKLOG EQUAL error { yyerror("number expected"); }
| TCP_MAX_CONNECTIONS EQUAL NUMBER { IFOR();
tcp_max_connections=$3;
}
| TCP_MAX_CONNECTIONS EQUAL error { yyerror("number expected"); }
| TCP_NO_NEW_CONN_BFLAG EQUAL ID { IFOR();
tcp_no_new_conn_bflag =
get_flag_id_by_name(FLAG_TYPE_BRANCH, $3, 0);
if (!flag_in_range( (flag_t)tcp_no_new_conn_bflag ) )
yyerror("invalid TCP no_new_conn Branch Flag");
flag_idx2mask( &tcp_no_new_conn_bflag );
}
| TCP_NO_NEW_CONN_BFLAG EQUAL error { yyerror("number value expected"); }
| TCP_NO_NEW_CONN_RPLFLAG EQUAL ID { IFOR();
tcp_no_new_conn_rplflag =
get_flag_id_by_name(FLAG_TYPE_MSG, $3, 0);
if (!flag_in_range( (flag_t)tcp_no_new_conn_rplflag ) )
yyerror("invalid TCP no_new_conn RePLy Flag");
flag_idx2mask( &tcp_no_new_conn_rplflag );
}
| TCP_NO_NEW_CONN_RPLFLAG EQUAL error { yyerror("number value expected"); }
| TCP_KEEPALIVE EQUAL NUMBER { IFOR();
tcp_keepalive=!!$3;
}
| TCP_KEEPALIVE EQUAL error { yyerror("boolean value expected"); }
| TCP_MAX_MSG_TIME EQUAL NUMBER { IFOR();
tcp_max_msg_time=$3;
}
| TCP_MAX_MSG_TIME EQUAL error { yyerror("boolean value expected"); }
| TCP_PARALLEL_READ_ON_WORKERS EQUAL NUMBER { IFOR();
tcp_parallel_read_on_workers=!!$3;
}
| TCP_PARALLEL_READ_ON_WORKERS EQUAL error {
yyerror("boolean value expected");
}
| TCP_KEEPCOUNT EQUAL NUMBER { IFOR();
#ifndef HAVE_TCP_KEEPCNT
warn("cannot be enabled TCP_KEEPCOUNT (no OS support)");
#else
tcp_keepcount=$3;
#endif
}
| TCP_KEEPCOUNT EQUAL error { yyerror("int value expected"); }
| TCP_KEEPIDLE EQUAL NUMBER { IFOR();
#ifndef HAVE_TCP_KEEPIDLE
warn("cannot be enabled TCP_KEEPIDLE (no OS support)");
#else
tcp_keepidle=$3;
#endif
}
| TCP_KEEPIDLE EQUAL error { yyerror("int value expected"); }
| TCP_KEEPINTERVAL EQUAL NUMBER { IFOR();
#ifndef HAVE_TCP_KEEPINTVL
warn("cannot be enabled TCP_KEEPINTERVAL (no OS support)");
#else
tcp_keepinterval=$3;
#endif
}
| TCP_KEEPINTERVAL EQUAL error { yyerror("int value expected"); }
| SERVER_SIGNATURE EQUAL NUMBER { IFOR();
server_signature=$3; }
| SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); }
| SERVER_HEADER EQUAL STRING { IFOR();
server_header->s=$3;
server_header->len=strlen($3);
}
| SERVER_HEADER EQUAL error { yyerror("string value expected"); }
| USER_AGENT_HEADER EQUAL STRING { user_agent_header->s=$3;
user_agent_header->len=strlen($3);
}
| USER_AGENT_HEADER EQUAL error { yyerror("string value expected"); }
| PV_PRINT_BUF_SIZE EQUAL NUMBER { IFOR();
pv_print_buf_size = $3; }
| PV_PRINT_BUF_SIZE EQUAL error { yyerror("number expected"); }
| XLOG_BUF_SIZE EQUAL NUMBER { IFOR();
xlog_buf_size = $3; }
| XLOG_FORCE_COLOR EQUAL NUMBER { IFOR();
xlog_force_color = $3; }
| XLOG_PRINT_LEVEL EQUAL NUMBER { IFOR();
xlog_print_level = $3; }
| XLOG_BUF_SIZE EQUAL error { yyerror("number expected"); }
| XLOG_FORCE_COLOR EQUAL error { yyerror("boolean value expected"); }
| XLOG_PRINT_LEVEL EQUAL error { yyerror("number expected"); }
| XLOG_LEVEL EQUAL snumber { IFOR();
*xlog_level = $3; }
| XLOG_LEVEL EQUAL error { yyerror("number expected"); }
| SOCKET EQUAL socket_def { IFOR();
if (add_listening_socket($3)!=0){
LM_CRIT("cfg. parser: failed"
" to add listening socket\n");
break;
}
}
| SOCKET EQUAL error { yyerror("ip address or hostname "
"expected (use quotes if the hostname includes"
" config keywords)"); }
| LISTEN EQUAL socket_def { IFOR();
warn("'listen' is deprecated, use 'socket' instead");
if (add_listening_socket($3)!=0){
LM_CRIT("cfg. parser: failed"
" to add listen address\n");
break;
}
}
| LISTEN EQUAL error { yyerror("ip address or hostname "
"expected (use quotes if the hostname includes"
" config keywords)"); }
| MEMGROUP EQUAL STRING COLON multi_string { IFOR();
/* convert STIRNG ($3) to an ID */
/* update the memstats type for each module */
#ifndef SHM_EXTRA_STATS
LM_CRIT("SHM_EXTRA_STATS not defined");
YYABORT;
#else
#ifdef SHM_SHOW_DEFAULT_GROUP
if(strcmp($3, "default") == 0){
LM_CRIT("default group name is not allowed");
YYABORT;
}
#endif
for(tmp_mod = mod_names; tmp_mod; tmp_mod=tmp_mod->next){
if(strcmp($3, tmp_mod->s) == 0){
LM_CRIT("The same mem-group name is used twice: [%s] [%s]\n", $3, tmp_mod->s);
YYABORT;
}
}
tmp_mod = pkg_malloc(sizeof(struct multi_str));
if(!tmp_mod){
LM_CRIT("out of pkg memory");
YYABORT;
}
tmp_mod->s = $3;
tmp_mod->next = mod_names;
mod_names = tmp_mod;
for (tmp_mod = $5; tmp_mod; tmp_mod = tmp_mod->next){
if(set_mem_idx(tmp_mod->s, mem_free_idx)){
YYABORT;
}
}
mem_free_idx++;
if(alloc_group_stat()){
YYABORT;
}
#endif
}
| MEMGROUP EQUAL STRING COLON error { yyerror("invalid or no module specified"); }
| ALIAS EQUAL id_lst { IFOR();
for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next)
add_alias(lst_tmp->name, strlen(lst_tmp->name),
lst_tmp->port, lst_tmp->proto);
}
| ALIAS EQUAL error { yyerror("hostname expected (use quotes"
" if the hostname includes config keywords)"); }
| AUTO_ALIASES EQUAL NUMBER { IFOR();
auto_aliases=$3; }
| AUTO_ALIASES EQUAL error { yyerror("number expected"); }
| ADVERTISED_ADDRESS EQUAL listen_id { IFOR();
if ($3) {
default_global_address->s=$3;
default_global_address->len=strlen($3);
}
}
| ADVERTISED_ADDRESS EQUAL error {yyerror("ip address or hostname "
"expected"); }
| ADVERTISED_PORT EQUAL NUMBER { IFOR();
tmp = int2str($3, &i_tmp);
if (i_tmp > default_global_port->len)
default_global_port->s =
pkg_realloc(default_global_port->s, i_tmp);
if (!default_global_port->s) {
LM_CRIT("cfg. parser: out of memory.\n");
YYABORT;
} else {
default_global_port->len = i_tmp;
memcpy(default_global_port->s, tmp,
default_global_port->len);
}
}
|ADVERTISED_PORT EQUAL error {yyerror("ip address or hostname "
"expected"); }
| DISABLE_CORE EQUAL NUMBER { IFOR();
disable_core_dump=$3;
}
| DISABLE_CORE EQUAL error { yyerror("boolean value expected"); }
| OPEN_FD_LIMIT EQUAL NUMBER { IFOR();
open_files_limit=$3;
}
| OPEN_FD_LIMIT EQUAL error { yyerror("number expected"); }
| MCAST_LOOPBACK EQUAL NUMBER { IFOR();
#ifdef USE_MCAST
mcast_loopback=$3;
#else
warn("no multicast support compiled in");
#endif
}
| MCAST_LOOPBACK EQUAL error { yyerror("boolean value expected"); }
| MCAST_TTL EQUAL NUMBER { IFOR();
#ifdef USE_MCAST
mcast_ttl=$3;
#else
warn("no multicast support compiled in");
#endif
}
| MCAST_TTL EQUAL error { yyerror("number expected as tos"); }
| TOS EQUAL NUMBER { IFOR(); tos = $3;
if (tos<=0)
yyerror("invalid tos value");
}
| TOS EQUAL ID { IFOR();
if (strcasecmp($3,"IPTOS_LOWDELAY")) {
tos=IPTOS_LOWDELAY;
} else if (strcasecmp($3,"IPTOS_THROUGHPUT")) {
tos=IPTOS_THROUGHPUT;
} else if (strcasecmp($3,"IPTOS_RELIABILITY")) {
tos=IPTOS_RELIABILITY;
#if defined(IPTOS_MINCOST)
} else if (strcasecmp($3,"IPTOS_MINCOST")) {
tos=IPTOS_MINCOST;
#endif
#if defined(IPTOS_LOWCOST)
} else if (strcasecmp($3,"IPTOS_LOWCOST")) {
tos=IPTOS_LOWCOST;
#endif
} else {
yyerror("invalid tos value - allowed: "
"IPTOS_LOWDELAY,IPTOS_THROUGHPUT,"
"IPTOS_RELIABILITY"
#if defined(IPTOS_LOWCOST)
",IPTOS_LOWCOST"
#endif
#if defined(IPTOS_MINCOST)
",IPTOS_MINCOST"
#endif
"\n");
}
}
| TOS EQUAL error { yyerror("number expected"); }
| MPATH EQUAL STRING {IFOR();
add_mpath($3); }
| MPATH EQUAL error { yyerror("string value expected"); }
| DISABLE_DNS_FAILOVER EQUAL NUMBER { IFOR();
disable_dns_failover=$3;
}
| DISABLE_DNS_FAILOVER error { yyerror("boolean value expected"); }
| DISABLE_DNS_BLACKLIST EQUAL NUMBER { IFOR();
disable_dns_blacklist=$3;
}
| DISABLE_DNS_BLACKLIST error { yyerror("boolean value expected"); }
| DST_BLACKLIST EQUAL ID SLASH blst_flags blst_def { IFOR();
s_tmp.s = $3;
s_tmp.len = strlen($3);
if (create_bl_head(_str("script"), $5,
bl_head, bl_tail, &s_tmp)==0) {
yyerror("failed to create blacklist\n");
YYABORT;
}
bl_head = bl_tail = NULL;
}
| DST_BLACKLIST EQUAL ID blst_def { IFOR();
s_tmp.s = $3;
s_tmp.len = strlen($3);
if (create_bl_head(_str("script"), BL_READONLY_LIST,
bl_head, bl_tail, &s_tmp)==0) {
yyerror("failed to create blacklist\n");
YYABORT;
}
bl_head = bl_tail = NULL;
}
| DISABLE_STATELESS_FWD EQUAL NUMBER { IFOR();
sl_fwd_disabled=$3; }
| DB_VERSION_TABLE EQUAL STRING { IFOR();
db_version_table=$3; }
| DB_VERSION_TABLE EQUAL error { yyerror("string value expected"); }
| DB_DEFAULT_URL EQUAL STRING { IFOR();
db_default_url=$3; }
| DB_DEFAULT_URL EQUAL error { yyerror("string value expected"); }
| DB_MAX_ASYNC_CONNECTIONS EQUAL NUMBER { IFOR();
db_max_async_connections=$3; }
| DB_MAX_ASYNC_CONNECTIONS EQUAL error {
yyerror("integer value expected");
}
| DISABLE_503_TRANSLATION EQUAL NUMBER { IFOR();
disable_503_translation=$3; }
| DISABLE_503_TRANSLATION EQUAL error {
yyerror("integer value expected");
}
| AUTO_SCALING_PROFILE EQUAL auto_scale_profile_def {}
| AUTO_SCALING_PROFILE EQUAL error {
yyerror("bad auto-scaling profile definition");
}
| AUTO_SCALING_CYCLE EQUAL NUMBER { IFOR();
auto_scaling_cycle=$3; }
| AUTO_SCALING_CYCLE EQUAL error {
yyerror("integer value expected");
}
| error EQUAL { yyerror("unknown config variable"); }
;
module_stm: LOADMODULE STRING { IFOR();
if (load_module($2) < 0)
yyerrorf("failed to load module %s\n", $2);
}
| LOADMODULE error { yyerror("string expected"); }
| MODPARAM LPAREN STRING COMMA STRING COMMA STRING RPAREN { IFOR();
if (set_mod_param_regex($3, $5, STR_PARAM, $7) != 0) {
yyerrorf("Parameter <%s> not found in module <%s> - "
"can't set", $5, $3);
}
}
| MODPARAM LPAREN STRING COMMA STRING COMMA folded_string RPAREN { IFOR();
if (set_mod_param_regex($3, $5, STR_PARAM, $7) != 0) {
yyerrorf("Parameter <%s> not found in module <%s> - "
"can't set", $5, $3);
}
}
| MODPARAM LPAREN STRING COMMA STRING COMMA snumber RPAREN { IFOR();
if (set_mod_param_regex($3, $5, INT_PARAM, (void*)$7) != 0) {
yyerrorf("Parameter <%s> not found in module <%s> - "
"can't set", $5, $3);
}
}
| MODPARAM error { yyerror("Invalid arguments"); }
;
ip: ipv4 { $$=$1; }
|ipv6 { $$=$1; }
;
ipv4: IPV4ADDR {
$$=pkg_malloc(sizeof(struct ip_addr));
if ($$==0){
LM_CRIT("ERROR: cfg. parser: out of memory.\n");
YYABORT;
}else{
memset($$, 0, sizeof(struct ip_addr));
$$->af=AF_INET;
$$->len=16;
if (inet_pton(AF_INET, $1, $$->u.addr)<=0){
yyerror("bad ipv4 address");
}
}
}
;
ipv6addr: IPV6ADDR {
$$=pkg_malloc(sizeof(struct ip_addr));
if ($$==0){
LM_CRIT("ERROR: cfg. parser: out of memory.\n");
YYABORT;
}else{
memset($$, 0, sizeof(struct ip_addr));
$$->af=AF_INET6;
$$->len=16;
if (inet_pton(AF_INET6, $1, $$->u.addr)<=0){
yyerror("bad ipv6 address");
}
}
}
;
ipv6: ipv6addr { $$=$1; }
| LBRACK ipv6addr RBRACK {$$=$2; }
;
ipnet: IPNET {
if (parse_ipnet($1, strlen($1), &net_tmp) < 0)
yyerror("unable to parse ip and/or netmask\n");
$$ = net_tmp;
}
| ip {
$$=mk_net_bitlen($1, $1->len*8);
pkg_free($1);
}
;
folded_string: STRING STRING {
$$ = pkg_malloc( strlen($1) + strlen($2) + 1);
if ($$==0){
yyerror("cfg. parser: out of memory");
YYABORT;
} else {
strcpy($$,$1); strcat($$,$2);
pkg_free($1); pkg_free($2);
}
}
| folded_string STRING {
$$ = pkg_malloc( strlen($1) + strlen($2) + 1);
if ($$==0){
LM_CRIT("ERROR: cfg. parser: out of memory.\n");
YYABORT;
} else {
strcpy($$,$1); strcat($$,$2);
pkg_free($1); pkg_free($2);
}
}
route_name: ID {
$$ = $1;
}
| NUMBER {
tmp=int2str($1, &i_tmp);
if (($$=pkg_malloc(i_tmp+1))==0) {
yyerror("cfg. parser: out of memory.\n");
YYABORT;
}
memcpy( $$, tmp, i_tmp);
$$[i_tmp] = 0;
}
|STRING {
$$ = $1;
}
;
route_name_var: route_name {
/* check to see if there are any "$" in the string name */
tmp = strchr($1, '$');
if (!tmp) {
/* route name is a cosntant string - search for the route */
rn_tmp.data = 0;
rn_tmp.iname = get_script_route_idx($1, sroutes->request,
RT_NO, 0);
if (rn_tmp.iname==-1)
yyerror("too many script routes");
$$ = NUMBER_ST;
} else {
tstr.s = $1;
tstr.len = strlen(tstr.s);
if (pv_parse_format(&tstr, &elem) < 0) {
yyerror("cannot parse format");
YYABORT;
}
/* the route name is a format, so we can't evaluate it now */
rn_tmp.ename = elem;
$$ = SCRIPTVAR_ELEM_ST;
}
}
| script_var {
rn_tmp.sname = $1;
$$ = SCRIPTVAR_ST;
}
route_stm: ROUTE LBRACE actions RBRACE {
if (sroutes->request[DEFAULT_RT].a!=0) {
yyerror("overwriting default "
"request routing table");
YYABORT;
}
push($3, &sroutes->request[DEFAULT_RT].a);
}
| ROUTE LBRACK route_name RBRACK LBRACE actions RBRACE {
if ( strtol($3,&tmp,10)==0 && *tmp==0) {
/* route[0] detected */
if (sroutes->request[DEFAULT_RT].a!=0) {
yyerror("overwriting(2) default "
"request routing table");
YYABORT;
}
push($6, &sroutes->request[DEFAULT_RT].a);
} else {
i_tmp = get_script_route_idx( $3,
sroutes->request, RT_NO,1);
if (i_tmp==-1) YYABORT;
push($6, &sroutes->request[i_tmp].a);
}
}
| ROUTE error { yyerror("invalid route statement"); }
;
failure_route_stm: ROUTE_FAILURE LBRACK route_name RBRACK LBRACE actions RBRACE {
i_tmp = get_script_route_idx( $3, sroutes->failure,
FAILURE_RT_NO,1);
if (i_tmp==-1) YYABORT;
push($6, &sroutes->failure[i_tmp].a);
}
| ROUTE_FAILURE error { yyerror("invalid failure_route statement"); }
;
onreply_route_stm: ROUTE_ONREPLY LBRACE actions RBRACE {
if (sroutes->onreply[DEFAULT_RT].a!=0) {
yyerror("overwriting default "
"onreply routing table");
YYABORT;
}
push($3, &sroutes->onreply[DEFAULT_RT].a);
}
| ROUTE_ONREPLY LBRACK route_name RBRACK LBRACE actions RBRACE {
i_tmp = get_script_route_idx( $3, sroutes->onreply,
ONREPLY_RT_NO,1);
if (i_tmp==-1) YYABORT;
push($6, &sroutes->onreply[i_tmp].a);
}
| ROUTE_ONREPLY error { yyerror("invalid onreply_route statement"); }
;
branch_route_stm: ROUTE_BRANCH LBRACK route_name RBRACK LBRACE actions RBRACE {
i_tmp = get_script_route_idx( $3, sroutes->branch,
BRANCH_RT_NO,1);
if (i_tmp==-1) YYABORT;
push($6, &sroutes->branch[i_tmp].a);
}
| ROUTE_BRANCH error { yyerror("invalid branch_route statement"); }
;
error_route_stm: ROUTE_ERROR LBRACE actions RBRACE {
if (sroutes->error.a!=0) {
yyerror("overwriting default "
"error routing table");
YYABORT;
}
push($3, &sroutes->error.a);
}
| ROUTE_ERROR error { yyerror("invalid error_route statement"); }
;
local_route_stm: ROUTE_LOCAL LBRACE actions RBRACE {
if (sroutes->local.a!=0) {
yyerror("re-definition of local "
"route detected");
YYABORT;
}
push($3, &sroutes->local.a);
}
| ROUTE_LOCAL error { yyerror("invalid local_route statement"); }
;
startup_route_stm: ROUTE_STARTUP LBRACE actions RBRACE {
if (sroutes->startup.a!=0) {
yyerror("re-definition of startup "
"route detected");
YYABORT;
}
push($3, &sroutes->startup.a);
}
| ROUTE_STARTUP error { yyerror("invalid startup_route statement"); }
;
timer_route_stm: ROUTE_TIMER LBRACK route_name COMMA NUMBER RBRACK LBRACE actions RBRACE {
i_tmp = 0;
while(i_tmp<TIMER_RT_NO && sroutes->timer[i_tmp].a!=0){
i_tmp++;
}
if(i_tmp == TIMER_RT_NO) {
yyerror("Too many timer routes defined\n");
YYABORT;
}
sroutes->timer[i_tmp].name = $3;
sroutes->timer[i_tmp].interval = $5;
push($8, &sroutes->timer[i_tmp].a);
}
| ROUTE_TIMER error { yyerror("invalid timer_route statement"); }
;
event_route_stm: ROUTE_EVENT LBRACK route_name RBRACK LBRACE actions RBRACE {
i_tmp = get_script_route_idx($3, sroutes->event,
EVENT_RT_NO,1);
if (i_tmp==-1) YYABORT;
push($6, &sroutes->event[i_tmp].a);
}
| ROUTE_EVENT error { yyerror("invalid event_route statement"); }
;
exp: exp AND exp { $$=mk_exp(AND_OP, $1, $3); }
| exp OR exp { $$=mk_exp(OR_OP, $1, $3); }
| NOT exp { $$=mk_exp(NOT_OP, $2, 0); }
| LPAREN exp RPAREN { $$=mk_exp(EVAL_OP, $2, 0); }
| LBRACK assignexp RBRACK { $$=$2; }
| exp_elem { $$=$1; }
;
equalop: EQUAL_T {$$=EQUAL_OP; }
| DIFF {$$=DIFF_OP; }
;
compop: GT {$$=GT_OP; }
| LT {$$=LT_OP; }
| GTE {$$=GTE_OP; }
| LTE {$$=LTE_OP; }
;
matchop: MATCH {$$=MATCH_OP; }
| NOTMATCH {$$=NOTMATCH_OP; }
;
intop: equalop {$$=$1; }
| compop {$$=$1; }
;
strop: equalop {$$=$1; }
| compop {$$=$1; }
| matchop {$$=$1; }
;
script_var: SCRIPTVAR {
spec = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t));
if (spec==NULL){
yyerror("no more pkg memory\n");
YYABORT;
}
memset(spec, 0, sizeof(pv_spec_t));
tstr.s = $1;
tstr.len = strlen(tstr.s);
if(pv_parse_spec(&tstr, spec)==NULL)
{
yyerror("unknown script variable");
}
$$ = spec;
}
| SCRIPTVARERR {
$$=0; yyerror("invalid script variable name");
}
;
exp_elem: exp_cond {$$=$1; }
| exp_stm {$$=mk_elem( NO_OP, ACTION_O, 0, ACTIONS_ST, $1 ); }
| snumber {$$=mk_elem( NO_OP, NUMBER_O, 0, NUMBER_ST,
(void*)$1 ); }
| script_var {
$$=mk_elem(NO_OP, SCRIPTVAR_O,0,SCRIPTVAR_ST,(void*)$1);
}
;
exp_cond: script_var strop script_var {
$$=mk_elem( $2, SCRIPTVAR_O,(void*)$1,SCRIPTVAR_ST,(void*)$3);
}
| script_var strop STRING {
$$=mk_elem( $2, SCRIPTVAR_O,(void*)$1,STR_ST,$3);
}
| script_var intop snumber {
$$=mk_elem( $2, SCRIPTVAR_O,(void*)$1,NUMBER_ST,(void *)$3);
}
| script_var equalop NULLV {
$$=mk_elem( $2, SCRIPTVAR_O,(void*)$1, NULLV_ST, 0);
}
| script_var equalop ipnet {
$$=mk_elem($2, SCRIPTVAR_O, (void*)$1, NET_ST, $3);
}
;
assignop:
EQUAL { $$ = EQ_T; }
| COLONEQ { $$ = COLONEQ_T; }
| PLUSEQ { $$ = PLUSEQ_T; }
| MINUSEQ { $$ = MINUSEQ_T;}
| SLASHEQ { $$ = DIVEQ_T; }
| MULTEQ { $$ = MULTEQ_T; }
| MODULOEQ { $$ = MODULOEQ_T; }
| BANDEQ { $$ = BANDEQ_T; }
| BOREQ { $$ = BOREQ_T; }
| BXOREQ { $$ = BXOREQ_T; }
;
assignexp :
snumber { $$ = mk_elem(VALUE_OP, NUMBERV_O, (void*)$1, 0, 0); }
| STRING { $$ = mk_elem(VALUE_OP, STRINGV_O, $1, 0, 0); }
| script_var { $$ = mk_elem(VALUE_OP, SCRIPTVAR_O, $1, 0, 0); }
| exp_cond { $$= $1; }
| cmd { $$=mk_elem( NO_OP, ACTION_O, 0, ACTIONS_ST, $1 ); }
| assignexp PLUS assignexp {
$$ = mk_elem(PLUS_OP, EXPR_O, $1, EXPR_ST, $3);
}
| assignexp MINUS assignexp {
$$ = mk_elem(MINUS_OP, EXPR_O, $1, EXPR_ST, $3);
}
| assignexp MULT assignexp {
$$ = mk_elem(MULT_OP, EXPR_O, $1, EXPR_ST, $3);
}
| assignexp SLASH assignexp {
$$ = mk_elem(DIV_OP, EXPR_O, $1, EXPR_ST, $3);
}
| assignexp MODULO assignexp {
$$ = mk_elem(MODULO_OP, EXPR_O, $1, EXPR_ST, $3);
}
| assignexp BAND assignexp {
$$ = mk_elem(BAND_OP, EXPR_O, $1, EXPR_ST, $3);
}
| assignexp BOR assignexp {
$$ = mk_elem(BOR_OP, EXPR_O, $1, EXPR_ST, $3);
}
| assignexp BXOR assignexp {
$$ = mk_elem(BXOR_OP, EXPR_O, $1, EXPR_ST, $3);
}
| assignexp BLSHIFT assignexp {
$$ = mk_elem(BLSHIFT_OP, EXPR_O, $1, EXPR_ST, $3);
}
| assignexp BRSHIFT assignexp {
$$ = mk_elem(BRSHIFT_OP, EXPR_O, $1, EXPR_ST, $3);
}
| BNOT assignexp {
$$ = mk_elem(BNOT_OP, EXPR_O, $2, 0, 0);
}
| LPAREN assignexp RPAREN { $$ = $2; }
;
assign_cmd: script_var assignop assignexp {
if(!pv_is_w($1))
yyerror("invalid left operand in assignment");
if($1->trans!=0)
yyerror("transformations not accepted in left side "
"of assignment");
mk_action2( $$, $2,
SCRIPTVAR_ST,
EXPR_ST,
$1,
$3);
}
| script_var EQUAL NULLV {
if(!pv_is_w($1))
yyerror("invalid left operand in assignment");
if($1->trans!=0)
yyerror("transformations not accepted in left side "
"of assignment");
mk_action2( $$, EQ_T,
SCRIPTVAR_ST,
NULLV_ST,
$1,
0);
}
| script_var COLONEQ NULLV {
if(!pv_is_w($1))
yyerror("invalid left operand in assignment");
/* not all can get NULL with := */
switch($1->type) {
case PVT_AVP:
break;
default:
yyerror("invalid left operand in NULL assignment");
}
if($1->trans!=0)
yyerror("transformations not accepted in left side "
"of assignment");
mk_action2( $$, COLONEQ_T,
SCRIPTVAR_ST,
NULLV_ST,
$1,
0);
}
;
exp_stm: cmd { $$=$1; }
| if_cmd { $$=$1; }
| assign_cmd { $$=$1; }
| LBRACE actions RBRACE { $$=$2; }
| LBRACE RBRACE { $$=0; }
;
brk_stm: brk_action { $$=$1; }
| LBRACE brk_actions RBRACE { $$=$2; }
| LBRACE RBRACE { $$=0; }
;
stm: action { $$=$1; }
| LBRACE actions RBRACE { $$=$2; }
| LBRACE RBRACE { $$=0; }
;
actions: actions action {$$=append_action($1, $2); }
| action {$$=$1;}
| actions error { $$=0; yyerror("bad command!)"); }
;
/* breakable actions, within a switch / while / for-each */
brk_actions: brk_actions brk_action {$$=append_action($1, $2); }
| brk_action {$$=$1;}
| brk_actions error { $$=0; yyerror("bad command!)"); }
;
action: cmd SEMICOLON {$$=$1;}
| if_cmd {$$=$1;}
| while_cmd {$$=$1;}
| foreach_cmd {$$=$1;}
| switch_cmd {$$=$1;}
| assign_cmd SEMICOLON {$$=$1;}
| SEMICOLON /* null action */ {$$=0;}
| cmd error { $$=0; yyerror("bad command: missing ';'?"); }
;
brk_action: BREAK SEMICOLON { mk_action0($$, BREAK_T);}
| cmd SEMICOLON {$$=$1;}
| brk_if_cmd {$$=$1;}
| while_cmd {$$=$1;}
| foreach_cmd {$$=$1;}
| switch_cmd {$$=$1;}
| assign_cmd SEMICOLON {$$=$1;}
| SEMICOLON /* null action */ {$$=0;}
| cmd error { $$=0; yyerror("bad command: missing ';'?"); }
;
brk_if_cmd: IF LPAREN exp RPAREN brk_stm { mk_action3( $$, IF_T,
EXPR_ST,
ACTIONS_ST,
NOSUBTYPE,
$3,
$5,
0);
}
| IF LPAREN exp RPAREN brk_stm ELSE brk_stm { mk_action3( $$, IF_T,
EXPR_ST,
ACTIONS_ST,
ACTIONS_ST,
$3,
$5,
$7);
}
;
if_cmd: IF LPAREN exp RPAREN stm { mk_action3( $$, IF_T,
EXPR_ST,
ACTIONS_ST,
NOSUBTYPE,
$3,
$5,
0);
}
| IF LPAREN exp RPAREN stm ELSE stm { mk_action3( $$, IF_T,
EXPR_ST,
ACTIONS_ST,
ACTIONS_ST,
$3,
$5,
$7);
}
;
while_cmd: WHILE LPAREN exp RPAREN brk_stm { mk_action2( $$, WHILE_T,
EXPR_ST,
ACTIONS_ST,
$3,
$5);
}
;
foreach_cmd: FOR LPAREN script_var IN script_var RPAREN brk_stm {
if ($3->type != PVT_SCRIPTVAR &&
$3->type != PVT_AVP &&
pv_type($3->type) != PVT_JSON) {
yyerror("\nfor-each statement: only \"var\", \"avp\" "
"and \"json\" iterators are supported!");
}
mk_action3( $$, FOR_EACH_T,
SCRIPTVAR_ST,
SCRIPTVAR_ST,
ACTIONS_ST,
$3,
$5,
$7);
}
;
switch_cmd: SWITCH LPAREN script_var RPAREN LBRACE switch_stm RBRACE {
mk_action2( $$, SWITCH_T,
SCRIPTVAR_ST,
ACTIONS_ST,
$3,
$6);
}
;
switch_stm: case_stms default_stm { $$=append_action($1, $2); }
| case_stms { $$=$1; }
;
case_stms: case_stms case_stm {$$=append_action($1, $2); }
| case_stm {$$=$1;}
;
case_stm: CASE snumber COLON brk_actions { mk_action2( $$, CASE_T,
NUMBER_ST,
ACTIONS_ST,
(void*)$2,
$4);
}
| CASE snumber COLON { mk_action2( $$, CASE_T,
NUMBER_ST,
ACTIONS_ST,
(void*)$2,
NULL);
}
| CASE STRING COLON brk_actions { mk_action2( $$, CASE_T,
STR_ST,
ACTIONS_ST,
(void*)$2,
$4);
}
| CASE STRING COLON { mk_action2( $$, CASE_T,
STR_ST,
ACTIONS_ST,
(void*)$2,
NULL);
}
;
default_stm: DEFAULT COLON brk_actions { mk_action1( $$, DEFAULT_T,
ACTIONS_ST, $3);
}
| DEFAULT COLON { mk_action1( $$, DEFAULT_T, ACTIONS_ST, NULL); }
;
func_param: STRING {
elems[1].type = STR_ST;
elems[1].u.data = $1;
$$=1;
}
| func_param COMMA STRING {
if ($1+1>=MAX_ACTION_ELEMS) {
yyerror("too many arguments "
"in function\n");
$$=0;
}
elems[$1+1].type = STR_ST;
elems[$1+1].u.data = $3;
$$=$1+1;
}
| COMMA {
elems[1].type = NULLV_ST;
elems[1].u.data = NULL;
elems[2].type = NULLV_ST;
elems[2].u.data = NULL;
$$=2;
}
| COMMA STRING {
elems[1].type = NULLV_ST;
elems[1].u.data = NULL;
elems[2].type = STR_ST;
elems[2].u.data = $2;
$$=2;
}
| func_param COMMA {
if ($1+1>=MAX_ACTION_ELEMS) {
yyerror("too many arguments "
"in function\n");
$$=0;
}
elems[$1+1].type = NULLV_ST;
elems[$1+1].u.data = NULL;
$$=$1+1;
}
| snumber {
elems[1].type = NUMBER_ST;
elems[1].u.number = $1;
$$=1;
}
| COMMA snumber {
elems[1].type = NULLV_ST;
elems[1].u.data = NULL;
elems[2].type = NUMBER_ST;
elems[2].u.number = $2;
$$=2;
}
| func_param COMMA snumber {
if ($1+1>=MAX_ACTION_ELEMS) {
yyerror("too many arguments "
"in function\n");
$$=0;
}
elems[$1+1].type = NUMBER_ST;
elems[$1+1].u.number = $3;
$$=$1+1;
}
| script_var {
elems[1].type = SCRIPTVAR_ST;
elems[1].u.data = $1;
$$=1;
}
| COMMA script_var {
elems[1].type = NULLV_ST;
elems[1].u.data = NULL;
elems[2].type = SCRIPTVAR_ST;
elems[2].u.data = $2;
$$=2;
}
| func_param COMMA script_var {
if ($1+1>=MAX_ACTION_ELEMS) {
yyerror("too many arguments "
"in function\n");
$$=0;
}
elems[$1+1].type = SCRIPTVAR_ST;
elems[$1+1].u.data = $3;
$$=$1+1;
}
;
route_param: STRING {
route_elems[0].type = STRING_ST;
route_elems[0].u.string = $1;
$$=1;
}
| snumber {
route_elems[0].type = NUMBER_ST;
route_elems[0].u.number = (long)$1;
$$=1;
}
| NULLV {
route_elems[0].type = NULLV_ST;
route_elems[0].u.data = 0;
$$=1;
}
| script_var {
route_elems[0].type = SCRIPTVAR_ST;
route_elems[0].u.data = $1;
$$=1;
}
| route_param COMMA STRING {
if ($1>=MAX_ACTION_ELEMS) {
yyerror("too many arguments in function\n");
$$=-1;
} else {
route_elems[$1].type = STRING_ST;
route_elems[$1].u.data = $3;
$$=$1+1;
}
}
| route_param COMMA snumber {
if ($1>=MAX_ACTION_ELEMS) {
yyerror("too many arguments in function\n");
$$=-1;
} else {
route_elems[$1].type = NUMBER_ST;
route_elems[$1].u.data = (void*)(long)$3;
$$=$1+1;
}
}
| route_param COMMA script_var {
if ($1+1>=MAX_ACTION_ELEMS) {
yyerror("too many arguments in function\n");
$$=-1;
} else {
route_elems[$1].type = SCRIPTVAR_ST;
route_elems[$1].u.data = $3;
$$=$1+1;
}
}
| route_param COMMA NULLV {
if ($1+1>=MAX_ACTION_ELEMS) {
yyerror("too many arguments in function\n");
$$=-1;
} else {
route_elems[$1].type = NULLV_ST;
route_elems[$1].u.data = 0;
$$=$1+1;
}
}
;
async_func: ID LPAREN RPAREN {
const acmd_export_t* acmd_tmp=find_mod_acmd_export_t($1);
if (acmd_tmp==0){
yyerrorf("unknown async command <%s>, "
"missing loadmodule?", $1);
$$=0;
}else{
if (check_acmd_call_params(acmd_tmp,elems,0)<0) {
yyerrorf("too few parameters "
"for command <%s>\n", $1);
$$=0;
} else {
elems[0].type = ACMD_ST;
elems[0].u.data_const = acmd_tmp;
mk_action_($$, AMODULE_T, 1, elems);
}
}
}
| ID LPAREN func_param RPAREN {
const acmd_export_t* acmd_tmp=find_mod_acmd_export_t($1);
if (acmd_tmp==0){
yyerrorf("unknown async command <%s>, "
"missing loadmodule?", $1);
$$=0;
}else{
rc = check_acmd_call_params(acmd_tmp,elems,$3);
switch (rc) {
case -1:
yyerrorf("too few parameters "
"for async command <%s>\n", $1);
$$=0;
break;
case -2:
yyerrorf("too many parameters "
"for async command <%s>\n", $1);
$$=0;
break;
case -3:
yyerrorf("mandatory parameter "
" omitted for async command <%s>\n", $1);
$$=0;
break;
default:
elems[0].type = ACMD_ST;
elems[0].u.data_const = acmd_tmp;
mk_action_($$, AMODULE_T, $3+1, elems);
}
}
}
| ID LPAREN error RPAREN {
$$=0;
yyerrorf("bad arguments for command <%s>", $1);
}
| ID error {
$$=0;
yyerrorf("bare word <%s> found, command calls need '()'", $1);
}
;
cmd: ASSERT LPAREN exp COMMA STRING RPAREN {
mk_action2( $$, ASSERT_T, EXPR_ST, STRING_ST, $3, $5);
}
| DROP {mk_action0( $$, DROP_T); }
| DROP LPAREN RPAREN {mk_action0( $$, DROP_T); }
| EXIT {mk_action0( $$, EXIT_T); }
| EXIT LPAREN RPAREN {mk_action0( $$, EXIT_T); }
| RETURN script_var
{mk_action1( $$, RETURN_T, SCRIPTVAR_ST, (void*)$2); }
| RETURN LPAREN script_var RPAREN
{mk_action1( $$, RETURN_T, SCRIPTVAR_ST, (void*)$3); }
| RETURN snumber
{mk_action1( $$, RETURN_T, NUMBER_ST, (void*)$2); }
| RETURN LPAREN snumber RPAREN
{mk_action1( $$, RETURN_T, NUMBER_ST, (void*)$3); }
| RETURN LPAREN RPAREN
{mk_action1( $$, RETURN_T, NUMBER_ST, (void*)1); }
| RETURN {mk_action1( $$, RETURN_T, NUMBER_ST, (void*)1); }
| LOG_TOK LPAREN STRING RPAREN {mk_action2( $$, LOG_T, NUMBER_ST,
STRING_ST,(void*)4,$3);
}
| LOG_TOK LPAREN snumber COMMA STRING RPAREN {mk_action2( $$, LOG_T,
NUMBER_ST,
STRING_ST,
(void*)$3,
$5);
}
| LOG_TOK error { $$=0; yyerror("missing '(' or ')' ?"); }
| LOG_TOK LPAREN error RPAREN { $$=0; yyerror("bad log"
"argument"); }
| ERROR LPAREN STRING COMMA STRING RPAREN {mk_action2( $$, ERROR_T,
STRING_ST,
STRING_ST,
$3,
$5);
}
| ERROR error { $$=0; yyerror("missing '(' or ')' ?"); }
| ERROR LPAREN error RPAREN { $$=0; yyerror("bad error"
"argument"); }
| ROUTE LPAREN route_name_var RPAREN {
mk_action2( $$, ROUTE_T, $3, 0, rn_tmp.data, 0);
}
| ROUTE LPAREN route_name_var COMMA route_param RPAREN {
if ($5 <= 0) yyerror("too many route parameters");
/* duplicate the list */
a_tmp = pkg_malloc($5 * sizeof(action_elem_t));
if (!a_tmp) {
yyerror("no more pkg memory");
YYABORT;
}
memcpy(a_tmp, route_elems, $5*sizeof(action_elem_t));
mk_action3( $$, ROUTE_T, $3, /* route idx */
NUMBER_ST, /* number of params */
SCRIPTVAR_ST, /* parameters */
rn_tmp.data,
(void*)(long)$5,
(void*)a_tmp);
}
| ROUTE error { $$=0; yyerror("missing '(' or ')' ?"); }
| ROUTE LPAREN error RPAREN { $$=0; yyerror("bad route"
"argument"); }
| ID LPAREN RPAREN {
const cmd_export_t* cmd_tmp=find_cmd_export_t($1, rt);
if (cmd_tmp==0){
if (find_cmd_export_t($1, 0)) {
yyerrorf("Command <%s> cannot be "
"used in the block\n", $1);
} else {
yyerrorf("unknown command <%s>, "
"missing loadmodule?", $1);
}
$$=0;
}else{
if (check_cmd_call_params(cmd_tmp,elems,0)<0) {
yyerrorf("too few parameters "
"for command <%s>\n", $1);
$$=0;
} else {
elems[0].type = CMD_ST;
elems[0].u.data_const = cmd_tmp;
mk_action_($$, CMD_T, 1, elems);
}
}
}
| ID LPAREN func_param RPAREN {
const cmd_export_t* cmd_tmp=find_cmd_export_t($1, rt);
if (cmd_tmp==0){
if (find_cmd_export_t($1, 0)) {
yyerrorf("Command <%s> cannot be "
"used in the block\n", $1);
} else {
yyerrorf("unknown command <%s>, "
"missing loadmodule?", $1);
}
$$=0;
}else{
rc = check_cmd_call_params(cmd_tmp,elems,$3);
switch (rc) {
case -1:
yyerrorf("too few parameters "
"for command <%s>\n", $1);
$$=0;
break;
case -2:
yyerrorf("too many parameters "
"for command <%s>\n", $1);
$$=0;
break;
case -3:
yyerrorf("mandatory parameter "
"omitted for command <%s>\n", $1);
$$=0;
break;
default:
elems[0].type = CMD_ST;
elems[0].u.data_const = cmd_tmp;
mk_action_($$, CMD_T, $3+1, elems);
}
}
}
| ID LPAREN error RPAREN { $$=0; yyerrorf("bad arguments for "
"command <%s>", $1); }
| ID error { $$=0;
yyerrorf("bare word <%s> found, command calls need '()'", $1);
}
| XDBG LPAREN STRING RPAREN {
mk_action1($$, XDBG_T, STR_ST, $3); }
| XDBG LPAREN folded_string RPAREN {
mk_action1($$, XDBG_T, STR_ST, $3); }
| XLOG LPAREN STRING RPAREN {
mk_action1($$, XLOG_T, STR_ST, $3); }
| XLOG LPAREN folded_string RPAREN {
mk_action1($$, XLOG_T, STR_ST, $3); }
| XLOG LPAREN STRING COMMA STRING RPAREN {
mk_action2($$, XLOG_T, STR_ST, STR_ST, $3, $5); }
| XLOG LPAREN STRING COMMA folded_string RPAREN {
mk_action2($$, XLOG_T, STR_ST, STR_ST, $3, $5); }
| ASYNC_TOKEN LPAREN async_func COMMA route_name RPAREN {
rt_ref = ref_script_route_by_name( $5, sroutes->request,
RT_NO, REQUEST_ROUTE, 0);
if (rt_ref==NULL) yyerror("fail to create route reference");
mk_action2($$, ASYNC_T, ACTIONS_ST, ROUTE_REF_ST,
$3, (void*)rt_ref);
}
| ASYNC_TOKEN LPAREN async_func COMMA route_name COMMA NUMBER RPAREN {
rt_ref = ref_script_route_by_name( $5, sroutes->request,
RT_NO, REQUEST_ROUTE, 0);
if (rt_ref==NULL) yyerror("fail to create route reference");
mk_action3($$, ASYNC_T, ACTIONS_ST, ROUTE_REF_ST, NUMBER_ST,
$3, (void*)rt_ref, (void*)(long)$7);
}
| LAUNCH_TOKEN LPAREN async_func COMMA route_name COMMA STRING RPAREN {
rt_ref = ref_script_route_by_name( $5, sroutes->request,
RT_NO, REQUEST_ROUTE, 0);
if (rt_ref==NULL) yyerror("fail to create route reference");
mk_action3($$, LAUNCH_T, ACTIONS_ST, ROUTE_REF_ST, STRING_ST,
$3, (void*)rt_ref, $7);
}
| LAUNCH_TOKEN LPAREN async_func COMMA route_name RPAREN {
rt_ref = ref_script_route_by_name( $5, sroutes->request,
RT_NO, REQUEST_ROUTE, 0);
if (rt_ref==NULL) yyerror("fail to create route reference");
mk_action2($$, LAUNCH_T, ACTIONS_ST, ROUTE_REF_ST,
$3, (void*)rt_ref);
}
| LAUNCH_TOKEN LPAREN async_func RPAREN {
mk_action2($$, LAUNCH_T, ACTIONS_ST, ROUTE_REF_ST,
$3, (void*)NULL);
}
;
%%
static inline void ALLOW_UNUSED warn(char* s)
{
LM_WARN("warning in config file %s, line %d, column %d-%d: %s\n",
get_cfg_file_name, line, startcolumn, column, s);
}
static void yyerror(char* s)
{
cfg_dump_backtrace();
LM_CRIT("parse error in %s:%d:%d-%d: %s\n",
get_cfg_file_name, line, startcolumn, column, s);
_cfg_dump_context(get_cfg_file_name, line, startcolumn, column, 1);
cfg_errors++;
}
#define ERROR_MAXLEN 1024
static void yyerrorf(char *fmt, ...)
{
char *tmp = pkg_malloc(ERROR_MAXLEN);
va_list ap;
va_start(ap, fmt);
vsnprintf(tmp, ERROR_MAXLEN, fmt, ap);
yyerror(tmp);
pkg_free(tmp);
va_end(ap);
}
static struct socket_id* mk_listen_id(char* host, enum sip_protos proto,
int port)
{
struct socket_id* l;
l=pkg_malloc(sizeof(struct socket_id));
if (l==0){
LM_CRIT("cfg. parser: out of memory.\n");
}else{
memset(l, 0, sizeof(*l));
l->name = host;
l->proto = proto;
l->port = port;
}
return l;
}
static void fill_socket_id(struct listen_param *param, struct socket_id *s)
{
s->flags |= param->flags;
s->workers = param->workers;
s->auto_scaling_profile = param->auto_scaling_profile;
if (param->socket)
set_listen_id_adv(s, param->socket->name, param->socket->port);
s->tag = param->tag;
}
static struct multi_str *new_string(char *s)
{
struct multi_str *ms = pkg_malloc(sizeof(struct multi_str));
if (!ms) {
LM_CRIT("cfg. parser: out of memory.\n");
}else{
ms->s = s;
ms->next = NULL;
}
return ms;
}
static struct socket_id* set_listen_id_adv(struct socket_id* sock,
char *adv_name,
int adv_port)
{
sock->adv_name=adv_name;
sock->adv_port=adv_port;
return sock;
}
static int parse_ipnet(char *in, int len, struct net **ipnet)
{
char *p = NULL;
str ip_s, mask_s;
struct ip_addr *ip = NULL, *mask = NULL, *ip_tmp;
int af;
unsigned int bitlen;
p = q_memchr(in, '.', len);
if (p)
af = AF_INET;
else if (q_memchr(in, ':', len)) {
af = AF_INET6;
} else {
LM_ERR("Not an IP");
return -1;
}
p = q_memchr(in, '/', len);
if (!p) {
LM_ERR("No netmask\n");
return -1;
}
ip_s.s = in;
ip_s.len = p - in;
mask_s.s = p + 1;
mask_s.len = len - ip_s.len - 1;
if (!mask_s.s || mask_s.len == 0) {
LM_ERR("Empty netmask\n");
return -1;
}
ip_tmp = (af == AF_INET) ? str2ip(&ip_s) : str2ip6(&ip_s);
if (!ip_tmp) {
LM_ERR("Invalid IP\n");
return -1;
}
ip = pkg_malloc(sizeof *ip);
if (!ip) {
LM_CRIT("No more pkg memory\n");
return -1;
}
memcpy(ip, ip_tmp, sizeof *ip);
p = (af == AF_INET) ? q_memchr(p, '.', len-(p-in)+1) : q_memchr(p, ':', len-(p-in)+1);
if (p) {
ip_tmp = (af == AF_INET) ? str2ip(&mask_s) : str2ip6(&mask_s);
if (!ip_tmp) {
LM_ERR("Invalid netmask\n");
return -1;
}
mask = pkg_malloc(sizeof *mask);
if (!mask) {
LM_CRIT("No more pkg memory\n");
return -1;
}
memcpy(mask, ip_tmp, sizeof *mask);
*ipnet = mk_net(ip, mask);
} else {
if (str2int(&mask_s, &bitlen) < 0) {
LM_ERR("Invalid netmask bitlen\n");
return -1;
}
*ipnet = mk_net_bitlen(ip, bitlen);
}
pkg_free(ip);
pkg_free(mask);
if (*ipnet == NULL)
return -1;
return 0;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化