1 /*
2  * Copyright (c) 2002-2012 Balabit
3  * Copyright (c) 1998-2012 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 
25 #ifndef CFGTREE_H_INCLUDED
26 #define CFGTREE_H_INCLUDED
27 
28 #include "syslog-ng.h"
29 #include "template/templates.h"
30 #include "cfg-lexer.h"
31 #include "messages.h"
32 #include "atomic.h"
33 
34 const gchar *log_expr_node_get_content_name(gint content);
35 
36 #define LC_CATCHALL       1
37 #define LC_FALLBACK       2
38 #define LC_FINAL          4
39 #define LC_FLOW_CONTROL   8
40 #define LC_DROP_UNMATCHED 16
41 
42 enum
43 {
44   /* expr node content type */
45   ENC_SOURCE,
46   ENC_DESTINATION,
47   ENC_FILTER,
48   ENC_PARSER,
49   ENC_REWRITE,
50   ENC_MAX,
51   /* */
52   ENC_PIPE,
53 
54   /* expr node layouts type */
55   ENL_SINGLE,
56   ENL_REFERENCE,
57   ENL_SEQUENCE,
58   ENL_JUNCTION,
59 };
60 
61 
62 typedef struct _LogExprNode LogExprNode;
63 
64 /**
65  * Log Expressions
66  * ===============
67  *
68  * Everything except a few things are parsed from the configuration as
69  * a log expression. The few exceptions are: templates, global options and blocks.
70  *
71  * Sources, destinations, filters, parsers, rewrite rules and global
72  * log statements are log expressions.
73  *
74  * Log expressions describe a graph, which is then traversed by
75  * messages received by syslog-ng. The graph used to be a tree
76  * (e.g. no cycles), but this limitation was lifted in syslog-ng 3.4,
77  * when the concept of log expression was introduced.
78  *
79  * Log expression is a part of the graph, the larger graph is created
80  * by connecting these parts as dictated by the configuration.
81  *
82  * Each log expression is represented using a tree of LogExprNode
83  * elements. Each node in this tree defines the layout how its children
84  * are to be connected:
85  *   - simple element: holds a single LogPipe, no children
86  *   - reference:      used to reference log expressions defined elsewhere, no children
87  *   - sequence:       holds a sequence of LogExprNodes
88  *   - junction:       holds a junction
89  *
90  * Sometimes syslog-ng needs to know what kind of object the user
91  * originally defined, this is stored in the "content" member.
92  *
93  *   ENC_PIPE: content is a single LogPipe instance (in the "object" member)
94  *   ENC_SOURCE: content is a source log expression node (source statement or one defined inline)
95  *   ENC_DESTINATION: content is a destination node
96  *   ENC_FILTER: content is a filter node
97  *   ENC_PARSER: content is a parser node
98  *   ENC_REWRITE: content is a rewrite node
99  */
100 struct _LogExprNode
101 {
102   GAtomicCounter ref_cnt;
103   gint16 layout;
104   gint16 content;
105 
106   guint32 flags;
107 
108   /* name of the rule for named rules and name of the named rule for references */
109   gchar *name;
110   /* parent node */
111   LogExprNode *parent;
112   /* list of children */
113   LogExprNode *children;
114   /* next sibling */
115   LogExprNode *next;
116 
117   gpointer object;
118   GDestroyNotify object_destroy;
119 
120   /* used during construction in case a rule specific object needs to be created. */
121   gpointer aux;
122   GDestroyNotify aux_destroy;
123   gchar *filename;
124   gint line, column;
125   gint child_id;
126 };
127 
128 gint log_expr_node_lookup_flag(const gchar *flag);
129 
130 LogExprNode *log_expr_node_append_tail(LogExprNode *a, LogExprNode *b);
131 void log_expr_node_set_object(LogExprNode *self, gpointer object, GDestroyNotify destroy);
132 const gchar *log_expr_node_format_location(LogExprNode *self, gchar *buf, gsize buf_len);
133 EVTTAG *log_expr_node_location_tag(LogExprNode *self);
134 
135 LogExprNode *log_expr_node_new(gint layout, gint content, const gchar *name, LogExprNode *children, guint32 flags,
136                                CFG_LTYPE *yylloc);
137 
138 LogExprNode *log_expr_node_ref(LogExprNode *self);
139 LogExprNode *log_expr_node_unref(LogExprNode *self);
140 
141 LogExprNode *log_expr_node_new_pipe(LogPipe *pipe, CFG_LTYPE *yylloc);
142 LogExprNode *log_expr_node_new_source(const gchar *name, LogExprNode *children, CFG_LTYPE *yylloc);
143 LogExprNode *log_expr_node_new_source_reference(const gchar *name, CFG_LTYPE *yylloc);
144 LogExprNode *log_expr_node_new_destination(const gchar *name, LogExprNode *children, CFG_LTYPE *yylloc);
145 LogExprNode *log_expr_node_new_destination_reference(const gchar *name, CFG_LTYPE *yylloc);
146 LogExprNode *log_expr_node_new_filter(const gchar *name, LogExprNode *node, CFG_LTYPE *yylloc);
147 LogExprNode *log_expr_node_new_filter_reference(const gchar *name, CFG_LTYPE *yylloc);
148 LogExprNode *log_expr_node_new_parser(const gchar *name, LogExprNode *children, CFG_LTYPE *yylloc);
149 LogExprNode *log_expr_node_new_parser_reference(const gchar *name, CFG_LTYPE *yylloc);
150 LogExprNode *log_expr_node_new_rewrite(const gchar *name, LogExprNode *children, CFG_LTYPE *yylloc);
151 LogExprNode *log_expr_node_new_rewrite_reference(const gchar *name, CFG_LTYPE *yylloc);
152 LogExprNode *log_expr_node_new_log(LogExprNode *children, guint32 flags, CFG_LTYPE *yylloc);
153 LogExprNode *log_expr_node_new_sequence(LogExprNode *children, CFG_LTYPE *yylloc);
154 LogExprNode *log_expr_node_new_junction(LogExprNode *children, CFG_LTYPE *yylloc);
155 void log_expr_node_conditional_set_false_branch_of_the_last_if(LogExprNode *conditional_node, LogExprNode *false_expr);
156 LogExprNode *log_expr_node_new_conditional_with_filter(LogExprNode *filter_pipe, LogExprNode *true_expr,
157                                                        CFG_LTYPE *yylloc);
158 LogExprNode *log_expr_node_new_conditional_with_block(LogExprNode *block, CFG_LTYPE *yylloc);
159 
160 typedef struct _CfgTree
161 {
162   GlobalConfig *cfg;
163   GPtrArray *initialized_pipes;
164   gint anon_counters[ENC_MAX];
165   /* hash of predefined source/filter/rewrite/parser/destination objects */
166   GHashTable *objects;
167   /* list of top-level rules */
168   GPtrArray *rules;
169   GHashTable *templates;
170   gboolean compiled;
171 } CfgTree;
172 
173 gboolean cfg_tree_add_object(CfgTree *self, LogExprNode *rule);
174 LogExprNode *cfg_tree_get_object(CfgTree *self, gint type, const gchar *name);
175 GList *cfg_tree_get_objects(CfgTree *self);
176 
177 gboolean cfg_tree_add_template(CfgTree *self, LogTemplate *template);
178 LogTemplate *cfg_tree_lookup_template(CfgTree *self, const gchar *name);
179 LogTemplate *cfg_tree_check_inline_template(CfgTree *self, const gchar *template_or_name, GError **error);
180 
181 gchar *cfg_tree_get_rule_name(CfgTree *self, gint content, LogExprNode *node);
182 gchar *cfg_tree_get_child_id(CfgTree *self, gint content, LogExprNode *node);
183 
184 gboolean cfg_tree_start(CfgTree *self);
185 gboolean cfg_tree_stop(CfgTree *self);
186 gboolean cfg_tree_on_inited(CfgTree *self);
187 
188 void cfg_tree_init_instance(CfgTree *self, GlobalConfig *cfg);
189 void cfg_tree_free_instance(CfgTree *self);
190 
191 
192 #endif
193