/* $Id$ */ %{ #include "config.h" #include "cfg_file.h" #include "main.h" #include "expressions.h" #include "classifiers/classifiers.h" #include "tokenizers/tokenizers.h" #include "view.h" #include "settings.h" #ifdef WITH_LUA #include "lua/lua_common.h" #else #include "perl.h" #endif #define YYDEBUG 1 extern struct config_file *yacc_cfg; extern int yylineno; extern char *yytext; GList *cur_module_opt = NULL; struct metric *cur_metric = NULL; struct classifier_config *cur_classifier = NULL; struct statfile *cur_statfile = NULL; struct statfile_section *cur_section = NULL; struct statfile_autolearn_params *cur_autolearn = NULL; struct worker_conf *cur_worker = NULL; struct rspamd_view *cur_view = NULL; %} %union { char *string; size_t limit; gboolean flag; unsigned int seconds; unsigned int number; double fract; } %token ERROR STRING QUOTEDSTRING FLAG %token FILENAME REGEXP QUOTE SEMICOLON OBRACE EBRACE COMMA EQSIGN %token BINDSOCK SOCKCRED DOMAINNAME IPADDR IPNETWORK HOSTPORT NUMBER CHECK_TIMEOUT %token MAXSIZE SIZELIMIT SECONDS BEANSTALK MYSQL USER PASSWORD DATABASE %token TEMPDIR PIDFILE SERVERS ERROR_TIME DEAD_TIME MAXERRORS CONNECT_TIMEOUT PROTOCOL RECONNECT_TIMEOUT %token READ_SERVERS WRITE_SERVER DIRECTORY_SERVERS MAILBOX_QUERY USERS_QUERY LASTLOGIN_QUERY %token MEMCACHED WORKER TYPE MODULES MODULE_PATH %token MODULE_OPT PARAM VARIABLE %token FILTERS FACTORS METRIC NAME CACHE_FILE %token REQUIRED_SCORE REJECT_SCORE FUNCTION FRACT COMPOSITES CONTROL PASSWORD %token LOGGING LOG_TYPE LOG_TYPE_CONSOLE LOG_TYPE_SYSLOG LOG_TYPE_FILE %token LOG_LEVEL LOG_LEVEL_DEBUG LOG_LEVEL_INFO LOG_LEVEL_WARNING LOG_LEVEL_ERROR LOG_FACILITY LOG_FILENAME LOG_URLS %token STATFILE ALIAS PATTERN WEIGHT STATFILE_POOL_SIZE SIZE TOKENIZER CLASSIFIER BINLOG BINLOG_MASTER BINLOG_ROTATE %token DELIVERY LMTP ENABLED AGENT SECTION LUACODE RAW_MODE PROFILE_FILE COUNT %token VIEW IP FROM SYMBOLS CLIENT_IP %token AUTOLEARN MIN_MARK MAX_MARK MAXFILES MAXCORE %token SETTINGS USER_SETTINGS DOMAIN_SETTINGS SYMBOL PATH SKIP_CHECK GROW_FACTOR %token LOG_BUFFER DEBUG_IP NORMALIZER HEADER_ONLY %type STRING %type VARIABLE %type QUOTEDSTRING MODULE_OPT PARAM %type FILENAME %type SOCKCRED %type IPADDR IPNETWORK %type HOSTPORT %type DOMAINNAME %type SIZELIMIT %type FLAG %type SECONDS %type NUMBER %type memcached_hosts bind_cred %type FRACT %% file : /* empty */ | file command SEMICOLON { } ; command : | tempdir | pidfile | memcached | worker | modules | filters | module_opt | variable | factors | metric | composites | logging | classifier | statfile_pool_size | luacode | raw_mode | profile_file | view | settings ; tempdir : TEMPDIR EQSIGN QUOTEDSTRING { struct stat st; if (stat ($3, &st) == -1) { yyerror ("yyparse: cannot stat directory \"%s\": %s", $3, strerror (errno)); YYERROR; } if (!S_ISDIR (st.st_mode)) { yyerror ("yyparse: \"%s\" is not a directory", $3); YYERROR; } yacc_cfg->temp_dir = memory_pool_strdup (yacc_cfg->cfg_pool, $3); free ($3); } ; pidfile : PIDFILE EQSIGN QUOTEDSTRING { if (yacc_cfg->pid_file == NULL) { /* Allow override this value from command line */ yacc_cfg->pid_file = $3; } } ; filters: FILTERS EQSIGN QUOTEDSTRING { yacc_cfg->filters_str = memory_pool_strdup (yacc_cfg->cfg_pool, $3); free ($3); } ; memcached: MEMCACHED OBRACE memcachedbody EBRACE ; memcachedbody: memcachedcmd SEMICOLON | memcachedbody memcachedcmd SEMICOLON ; memcachedcmd: memcached_servers | memcached_connect_timeout | memcached_error_time | memcached_dead_time | memcached_maxerrors | memcached_protocol ; memcached_servers: SERVERS EQSIGN memcached_server ; memcached_server: memcached_params | memcached_server COMMA memcached_params ; memcached_params: memcached_hosts { if (!add_memcached_server (yacc_cfg, $1)) { yyerror ("yyparse: add_memcached_server"); YYERROR; } free ($1); } ; memcached_hosts: STRING | IPADDR | DOMAINNAME | HOSTPORT ; memcached_error_time: ERROR_TIME EQSIGN NUMBER { yacc_cfg->memcached_error_time = $3; } ; memcached_dead_time: DEAD_TIME EQSIGN NUMBER { yacc_cfg->memcached_dead_time = $3; } ; memcached_maxerrors: MAXERRORS EQSIGN NUMBER { yacc_cfg->memcached_maxerrors = $3; } ; memcached_connect_timeout: CONNECT_TIMEOUT EQSIGN SECONDS { yacc_cfg->memcached_connect_timeout = $3; } ; memcached_protocol: PROTOCOL EQSIGN STRING { if (strncasecmp ($3, "udp", sizeof ("udp") - 1) == 0) { yacc_cfg->memcached_protocol = UDP_TEXT; } else if (strncasecmp ($3, "tcp", sizeof ("tcp") - 1) == 0) { yacc_cfg->memcached_protocol = TCP_TEXT; } else { yyerror ("yyparse: cannot recognize protocol: %s", $3); YYERROR; } } ; /* Workers section */ worker: WORKER OBRACE workerbody EBRACE { yacc_cfg->workers = g_list_prepend (yacc_cfg->workers, cur_worker); cur_worker = NULL; } ; workerbody: workercmd SEMICOLON | workerbody workercmd SEMICOLON ; workercmd: | bindsock | workertype | workercount | workerlimitfiles | workerlimitcore | workerparam ; bindsock: BINDSOCK EQSIGN bind_cred { cur_worker = check_worker_conf (yacc_cfg, cur_worker); if (!parse_bind_line (yacc_cfg, cur_worker, $3)) { yyerror ("yyparse: parse_bind_line"); YYERROR; } free ($3); } ; bind_cred: STRING { $$ = $1; } | IPADDR{ $$ = $1; } | DOMAINNAME { $$ = $1; } | HOSTPORT { $$ = $1; } | QUOTEDSTRING { $$ = $1; } ; workertype: TYPE EQSIGN QUOTEDSTRING { cur_worker = check_worker_conf (yacc_cfg, cur_worker); if (g_ascii_strcasecmp ($3, "normal") == 0) { cur_worker->type = TYPE_WORKER; cur_worker->has_socket = TRUE; } else if (g_ascii_strcasecmp ($3, "controller") == 0) { cur_worker->type = TYPE_CONTROLLER; cur_worker->has_socket = TRUE; } else if (g_ascii_strcasecmp ($3, "lmtp") == 0) { cur_worker->type = TYPE_LMTP; cur_worker->has_socket = TRUE; } else if (g_ascii_strcasecmp ($3, "fuzzy") == 0) { cur_worker->type = TYPE_FUZZY; cur_worker->has_socket = FALSE; } else { yyerror ("yyparse: unknown worker type: %s", $3); YYERROR; } } ; workercount: COUNT EQSIGN NUMBER { cur_worker = check_worker_conf (yacc_cfg, cur_worker); if ($3 > 0) { cur_worker->count = $3; } else { yyerror ("yyparse: invalid number of workers: %d", $3); YYERROR; } } ; workerlimitfiles: MAXFILES EQSIGN NUMBER { cur_worker = check_worker_conf (yacc_cfg, cur_worker); cur_worker->rlimit_nofile = $3; } ; workerlimitcore: MAXCORE EQSIGN NUMBER { cur_worker = check_worker_conf (yacc_cfg, cur_worker); cur_worker->rlimit_maxcore = $3; } ; workerparam: STRING EQSIGN QUOTEDSTRING { cur_worker = check_worker_conf (yacc_cfg, cur_worker); g_hash_table_insert (cur_worker->params, $1, $3); } metric: METRIC OBRACE metricbody EBRACE { if (cur_metric == NULL || cur_metric->name == NULL) { yyerror ("yyparse: not enough arguments in metric definition"); YYERROR; } if (cur_metric->classifier == NULL) { cur_metric->classifier = get_classifier ("winnow"); } g_hash_table_insert (yacc_cfg->metrics, cur_metric->name, cur_metric); yacc_cfg->metrics_list = g_list_prepend (yacc_cfg->metrics_list, cur_metric); cur_metric = NULL; } ; metricbody: | metriccmd SEMICOLON | metricbody metriccmd SEMICOLON ; metriccmd: | metricname | metricfunction | metricscore | metricrjscore | metriccache ; metricname: NAME EQSIGN QUOTEDSTRING { if (cur_metric == NULL) { cur_metric = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct metric)); } cur_metric->name = memory_pool_strdup (yacc_cfg->cfg_pool, $3); } ; metricfunction: FUNCTION EQSIGN QUOTEDSTRING { if (cur_metric == NULL) { cur_metric = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct metric)); } cur_metric->func_name = memory_pool_strdup (yacc_cfg->cfg_pool, $3); #ifdef WITH_LUA cur_metric->func = lua_consolidation_func; #elif !defined(WITHOUT_PERL) cur_metric->func = perl_consolidation_func; #else yyerror ("yyparse: rspamd is not compiled with perl or lua, so it is not possible to use custom consolidation functions"); #endif } ; metricscore: REQUIRED_SCORE EQSIGN NUMBER { if (cur_metric == NULL) { cur_metric = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct metric)); } cur_metric->required_score = $3; } | REQUIRED_SCORE EQSIGN FRACT { if (cur_metric == NULL) { cur_metric = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct metric)); } cur_metric->required_score = $3; } ; metricrjscore: REJECT_SCORE EQSIGN NUMBER { if (cur_metric == NULL) { cur_metric = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct metric)); } cur_metric->reject_score = $3; } | REJECT_SCORE EQSIGN FRACT { if (cur_metric == NULL) { cur_metric = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct metric)); } cur_metric->reject_score = $3; } ; metriccache: CACHE_FILE EQSIGN QUOTEDSTRING { if (cur_metric == NULL) { cur_metric = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct metric)); } cur_metric->cache_filename = memory_pool_strdup (yacc_cfg->cfg_pool, $3); } ; factors: FACTORS OBRACE factorsbody EBRACE ; factorsbody: factorparam SEMICOLON | factorsbody factorparam SEMICOLON ; factorparam: QUOTEDSTRING EQSIGN FRACT { double *tmp = memory_pool_alloc (yacc_cfg->cfg_pool, sizeof (double)); *tmp = $3; g_hash_table_insert (yacc_cfg->factors, $1, tmp); } | QUOTEDSTRING EQSIGN NUMBER { double *tmp = memory_pool_alloc (yacc_cfg->cfg_pool, sizeof (double)); *tmp = $3; g_hash_table_insert (yacc_cfg->factors, $1, tmp); } | GROW_FACTOR EQSIGN FRACT { yacc_cfg->grow_factor = $3; } | GROW_FACTOR EQSIGN NUMBER { yacc_cfg->grow_factor = $3; } modules: MODULES OBRACE modulesbody EBRACE ; modulesbody: modulescmd SEMICOLON | modulesbody modulescmd SEMICOLON ; modulescmd: MODULE_PATH EQSIGN QUOTEDSTRING { struct stat st; struct script_module *cur; glob_t globbuf; char *pattern; size_t len; int i; if (stat ($3, &st) == -1) { yyerror ("yyparse: cannot stat path %s, %s", $3, strerror (errno)); YYERROR; } globbuf.gl_offs = 0; len = strlen ($3) + sizeof ("*.lua"); pattern = g_malloc (len); snprintf (pattern, len, "%s%s", $3, "*.lua"); if (glob(pattern, GLOB_DOOFFS, NULL, &globbuf) == 0) { for (i = 0; i < globbuf.gl_pathc; i ++) { cur = memory_pool_alloc (yacc_cfg->cfg_pool, sizeof (struct script_module)); if (cur == NULL) { yyerror ("yyparse: g_malloc: %s", strerror(errno)); YYERROR; } cur->path = memory_pool_strdup (yacc_cfg->cfg_pool, globbuf.gl_pathv[i]); yacc_cfg->script_modules = g_list_prepend (yacc_cfg->script_modules, cur); } globfree (&globbuf); } else { yyerror ("yyparse: glob: %s", strerror (errno)); YYERROR; } g_free (pattern); } ; composites: COMPOSITES OBRACE compositesbody EBRACE ; compositesbody: compositescmd SEMICOLON | compositesbody compositescmd SEMICOLON ; compositescmd: PARAM EQSIGN QUOTEDSTRING { struct expression *expr; if ((expr = parse_expression (yacc_cfg->cfg_pool, $3)) == NULL) { yyerror ("yyparse: cannot parse composite expression: %s", $3); YYERROR; } g_hash_table_insert (yacc_cfg->composite_symbols, $1, expr); } ; module_opt: MODULE_OPT OBRACE moduleoptbody EBRACE { g_hash_table_insert (yacc_cfg->modules_opts, $1, cur_module_opt); cur_module_opt = NULL; } ; moduleoptbody: optcmd SEMICOLON | moduleoptbody optcmd SEMICOLON ; optcmd: PARAM EQSIGN QUOTEDSTRING { struct module_opt *mopt; mopt = memory_pool_alloc (yacc_cfg->cfg_pool, sizeof (struct module_opt)); mopt->param = $1; mopt->value = $3; cur_module_opt = g_list_prepend (cur_module_opt, mopt); } | VARIABLE EQSIGN QUOTEDSTRING { g_hash_table_insert (yacc_cfg->variables, $1, $3); } ; variable: VARIABLE EQSIGN QUOTEDSTRING { g_hash_table_insert (yacc_cfg->variables, $1, $3); } ; logging: LOGGING OBRACE loggingbody EBRACE ; loggingbody: loggingcmd SEMICOLON | loggingbody loggingcmd SEMICOLON ; loggingcmd: loggingtype | logginglevel | loggingfacility | loggingfile | loggingurls | loggingbuffer | loggingdebugip ; loggingtype: LOG_TYPE EQSIGN LOG_TYPE_CONSOLE { yacc_cfg->log_type = RSPAMD_LOG_CONSOLE; } | LOG_TYPE EQSIGN LOG_TYPE_SYSLOG { yacc_cfg->log_type = RSPAMD_LOG_SYSLOG; } | LOG_TYPE EQSIGN LOG_TYPE_FILE { yacc_cfg->log_type = RSPAMD_LOG_FILE; } ; logginglevel: LOG_LEVEL EQSIGN LOG_LEVEL_DEBUG { yacc_cfg->log_level = G_LOG_LEVEL_DEBUG; } | LOG_LEVEL EQSIGN LOG_LEVEL_INFO { yacc_cfg->log_level = G_LOG_LEVEL_INFO | G_LOG_LEVEL_MESSAGE; } | LOG_LEVEL EQSIGN LOG_LEVEL_WARNING { yacc_cfg->log_level = G_LOG_LEVEL_WARNING; } | LOG_LEVEL EQSIGN LOG_LEVEL_ERROR { yacc_cfg->log_level = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL; } ; loggingfacility: LOG_FACILITY EQSIGN QUOTEDSTRING { if (strncasecmp ($3, "LOG_AUTH", sizeof ("LOG_AUTH") - 1) == 0) { yacc_cfg->log_facility = LOG_AUTH; } else if (strncasecmp ($3, "LOG_CRON", sizeof ("LOG_CRON") - 1) == 0) { yacc_cfg->log_facility = LOG_CRON; } else if (strncasecmp ($3, "LOG_DAEMON", sizeof ("LOG_DAEMON") - 1) == 0) { yacc_cfg->log_facility = LOG_DAEMON; } else if (strncasecmp ($3, "LOG_MAIL", sizeof ("LOG_MAIL") - 1) == 0) { yacc_cfg->log_facility = LOG_MAIL; } else if (strncasecmp ($3, "LOG_USER", sizeof ("LOG_USER") - 1) == 0) { yacc_cfg->log_facility = LOG_USER; } else if (strncasecmp ($3, "LOG_LOCAL0", sizeof ("LOG_LOCAL0") - 1) == 0) { yacc_cfg->log_facility = LOG_LOCAL0; } else if (strncasecmp ($3, "LOG_LOCAL1", sizeof ("LOG_LOCAL1") - 1) == 0) { yacc_cfg->log_facility = LOG_LOCAL1; } else if (strncasecmp ($3, "LOG_LOCAL2", sizeof ("LOG_LOCAL2") - 1) == 0) { yacc_cfg->log_facility = LOG_LOCAL2; } else if (strncasecmp ($3, "LOG_LOCAL3", sizeof ("LOG_LOCAL3") - 1) == 0) { yacc_cfg->log_facility = LOG_LOCAL3; } else if (strncasecmp ($3, "LOG_LOCAL4", sizeof ("LOG_LOCAL4") - 1) == 0) { yacc_cfg->log_facility = LOG_LOCAL4; } else if (strncasecmp ($3, "LOG_LOCAL5", sizeof ("LOG_LOCAL5") - 1) == 0) { yacc_cfg->log_facility = LOG_LOCAL5; } else if (strncasecmp ($3, "LOG_LOCAL6", sizeof ("LOG_LOCAL6") - 1) == 0) { yacc_cfg->log_facility = LOG_LOCAL6; } else if (strncasecmp ($3, "LOG_LOCAL7", sizeof ("LOG_LOCAL7") - 1) == 0) { yacc_cfg->log_facility = LOG_LOCAL7; } else { yyerror ("yyparse: invalid logging facility: %s", $3); YYERROR; } free ($3); } ; loggingfile: LOG_FILENAME EQSIGN QUOTEDSTRING { yacc_cfg->log_file = memory_pool_strdup (yacc_cfg->cfg_pool, $3); free ($3); } ; loggingurls: LOG_URLS EQSIGN FLAG { if ($3 != 0) { yacc_cfg->log_urls = TRUE; } } ; loggingbuffer: LOG_BUFFER EQSIGN NUMBER | LOG_BUFFER EQSIGN SIZELIMIT { yacc_cfg->log_buf_size = $3; yacc_cfg->log_buffered = TRUE; } ; loggingdebugip: DEBUG_IP EQSIGN QUOTEDSTRING { yacc_cfg->debug_ip_map = $3; } ; classifier: CLASSIFIER OBRACE classifierbody EBRACE { if (cur_classifier == NULL || cur_classifier->classifier == NULL) { yyerror ("yyparse: invalid classifier definition"); YYERROR; } if (cur_classifier->metric == NULL) { cur_classifier->metric = DEFAULT_METRIC; } if (cur_classifier->tokenizer == NULL) { cur_classifier->tokenizer = get_tokenizer ("osb-text"); } yacc_cfg->classifiers = g_list_prepend (yacc_cfg->classifiers, cur_classifier); cur_classifier = NULL; } ; classifierbody: | classifiercmd SEMICOLON | classifierbody classifiercmd SEMICOLON ; classifiercmd: | statfile | classifiertype | classifiermetric | classifiertokenizer | classifieroption ; classifiertype: TYPE EQSIGN QUOTEDSTRING { cur_classifier = check_classifier_cfg (yacc_cfg, cur_classifier); if ((cur_classifier->classifier = get_classifier ($3)) == NULL) { yyerror ("yyparse: unknown classifier type: %s", $3); YYERROR; } } ; classifiertokenizer: TOKENIZER EQSIGN QUOTEDSTRING { cur_classifier = check_classifier_cfg (yacc_cfg, cur_classifier); if ((cur_classifier->tokenizer = get_tokenizer ($3)) == NULL) { yyerror ("yyparse: unknown tokenizer %s", $3); YYERROR; } } ; classifiermetric: METRIC EQSIGN QUOTEDSTRING { cur_classifier = check_classifier_cfg (yacc_cfg, cur_classifier); cur_classifier->metric = $3; memory_pool_add_destructor (yacc_cfg->cfg_pool, g_free, cur_classifier->metric); } ; classifieroption: PARAM EQSIGN QUOTEDSTRING { cur_classifier = check_classifier_cfg (yacc_cfg, cur_classifier); g_hash_table_insert (cur_classifier->opts, $1, $3); memory_pool_add_destructor (yacc_cfg->cfg_pool, g_free, $1); memory_pool_add_destructor (yacc_cfg->cfg_pool, g_free, $3); }; statfile: STATFILE OBRACE statfilebody EBRACE { if (cur_statfile == NULL || cur_statfile->path == NULL || cur_statfile->size == 0) { yyerror ("yyparse: not enough arguments in statfile definition"); YYERROR; } cur_classifier = check_classifier_cfg (yacc_cfg, cur_classifier); cur_classifier->statfiles = g_list_prepend (cur_classifier->statfiles, cur_statfile); yacc_cfg->statfiles = g_list_prepend (yacc_cfg->statfiles, cur_statfile); cur_statfile = NULL; } ; statfilebody: | statfilecmd SEMICOLON | statfilebody statfilecmd SEMICOLON ; statfilecmd: | statfilesymbol | statfilepath | statfilesize | statfilesection | statfileautolearn | statfilebinlog | statfilebinlogrotate | statfilebinlogmaster | statfilenormalizer ; statfilesymbol: SYMBOL EQSIGN QUOTEDSTRING { cur_classifier = check_classifier_cfg (yacc_cfg, cur_classifier); if (cur_statfile == NULL) { cur_statfile = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile)); } cur_statfile->symbol = memory_pool_strdup (yacc_cfg->cfg_pool, $3); g_hash_table_insert (yacc_cfg->classifiers_symbols, $3, cur_classifier); } ; statfilepath: PATH EQSIGN QUOTEDSTRING { if (cur_statfile == NULL) { cur_statfile = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile)); } cur_statfile->path = memory_pool_strdup (yacc_cfg->cfg_pool, $3); } ; statfilesize: SIZE EQSIGN NUMBER { if (cur_statfile == NULL) { cur_statfile = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile)); } cur_statfile->size = $3; } | SIZE EQSIGN SIZELIMIT { if (cur_statfile == NULL) { cur_statfile = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile)); } cur_statfile->size = $3; } ; statfilesection: SECTION OBRACE sectionbody EBRACE { if (cur_statfile == NULL) { cur_statfile = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile)); } if (cur_section == NULL || cur_section->code == 0) { yyerror ("yyparse: error in section definition"); YYERROR; } cur_statfile->sections = g_list_prepend (cur_statfile->sections, cur_section); cur_section = NULL; } ; sectionbody: sectioncmd SEMICOLON | sectionbody sectioncmd SEMICOLON ; sectioncmd: sectionname | sectionsize | sectionweight ; sectionname: NAME EQSIGN QUOTEDSTRING { if (cur_section == NULL) { cur_section = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_section)); } cur_section->code = statfile_get_section_by_name ($3); } ; sectionsize: SIZE EQSIGN NUMBER { if (cur_section == NULL) { cur_section = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_section)); } cur_section->size = $3; } | SIZE EQSIGN SIZELIMIT { if (cur_section == NULL) { cur_section = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_section)); } cur_section->size = $3; } ; sectionweight: WEIGHT EQSIGN NUMBER { if (cur_section == NULL) { cur_section = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_section)); } cur_section->weight = $3; } | WEIGHT EQSIGN FRACT { if (cur_section == NULL) { cur_section = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_section)); } cur_section->weight = $3; } ; statfileautolearn: AUTOLEARN OBRACE autolearnbody EBRACE { if (cur_statfile == NULL) { cur_statfile = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile)); } if (cur_autolearn == NULL) { yyerror ("yyparse: error in autolearn definition"); YYERROR; } cur_statfile->autolearn = cur_autolearn; cur_autolearn = NULL; } ; autolearnbody: autolearncmd SEMICOLON | autolearnbody autolearncmd SEMICOLON ; autolearncmd: autolearnmetric | autolearnmin | autolearnmax | autolearnsymbols ; autolearnmetric: METRIC EQSIGN QUOTEDSTRING { if (cur_autolearn == NULL) { cur_autolearn = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_autolearn_params)); } cur_autolearn->metric = memory_pool_strdup (yacc_cfg->cfg_pool, $3); } ; autolearnmin: MIN_MARK EQSIGN NUMBER { if (cur_autolearn == NULL) { cur_autolearn = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_autolearn_params)); } cur_autolearn->threshold_min = $3; } | MIN_MARK EQSIGN FRACT { if (cur_autolearn == NULL) { cur_autolearn = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_autolearn_params)); } cur_autolearn->threshold_min = $3; } ; autolearnmax: MAX_MARK EQSIGN NUMBER { if (cur_autolearn == NULL) { cur_autolearn = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_autolearn_params)); } cur_autolearn->threshold_max = $3; } | MAX_MARK EQSIGN FRACT { if (cur_autolearn == NULL) { cur_autolearn = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_autolearn_params)); } cur_autolearn->threshold_max = $3; } ; autolearnsymbols: SYMBOLS EQSIGN QUOTEDSTRING { if (cur_autolearn == NULL) { cur_autolearn = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_autolearn_params)); } cur_autolearn->symbols = parse_comma_list (yacc_cfg->cfg_pool, $3); } ; statfilebinlog: BINLOG EQSIGN QUOTEDSTRING { if (cur_statfile == NULL) { cur_statfile = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile)); } if (cur_statfile->binlog == NULL) { cur_statfile->binlog = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_binlog_params)); } if (g_ascii_strcasecmp ($3, "master") == 0) { cur_statfile->binlog->affinity = AFFINITY_MASTER; } else if (g_ascii_strcasecmp ($3, "slave") == 0) { cur_statfile->binlog->affinity = AFFINITY_SLAVE; } else { cur_statfile->binlog->affinity = AFFINITY_NONE; } } ; statfilebinlogrotate: BINLOG_ROTATE EQSIGN QUOTEDSTRING { if (cur_statfile == NULL) { cur_statfile = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile)); } if (cur_statfile->binlog == NULL) { cur_statfile->binlog = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_binlog_params)); } cur_statfile->binlog->rotate_time = parse_seconds ($3); } ; statfilebinlogmaster: BINLOG_MASTER EQSIGN QUOTEDSTRING { if (cur_statfile == NULL) { cur_statfile = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile)); } if (cur_statfile->binlog == NULL) { cur_statfile->binlog = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_binlog_params)); } if (!parse_host_port ($3, &cur_statfile->binlog->master_addr, &cur_statfile->binlog->master_port)) { YYERROR; } } ; statfilenormalizer: NORMALIZER EQSIGN QUOTEDSTRING { if (!parse_normalizer (yacc_cfg, cur_statfile, $3)) { yyerror ("cannot parse normalizer string: %s", $3); YYERROR; } cur_statfile->normalizer_str = memory_pool_strdup (yacc_cfg->cfg_pool, $3); } ; statfile_pool_size: STATFILE_POOL_SIZE EQSIGN SIZELIMIT { yacc_cfg->max_statfile_size = $3; } | STATFILE_POOL_SIZE EQSIGN NUMBER { yacc_cfg->max_statfile_size = $3; } ; luacode: LUACODE ; raw_mode: RAW_MODE EQSIGN FLAG { yacc_cfg->raw_mode = $3; } ; profile_file: PROFILE_FILE EQSIGN QUOTEDSTRING { #ifdef WITH_GPREF_TOOLS yacc_cfg->profile_path = $3; #else yywarn ("yyparse: profile_file directive is ignored as gperf support is not enabled"); #endif } ; view: VIEW OBRACE viewbody EBRACE { if (cur_view == NULL) { yyerror ("yyparse: not enough arguments in view definition"); YYERROR; } yacc_cfg->views = g_list_prepend (yacc_cfg->views, cur_view); cur_view = NULL; } ; viewbody: | viewcmd SEMICOLON | viewbody viewcmd SEMICOLON ; viewcmd: | viewip | viewclientip | viewfrom | viewsymbols | viewskipcheck ; viewip: IP EQSIGN QUOTEDSTRING { if (cur_view == NULL) { cur_view = init_view (yacc_cfg->cfg_pool); } if (!add_view_ip (cur_view, $3)) { yyerror ("yyparse: invalid ip line in view definition: ip = '%s'", $3); YYERROR; } } ; viewclientip: CLIENT_IP EQSIGN QUOTEDSTRING { if (cur_view == NULL) { cur_view = init_view (yacc_cfg->cfg_pool); } if (!add_view_client_ip (cur_view, $3)) { yyerror ("yyparse: invalid ip line in view definition: ip = '%s'", $3); YYERROR; } } ; viewfrom: FROM EQSIGN QUOTEDSTRING { if (cur_view == NULL) { cur_view = init_view (yacc_cfg->cfg_pool); } if (!add_view_from (cur_view, $3)) { yyerror ("yyparse: invalid from line in view definition: from = '%s'", $3); YYERROR; } } ; viewsymbols: SYMBOLS EQSIGN QUOTEDSTRING { if (cur_view == NULL) { cur_view = init_view (yacc_cfg->cfg_pool); } if (!add_view_symbols (cur_view, $3)) { yyerror ("yyparse: invalid symbols line in view definition: symbols = '%s'", $3); YYERROR; } } ; viewskipcheck: SKIP_CHECK EQSIGN FLAG { if (cur_view == NULL) { cur_view = init_view (yacc_cfg->cfg_pool); } cur_view->skip_check = $3; } ; settings: SETTINGS OBRACE settingsbody EBRACE ; settingsbody: | settingscmd SEMICOLON | settingsbody settingscmd SEMICOLON ; settingscmd: | usersettings | domainsettings ; usersettings: USER_SETTINGS EQSIGN QUOTEDSTRING { if (!read_settings ($3, yacc_cfg, yacc_cfg->user_settings)) { yyerror ("yyparse: cannot read settings %s", $3); YYERROR; } yacc_cfg->user_settings_str = memory_pool_strdup (yacc_cfg->cfg_pool, $3); } ; domainsettings: DOMAIN_SETTINGS EQSIGN QUOTEDSTRING { if (!read_settings ($3, yacc_cfg, yacc_cfg->domain_settings)) { yyerror ("yyparse: cannot read settings %s", $3); YYERROR; } yacc_cfg->domain_settings_str = memory_pool_strdup (yacc_cfg->cfg_pool, $3); } ; %% /* * vi:ts=4 */