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 #include "logpipe.h"
26 #include "cfg-tree.h"
27 #include "cfg-walker.h"
28 
29 gboolean (*pipe_single_step_hook)(LogPipe *pipe, LogMessage *msg, const LogPathOptions *path_options);
30 
31 EVTTAG *
log_pipe_location_tag(LogPipe * pipe)32 log_pipe_location_tag(LogPipe *pipe)
33 {
34   return log_expr_node_location_tag(pipe->expr_node);
35 }
36 
37 void
log_pipe_attach_expr_node(LogPipe * self,LogExprNode * expr_node)38 log_pipe_attach_expr_node(LogPipe *self, LogExprNode *expr_node)
39 {
40   self->expr_node = log_expr_node_ref(expr_node);
41 }
42 
log_pipe_detach_expr_node(LogPipe * self)43 void log_pipe_detach_expr_node(LogPipe *self)
44 {
45   if (!self->expr_node)
46     return;
47   log_expr_node_unref(self->expr_node);
48   self->expr_node = NULL;
49 }
50 
51 static GList *
_arcs(LogPipe * self)52 _arcs(LogPipe *self)
53 {
54   if (self->pipe_next)
55     return g_list_append(NULL, arc_new(self, self->pipe_next, ARC_TYPE_PIPE_NEXT));
56   else
57     return NULL;
58 }
59 
60 void
log_pipe_init_instance(LogPipe * self,GlobalConfig * cfg)61 log_pipe_init_instance(LogPipe *self, GlobalConfig *cfg)
62 {
63   g_atomic_counter_set(&self->ref_cnt, 1);
64   self->cfg = cfg;
65   self->pipe_next = NULL;
66   self->persist_name = NULL;
67   self->plugin_name = NULL;
68   self->signal_slot_connector = signal_slot_connector_new();
69 
70   /* NOTE: queue == NULL means that this pipe simply forwards the
71    * message along the pipeline, e.g. like it has called
72    * log_msg_forward_msg. Since this is a common case, it is better
73    * inlined (than to use an indirect call) for performance. */
74 
75   self->queue = NULL;
76   self->free_fn = log_pipe_free_method;
77   self->arcs = _arcs;
78 }
79 
80 LogPipe *
log_pipe_new(GlobalConfig * cfg)81 log_pipe_new(GlobalConfig *cfg)
82 {
83   LogPipe *self = g_new0(LogPipe, 1);
84 
85   log_pipe_init_instance(self, cfg);
86   return self;
87 }
88 
89 void
log_pipe_free_method(LogPipe * self)90 log_pipe_free_method(LogPipe *self)
91 {
92   ;
93 }
94 
95 LogPipe *
log_pipe_ref(LogPipe * self)96 log_pipe_ref(LogPipe *self)
97 {
98   g_assert(!self || g_atomic_counter_get(&self->ref_cnt) > 0);
99 
100   if (self)
101     {
102       g_atomic_counter_inc(&self->ref_cnt);
103     }
104   return self;
105 }
106 
107 static void
_free(LogPipe * self)108 _free(LogPipe *self)
109 {
110   if (self->free_fn)
111     self->free_fn(self);
112   g_free((gpointer)self->persist_name);
113   g_free(self->plugin_name);
114   g_list_free_full(self->info, g_free);
115   signal_slot_connector_free(self->signal_slot_connector);
116   g_free(self);
117 }
118 
119 gboolean
log_pipe_unref(LogPipe * self)120 log_pipe_unref(LogPipe *self)
121 {
122   g_assert(!self || g_atomic_counter_get(&self->ref_cnt));
123 
124   if (self && (g_atomic_counter_dec_and_test(&self->ref_cnt)))
125     {
126       _free(self);
127       return TRUE;
128     }
129 
130   return FALSE;
131 }
132 
133 void
log_pipe_forward_notify(LogPipe * self,gint notify_code,gpointer user_data)134 log_pipe_forward_notify(LogPipe *self, gint notify_code, gpointer user_data)
135 {
136   log_pipe_notify(self->pipe_next, notify_code, user_data);
137 }
138 
139 void
log_pipe_set_persist_name(LogPipe * self,const gchar * persist_name)140 log_pipe_set_persist_name(LogPipe *self, const gchar *persist_name)
141 {
142   g_free((gpointer)self->persist_name);
143   self->persist_name = g_strdup(persist_name);
144 }
145 
146 const gchar *
log_pipe_get_persist_name(const LogPipe * self)147 log_pipe_get_persist_name(const LogPipe *self)
148 {
149   return (self->generate_persist_name != NULL) ? self->generate_persist_name(self)
150          : self->persist_name;
151 }
152 
153 void
log_pipe_add_info(LogPipe * self,const gchar * info)154 log_pipe_add_info(LogPipe *self, const gchar *info)
155 {
156   self->info = g_list_append(self->info, g_strdup(info));
157 }
158 
159 #ifdef __linux__
160 
161 void
162 __log_pipe_forward_msg(LogPipe *self, LogMessage *msg, const LogPathOptions *path_options)
163 __attribute__((alias("log_pipe_forward_msg")));
164 
165 #endif
166