PageRenderTime 49ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/syslog-ng-3.2.5/lib/rewrite-expr-grammar.y

#
Happy | 566 lines | 469 code | 97 blank | 0 comment | 0 complexity | 9b923403065155ae02b0cb9d6ff48cb9 MD5 | raw file
  1. /*
  2. * Copyright (c) 2002-2010 BalaBit IT Ltd, Budapest, Hungary
  3. * Copyright (c) 1998-2010 Bal??zs Scheidler
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2.1 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18. *
  19. * As an additional exemption you are allowed to compile & link against the
  20. * OpenSSL libraries as published by the OpenSSL project. See the file
  21. * COPYING for details.
  22. *
  23. */
  24. %code requires {
  25. #include "rewrite-expr-parser.h"
  26. }
  27. %code {
  28. #include "syslog-names.h"
  29. #include "rewrite-expr-grammar.h"
  30. #include "logrewrite.h"
  31. #include "plugin.h"
  32. #include "filter.h"
  33. #include "filter-expr-parser.h"
  34. #include <string.h>
  35. LogRewrite *last_rewrite;
  36. static gboolean
  37. is_sdata_valid(const gchar *buffer)
  38. {
  39. gboolean result = FALSE;
  40. const gchar *dot;
  41. int dot_found = 0;
  42. if (strlen(buffer)>6 && strncmp(buffer,".SDATA.",7)==0)
  43. {
  44. dot = memchr(buffer,'.',strlen(buffer));
  45. while (dot && strlen(dot)>1)
  46. {
  47. dot_found++;
  48. dot++;
  49. dot = memchr(dot, '.',strlen(dot));
  50. }
  51. if (dot_found >= 3)
  52. result = TRUE;
  53. }
  54. return result;
  55. }
  56. }
  57. %name-prefix "rewrite_expr_"
  58. %lex-param {CfgLexer *lexer}
  59. %parse-param {CfgLexer *lexer}
  60. %parse-param {GList **result}
  61. %type <ptr> rewrite_expr
  62. %type <ptr> rewrite_expr_list
  63. %type <ptr> rewrite_expr_list_build
  64. %require "2.4.1"
  65. %locations
  66. %define api.pure
  67. %pure-parser
  68. %error-verbose
  69. %code {
  70. # define YYLLOC_DEFAULT(Current, Rhs, N) \
  71. do { \
  72. if (YYID (N)) \
  73. { \
  74. (Current).level = YYRHSLOC(Rhs, 1).level; \
  75. (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
  76. (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
  77. (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
  78. (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
  79. } \
  80. else \
  81. { \
  82. (Current).level = YYRHSLOC(Rhs, 0).level; \
  83. (Current).first_line = (Current).last_line = \
  84. YYRHSLOC (Rhs, 0).last_line; \
  85. (Current).first_column = (Current).last_column = \
  86. YYRHSLOC (Rhs, 0).last_column; \
  87. } \
  88. } while (YYID (0))
  89. #define CHECK_ERROR(val, token, errorfmt, ...) do { \
  90. if (!(val)) \
  91. { \
  92. if (errorfmt) \
  93. { \
  94. gchar __buf[256]; \
  95. g_snprintf(__buf, sizeof(__buf), errorfmt ? errorfmt : "x", ## __VA_ARGS__); \
  96. yyerror(& (token), lexer, NULL, __buf); \
  97. } \
  98. YYERROR; \
  99. } \
  100. } while (0)
  101. #define YYMAXDEPTH 20000
  102. }
  103. /* plugin types, must be equal to the numerical values of the plugin type in plugin.h */
  104. %token LL_CONTEXT_ROOT 1
  105. %token LL_CONTEXT_DESTINATION 2
  106. %token LL_CONTEXT_SOURCE 3
  107. %token LL_CONTEXT_PARSER 4
  108. %token LL_CONTEXT_REWRITE 5
  109. %token LL_CONTEXT_FILTER 6
  110. %token LL_CONTEXT_LOG 7
  111. %token LL_CONTEXT_BLOCK_DEF 8
  112. %token LL_CONTEXT_BLOCK_REF 9
  113. %token LL_CONTEXT_BLOCK_CONTENT 10
  114. %token LL_CONTEXT_PRAGMA 11
  115. %token LL_CONTEXT_FORMAT 12
  116. %token LL_CONTEXT_TEMPLATE_FUNC 13
  117. /* statements */
  118. %token KW_SOURCE 10000
  119. %token KW_FILTER 10001
  120. %token KW_PARSER 10002
  121. %token KW_DESTINATION 10003
  122. %token KW_LOG 10004
  123. %token KW_OPTIONS 10005
  124. %token KW_INCLUDE 10006
  125. %token KW_BLOCK 10007
  126. /* source & destination items */
  127. %token KW_INTERNAL 10010
  128. %token KW_FILE 10011
  129. %token KW_SQL 10030
  130. %token KW_TYPE 10031
  131. %token KW_COLUMNS 10032
  132. %token KW_INDEXES 10033
  133. %token KW_VALUES 10034
  134. %token KW_PASSWORD 10035
  135. %token KW_DATABASE 10036
  136. %token KW_USERNAME 10037
  137. %token KW_TABLE 10038
  138. %token KW_ENCODING 10039
  139. %token KW_SESSION_STATEMENTS 10040
  140. %token KW_DELIMITERS 10050
  141. %token KW_QUOTES 10051
  142. %token KW_QUOTE_PAIRS 10052
  143. %token KW_NULL 10053
  144. %token KW_SYSLOG 10060
  145. /* option items */
  146. %token KW_MARK_FREQ 10071
  147. %token KW_STATS_FREQ 10072
  148. %token KW_STATS_LEVEL 10073
  149. %token KW_FLUSH_LINES 10074
  150. %token KW_SUPPRESS 10075
  151. %token KW_FLUSH_TIMEOUT 10076
  152. %token KW_LOG_MSG_SIZE 10077
  153. %token KW_FILE_TEMPLATE 10078
  154. %token KW_PROTO_TEMPLATE 10079
  155. %token KW_CHAIN_HOSTNAMES 10090
  156. %token KW_NORMALIZE_HOSTNAMES 10091
  157. %token KW_KEEP_HOSTNAME 10092
  158. %token KW_CHECK_HOSTNAME 10093
  159. %token KW_BAD_HOSTNAME 10094
  160. %token KW_KEEP_TIMESTAMP 10100
  161. %token KW_USE_DNS 10110
  162. %token KW_USE_FQDN 10111
  163. %token KW_DNS_CACHE 10120
  164. %token KW_DNS_CACHE_SIZE 10121
  165. %token KW_DNS_CACHE_EXPIRE 10130
  166. %token KW_DNS_CACHE_EXPIRE_FAILED 10131
  167. %token KW_DNS_CACHE_HOSTS 10132
  168. %token KW_PERSIST_ONLY 10140
  169. %token KW_TZ_CONVERT 10150
  170. %token KW_TS_FORMAT 10151
  171. %token KW_FRAC_DIGITS 10152
  172. %token KW_LOG_FIFO_SIZE 10160
  173. %token KW_LOG_FETCH_LIMIT 10162
  174. %token KW_LOG_IW_SIZE 10163
  175. %token KW_LOG_PREFIX 10164
  176. %token KW_PROGRAM_OVERRIDE 10165
  177. %token KW_HOST_OVERRIDE 10166
  178. %token KW_THROTTLE 10170
  179. /* log statement options */
  180. %token KW_FLAGS 10190
  181. /* reader options */
  182. %token KW_PAD_SIZE 10200
  183. %token KW_TIME_ZONE 10201
  184. %token KW_RECV_TIME_ZONE 10202
  185. %token KW_SEND_TIME_ZONE 10203
  186. %token KW_LOCAL_TIME_ZONE 10204
  187. %token KW_FORMAT 10205
  188. /* timers */
  189. %token KW_TIME_REOPEN 10210
  190. %token KW_TIME_REAP 10211
  191. %token KW_TIME_SLEEP 10212
  192. /* destination options */
  193. %token KW_TMPL_ESCAPE 10220
  194. /* driver specific options */
  195. %token KW_OPTIONAL 10230
  196. /* file related options */
  197. %token KW_CREATE_DIRS 10240
  198. %token KW_OWNER 10250
  199. %token KW_GROUP 10251
  200. %token KW_PERM 10252
  201. %token KW_DIR_OWNER 10260
  202. %token KW_DIR_GROUP 10261
  203. %token KW_DIR_PERM 10262
  204. %token KW_TEMPLATE 10270
  205. %token KW_TEMPLATE_ESCAPE 10271
  206. %token KW_DEFAULT_FACILITY 10300
  207. %token KW_DEFAULT_LEVEL 10301
  208. %token KW_PORT 10323
  209. /* misc options */
  210. %token KW_USE_TIME_RECVD 10340
  211. /* filter items*/
  212. %token KW_FACILITY 10350
  213. %token KW_LEVEL 10351
  214. %token KW_HOST 10352
  215. %token KW_MATCH 10353
  216. %token KW_MESSAGE 10354
  217. %token KW_NETMASK 10355
  218. %token KW_TAGS 10356
  219. /* parser items */
  220. %token KW_VALUE 10361
  221. /* rewrite items */
  222. %token KW_REWRITE 10370
  223. %token KW_SET 10371
  224. %token KW_SUBST 10372
  225. /* yes/no switches */
  226. %token KW_YES 10380
  227. %token KW_NO 10381
  228. %token KW_IFDEF 10410
  229. %token KW_ENDIF 10411
  230. %token LL_DOTDOT 10420
  231. %token <cptr> LL_IDENTIFIER 10421
  232. %token <num> LL_NUMBER 10422
  233. %token <fnum> LL_FLOAT 10423
  234. %token <cptr> LL_STRING 10424
  235. %token <token> LL_TOKEN 10425
  236. %token <cptr> LL_BLOCK 10426
  237. %token LL_PRAGMA 10427
  238. %token LL_EOL 10428
  239. %token LL_ERROR 10429
  240. %type <num> yesno
  241. %type <num> dnsmode
  242. %type <num> regexp_option_flags
  243. %type <num> dest_writer_options_flags
  244. %type <cptr> string
  245. %type <cptr> string_or_number
  246. %type <ptr> string_list
  247. %type <ptr> string_list_build
  248. %type <num> facility_string
  249. %type <num> level_string
  250. %token KW_CONDITION
  251. %%
  252. start
  253. : rewrite_expr_list { *result = $1; if (yychar != YYEMPTY) { cfg_lexer_unput_token(lexer, &yylval); } YYACCEPT; }
  254. ;
  255. rewrite_expr_list
  256. : rewrite_expr_list_build { $$ = g_list_reverse($1); }
  257. ;
  258. rewrite_expr_list_build
  259. : rewrite_expr ';' rewrite_expr_list_build { $$ = g_list_append($3, $1); }
  260. | ';' rewrite_expr_list_build { $$ = $2; }
  261. | { $$ = NULL; }
  262. ;
  263. rewrite_expr
  264. : KW_SUBST '(' string string
  265. {
  266. last_rewrite = log_rewrite_subst_new($4);
  267. free($4);
  268. }
  269. rewrite_subst_opts ')'
  270. {
  271. CHECK_ERROR(log_rewrite_subst_set_regexp(last_rewrite, $3), @3, "Error compiling regular expression");
  272. free($3);
  273. $$ = last_rewrite;
  274. }
  275. | KW_SET '(' string
  276. {
  277. last_rewrite = log_rewrite_set_new($3);
  278. free($3);
  279. }
  280. rewrite_expr_opts ')' { $$ = last_rewrite; }
  281. | LL_IDENTIFIER
  282. {
  283. Plugin *p;
  284. gint context = LL_CONTEXT_REWRITE;
  285. p = plugin_find(configuration, context, $1);
  286. CHECK_ERROR(p, @1, "%s plugin %s not found", cfg_lexer_lookup_context_name_by_type(context), $1);
  287. last_rewrite = (LogRewrite *) plugin_parse_config(p, configuration, &@1);
  288. free($1);
  289. if (!last_rewrite)
  290. {
  291. YYERROR;
  292. }
  293. $$ = last_rewrite;
  294. }
  295. ;
  296. rewrite_subst_opts
  297. : rewrite_expr_opt rewrite_subst_opts
  298. | rewrite_subst_opt rewrite_subst_opts
  299. |
  300. ;
  301. rewrite_subst_opt
  302. : KW_TYPE '(' string ')'
  303. {
  304. CHECK_ERROR((strcmp($3, "glob") != 0), @3, "Rewrite rules do not support glob expressions");
  305. log_rewrite_subst_set_matcher(last_rewrite, log_matcher_new($3));
  306. free($3);
  307. }
  308. | KW_FLAGS '(' regexp_option_flags ')' { log_rewrite_subst_set_flags(last_rewrite, $3); }
  309. ;
  310. rewrite_expr_opts
  311. : rewrite_expr_opt rewrite_expr_opts
  312. |
  313. ;
  314. rewrite_expr_opt
  315. : KW_VALUE '(' string ')'
  316. {
  317. const gchar *p = $3;
  318. if (p[0] == '$')
  319. {
  320. msg_warning("Value references in rewrite rules should not use the '$' prefix, those are only needed in templates",
  321. evt_tag_str("value", $3),
  322. NULL);
  323. p++;
  324. }
  325. last_rewrite->value_handle = log_msg_get_value_handle(p);
  326. if (log_msg_is_handle_macro(last_rewrite->value_handle))
  327. {
  328. msg_warning("Macros are read-only, they cannot be changed in rewrite rules, falling back to MESSAGE instead",
  329. evt_tag_str("macro", p),
  330. NULL);
  331. last_rewrite->value_handle = LM_V_MESSAGE;
  332. }
  333. /* SDATA validation */
  334. if (strlen($3)>6 && strncmp($3,".SDATA.",7)==0)
  335. {
  336. if (!is_sdata_valid($3))
  337. {
  338. msg_error("Invalid structured data format",evt_tag_str("SDATA",$3), NULL);
  339. YYERROR;
  340. }
  341. }
  342. free($3);
  343. }
  344. | KW_CONDITION '('
  345. {
  346. FilterExprNode *filter_expr;
  347. CHECK_ERROR(cfg_parser_parse(&filter_expr_parser, lexer, (gpointer *) &filter_expr), @1, NULL);
  348. log_rewrite_set_condition(last_rewrite, filter_expr);
  349. } ')'
  350. ;
  351. string
  352. : LL_IDENTIFIER
  353. | LL_STRING
  354. ;
  355. yesno
  356. : KW_YES { $$ = 1; }
  357. | KW_NO { $$ = 0; }
  358. | LL_NUMBER { $$ = $1; }
  359. ;
  360. dnsmode
  361. : yesno { $$ = $1; }
  362. | KW_PERSIST_ONLY { $$ = 2; }
  363. ;
  364. string_or_number
  365. : string { $$ = $1; }
  366. | LL_NUMBER { $$ = strdup(lexer->token_text->str); }
  367. | LL_FLOAT { $$ = strdup(lexer->token_text->str); }
  368. ;
  369. string_list
  370. : string_list_build { $$ = g_list_reverse($1); }
  371. ;
  372. string_list_build
  373. : string string_list_build { $$ = g_list_append($2, g_strdup($1)); free($1); }
  374. | { $$ = NULL; }
  375. ;
  376. level_string
  377. : string
  378. {
  379. /* return the numeric value of the "level" */
  380. int n = syslog_name_lookup_level_by_name($1);
  381. CHECK_ERROR((n != -1), @1, "Unknown priority level\"%s\"", $1);
  382. free($1);
  383. $$ = n;
  384. }
  385. ;
  386. facility_string
  387. : string
  388. {
  389. /* return the numeric value of facility */
  390. int n = syslog_name_lookup_facility_by_name($1);
  391. CHECK_ERROR((n != -1), @1, "Unknown facility \"%s\"", $1);
  392. free($1);
  393. $$ = n;
  394. }
  395. | KW_SYSLOG { $$ = LOG_SYSLOG; }
  396. ;
  397. regexp_option_flags
  398. : string regexp_option_flags { $$ = log_matcher_lookup_flag($1) | $2; free($1); }
  399. | { $$ = 0; }
  400. ;
  401. source_reader_options
  402. : source_reader_option source_reader_options
  403. |
  404. ;
  405. source_reader_option
  406. : KW_LOG_IW_SIZE '(' LL_NUMBER ')' { last_reader_options->super.init_window_size = $3; }
  407. | KW_CHAIN_HOSTNAMES '(' yesno ')' { last_reader_options->super.chain_hostnames = $3; }
  408. | KW_NORMALIZE_HOSTNAMES '(' yesno ')' { last_reader_options->super.normalize_hostnames = $3; }
  409. | KW_KEEP_HOSTNAME '(' yesno ')' { last_reader_options->super.keep_hostname = $3; }
  410. | KW_USE_FQDN '(' yesno ')' { last_reader_options->super.use_fqdn = $3; }
  411. | KW_USE_DNS '(' dnsmode ')' { last_reader_options->super.use_dns = $3; }
  412. | KW_DNS_CACHE '(' yesno ')' { last_reader_options->super.use_dns_cache = $3; }
  413. | KW_PROGRAM_OVERRIDE '(' string ')' { last_reader_options->super.program_override = g_strdup($3); free($3); }
  414. | KW_HOST_OVERRIDE '(' string ')' { last_reader_options->super.host_override = g_strdup($3); free($3); }
  415. | KW_LOG_PREFIX '(' string ')' { gchar *p = strrchr($3, ':'); if (p) *p = 0; last_reader_options->super.program_override = g_strdup($3); free($3); }
  416. | KW_TIME_ZONE '(' string ')' { last_reader_options->parse_options.recv_time_zone = g_strdup($3); free($3); }
  417. | KW_CHECK_HOSTNAME '(' yesno ')' { last_reader_options->check_hostname = $3; }
  418. | KW_FLAGS '(' source_reader_option_flags ')'
  419. | KW_LOG_MSG_SIZE '(' LL_NUMBER ')' { last_reader_options->msg_size = $3; }
  420. | KW_LOG_FETCH_LIMIT '(' LL_NUMBER ')' { last_reader_options->fetch_limit = $3; }
  421. | KW_PAD_SIZE '(' LL_NUMBER ')' { last_reader_options->padding = $3; }
  422. | KW_KEEP_TIMESTAMP '(' yesno ')' { last_reader_options->super.keep_timestamp = $3; }
  423. | KW_ENCODING '(' string ')' { last_reader_options->text_encoding = g_strdup($3); free($3); }
  424. | KW_TAGS '(' string_list ')' { log_reader_options_set_tags(last_reader_options, $3); }
  425. | KW_FORMAT '(' string ')' { last_reader_options->parse_options.format = g_strdup($3); free($3); }
  426. | KW_DEFAULT_LEVEL '(' level_string ')'
  427. {
  428. if (last_reader_options->parse_options.default_pri == 0xFFFF)
  429. last_reader_options->parse_options.default_pri = LOG_USER;
  430. last_reader_options->parse_options.default_pri = (last_reader_options->parse_options.default_pri & ~7) | $3;
  431. }
  432. | KW_DEFAULT_FACILITY '(' facility_string ')'
  433. {
  434. if (last_reader_options->parse_options.default_pri == 0xFFFF)
  435. last_reader_options->parse_options.default_pri = LOG_NOTICE;
  436. last_reader_options->parse_options.default_pri = (last_reader_options->parse_options.default_pri & 7) | $3;
  437. }
  438. ;
  439. source_reader_option_flags
  440. : string source_reader_option_flags { CHECK_ERROR(log_reader_options_process_flag(last_reader_options, $1), @1, "Unknown flag %s", $1); free($1); }
  441. |
  442. ;
  443. dest_writer_options
  444. : dest_writer_option dest_writer_options
  445. |
  446. ;
  447. dest_writer_option
  448. : KW_FLAGS '(' dest_writer_options_flags ')' { last_writer_options->options = $3; }
  449. | KW_LOG_FIFO_SIZE '(' LL_NUMBER ')' { last_writer_options->mem_fifo_size = $3; }
  450. | KW_FLUSH_LINES '(' LL_NUMBER ')' { last_writer_options->flush_lines = $3; }
  451. | KW_FLUSH_TIMEOUT '(' LL_NUMBER ')' { last_writer_options->flush_timeout = $3; }
  452. | KW_SUPPRESS '(' LL_NUMBER ')' { last_writer_options->suppress = $3; }
  453. | KW_TEMPLATE '(' string ')' {
  454. GError *error = NULL;
  455. last_writer_options->template = cfg_check_inline_template(configuration, $3);
  456. CHECK_ERROR(log_template_compile(last_writer_options->template, &error), @3, "Error compiling template (%s)", error->message);
  457. free($3);
  458. }
  459. | KW_TEMPLATE_ESCAPE '(' yesno ')' { log_writer_options_set_template_escape(last_writer_options, $3); }
  460. | KW_TIME_ZONE '(' string ')' { last_writer_options->template_options.time_zone[LTZ_SEND] = g_strdup($3); free($3); }
  461. | KW_TS_FORMAT '(' string ')' { last_writer_options->template_options.ts_format = cfg_ts_format_value($3); free($3); }
  462. | KW_FRAC_DIGITS '(' LL_NUMBER ')' { last_writer_options->template_options.frac_digits = $3; }
  463. | KW_THROTTLE '(' LL_NUMBER ')' { last_writer_options->throttle = $3; }
  464. ;
  465. dest_writer_options_flags
  466. : string dest_writer_options_flags { $$ = log_writer_options_lookup_flag($1) | $2; free($1); }
  467. | { $$ = 0; }
  468. ;
  469. %%