%PDF- %PDF-
Direktori : /backups/router/usr/local/share/syslog-ng/tools/ |
Current File : //backups/router/usr/local/share/syslog-ng/tools/cfg-grammar.y |
/* * Copyright (c) 2002-2014 Balabit * Copyright (c) 1998-2013 Balázs Scheidler * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * As an additional exemption you are allowed to compile & link against the * OpenSSL libraries as published by the OpenSSL project. See the file * COPYING for details. * */ %code requires { /* this block is inserted into cfg-grammar.h, so it is included practically all of the syslog-ng code. Please add headers here with care. If you need additional headers, please look for a massive list of includes further below. */ /* YYSTYPE and YYLTYPE is defined by the lexer */ #include "cfg-lexer.h" #include "cfg-grammar-internal.h" #include "syslog-names.h" /* uses struct declarations instead of the typedefs to avoid having to * include logreader/logwriter/driver.h, which defines the typedefs. This * is to avoid including unnecessary dependencies into grammars that are not * themselves reader/writer based */ } %define api.prefix {main_} %lex-param {CfgLexer *lexer} %parse-param {CfgLexer *lexer} %parse-param {gpointer *dummy} %parse-param {gpointer arg} /* START_DECLS */ %require "3.7.6" %locations %define api.pure %define api.value.type {CFG_STYPE} %define api.location.type {CFG_LTYPE} %define parse.error verbose %code { #pragma GCC diagnostic ignored "-Wswitch-default" #pragma GCC diagnostic ignored "-Wunused-but-set-variable" #if (defined(__GNUC__) && __GNUC__ >= 6) || (defined(__clang__) && __clang_major__ >= 10) # pragma GCC diagnostic ignored "-Wmisleading-indentation" #endif # define YYLLOC_DEFAULT(Current, Rhs, N) \ do { \ if (N) \ { \ (Current).name = YYRHSLOC(Rhs, 1).name; \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).name = YYRHSLOC(Rhs, 0).name; \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ } while (0) #define CHECK_ERROR_WITHOUT_MESSAGE(val, token) do { \ if (!(val)) \ { \ YYERROR; \ } \ } while (0) #define CHECK_ERROR(val, token, errorfmt, ...) do { \ if (!(val)) \ { \ if (errorfmt) \ { \ gchar __buf[256]; \ g_snprintf(__buf, sizeof(__buf), errorfmt, ## __VA_ARGS__); \ yyerror(& (token), lexer, NULL, NULL, __buf); \ } \ YYERROR; \ } \ } while (0) #define CHECK_ERROR_GERROR(val, token, error, errorfmt, ...) do { \ if (!(val)) \ { \ if (errorfmt) \ { \ gchar __buf[256]; \ g_snprintf(__buf, sizeof(__buf), errorfmt ", error=%s", ## __VA_ARGS__, error->message); \ yyerror(& (token), lexer, NULL, NULL, __buf); \ } \ g_clear_error(&error); \ YYERROR; \ } \ } while (0) #define YYMAXDEPTH 20000 } /* plugin types, must be equal to the numerical values of the plugin type in plugin.h */ %token LL_CONTEXT_ROOT 1 %token LL_CONTEXT_DESTINATION 2 %token LL_CONTEXT_SOURCE 3 %token LL_CONTEXT_PARSER 4 %token LL_CONTEXT_REWRITE 5 %token LL_CONTEXT_FILTER 6 %token LL_CONTEXT_LOG 7 %token LL_CONTEXT_BLOCK_DEF 8 %token LL_CONTEXT_BLOCK_REF 9 %token LL_CONTEXT_BLOCK_CONTENT 10 %token LL_CONTEXT_BLOCK_ARG 11 %token LL_CONTEXT_BLOCK_FUNCARG 12 %token LL_CONTEXT_PRAGMA 13 %token LL_CONTEXT_FORMAT 14 %token LL_CONTEXT_TEMPLATE_FUNC 15 %token LL_CONTEXT_INNER_DEST 16 %token LL_CONTEXT_INNER_SRC 17 %token LL_CONTEXT_CLIENT_PROTO 18 %token LL_CONTEXT_SERVER_PROTO 19 %token LL_CONTEXT_OPTIONS 20 %token LL_CONTEXT_CONFIG 21 %token LL_CONTEXT_TEMPLATE_REF 22 %token LL_CONTEXT_FILTERX 23 %token LL_CONTEXT_FILTERX_SIMPLE_FUNC 24 %token LL_CONTEXT_FILTERX_ENUM 25 %token LL_CONTEXT_FILTERX_FUNC 26 /* this is a placeholder for unit tests, must be the latest & largest */ %token LL_CONTEXT_MAX 27 %left ';' /* operators in the filter language, the order of this determines precedence */ %right KW_ASSIGN 9000 %right '?' ':' %left KW_OR 9010 %left KW_AND 9020 %left KW_STR_EQ 9030 KW_STR_NE 9031, KW_TA_EQ 9032, KW_TA_NE 9033, KW_TAV_EQ 9034, KW_TAV_NE 9035 %left KW_STR_LT 9040, KW_STR_LE 9041, KW_STR_GE, 9042 KW_STR_GT, 9043, KW_TA_LT 9044, KW_TA_LE 9045, KW_TA_GE 9046, KW_TA_GT 9047 %right KW_PLUS_ASSIGN 9050 %left KW_REGEXP_MATCH 9060 %left '+' '-' %left '*' %left '.' '[' ']' KW_NOT 9049 /* statements */ %token KW_SOURCE 10000 %token KW_FILTER 10001 %token KW_PARSER 10002 %token KW_DESTINATION 10003 %token KW_LOG 10004 %token KW_OPTIONS 10005 %token KW_INCLUDE 10006 %token KW_BLOCK 10007 %token KW_JUNCTION 10008 %token KW_CHANNEL 10009 %token KW_IF 10010 %token KW_ELSE 10011 %token KW_ELIF 10012 %token KW_FILTERX 10013 /* source & destination items */ %token KW_INTERNAL 10020 %token KW_SYSLOG 10060 /* option items */ %token KW_MARK_FREQ 10071 %token KW_STATS_FREQ 10072 %token KW_STATS_LEVEL 10073 %token KW_STATS_LIFETIME 10074 %token KW_FLUSH_LINES 10075 %token KW_SUPPRESS 10076 %token KW_FLUSH_TIMEOUT 10077 %token KW_LOG_MSG_SIZE 10078 %token KW_FILE_TEMPLATE 10079 %token KW_PROTO_TEMPLATE 10080 %token KW_MARK_MODE 10081 %token KW_ENCODING 10082 %token KW_TYPE 10083 %token KW_STATS_MAX_DYNAMIC 10084 %token KW_MIN_IW_SIZE_PER_READER 10085 %token KW_WORKERS 10086 %token KW_BATCH_LINES 10087 %token KW_BATCH_TIMEOUT 10088 %token KW_TRIM_LARGE_MESSAGES 10089 %token KW_STATS 10400 %token KW_FREQ 10401 %token KW_LEVEL 10402 %token KW_LIFETIME 10403 %token KW_MAX_DYNAMIC 10404 %token KW_SYSLOG_STATS 10405 %token KW_HEALTHCHECK_FREQ 10406 %token KW_WORKER_PARTITION_KEY 10407 %token KW_CHAIN_HOSTNAMES 10090 %token KW_NORMALIZE_HOSTNAMES 10091 %token KW_KEEP_HOSTNAME 10092 %token KW_CHECK_HOSTNAME 10093 %token KW_BAD_HOSTNAME 10094 %token KW_LOG_LEVEL 10095 %token KW_KEEP_TIMESTAMP 10100 %token KW_USE_DNS 10110 %token KW_USE_FQDN 10111 %token KW_CUSTOM_DOMAIN 10112 %token KW_DNS_CACHE 10120 %token KW_DNS_CACHE_SIZE 10121 %token KW_DNS_CACHE_EXPIRE 10130 %token KW_DNS_CACHE_EXPIRE_FAILED 10131 %token KW_DNS_CACHE_HOSTS 10132 %token KW_PERSIST_ONLY 10140 %token KW_USE_RCPTID 10141 %token KW_USE_UNIQID 10142 %token KW_TZ_CONVERT 10150 %token KW_TS_FORMAT 10151 %token KW_FRAC_DIGITS 10152 %token KW_LOG_FIFO_SIZE 10160 %token KW_LOG_FETCH_LIMIT 10162 %token KW_LOG_IW_SIZE 10163 %token KW_LOG_PREFIX 10164 %token KW_PROGRAM_OVERRIDE 10165 %token KW_HOST_OVERRIDE 10166 %token KW_THROTTLE 10170 %token KW_THREADED 10171 %token KW_PASS_UNIX_CREDENTIALS 10180 %token KW_PERSIST_NAME 10181 %token KW_READ_OLD_RECORDS 10182 %token KW_USE_SYSLOGNG_PID 10183 /* log statement options */ %token KW_FLAGS 10190 /* reader options */ %token KW_PAD_SIZE 10200 %token KW_TIME_ZONE 10201 %token KW_RECV_TIME_ZONE 10202 %token KW_SEND_TIME_ZONE 10203 %token KW_LOCAL_TIME_ZONE 10204 %token KW_FORMAT 10205 /* multi-line options */ %token KW_MULTI_LINE_MODE 10206 %token KW_MULTI_LINE_PREFIX 10207 %token KW_MULTI_LINE_GARBAGE 10208 /* destination writer options */ %token KW_TRUNCATE_SIZE 10209 /* timers */ %token KW_TIME_REOPEN 10210 %token KW_TIME_REAP 10211 %token KW_TIME_SLEEP 10212 %token KW_PARTITIONS 10213 %token KW_PARTITION_KEY 10214 %token KW_PARALLELIZE 10215 /* destination options */ %token KW_TMPL_ESCAPE 10220 /* driver specific options */ %token KW_OPTIONAL 10230 /* file related options */ %token KW_CREATE_DIRS 10240 %token KW_OWNER 10250 %token KW_GROUP 10251 %token KW_PERM 10252 %token KW_DIR_OWNER 10260 %token KW_DIR_GROUP 10261 %token KW_DIR_PERM 10262 %token KW_TEMPLATE 10270 %token KW_TEMPLATE_ESCAPE 10271 %token KW_TEMPLATE_FUNCTION 10272 %token KW_DEFAULT_FACILITY 10300 %token KW_DEFAULT_SEVERITY 10301 %token KW_SDATA_PREFIX 10302 %token KW_PORT 10323 /* misc options */ %token KW_USE_TIME_RECVD 10340 /* filter items*/ %token KW_FACILITY 10350 %token KW_SEVERITY 10351 %token KW_HOST 10352 %token KW_MATCH 10353 %token KW_MESSAGE 10354 %token KW_NETMASK 10355 %token KW_TAGS 10356 %token KW_NETMASK6 10357 /* parser items */ /* rewrite items */ %token KW_REWRITE 10370 %token KW_CONDITION 10371 %token KW_VALUE 10372 /* yes/no switches */ %token KW_YES 10380 %token KW_NO 10381 %token KW_AUTO 10382 %token KW_IFDEF 10410 %token KW_ENDIF 10411 %token LL_DOTDOT 10420 %token LL_DOTDOTDOT 10421 %token LL_PRAGMA 10422 %token LL_EOL 10423 %token LL_ERROR 10424 %token LL_ARROW 10425 %token <cptr> LL_IDENTIFIER 10430 %token <num> LL_NUMBER 10431 %token <fnum> LL_FLOAT 10432 %token <cptr> LL_STRING 10433 %token <token> LL_TOKEN 10434 %token <cptr> LL_BLOCK 10435 %token <cptr> LL_PLUGIN 10436 %token <cptr> LL_TEMPLATE_REF 10437 %token <cptr> LL_MESSAGE_REF 10438 %destructor { free($$); } <cptr> /* value pairs */ %token KW_VALUE_PAIRS 10500 %token KW_EXCLUDE 10502 %token KW_PAIR 10503 %token KW_KEY 10504 %token KW_SCOPE 10505 %token KW_SHIFT 10506 %token KW_SHIFT_LEVELS 10507 %token KW_REKEY 10508 %token KW_ADD_PREFIX 10509 %token KW_REPLACE_PREFIX 10510 %token KW_CAST 10511 %token KW_UPPER 10512 %token KW_LOWER 10513 %token KW_INCLUDE_BYTES 10514 %token KW_ON_ERROR 10520 %token KW_RETRIES 10521 %token KW_FETCH_NO_DATA_DELAY 10522 /* metrics template */ %token KW_LABELS 10530 /* END_DECLS */ %type <ptr> expr_stmt %type <ptr> source_stmt %type <ptr> dest_stmt %type <ptr> filter_stmt %type <ptr> parser_stmt %type <ptr> rewrite_stmt %type <ptr> log_stmt %type <ptr> plugin_stmt /* START_DECLS */ %type <ptr> source_content %type <ptr> source_items %type <ptr> source_item %type <ptr> source_afinter %type <ptr> source_plugin %type <ptr> source_afinter_params %type <ptr> dest_content %type <ptr> dest_items %type <ptr> dest_item %type <ptr> dest_plugin %type <ptr> template_content %type <ptr> template_content_list %type <ptr> template_name_or_content %type <ptr> template_name_or_content_tail %type <num> type_hint %type <ptr> filter_content %type <ptr> filterx_content %type <ptr> parser_content %type <ptr> rewrite_content %type <ptr> log_items %type <ptr> log_item %type <ptr> log_last_junction %type <ptr> log_scheduler %type <ptr> log_junction %type <ptr> log_content %type <ptr> log_conditional %type <ptr> log_if %type <ptr> log_forks %type <ptr> log_fork %type <num> log_flags %type <num> log_flags_items %type <ptr> value_pair_option %type <num> yesno_strict %type <num> yesno %type <num> yesnoauto %type <num> dnsmode %type <num> dest_writer_options_flags %type <cptr> string %type <cptr> string_or_number %type <cptr> optional_string %type <cptr> normalized_flag %type <ptr> string_list %type <ptr> string_list_build %type <num> facility_string %type <num> severity_string %type <num> positive_integer %type <num> positive_integer64 %type <num> nonnegative_integer %type <num> nonnegative_integer64 %type <fnum> positive_float %type <fnum> nonnegative_float %type <cptr> path_no_check %type <cptr> path_secret %type <cptr> path_check %type <cptr> path /* END_DECLS */ %type <ptr> template_def %type <ptr> template_block %type <ptr> template_simple %type <ptr> template_fn %% start : stmts ; stmts : stmt semicolons stmts | ; stmt : expr_stmt { CHECK_ERROR(cfg_tree_add_object(&configuration->tree, $1) || cfg_allow_config_dups(configuration), @1, "duplicate %s definition", log_expr_node_get_content_name(((LogExprNode *) $1)->content)); } | template_stmt | options_stmt | block_stmt | plugin_stmt ; expr_stmt : source_stmt | dest_stmt | filter_stmt | parser_stmt | rewrite_stmt | log_stmt ; source_stmt : KW_SOURCE string '{' source_content '}' { $$ = log_expr_node_new_source($2, $4, &@1); free($2); } ; dest_stmt : KW_DESTINATION string '{' dest_content '}' { $$ = log_expr_node_new_destination($2, $4, &@1); free($2); } ; filter_stmt : KW_FILTER string '{' filter_content '}' { /* NOTE: the filter() subexpression (e.g. the one that invokes * one filter expression from another) depends on the layout * parsed into the cfg-tree when looking up the referenced * filter expression. So when changing how a filter statement * is transformed into the cfg-tree, make sure you check * filter-call.c, especially filter_call_init() function as * well. */ $$ = log_expr_node_new_filter($2, $4, &@1); free($2); } ; parser_stmt : KW_PARSER string '{' parser_content '}' { $$ = log_expr_node_new_parser($2, $4, &@1); free($2); } ; rewrite_stmt : KW_REWRITE string '{' rewrite_content '}' { $$ = log_expr_node_new_rewrite($2, $4, &@1); free($2); } log_stmt : KW_LOG optional_string _log_context_push '{' log_content '}' _log_context_pop { if ($2) { log_expr_node_set_name($5, $2); free($2); } $$ = $5; } ; plugin_stmt : LL_PLUGIN { Plugin *p; gint context = LL_CONTEXT_ROOT; gpointer result; p = cfg_find_plugin(configuration, context, $1); CHECK_ERROR(p, @1, "%s plugin %s not found", cfg_lexer_lookup_context_name_by_type(context), $1); result = cfg_parse_plugin(configuration, p, &@1, NULL); free($1); if (!result) YYERROR; $$ = NULL; } /* START_RULES */ source_content : _source_context_push source_items _source_context_pop { $$ = log_expr_node_new_source_junction($2, &@$); } ; source_items : source_item semicolons source_items { $$ = log_expr_node_append_tail(log_expr_node_new_pipe($1, &@1), $3); } | log_fork semicolons source_items { $$ = log_expr_node_append_tail($1, $3); } | { $$ = NULL; } ; source_item : source_afinter { $$ = $1; } | source_plugin { $$ = $1; } ; source_plugin : LL_PLUGIN { Plugin *p; gint context = LL_CONTEXT_SOURCE; p = cfg_find_plugin(configuration, context, $1); CHECK_ERROR(p, @1, "%s plugin %s not found", cfg_lexer_lookup_context_name_by_type(context), $1); last_driver = (LogDriver *) cfg_parse_plugin(configuration, p, &@1, NULL); free($1); if (!last_driver) { YYERROR; } $$ = last_driver; } ; source_afinter : KW_INTERNAL '(' source_afinter_params ')' { $$ = $3; } ; source_afinter_params : { last_driver = afinter_sd_new(configuration); last_source_options = &((AFInterSourceDriver *) last_driver)->source_options.super; } source_afinter_options { $$ = last_driver; } ; source_afinter_options : source_afinter_option source_afinter_options | ; source_afinter_option : KW_LOG_FIFO_SIZE '(' positive_integer ')' { ((AFInterSourceOptions *) last_source_options)->queue_capacity = $3; } | source_option ; filter_content : { FilterExprNode *filter_expr = NULL; CHECK_ERROR_WITHOUT_MESSAGE(cfg_parser_parse(&filter_expr_parser, lexer, (gpointer *) &filter_expr, NULL), @$); $$ = log_expr_node_new_pipe(log_filter_pipe_new(filter_expr, configuration), &@$); } ; filterx_content : _filterx_context_push <ptr>{ GList *filterx_stmts = NULL; CHECK_ERROR_WITHOUT_MESSAGE(cfg_parser_parse(&filterx_parser, lexer, (gpointer *) &filterx_stmts, NULL), @$); $$ = log_expr_node_new_pipe(log_filterx_pipe_new(filterx_stmts, configuration), &@$); } _filterx_context_pop { $$ = $2; } ; parser_content : { LogExprNode *last_parser_expr = NULL; CHECK_ERROR_WITHOUT_MESSAGE(cfg_parser_parse(&parser_expr_parser, lexer, (gpointer *) &last_parser_expr, NULL), @$); $$ = last_parser_expr; } ; rewrite_content : { LogExprNode *last_rewrite_expr = NULL; CHECK_ERROR_WITHOUT_MESSAGE(cfg_parser_parse(&rewrite_expr_parser, lexer, (gpointer *) &last_rewrite_expr, NULL), @$); $$ = last_rewrite_expr; } ; dest_content : _destination_context_push dest_items _destination_context_pop { $$ = log_expr_node_new_destination_junction($2, &@$); } ; dest_items /* all destination drivers are added as an independent branch in a junction*/ : dest_item semicolons dest_items { $$ = log_expr_node_append_tail(log_expr_node_new_pipe($1, &@1), $3); } | log_fork semicolons dest_items { $$ = log_expr_node_append_tail($1, $3); } | { $$ = NULL; } ; dest_item : dest_plugin { $$ = $1; } ; dest_plugin : LL_PLUGIN { Plugin *p; gint context = LL_CONTEXT_DESTINATION; p = cfg_find_plugin(configuration, context, $1); CHECK_ERROR(p, @1, "%s plugin %s not found", cfg_lexer_lookup_context_name_by_type(context), $1); last_driver = (LogDriver *) cfg_parse_plugin(configuration, p, &@1, NULL); free($1); if (!last_driver) { YYERROR; } $$ = last_driver; } ; log_items : log_item semicolons log_items { log_expr_node_append_tail($1, $3); $$ = $1; } | { $$ = NULL; } ; log_item : KW_SOURCE '(' string ')' { $$ = log_expr_node_new_source_reference($3, &@$); free($3); } | KW_SOURCE '{' source_content '}' { $$ = log_expr_node_new_source(NULL, $3, &@$); } | KW_FILTER '(' string ')' { $$ = log_expr_node_new_filter_reference($3, &@$); free($3); } | KW_FILTER '{' filter_content '}' { $$ = log_expr_node_new_filter(NULL, $3, &@$); } | KW_FILTERX '{' filterx_content '}' { $$ = log_expr_node_new_filter(NULL, $3, &@$); } | KW_PARSER '(' string ')' { $$ = log_expr_node_new_parser_reference($3, &@$); free($3); } | KW_PARSER '{' parser_content '}' { $$ = log_expr_node_new_parser(NULL, $3, &@$); } | KW_REWRITE '(' string ')' { $$ = log_expr_node_new_rewrite_reference($3, &@$); free($3); } | KW_REWRITE '{' rewrite_content '}' { $$ = log_expr_node_new_rewrite(NULL, $3, &@$); } | KW_DESTINATION '(' string ')' { $$ = log_expr_node_new_destination_reference($3, &@$); free($3); } | KW_DESTINATION '{' dest_content '}' { $$ = log_expr_node_new_destination(NULL, $3, &@$); } | log_scheduler { $$ = $1; } | log_conditional { $$ = $1; } | log_junction { $$ = $1; } ; log_scheduler : KW_PARALLELIZE '(' { LogPipe *scheduler_pipe = log_scheduler_pipe_new(configuration); last_scheduler_options = log_scheduler_pipe_get_scheduler_options(scheduler_pipe); $<ptr>$ = scheduler_pipe; } log_scheduler_options ')' { $$ = log_expr_node_new_pipe($<ptr>3, &@$); } ; log_scheduler_options : log_scheduler_option log_scheduler_options | ; log_scheduler_option : KW_PARTITIONS '(' nonnegative_integer ')' { last_scheduler_options->num_partitions = $3; } | KW_PARTITION_KEY '(' template_content ')' { log_scheduler_options_set_partition_key_ref(last_scheduler_options, $3); } ; log_junction : KW_JUNCTION '{' log_forks '}' { $$ = log_expr_node_new_junction($3, &@$); } ; log_last_junction /* this rule matches the last set of embedded log {} * statements at the end of the log {} block. * It is the final junction and was the only form of creating * a processing tree before syslog-ng 3.4. * * We emulate if the user was writing junction {} explicitly. */ : log_forks { $$ = $1 ? log_expr_node_new_junction($1, &@1) : NULL; } ; log_forks : log_fork semicolons log_forks { log_expr_node_append_tail($1, $3); $$ = $1; } | { $$ = NULL; } ; log_fork : KW_LOG optional_string '{' _log_context_push log_content _log_context_pop '}' { if ($2) { log_expr_node_set_name($5, $2); free($2); } $$ = $5; } | KW_CHANNEL optional_string '{' _log_context_push log_content _log_context_pop '}' { if ($2) { log_expr_node_set_name($5, $2); free($2); } $$ = $5; } ; log_conditional : log_if { $$ = $1; } | log_if KW_ELSE '{' log_content '}' { log_expr_node_conditional_set_false_branch_of_the_last_if($1, $4); $$ = $1; } ; log_if : KW_IF '(' filter_content ')' '{' log_content '}' { $$ = log_expr_node_new_simple_conditional($3, $6, &@$); } | KW_IF '{' log_content '}' { $$ = log_expr_node_new_compound_conditional($3, &@$); } | log_if KW_ELIF '(' filter_content ')' '{' log_content '}' { LogExprNode *false_branch; false_branch = log_expr_node_new_simple_conditional($4, $7, &@$); log_expr_node_conditional_set_false_branch_of_the_last_if($1, false_branch); $$ = $1; } | log_if KW_ELIF '{' log_content '}' { LogExprNode *false_branch; false_branch = log_expr_node_new_compound_conditional($4, &@$); log_expr_node_conditional_set_false_branch_of_the_last_if($1, false_branch); $$ = $1; } ; log_content : log_items log_last_junction log_flags { $$ = log_expr_node_new_log(log_expr_node_append_tail($1, $2), $3, &@$); } ; log_flags : KW_FLAGS '(' log_flags_items ')' semicolons { $$ = $3; } | { $$ = 0; } ; log_flags_items : normalized_flag log_flags_items { $$ = log_expr_node_lookup_flag($1) | $2; free($1); } | { $$ = 0; } ; /* END_RULES */ options_stmt : KW_OPTIONS _options_context_push '{' options_items '}' _options_context_pop ; template_stmt : template_def { CHECK_ERROR(cfg_tree_add_template(&configuration->tree, $1) || cfg_allow_config_dups(configuration), @1, "duplicate template"); } | template_fn { LogTemplate *template = $1; user_template_function_register(configuration, template->name, template); log_template_unref(template); } ; template_def : template_block | template_simple ; template_block : KW_TEMPLATE string <ptr>{ $$ = log_template_new(configuration, $2); } '{' { $<ptr>$ = $3; } template_items '}' { $$ = $3; free($2); } ; template_simple : KW_TEMPLATE string <ptr>{ $$ = log_template_new(configuration, $2); } template_content_inner { $$ = $3; free($2); } ; template_fn : KW_TEMPLATE_FUNCTION string <ptr>{ $$ = log_template_new(configuration, $2); } template_content_inner { $$ = $3; free($2); } ; template_items : { $<ptr>$ = $<ptr>0; } template_item semicolons { $<ptr>$ = $<ptr>0; } template_items | ; template_item : KW_TEMPLATE '(' { $<ptr>$ = $<ptr>0; } template_content_inner ')' | KW_TEMPLATE_ESCAPE '(' yesno ')' { log_template_set_escape($<ptr>0, $3); } ; /* START_RULES */ /* $0 must be the <ptr> for the LogTemplate to be populated */ template_content_inner : string { GError *error = NULL; CHECK_ERROR_GERROR(log_template_compile($<ptr>0, $1, &error), @1, error, "Error compiling template"); free($1); } | type_hint '(' string_or_number ')' { GError *error = NULL; CHECK_ERROR_GERROR(log_template_compile($<ptr>0, $3, &error), @3, error, "Error compiling template"); free($3); log_template_set_type_hint_value($<ptr>0, $1); } | LL_NUMBER { gchar decimal[32]; g_snprintf(decimal, sizeof(decimal), "%" G_GINT64_FORMAT, $1); log_template_compile_literal_string($<ptr>0, decimal); log_template_set_type_hint($<ptr>0, "int64", NULL); } | LL_FLOAT { log_template_compile_literal_string($<ptr>0, lexer->token_text->str); log_template_set_type_hint($<ptr>0, "float", NULL); } ; type_hint : LL_IDENTIFIER { LogMessageValueType type; GError *error = NULL; CHECK_ERROR_GERROR(type_hint_parse($1, &type, &error), @1, error, "Unknown type hint"); free($1); $$ = type; }; template_content : <ptr>{ $$ = log_template_new(configuration, NULL); } template_content_inner { $$ = $1; } ; template_content_list : template_content template_content_list { $$ = g_list_prepend($2, $1); } | { $$ = NULL; } ; template_name_or_content : _template_ref_context_push template_name_or_content_tail { $$ = $2; }; ; template_name_or_content_tail : LL_TEMPLATE_REF { $$ = cfg_tree_lookup_template(&configuration->tree, $1); free($1); } | template_content { $$ = $1; }; ; /* END_RULES */ block_stmt : KW_BLOCK _block_def_context_push LL_IDENTIFIER LL_IDENTIFIER '(' { last_block_args = cfg_args_new(); } block_definition ')' _block_content_context_push LL_BLOCK _block_content_context_pop _block_def_context_pop { CfgBlockGenerator *block; gint context_type = cfg_lexer_lookup_context_type_by_name($3); CHECK_ERROR(context_type, @3, "unknown context \"%s\"", $3); block = cfg_block_new(context_type, $4, $10, last_block_args, &@10); cfg_lexer_register_generator_plugin(&configuration->plugin_context, block); free($3); free($4); free($10); last_block_args = NULL; } ; block_definition : block_args | block_args LL_DOTDOTDOT { cfg_args_accept_varargs(last_block_args); } ; block_args : block_arg block_args | ; block_arg : LL_IDENTIFIER _block_arg_context_push LL_BLOCK _block_arg_context_pop { cfg_args_set(last_block_args, $1, $3); free($1); free($3); } ; options_items : options_item semicolons options_items | ; options_item : KW_MARK_FREQ '(' nonnegative_integer ')' { configuration->mark_freq = $3; } | KW_FLUSH_LINES '(' nonnegative_integer ')' { configuration->flush_lines = $3; } | KW_MARK_MODE '(' KW_INTERNAL ')' { cfg_set_mark_mode(configuration, "internal"); } | KW_MARK_MODE '(' string ')' { CHECK_ERROR(cfg_lookup_mark_mode($3) > 0 && cfg_lookup_mark_mode($3) != MM_GLOBAL, @3, "illegal global mark-mode \"%s\"", $3); cfg_set_mark_mode(configuration, $3); free($3); } | KW_FLUSH_TIMEOUT '(' positive_integer ')' { } | KW_CHAIN_HOSTNAMES '(' yesno ')' { configuration->chain_hostnames = $3; } | KW_KEEP_HOSTNAME '(' yesno ')' { configuration->keep_hostname = $3; } | KW_CHECK_HOSTNAME '(' yesno ')' { configuration->check_hostname = $3; } | KW_BAD_HOSTNAME '(' string ')' { cfg_bad_hostname_set(configuration, $3); free($3); } | KW_TIME_REOPEN '(' positive_integer ')' { configuration->time_reopen = $3; } | KW_TIME_REAP '(' nonnegative_integer ')' { configuration->time_reap = $3; } | KW_TIME_SLEEP '(' nonnegative_integer ')' {} | KW_SUPPRESS '(' nonnegative_integer ')' { configuration->suppress = $3; } | KW_THREADED '(' yesno ')' { configuration->threaded = $3; } | KW_PASS_UNIX_CREDENTIALS '(' yesno ')' { configuration->pass_unix_credentials = $3; } | KW_USE_RCPTID '(' yesno ')' { cfg_set_use_uniqid($3); } | KW_USE_UNIQID '(' yesno ')' { cfg_set_use_uniqid($3); } | KW_LOG_FIFO_SIZE '(' positive_integer ')' { configuration->log_fifo_size = $3; } | KW_LOG_IW_SIZE '(' positive_integer ')' { msg_warning("WARNING: Support for the global log-iw-size() option was removed, please use a per-source log-iw-size()", cfg_lexer_format_location_tag(lexer, &@1)); } | KW_LOG_FETCH_LIMIT '(' positive_integer ')' { msg_warning("WARNING: Support for the global log-fetch-limit() option was removed, please use a per-source log-fetch-limit()", cfg_lexer_format_location_tag(lexer, &@1)); } | KW_LOG_MSG_SIZE '(' positive_integer ')' { configuration->log_msg_size = $3; } | KW_TRIM_LARGE_MESSAGES '(' yesno ')' { configuration->trim_large_messages = $3; } | KW_KEEP_TIMESTAMP '(' yesno ')' { configuration->keep_timestamp = $3; } | KW_CREATE_DIRS '(' yesno ')' { configuration->create_dirs = $3; } | KW_CUSTOM_DOMAIN '(' string ')' { configuration->custom_domain = g_strdup($3); free($3); } | KW_FILE_TEMPLATE '(' string ')' { configuration->file_template_name = g_strdup($3); free($3); } | KW_PROTO_TEMPLATE '(' string ')' { configuration->proto_template_name = g_strdup($3); free($3); } | KW_RECV_TIME_ZONE '(' string ')' { configuration->recv_time_zone = g_strdup($3); free($3); } | KW_MIN_IW_SIZE_PER_READER '(' positive_integer ')' { configuration->min_iw_size_per_reader = $3; } | KW_LOG_LEVEL '(' string ')' { CHECK_ERROR(cfg_set_log_level(configuration, $3), @3, "Unknown log-level() option"); free($3); } | { last_template_options = &configuration->template_options; } template_option | { last_host_resolve_options = &configuration->host_resolve_options; } host_resolve_option | { last_stats_options = &configuration->stats_options; last_healthcheck_options = &configuration->healthcheck_options; } stat_option | { last_dns_cache_options = &configuration->dns_cache_options; } dns_cache_option | { last_file_perm_options = &configuration->file_perm_options; } file_perm_option | LL_PLUGIN { Plugin *p; gint context = LL_CONTEXT_OPTIONS; p = cfg_find_plugin(configuration, context, $1); CHECK_ERROR(p, @1, "%s plugin %s not found", cfg_lexer_lookup_context_name_by_type(context), $1); cfg_parse_plugin(configuration, p, &@1, NULL); free($1); } ; stat_option : KW_STATS_FREQ '(' nonnegative_integer ')' { last_stats_options->log_freq = $3; } | KW_STATS_LEVEL '(' nonnegative_integer ')' { last_stats_options->level = $3; } | KW_STATS_LIFETIME '(' positive_integer ')' { last_stats_options->lifetime = $3; } | KW_STATS_MAX_DYNAMIC '(' nonnegative_integer ')' { last_stats_options->max_dynamic = $3; } | KW_STATS '(' stats_group_options ')' ; stats_group_options : stats_group_option stats_group_options | ; stats_group_option : KW_FREQ '(' nonnegative_integer ')' { last_stats_options->log_freq = $3; } | KW_LEVEL '(' nonnegative_integer ')' { last_stats_options->level = $3; } | KW_LIFETIME '(' positive_integer ')' { last_stats_options->lifetime = $3; } | KW_MAX_DYNAMIC '(' nonnegative_integer ')' { last_stats_options->max_dynamic = $3; } | KW_SYSLOG_STATS '(' yesnoauto ')' { last_stats_options->syslog_stats = $3; } | KW_HEALTHCHECK_FREQ '(' nonnegative_integer ')' { last_healthcheck_options->freq = $3; } ; dns_cache_option : KW_DNS_CACHE_SIZE '(' positive_integer ')' { last_dns_cache_options->cache_size = $3; } | KW_DNS_CACHE_EXPIRE '(' positive_integer ')' { last_dns_cache_options->expire = $3; } | KW_DNS_CACHE_EXPIRE_FAILED '(' positive_integer ')' { last_dns_cache_options->expire_failed = $3; } | KW_DNS_CACHE_HOSTS '(' string ')' { last_dns_cache_options->hosts = g_strdup($3); free($3); } ; /* START_RULES */ string : LL_IDENTIFIER | LL_STRING ; yesno_strict : KW_YES { $$ = 1; } | KW_NO { $$ = 0; } ; yesno : yesno_strict | LL_NUMBER { $$ = $1; } ; yesnoauto : KW_YES { $$ = CYNA_YES; } | KW_NO { $$ = CYNA_NO; } | KW_AUTO { $$ = CYNA_AUTO; } ; dnsmode : yesno { $$ = $1; } | KW_PERSIST_ONLY { $$ = 2; } ; nonnegative_integer64 : LL_NUMBER { CHECK_ERROR(($1 >= 0), @1, "It cannot be negative"); } ; nonnegative_integer : nonnegative_integer64 { CHECK_ERROR(($1 <= G_MAXINT32), @1, "Must be smaller than 2^31"); } ; positive_integer64 : LL_NUMBER { CHECK_ERROR(($1 > 0), @1, "Must be positive"); } ; positive_integer : positive_integer64 { CHECK_ERROR(($1 <= G_MAXINT32), @1, "Must be smaller than 2^31"); } ; nonnegative_float : LL_FLOAT { CHECK_ERROR(($1 >= 0), @1, "It cannot be negative"); } | nonnegative_integer { $$ = (double) $1; } ; positive_float : LL_FLOAT { CHECK_ERROR(($1 > 0), @1, "Must be positive"); } | positive_integer { $$ = (double) $1; } ; string_or_number : string { $$ = $1; } | LL_NUMBER { $$ = strdup(lexer->token_text->str); } | LL_FLOAT { $$ = strdup(lexer->token_text->str); } ; optional_string : string { $$ = $1; } | { $$ = NULL; } ; path : string { struct stat buffer; int ret = stat($1, &buffer); CHECK_ERROR((ret == 0), @1, "File \"%s\" not found: %s", $1, strerror(errno)); $$ = $1; } ; path_check : path { cfg_path_track_file(configuration, $1, "path_check"); } ; path_secret : path { cfg_path_track_file(configuration, $1, "path_secret"); } ; path_no_check : string { cfg_path_track_file(configuration, $1, "path_no_check"); } ; normalized_flag : string { $$ = normalize_flag($1); free($1); } ; string_list : string_list_build { $$ = $1; } ; string_list_build : string string_list_build { $$ = g_list_prepend($2, g_strdup($1)); free($1); } | { $$ = NULL; } ; semicolons : ';' | ';' semicolons ; severity_string : string { /* return the numeric value of the "level" */ int n = syslog_name_lookup_severity_by_name($1); CHECK_ERROR((n != -1), @1, "Unknown priority level\"%s\"", $1); free($1); $$ = n; } ; facility_string : string { /* return the numeric value of facility */ int n = syslog_name_lookup_facility_by_name($1); CHECK_ERROR((n != -1), @1, "Unknown facility \"%s\"", $1); free($1); $$ = n; } | KW_SYSLOG { $$ = LOG_SYSLOG; } ; parser_opt : KW_TEMPLATE '(' template_name_or_content ')' { log_parser_set_template(last_parser, $3); } | KW_INTERNAL '(' yesno ')' { log_pipe_set_internal(&last_parser->super, $3); } ; driver_option : KW_PERSIST_NAME '(' string ')' { log_pipe_set_persist_name(&last_driver->super, $3); free($3); } | KW_INTERNAL '(' yesno ')' { log_pipe_set_internal(&last_driver->super, $3); } ; inner_source : LL_PLUGIN { Plugin *p; gint context = LL_CONTEXT_INNER_SRC; gpointer value; p = cfg_find_plugin(configuration, context, $1); CHECK_ERROR(p, @1, "%s plugin %s not found", cfg_lexer_lookup_context_name_by_type(context), $1); value = cfg_parse_plugin(configuration, p, &@1, last_driver); free($1); if (!value) { YYERROR; } if (!log_driver_add_plugin(last_driver, (LogDriverPlugin *) value)) { log_driver_plugin_free(value); CHECK_ERROR(TRUE, @1, "Error while registering the plugin %s in this destination", $1); } } ; /* All source drivers should incorporate this rule, implies driver_option */ source_driver_option : inner_source | driver_option ; inner_dest : LL_PLUGIN { Plugin *p; gint context = LL_CONTEXT_INNER_DEST; gpointer value; p = cfg_find_plugin(configuration, context, $1); CHECK_ERROR(p, @1, "%s plugin %s not found", cfg_lexer_lookup_context_name_by_type(context), $1); value = cfg_parse_plugin(configuration, p, &@1, last_driver); free($1); if (!value) { YYERROR; } if (!log_driver_add_plugin(last_driver, (LogDriverPlugin *) value)) { log_driver_plugin_free(value); CHECK_ERROR(TRUE, @1, "Error while registering the plugin %s in this destination", $1); } } ; /* implies driver_option */ dest_driver_option /* NOTE: plugins need to set "last_driver" in order to incorporate this rule in their grammar */ : KW_LOG_FIFO_SIZE '(' positive_integer ')' { ((LogDestDriver *) last_driver)->log_fifo_size = $3; } | KW_THROTTLE '(' nonnegative_integer ')' { ((LogDestDriver *) last_driver)->throttle = $3; } | inner_dest | driver_option ; threaded_dest_driver_batch_option : KW_BATCH_LINES '(' nonnegative_integer ')' { log_threaded_dest_driver_set_batch_lines(last_driver, $3); } | KW_BATCH_TIMEOUT '(' positive_integer ')' { log_threaded_dest_driver_set_batch_timeout(last_driver, $3); } ; threaded_dest_driver_workers_option : KW_WORKERS '(' positive_integer ')' { log_threaded_dest_driver_set_num_workers(last_driver, $3); } | KW_WORKER_PARTITION_KEY '(' template_content ')' { log_threaded_dest_driver_set_worker_partition_key_ref(last_driver, $3); } ; /* implies dest_driver_option */ threaded_dest_driver_general_option : threaded_dest_driver_general_option_noflags | threaded_dest_driver_flags_option ; threaded_dest_driver_general_option_noflags : KW_RETRIES '(' positive_integer ')' { log_threaded_dest_driver_set_max_retries_on_error(last_driver, $3); } | KW_TIME_REOPEN '(' positive_integer ')' { log_threaded_dest_driver_set_time_reopen(last_driver, $3); } | dest_driver_option ; threaded_dest_driver_flags_option : KW_FLAGS '(' threaded_dest_driver_flags ')' ; threaded_dest_driver_flags : string threaded_dest_driver_flags { CHECK_ERROR(log_threaded_dest_driver_process_flag(last_driver, $1), @1, "Unknown flag \"%s\"", $1); free($1); } | ; /* implies source_driver_option and source_option */ threaded_source_driver_option : KW_FORMAT '(' string ')' { log_threaded_source_driver_get_parse_options(last_driver)->format = g_strdup($3); free($3); } | KW_FLAGS '(' threaded_source_driver_option_flags ')' | { last_msg_format_options = log_threaded_source_driver_get_parse_options(last_driver); } msg_format_option | { last_source_options = log_threaded_source_driver_get_source_options(last_driver); } source_option | source_driver_option ; threaded_source_driver_workers_option : KW_WORKERS '(' positive_integer ')' { log_threaded_source_driver_set_num_workers(last_driver, $3); } ; threaded_fetcher_driver_option : KW_FETCH_NO_DATA_DELAY '(' nonnegative_float ')' { log_threaded_fetcher_driver_set_fetch_no_data_delay(last_driver, $3); } | KW_TIME_REOPEN '(' positive_integer ')' { log_threaded_fetcher_driver_set_time_reopen(last_driver, $3); } ; threaded_source_driver_option_flags : string threaded_source_driver_option_flags { CHECK_ERROR(msg_format_options_process_flag(log_threaded_source_driver_get_parse_options(last_driver), $1), @1, "Unknown flag \"%s\"", $1); free($1); } | ; /* LogSource related options */ source_option /* NOTE: plugins need to set "last_source_options" in order to incorporate this rule in their grammar */ : KW_LOG_IW_SIZE '(' positive_integer ')' { last_source_options->init_window_size = $3; } | KW_CHAIN_HOSTNAMES '(' yesno ')' { last_source_options->chain_hostnames = $3; } | KW_KEEP_HOSTNAME '(' yesno ')' { last_source_options->keep_hostname = $3; } | KW_PROGRAM_OVERRIDE '(' string ')' { last_source_options->program_override = g_strdup($3); free($3); } | KW_HOST_OVERRIDE '(' string ')' { last_source_options->host_override = g_strdup($3); free($3); } | KW_LOG_PREFIX '(' string ')' { gchar *p = strrchr($3, ':'); if (p) *p = 0; last_source_options->program_override = g_strdup($3); free($3); } | KW_KEEP_TIMESTAMP '(' yesno ')' { last_source_options->keep_timestamp = $3; } | KW_READ_OLD_RECORDS '(' yesno ')' { last_source_options->read_old_records = $3; } | KW_USE_SYSLOGNG_PID '(' yesno ')' { last_source_options->use_syslogng_pid = $3; } | KW_TAGS '(' string_list ')' { log_source_options_set_tags(last_source_options, $3); } | { last_host_resolve_options = &last_source_options->host_resolve_options; } host_resolve_option ; /* LogReader related options, implies source_option */ source_reader_option /* NOTE: plugins need to set "last_reader_options" in order to incorporate this rule in their grammar */ : KW_CHECK_HOSTNAME '(' yesno ')' { last_reader_options->check_hostname = $3; } | KW_FLAGS '(' source_reader_option_flags ')' | KW_LOG_FETCH_LIMIT '(' positive_integer ')' { last_reader_options->fetch_limit = $3; } | KW_FORMAT '(' string ')' { last_reader_options->parse_options.format = g_strdup($3); free($3); } | { last_source_options = &last_reader_options->super; } source_option | { last_proto_server_options = &last_reader_options->proto_options.super; } source_proto_option | { last_msg_format_options = &last_reader_options->parse_options; } msg_format_option ; source_reader_option_flags : string source_reader_option_flags { CHECK_ERROR(log_reader_options_process_flag(last_reader_options, $1), @1, "Unknown flag \"%s\"", $1); free($1); } | KW_CHECK_HOSTNAME source_reader_option_flags { log_reader_options_process_flag(last_reader_options, "check-hostname"); } | ; /* LogProtoSource related options */ source_proto_option : KW_ENCODING '(' string ')' { CHECK_ERROR(log_proto_server_options_set_encoding(last_proto_server_options, $3), @3, "unknown encoding \"%s\"", $3); free($3); } | KW_LOG_MSG_SIZE '(' positive_integer ')' { last_proto_server_options->max_msg_size = $3; } | KW_TRIM_LARGE_MESSAGES '(' yesno ')' { last_proto_server_options->trim_large_messages = $3; } ; host_resolve_option : KW_USE_FQDN '(' yesno ')' { last_host_resolve_options->use_fqdn = $3; } | KW_USE_DNS '(' dnsmode ')' { last_host_resolve_options->use_dns = $3; } | KW_DNS_CACHE '(' yesno ')' { last_host_resolve_options->use_dns_cache = $3; } | KW_NORMALIZE_HOSTNAMES '(' yesno ')' { last_host_resolve_options->normalize_hostnames = $3; } ; msg_format_option : KW_TIME_ZONE '(' string ')' { last_msg_format_options->recv_time_zone = g_strdup($3); free($3); } | KW_DEFAULT_SEVERITY '(' severity_string ')' { if (last_msg_format_options->default_pri == 0xFFFF) last_msg_format_options->default_pri = LOG_USER; last_msg_format_options->default_pri = (last_msg_format_options->default_pri & ~SYSLOG_PRIMASK) | $3; } | KW_DEFAULT_FACILITY '(' facility_string ')' { if (last_msg_format_options->default_pri == 0xFFFF) last_msg_format_options->default_pri = LOG_NOTICE; last_msg_format_options->default_pri = (last_msg_format_options->default_pri & SYSLOG_PRIMASK) | $3; } | KW_SDATA_PREFIX '(' string ')' { CHECK_ERROR(msg_format_options_set_sdata_prefix(last_msg_format_options, $3), @3, "Prefix is too long \"%s\"", $3); free($3); } ; dest_writer_options : dest_writer_option dest_writer_options | ; /* NOTE: plugins need to set "last_writer_options" in order to incorporate this rule in their grammar */ dest_writer_option : KW_FLAGS '(' dest_writer_options_flags ')' | KW_FLUSH_LINES '(' nonnegative_integer ')' { last_writer_options->flush_lines = $3; } | KW_FLUSH_TIMEOUT '(' positive_integer ')' { } | KW_SUPPRESS '(' nonnegative_integer ')' { last_writer_options->suppress = $3; } | KW_TEMPLATE '(' template_name_or_content ')' { last_writer_options->template = $3; } | KW_PAD_SIZE '(' nonnegative_integer ')' { last_writer_options->padding = $3; } | KW_TRUNCATE_SIZE '(' nonnegative_integer ')' { last_writer_options->truncate_size = $3; } | KW_MARK_FREQ '(' nonnegative_integer ')' { last_writer_options->mark_freq = $3; } | KW_MARK_MODE '(' KW_INTERNAL ')' { log_writer_options_set_mark_mode(last_writer_options, "internal"); } | KW_MARK_MODE '(' string ')' { CHECK_ERROR(cfg_lookup_mark_mode($3) != -1, @3, "illegal mark mode \"%s\"", $3); log_writer_options_set_mark_mode(last_writer_options, $3); free($3); } | KW_TIME_REOPEN '(' positive_integer ')' { last_writer_options->time_reopen = $3; } | { last_template_options = &last_writer_options->template_options; } template_option ; dest_writer_options_flags : string dest_writer_options_flags { CHECK_ERROR(log_writer_options_process_flag(last_writer_options, $1), @1, "Unknown flag \"%s\"", $1); free($1); } | ; file_perm_option : KW_OWNER '(' string_or_number ')' { file_perm_options_set_file_uid(last_file_perm_options, $3); free($3); } | KW_OWNER '(' ')' { file_perm_options_dont_change_file_uid(last_file_perm_options); } | KW_GROUP '(' string_or_number ')' { file_perm_options_set_file_gid(last_file_perm_options, $3); free($3); } | KW_GROUP '(' ')' { file_perm_options_dont_change_file_gid(last_file_perm_options); } | KW_PERM '(' LL_NUMBER ')' { file_perm_options_set_file_perm(last_file_perm_options, $3); } | KW_PERM '(' ')' { file_perm_options_dont_change_file_perm(last_file_perm_options); } | KW_DIR_OWNER '(' string_or_number ')' { file_perm_options_set_dir_uid(last_file_perm_options, $3); free($3); } | KW_DIR_OWNER '(' ')' { file_perm_options_dont_change_dir_uid(last_file_perm_options); } | KW_DIR_GROUP '(' string_or_number ')' { file_perm_options_set_dir_gid(last_file_perm_options, $3); free($3); } | KW_DIR_GROUP '(' ')' { file_perm_options_dont_change_dir_gid(last_file_perm_options); } | KW_DIR_PERM '(' LL_NUMBER ')' { file_perm_options_set_dir_perm(last_file_perm_options, $3); } | KW_DIR_PERM '(' ')' { file_perm_options_dont_change_dir_perm(last_file_perm_options); } ; template_option : KW_TS_FORMAT '(' string ')' { last_template_options->ts_format = cfg_ts_format_value($3); free($3); } | KW_FRAC_DIGITS '(' nonnegative_integer ')' { last_template_options->frac_digits = $3; } | KW_TIME_ZONE '(' string ')' { last_template_options->time_zone[LTZ_SEND] = g_strdup($3); free($3); } | KW_SEND_TIME_ZONE '(' string ')' { last_template_options->time_zone[LTZ_SEND] = g_strdup($3); free($3); } | KW_LOCAL_TIME_ZONE '(' string ')' { last_template_options->time_zone[LTZ_LOCAL] = g_strdup($3); free($3); } | KW_TEMPLATE_ESCAPE '(' yesno ')' { last_template_options->escape = $3; } | KW_ON_ERROR '(' string ')' { gint on_error; CHECK_ERROR(log_template_on_error_parse($3, &on_error), @3, "Invalid on-error() setting \"%s\"", $3); free($3); log_template_options_set_on_error(last_template_options, on_error); } ; matcher_option : KW_TYPE '(' string ')' { CHECK_ERROR(log_matcher_options_set_type(last_matcher_options, $3), @3, "unknown matcher type \"%s\"", $3); free($3); } | KW_FLAGS '(' matcher_flags ')' ; matcher_flags : string matcher_flags { CHECK_ERROR(log_matcher_options_process_flag(last_matcher_options, $1), @1, "unknown matcher flag \"%s\"", $1); free($1); } | ; value_pair_option : KW_VALUE_PAIRS { last_value_pairs = value_pairs_new(configuration); } '(' vp_options ')' { $$ = last_value_pairs; } ; vp_options : vp_option vp_options | ; vp_option : KW_PAIR '(' string ':' template_content ')' { value_pairs_add_pair(last_value_pairs, $3, $5); free($3); } | KW_PAIR '(' string template_content ')' { value_pairs_add_pair(last_value_pairs, $3, $4); free($3); } | KW_KEY '(' string KW_REKEY '(' { last_vp_transset = value_pairs_transform_set_new($3); value_pairs_add_glob_pattern(last_value_pairs, $3, TRUE); free($3); } vp_rekey_options ')' { value_pairs_add_transforms(last_value_pairs, last_vp_transset); } ')' | KW_KEY '(' string_list ')' { value_pairs_add_glob_patterns(last_value_pairs, $3, TRUE); } | KW_REKEY '(' string { last_vp_transset = value_pairs_transform_set_new($3); free($3); } vp_rekey_options ')' { value_pairs_add_transforms(last_value_pairs, last_vp_transset); } | KW_EXCLUDE '(' string_list ')' { value_pairs_add_glob_patterns(last_value_pairs, $3, FALSE); } | KW_SCOPE '(' vp_scope_list ')' | KW_CAST '(' yesno ')' { value_pairs_set_cast_to_strings(last_value_pairs, $3); } | KW_INCLUDE_BYTES '(' yesno ')' { value_pairs_set_include_bytes(last_value_pairs, $3); } ; vp_scope_list : string vp_scope_list { value_pairs_add_scope(last_value_pairs, $1); free($1); } | ; vp_rekey_options : vp_rekey_option vp_rekey_options | ; vp_rekey_option : KW_SHIFT '(' positive_integer ')' { value_pairs_transform_set_add_func(last_vp_transset, value_pairs_new_transform_shift($3)); } | KW_SHIFT_LEVELS '(' positive_integer ')' { value_pairs_transform_set_add_func(last_vp_transset, value_pairs_new_transform_shift_levels($3)); } | KW_ADD_PREFIX '(' string ')' { value_pairs_transform_set_add_func(last_vp_transset, value_pairs_new_transform_add_prefix($3)); free($3); } | KW_REPLACE_PREFIX '(' string string ')' { value_pairs_transform_set_add_func(last_vp_transset, value_pairs_new_transform_replace_prefix($3, $4)); free($3); free($4); } | KW_UPPER '(' ')' { value_pairs_transform_set_add_func(last_vp_transset, value_pairs_new_transform_upper()); } | KW_LOWER '(' ')' { value_pairs_transform_set_add_func(last_vp_transset, value_pairs_new_transform_lower()); } ; dyn_metrics_template_opt : KW_KEY '(' string ')' { dyn_metrics_template_set_key(last_dyn_metrics_template, $3); g_free($3); } | KW_LABELS '(' dyn_metrics_template_labels_opts ')' | KW_LEVEL '(' nonnegative_integer ')' { dyn_metrics_template_set_level(last_dyn_metrics_template, $3); } dyn_metrics_template_labels_opts : dyn_metrics_template_labels_opt dyn_metrics_template_labels_opts | ; dyn_metrics_template_labels_opt : dyn_metrics_template_label_template | { last_value_pairs = dyn_metrics_template_get_value_pairs(last_dyn_metrics_template); } vp_option ; dyn_metrics_template_label_template : string LL_ARROW template_content { dyn_metrics_template_add_label_template(last_dyn_metrics_template, $1, $3); free($1); log_template_unref($3); } ; rewrite_expr_opt : KW_VALUE '(' string ')' { const gchar *p = $3; if (p[0] == '$') { msg_warning("Value references in rewrite rules should not use the '$' prefix, those are only needed in templates", evt_tag_str("value", $3), cfg_lexer_format_location_tag(lexer, &@3)); p++; } last_rewrite->value_handle = log_msg_get_value_handle(p); CHECK_ERROR(!log_msg_is_handle_macro(last_rewrite->value_handle), @3, "%s is read-only, it cannot be changed in rewrite rules", p); CHECK_ERROR(log_msg_is_value_name_valid(p), @3, "%s is not a valid name for a name-value pair, perhaps a misspelled .SDATA reference?", p); free($3); } | KW_INTERNAL '(' yesno ')' { log_pipe_set_internal(&last_rewrite->super, $3); } | rewrite_condition_opt ; rewrite_condition_opt : KW_CONDITION '(' { FilterExprNode *filter_expr; CHECK_ERROR_WITHOUT_MESSAGE(cfg_parser_parse(&filter_expr_parser, lexer, (gpointer *) &filter_expr, NULL), @1); log_rewrite_set_condition(last_rewrite, filter_expr); } ')' ; multi_line_option : KW_MULTI_LINE_MODE '(' string ')' { CHECK_ERROR(multi_line_options_set_mode(last_multi_line_options, $3), @3, "Invalid multi-line mode"); free($3); } | KW_MULTI_LINE_PREFIX '(' string ')' { GError *error = NULL; CHECK_ERROR_GERROR(multi_line_options_set_prefix(last_multi_line_options, $3, &error), @3, error, "error compiling multi-line regexp"); free($3); } | KW_MULTI_LINE_GARBAGE '(' string ')' { GError *error = NULL; CHECK_ERROR_GERROR(multi_line_options_set_garbage(last_multi_line_options, $3, &error), @3, error, "error compiling multi-line regexp"); free($3); } ; _root_context_push: { cfg_lexer_push_context(lexer, LL_CONTEXT_ROOT, NULL, "root context"); }; _root_context_pop: { cfg_lexer_pop_context(lexer); }; _destination_context_push: { cfg_lexer_push_context(lexer, LL_CONTEXT_DESTINATION, NULL, "destination statement"); }; _destination_context_pop: { cfg_lexer_pop_context(lexer); }; _source_context_push: { cfg_lexer_push_context(lexer, LL_CONTEXT_SOURCE, NULL, "source statement"); }; _source_context_pop: { cfg_lexer_pop_context(lexer); }; _parser_context_push: { cfg_lexer_push_context(lexer, LL_CONTEXT_PARSER, NULL, "parser statement"); }; _parser_context_pop: { cfg_lexer_pop_context(lexer); }; _rewrite_context_push: { cfg_lexer_push_context(lexer, LL_CONTEXT_REWRITE, NULL, "rewrite statement"); }; _rewrite_context_pop: { cfg_lexer_pop_context(lexer); }; _filter_context_push: { cfg_lexer_push_context(lexer, LL_CONTEXT_FILTER, NULL, "filter statement"); }; _filter_context_pop: { cfg_lexer_pop_context(lexer); }; _filterx_context_push: { cfg_lexer_push_context(lexer, LL_CONTEXT_FILTERX, NULL, "filterx statement"); }; _filterx_context_pop: { cfg_lexer_pop_context(lexer); }; _log_context_push: { cfg_lexer_push_context(lexer, LL_CONTEXT_LOG, NULL, "log statement"); }; _log_context_pop: { cfg_lexer_pop_context(lexer); }; _block_def_context_push: { cfg_lexer_push_context(lexer, LL_CONTEXT_BLOCK_DEF, block_def_keywords, "block definition"); }; _block_def_context_pop: { cfg_lexer_pop_context(lexer); }; _block_ref_context_push: { cfg_lexer_push_context(lexer, LL_CONTEXT_BLOCK_REF, NULL, "block reference"); }; _block_ref_context_pop: { cfg_lexer_pop_context(lexer); }; _block_content_context_push: { cfg_lexer_push_context(lexer, LL_CONTEXT_BLOCK_CONTENT, NULL, "block content"); }; _block_content_context_pop: { cfg_lexer_pop_context(lexer); }; _block_arg_context_push: { cfg_lexer_push_context(lexer, LL_CONTEXT_BLOCK_ARG, NULL, "block argument"); }; _block_arg_context_pop: { cfg_lexer_pop_context(lexer); }; _block_func_arg_context_push: { cfg_lexer_push_context(lexer, LL_CONTEXT_BLOCK_FUNCARG, NULL, "block argument"); }; _block_func_arg_context_pop: { cfg_lexer_pop_context(lexer); }; _template_ref_context_push: { cfg_lexer_push_context(lexer, LL_CONTEXT_TEMPLATE_REF, NULL, "template reference"); }; _inner_dest_context_push: { cfg_lexer_push_context(lexer, LL_CONTEXT_INNER_DEST, NULL, "within destination"); }; _inner_dest_context_pop: { cfg_lexer_pop_context(lexer); }; _inner_src_context_push: { cfg_lexer_push_context(lexer, LL_CONTEXT_INNER_SRC, NULL, "within source"); }; _inner_src_context_pop: { cfg_lexer_pop_context(lexer); }; _options_context_push: { cfg_lexer_push_context(lexer, LL_CONTEXT_OPTIONS, NULL, "options statement"); }; _options_context_pop: { cfg_lexer_pop_context(lexer); }; /* END_RULES */ %%