This is the implementation of the value-pairs() framework discussed on the list in the past. The syntax is as follows: destination d_driver { driver( value-pairs( scope($SCOPE) exclude("S_*") # shell-style glob to exclude keys pair("my-own-key" "$SOURCE/$HOST") key("HOST_FROM") ) ); }; Of course, this is not only for destination drivers: there is support for parsing arguments passed to template functions. The above set would look like this in a template function: $(function --scope $SCOPE --exclude S_* --pair my-own-key=$SOURCE/$HOST --key HOST_FROM) The idea is that we select a scope (see later for the list of scopes currently supported), from which we can exclude certain keys using a shell-style glob pattern, or add custom key-value pairs of our own, or add back pre-defined keys that we do want, but the scope doesn't have by default. The available scopes at the moment are: * rfc3164: Key-value pairs based on the old syslog protocol, also available as "core" and "base". * rfc5424: Key-value pairs based on the new syslog protocol, also available as "syslog_proto". * all_macros: All macros known to syslog-ng (this only includes the pre-defined macros!) * selected_macros: A smaller set of selected macros, which the developers deemed important (see the source for the list, for now). * nv_pairs: Name-value pairs, the results of SDATA or patterndb parsing. * everything: All of the above, combined into one big set. On the driver side, supporting value-pairs is reasonably easy: driver_option : value_pair_stmt { driver_dd_set_value_pairs(last_driver, last_value_pairs); } | <etc...> ; And in the driver itself, make a foreach callback: static gboolean driver_vp_foreach (const gchar *name, const gchar *value, gpointer user_data) { /* Do something here with the name-value pairs */ return FALSE; } And whenever you want to work with the set, call value_pairs_foreach(): value_pairs_foreach (self->value_pairs, driver_vp_foreach, msg, self->seq_num, USER_DATA); And that's about it. Signed-off-by: Gergely Nagy <algernon@balabit.hu> --- lib/Makefile.am | 3 +- lib/cfg-grammar.y | 68 ++++++++- lib/cfg-parser.c | 17 ++ lib/cfg-parser.h | 1 + lib/syslog-ng.h | 2 + lib/value-pairs.c | 458 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/value-pairs.h | 62 +++++++ 7 files changed, 608 insertions(+), 3 deletions(-) create mode 100644 lib/value-pairs.c create mode 100644 lib/value-pairs.h diff --git a/lib/Makefile.am b/lib/Makefile.am index 33a886e..16075b9 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -59,7 +59,8 @@ libsyslog_ng_la_SOURCES = \ block-ref-grammar.y block-ref-parser.c block-ref-parser.h \ pragma-grammar.y pragma-parser.h pragma-parser.c \ parser-expr-grammar.y parser-expr-parser.c parser-expr-parser.h \ - rewrite-expr-grammar.y rewrite-expr-parser.c rewrite-expr-parser.h + rewrite-expr-grammar.y rewrite-expr-parser.c rewrite-expr-parser.h \ + value-pairs.c value-pairs.h BUILT_SOURCES = cfg-lex.c cfg-lex.h cfg-grammar.c cfg-grammar.h \ filter-expr-grammar.y filter-expr-grammar.c filter-expr-grammar.h \ diff --git a/lib/cfg-grammar.y b/lib/cfg-grammar.y index 0ec55ad..e1d97b6 100644 --- a/lib/cfg-grammar.y +++ b/lib/cfg-grammar.y @@ -28,6 +28,7 @@ #include "cfg-lexer.h" #include "driver.h" +#include "value-pairs.h" } %name-prefix "main_" @@ -134,7 +135,6 @@ %token KW_SYSLOG 10060 - /* option items */ %token KW_MARK_FREQ 10071 %token KW_STATS_FREQ 10072 @@ -263,6 +263,20 @@ %token LL_EOL 10428 %token LL_ERROR 10429 +/* value pairs */ +%token KW_VALUE_PAIRS 10500 +%token KW_SELECT 10501 +%token KW_EXCLUDE 10502 +%token KW_PAIR 10503 +%token KW_KEY 10504 +%token KW_SCOPE 10505 +%token KW_SCOPE_NV_PAIRS 10506 +%token KW_SCOPE_RFC3164 10507 +%token KW_SCOPE_RFC5424 10508 +%token KW_SCOPE_ALL_MACROS 10509 +%token KW_SCOPE_SELECTED_MACROS 10510 +%token KW_SCOPE_EVERYTHING 10511 + /* END_DECLS */ %code { @@ -277,6 +291,7 @@ #include "logreader.h" #include "logparser.h" #include "logrewrite.h" +#include "value-pairs.h" #include "filter-expr-parser.h" #include "rewrite-expr-parser.h" #include "block-ref-parser.h" @@ -306,7 +321,7 @@ GList *last_rewrite_expr; GList *last_parser_expr; FilterExprNode *last_filter_expr; CfgArgs *last_block_args; - +ValuePairs *last_value_pairs; } @@ -318,6 +333,7 @@ CfgArgs *last_block_args; %type <ptr> log_stmt %type <ptr> options_stmt %type <ptr> template_stmt +%type <ptr> value_pair_stmt %type <ptr> source_items %type <ptr> source_item @@ -803,6 +819,54 @@ dest_writer_options_flags | { $$ = 0; } ; +value_pair_stmt + : KW_VALUE_PAIRS value_pairs_def { } + ; + +value_pairs_def + : { last_value_pairs = value_pairs_new(configuration); } + '(' value_pair_options ')' + { } + ; + +value_pair_options + : value_pair_option value_pair_options + | + ; + +value_pair_option + : KW_PAIR '(' string ':' string ')' { value_pairs_add_pair(last_value_pairs, $3, $5); free($3); free($5); } + | KW_PAIR '(' string string ')' { value_pairs_add_pair(last_value_pairs, $3, $4); free($3); free($4); } + | KW_KEY '(' string ')' { + gchar *k = g_strconcat("$", $3, NULL); + value_pairs_add_pair(last_value_pairs, $3, k); + g_free(k); + free($3); + } + | KW_EXCLUDE '(' string ')' { value_pairs_exclude_glob_pattern(last_value_pairs, $3); free($3); } + | KW_SCOPE '(' vp_scope_list ')' { } + ; + +vp_scope_list + : vp_scope vp_scope_list + | + ; + +vp_scope + : KW_SCOPE_NV_PAIRS + { value_pairs_add_scope(last_value_pairs, VALUE_PAIR_SCOPE_NV_PAIRS); } + | KW_SCOPE_RFC3164 + { value_pairs_add_scope(last_value_pairs, VALUE_PAIR_SCOPE_RFC3164); } + | KW_SCOPE_RFC5424 + { value_pairs_add_scope(last_value_pairs, VALUE_PAIR_SCOPE_RFC5424); } + | KW_SCOPE_ALL_MACROS + { value_pairs_add_scope(last_value_pairs, VALUE_PAIR_SCOPE_ALL_MACROS); } + | KW_SCOPE_SELECTED_MACROS + { value_pairs_add_scope(last_value_pairs, VALUE_PAIR_SCOPE_SELECTED_MACROS); } + | KW_SCOPE_EVERYTHING + { value_pairs_add_scope(last_value_pairs, VALUE_PAIR_SCOPE_EVERYTHING); } + ; + /* END_RULES */ diff --git a/lib/cfg-parser.c b/lib/cfg-parser.c index e53c58d..1123d87 100644 --- a/lib/cfg-parser.c +++ b/lib/cfg-parser.c @@ -53,6 +53,23 @@ static CfgLexerKeyword main_keywords[] = { { "quote_pairs", KW_QUOTE_PAIRS, 0x0300}, { "null", KW_NULL, 0x0300 }, + /* value pairs */ + { "value_pairs", KW_VALUE_PAIRS }, + { "select", KW_SELECT }, + { "exclude", KW_EXCLUDE }, + { "pair", KW_PAIR }, + { "key", KW_KEY }, + { "scope", KW_SCOPE }, + { "nv_pairs", KW_SCOPE_NV_PAIRS }, + { "rfc3164", KW_SCOPE_RFC3164 }, + { "core", KW_SCOPE_RFC3164 }, + { "base", KW_SCOPE_RFC3164 }, + { "rfc5424", KW_SCOPE_RFC5424 }, + { "syslog_proto", KW_SCOPE_RFC5424 }, + { "all_macros", KW_SCOPE_ALL_MACROS }, + { "selected_macros", KW_SCOPE_SELECTED_MACROS }, + { "everything", KW_SCOPE_EVERYTHING }, + /* option items */ { "flags", KW_FLAGS }, { "pad_size", KW_PAD_SIZE }, diff --git a/lib/cfg-parser.h b/lib/cfg-parser.h index 3527621..b874cd9 100644 --- a/lib/cfg-parser.h +++ b/lib/cfg-parser.h @@ -27,6 +27,7 @@ #include "syslog-ng.h" #include "cfg-lexer.h" +#include "value-pairs.h" /* high level interface to a configuration file parser, it encapsulates the * grammar/lexer pair. */ diff --git a/lib/syslog-ng.h b/lib/syslog-ng.h index ce4c017..83a9651 100644 --- a/lib/syslog-ng.h +++ b/lib/syslog-ng.h @@ -61,10 +61,12 @@ typedef struct _LogMessage LogMessage; typedef struct _GlobalConfig GlobalConfig; +typedef struct _ValuePairs TValuePairs; extern GlobalConfig *configuration; extern gboolean seed_rng; extern gchar *module_path; extern gchar *default_modules; +extern TValuePairs *last_value_pairs; #endif diff --git a/lib/value-pairs.c b/lib/value-pairs.c new file mode 100644 index 0000000..5dfbb6f --- /dev/null +++ b/lib/value-pairs.c @@ -0,0 +1,458 @@ +/* + * Copyright (c) 2002-2011 BalaBit IT Ltd, Budapest, Hungary + * Copyright (c) 2011 Gergely Nagy <algernon@balabit.hu> + * + * 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. + * + */ + +#include "logmsg.h" +#include "templates.h" + +#include "value-pairs.h" + +#include <string.h> + +typedef struct +{ + gchar *name; + LogTemplate *template; +} vp_template_set; + +struct _ValuePairs +{ + GlobalConfig *cfg; + + guint8 scopes; + + GPatternSpec **excludes; + gsize exclude_size; + GHashTable *vpairs; + + struct + { + vp_template_set *rfc3164; + vp_template_set *rfc5424; + vp_template_set *selected_macros; + vp_template_set *all_macros; + } templates; + + /* Temporary */ + GString *res; +}; + +static inline void +vp_add_scope_template (GlobalConfig *cfg, vp_template_set *target, + gint index, const gchar *name, const gchar *macro) +{ + LogTemplate *t = NULL; + gchar *m; + + if (macro) + m = g_strdup (macro); + else + m = g_strconcat ("$", name, NULL); + + t = log_template_new(cfg, NULL, m); + target[index].name = g_strdup(name); + target[index].template = t; + g_free (m); +} + +ValuePairs * +value_pairs_new (GlobalConfig *cfg) +{ + ValuePairs *vp; + gint i = 0; + + vp = g_try_new0(ValuePairs, 1); + if (!vp) + return NULL; + vp->res = g_string_sized_new(256); + if (!vp->res) + { + g_free(vp); + return NULL; + } + vp->vpairs = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, + (GDestroyNotify) log_template_unref); + if (!vp->vpairs) + { + g_string_free(vp->res, TRUE); + g_free(vp); + return NULL; + } + + vp->cfg = cfg; + + vp->templates.rfc3164 = g_try_new0 (vp_template_set, 8); + vp->templates.rfc5424 = g_try_new0 (vp_template_set, 3); + vp->templates.selected_macros = g_try_new0 (vp_template_set, 5); + + while (macros[i].name) + i++; + + vp->templates.all_macros = g_try_new0 (vp_template_set, i + 1); + i = 0; + + vp_add_scope_template (vp->cfg, vp->templates.rfc3164, 0, "FACILITY", NULL); + vp_add_scope_template (vp->cfg, vp->templates.rfc3164, 1, "PRIORITY", NULL); + vp_add_scope_template (vp->cfg, vp->templates.rfc3164, 2, "DATE", "$S_DATE"); + vp_add_scope_template (vp->cfg, vp->templates.rfc3164, 3, "HOST", NULL); + vp_add_scope_template (vp->cfg, vp->templates.rfc3164, 4, "PROGRAM", NULL); + vp_add_scope_template (vp->cfg, vp->templates.rfc3164, 5, "PID", NULL); + vp_add_scope_template (vp->cfg, vp->templates.rfc3164, 6, "MSG", NULL); + + vp_add_scope_template (vp->cfg, vp->templates.rfc5424, 0, "MSGID", NULL); + vp_add_scope_template (vp->cfg, vp->templates.rfc5424, 1, "SDATA", NULL); + + vp_add_scope_template (vp->cfg, vp->templates.selected_macros, 0, "TAGS", NULL); + vp_add_scope_template (vp->cfg, vp->templates.selected_macros, 1, "SDATA", NULL); + vp_add_scope_template (vp->cfg, vp->templates.selected_macros, 2, "SOURCEIP", NULL); + vp_add_scope_template (vp->cfg, vp->templates.selected_macros, 3, "SEQNUM", NULL); + + while (macros[i].name) + { + vp_add_scope_template (vp->cfg, vp->templates.all_macros, i, macros[i].name, NULL); + i++; + } + + return vp; +} + +static gboolean +vp_cmdline_parse_scope (const gchar *option_name, const gchar *value, + gpointer data, GError **error) +{ + ValuePairs *vp = (ValuePairs *)data; + + if (g_ascii_strcasecmp (value, "nv_pairs") == 0) + value_pairs_add_scope (vp, VALUE_PAIR_SCOPE_NV_PAIRS); + else if (g_ascii_strcasecmp (value, "rfc3164") == 0 || + g_ascii_strcasecmp (value, "core") == 0 || + g_ascii_strcasecmp (value, "base")) + value_pairs_add_scope (vp, VALUE_PAIR_SCOPE_RFC3164); + else if (g_ascii_strcasecmp (value, "rfc5424") == 0 || + g_ascii_strcasecmp (value, "syslog_proto") == 0) + value_pairs_add_scope (vp, VALUE_PAIR_SCOPE_RFC5424); + else if (g_ascii_strcasecmp (value, "selected_macros") == 0) + value_pairs_add_scope (vp, VALUE_PAIR_SCOPE_SELECTED_MACROS); + else if (g_ascii_strcasecmp (value, "all_macros") == 0) + value_pairs_add_scope (vp, VALUE_PAIR_SCOPE_ALL_MACROS); + else if (g_ascii_strcasecmp (value, "everything") == 0) + value_pairs_add_scope (vp, VALUE_PAIR_SCOPE_EVERYTHING); + else + { + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Error parsing value-pairs' scope()"); + return FALSE; + } + return TRUE; +} + +static gboolean +vp_cmdline_parse_exclude (const gchar *option_name, const gchar *value, + gpointer data, GError **error) +{ + ValuePairs *vp = (ValuePairs *)data; + + value_pairs_exclude_glob_pattern (vp, value); + return TRUE; +} + +static gboolean +vp_cmdline_parse_key (const gchar *option_name, const gchar *value, + gpointer data, GError **error) +{ + ValuePairs *vp = (ValuePairs *)data; + gchar *k = g_strconcat ("$", value, NULL); + + value_pairs_add_pair (vp, value, k); + g_free (k); + + return TRUE; +} + +static gboolean +vp_cmdline_parse_pair (const gchar *option_name, const gchar *value, + gpointer data, GError **error) +{ + ValuePairs *vp = (ValuePairs *)data; + gchar **kv; + + if (!g_strstr_len (value, strlen (value), "=")) + { + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Error parsing value-pairs' key=value pair"); + return FALSE; + } + + kv = g_strsplit(value, "=", 2); + value_pairs_add_pair (vp, kv[0], kv[1]); + + g_free (kv[0]); + g_free (kv[1]); + g_free (kv); + + return TRUE; +} + +ValuePairs * +value_pairs_new_from_cmdline (GlobalConfig *cfg, + gint cargc, gchar **cargv, + GError **error) +{ + ValuePairs *vp; + GOptionContext *ctx; + GOptionEntry vp_options[] = { + { "scope", 's', 0, G_OPTION_ARG_CALLBACK, vp_cmdline_parse_scope, + NULL, NULL }, + { "exclude", 'x', 0, G_OPTION_ARG_CALLBACK, vp_cmdline_parse_exclude, + NULL, NULL }, + { "key", 'k', 0, G_OPTION_ARG_CALLBACK, vp_cmdline_parse_key, + NULL, NULL }, + { "pair", 'p', 0, G_OPTION_ARG_CALLBACK, vp_cmdline_parse_pair, + NULL, NULL }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_CALLBACK, vp_cmdline_parse_pair, + NULL, NULL }, + { NULL } + }; + gchar **argv; + gint argc = cargc + 1; + gint i; + GOptionGroup *og; + + argv = g_new (gchar *, argc + 1); + for (i = 0; i < argc; i++) + argv[i + 1] = cargv[i]; + argv[0] = "value-pairs"; + argv[argc] = NULL; + + vp = value_pairs_new (cfg); + + ctx = g_option_context_new ("value-pairs"); + og = g_option_group_new (NULL, NULL, NULL, vp, NULL); + g_option_group_add_entries (og, vp_options); + g_option_context_set_main_group (ctx, og); + + if (!g_option_context_parse (ctx, &argc, &argv, error)) + { + value_pairs_free (vp); + g_option_context_free (ctx); + g_free (argv); + return NULL; + } + g_option_context_free (ctx); + + if (vp->scopes == 0) + value_pairs_add_scope (vp, VALUE_PAIR_SCOPE_RFC3164); + + return vp; +} + +void +value_pairs_free (ValuePairs *vp) +{ + gint i; + + if (!vp) + return; + + g_hash_table_destroy(vp->vpairs); + + for (i = 0; vp->templates.rfc3164[i].name; i++) + { + g_free (vp->templates.rfc3164[i].name); + log_template_unref (vp->templates.rfc3164[i].template); + } + g_free (vp->templates.rfc3164); + + for (i = 0; vp->templates.rfc5424[i].name; i++) + { + g_free (vp->templates.rfc5424[i].name); + log_template_unref (vp->templates.rfc5424[i].template); + } + g_free (vp->templates.rfc5424); + + for (i = 0; vp->templates.selected_macros[i].name; i++) + { + g_free (vp->templates.selected_macros[i].name); + log_template_unref (vp->templates.selected_macros[i].template); + } + g_free (vp->templates.selected_macros); + + for (i = 0; vp->templates.all_macros[i].name; i++) + { + g_free (vp->templates.all_macros[i].name); + log_template_unref (vp->templates.all_macros[i].template); + } + g_free (vp->templates.all_macros); + + for (i = 0; i < vp->exclude_size; i++) + g_pattern_spec_free(vp->excludes[i]); + g_free(vp->excludes); + g_string_free(vp->res, TRUE); + g_free(vp); +} + +void +value_pairs_add_scope (ValuePairs *vp, value_pair_scope_t scope) +{ + if (!vp) + return; + + vp->scopes |= scope; +} + +void +value_pairs_exclude_glob_pattern (ValuePairs *vp, const gchar *pattern) +{ + gint i; + + if (!vp || !pattern) + return; + + i = vp->exclude_size++; + vp->excludes = g_renew(GPatternSpec *, vp->excludes, vp->exclude_size); + vp->excludes[i] = g_pattern_spec_new(pattern); +} + +void +value_pairs_add_pair (ValuePairs *vp, const gchar *key, + const gchar *value) +{ + LogTemplate *t = NULL; + + if (!vp || !key || !value) + return; + + t = log_template_new(vp->cfg, NULL, value); + g_hash_table_insert(vp->vpairs, g_strdup(key), t); +} + +static void +vp_foreach_merge_vp(gpointer key, gpointer value, gpointer user_data) +{ + ValuePairs *vp = ((gpointer *)user_data)[0]; + LogMessage *msg = ((gpointer *)user_data)[2]; + gint32 seq_num = GPOINTER_TO_INT (((gpointer *)user_data)[3]); + GHashTable *scope_set = ((gpointer *)user_data)[5]; + + g_string_truncate(vp->res, 0); + log_template_format((LogTemplate *)value, msg, NULL, LTZ_LOCAL, + seq_num, NULL, vp->res); + + if (!vp->res->str || !vp->res->str[0]) + return; + + g_hash_table_insert(scope_set, key, g_strdup (vp->res->str)); +} + +static gboolean +vp_foreach_nv_add(NVHandle handle, gchar *name, + const gchar *value, gssize value_len, + gpointer user_data) +{ + ValuePairs *vp = ((gpointer *)user_data)[0]; + GHashTable *scope_set = ((gpointer *)user_data)[5]; + gint j; + + for (j = 0; j < vp->exclude_size; j++) + if (g_pattern_match_string(vp->excludes[j], name)) + return FALSE; + + g_hash_table_insert (scope_set, name, (gpointer)g_strndup (value, value_len)); + return FALSE; +} + +static void +vp_foreach_merge_template (ValuePairs *vp, LogMessage *msg, gint32 seq_num, + vp_template_set *set, GHashTable *dest) +{ + gint i; + + for (i = 0; set[i].name; i++) + { + gint j; + gboolean exclude = FALSE; + + for (j = 0; j < vp->exclude_size; j++) + if (g_pattern_match_string(vp->excludes[j], set[i].name)) + exclude = TRUE; + if (exclude) + continue; + + g_string_truncate(vp->res, 0); + log_template_format(set[i].template, msg, NULL, LTZ_LOCAL, seq_num, NULL, + vp->res); + + if (!vp->res->str || !vp->res->str[0]) + continue; + + g_hash_table_insert (dest, set[i].name, g_strdup (vp->res->str)); + } +} + +void +value_pairs_foreach (ValuePairs *vp, VPForeachFunc func, + LogMessage *msg, gint32 seq_num, gpointer user_data) +{ + gpointer args[] = { vp, func, msg, GINT_TO_POINTER (seq_num), user_data, NULL }; + GHashTable *scope_set; + + scope_set = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, + (GDestroyNotify) g_free); + + args[5] = scope_set; + + /* + * Build up the base set + */ + if (vp->scopes & VALUE_PAIR_SCOPE_NV_PAIRS) + { + nv_table_foreach(msg->payload, logmsg_registry, + (NVTableForeachFunc)vp_foreach_nv_add, args); + } + + if (vp->scopes & VALUE_PAIR_SCOPE_RFC3164 || + vp->scopes & VALUE_PAIR_SCOPE_RFC5424 || + vp->scopes & VALUE_PAIR_SCOPE_SELECTED_MACROS) + vp_foreach_merge_template (vp, msg, seq_num, vp->templates.rfc3164, + scope_set); + + if (vp->scopes & VALUE_PAIR_SCOPE_RFC5424) + vp_foreach_merge_template (vp, msg, seq_num, vp->templates.rfc5424, + scope_set); + + if (vp->scopes & VALUE_PAIR_SCOPE_SELECTED_MACROS) + vp_foreach_merge_template (vp, msg, seq_num, vp->templates.selected_macros, + scope_set); + + if (vp->scopes & VALUE_PAIR_SCOPE_ALL_MACROS) + vp_foreach_merge_template (vp, msg, seq_num, vp->templates.all_macros, + scope_set); + + /* Merge the explicit key-value pairs too */ + g_hash_table_foreach (vp->vpairs, (GHFunc)vp_foreach_merge_vp, args); + + /* Aaand we run it through the callback! */ + g_hash_table_foreach (scope_set, (GHFunc)func, user_data); + + g_hash_table_destroy (scope_set); +} diff --git a/lib/value-pairs.h b/lib/value-pairs.h new file mode 100644 index 0000000..5642f28 --- /dev/null +++ b/lib/value-pairs.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2002-2011 BalaBit IT Ltd, Budapest, Hungary + * Copyright (c) 2011 Gergely Nagy <algernon@balabit.hu> + * + * 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. + * + */ + +#ifndef VALUE_PAIRS_H_INCLUDED +#define VALUE_PAIRS_H_INCLUDED 1 + +#include "syslog-ng.h" +#include "nvtable.h" + +#include <glib.h> + +typedef enum + { + VALUE_PAIR_SCOPE_NV_PAIRS = 0x01, + VALUE_PAIR_SCOPE_RFC3164 = 0x02, + VALUE_PAIR_SCOPE_RFC5424 = 0x04, + VALUE_PAIR_SCOPE_ALL_MACROS = 0x08, + VALUE_PAIR_SCOPE_SELECTED_MACROS = 0x10, + VALUE_PAIR_SCOPE_EVERYTHING = 0xff, + } value_pair_scope_t; + +typedef struct _ValuePairs ValuePairs; +typedef gboolean (*VPForeachFunc) (const gchar *name, const gchar *value, + gpointer user_data); + +ValuePairs *value_pairs_new (GlobalConfig *cfg); +void value_pairs_free (ValuePairs *vp); + +void value_pairs_add_scope (ValuePairs *vp, value_pair_scope_t scope); +void value_pairs_exclude_glob_pattern (ValuePairs *vp, const gchar *pattern); +void value_pairs_add_pair (ValuePairs *vp, const gchar *key, const gchar *value); + +void value_pairs_foreach (ValuePairs *vp, VPForeachFunc func, + LogMessage *msg, gint32 seq_num, + gpointer user_data); + +ValuePairs *value_pairs_new_from_cmdline (GlobalConfig *cfg, + gint argc, gchar **argv, + GError **error); + +#endif -- 1.7.2.5