1 /*
2 ** Zabbix
3 ** Copyright (C) 2001-2021 Zabbix SIA
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program 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
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 **/
19 
20 #include "common.h"
21 #include "db.h"
22 #include "log.h"
23 #include "dbcache.h"
24 
25 /******************************************************************************
26  *                                                                            *
27  * Function: zbx_get_events_by_eventids                                       *
28  *                                                                            *
29  * Purpose: get events and flags that indicate what was filled in DB_EVENT    *
30  *          structure                                                         *
31  *                                                                            *
32  * Parameters: eventids   - [IN] requested event ids                          *
33  *             events     - [OUT] the array of events                         *
34  *                                                                            *
35  * Comments: use 'free_db_event' function to release allocated memory         *
36  *                                                                            *
37  ******************************************************************************/
zbx_db_get_events_by_eventids(zbx_vector_uint64_t * eventids,zbx_vector_ptr_t * events)38 void	zbx_db_get_events_by_eventids(zbx_vector_uint64_t *eventids, zbx_vector_ptr_t *events)
39 {
40 	DB_RESULT		result;
41 	DB_ROW			row;
42 	char			*sql = NULL;
43 	size_t			sql_alloc = 0, sql_offset = 0;
44 	zbx_vector_uint64_t	trigger_eventids, triggerids;
45 	int			i, index;
46 
47 	zbx_vector_uint64_create(&trigger_eventids);
48 	zbx_vector_uint64_create(&triggerids);
49 
50 	zbx_vector_uint64_sort(eventids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
51 	zbx_vector_uint64_uniq(eventids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
52 
53 	/* read event data */
54 
55 	zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
56 			"select eventid,source,object,objectid,clock,value,acknowledged,ns,name,severity"
57 			" from events"
58 			" where");
59 	DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "eventid", eventids->values, eventids->values_num);
60 	zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " order by eventid");
61 
62 	result = DBselect("%s", sql);
63 
64 	while (NULL != (row = DBfetch(result)))
65 	{
66 		DB_EVENT	*event = NULL;
67 
68 		event = (DB_EVENT *)zbx_malloc(event, sizeof(DB_EVENT));
69 		ZBX_STR2UINT64(event->eventid, row[0]);
70 		event->source = atoi(row[1]);
71 		event->object = atoi(row[2]);
72 		ZBX_STR2UINT64(event->objectid, row[3]);
73 		event->clock = atoi(row[4]);
74 		event->value = atoi(row[5]);
75 		event->acknowledged = atoi(row[6]);
76 		event->ns = atoi(row[7]);
77 		event->name = zbx_strdup(NULL, row[8]);
78 		event->severity = atoi(row[9]);
79 		event->suppressed = ZBX_PROBLEM_SUPPRESSED_FALSE;
80 
81 		event->trigger.triggerid = 0;
82 
83 		if (EVENT_SOURCE_TRIGGERS == event->source)
84 		{
85 			zbx_vector_ptr_create(&event->tags);
86 			zbx_vector_uint64_append(&trigger_eventids, event->eventid);
87 		}
88 
89 		if (EVENT_OBJECT_TRIGGER == event->object)
90 			zbx_vector_uint64_append(&triggerids, event->objectid);
91 
92 		zbx_vector_ptr_append(events, event);
93 	}
94 	DBfree_result(result);
95 
96 	/* read event_suppress data */
97 
98 	sql_offset = 0;
99 	zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select distinct eventid from event_suppress where");
100 	DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "eventid", eventids->values, eventids->values_num);
101 
102 	result = DBselect("%s", sql);
103 
104 	while (NULL != (row = DBfetch(result)))
105 	{
106 		DB_EVENT	*event;
107 		zbx_uint64_t	eventid;
108 
109 		ZBX_STR2UINT64(eventid, row[0]);
110 		if (FAIL == (index = zbx_vector_ptr_bsearch(events, &eventid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC)))
111 		{
112 			THIS_SHOULD_NEVER_HAPPEN;
113 			continue;
114 		}
115 
116 		event = (DB_EVENT *)events->values[index];
117 		event->suppressed = ZBX_PROBLEM_SUPPRESSED_TRUE;
118 	}
119 	DBfree_result(result);
120 
121 	if (0 != trigger_eventids.values_num)	/* EVENT_SOURCE_TRIGGERS */
122 	{
123 		DB_EVENT	*event = NULL;
124 
125 		sql_offset = 0;
126 		DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "eventid", trigger_eventids.values,
127 				trigger_eventids.values_num);
128 
129 		result = DBselect("select eventid,tag,value from event_tag where%s order by eventid", sql);
130 
131 		while (NULL != (row = DBfetch(result)))
132 		{
133 			zbx_uint64_t	eventid;
134 			zbx_tag_t	*tag;
135 
136 			ZBX_STR2UINT64(eventid, row[0]);
137 
138 			if (NULL == event || eventid != event->eventid)
139 			{
140 				if (FAIL == (index = zbx_vector_ptr_bsearch(events, &eventid,
141 						ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC)))
142 				{
143 					THIS_SHOULD_NEVER_HAPPEN;
144 					continue;
145 				}
146 
147 				event = (DB_EVENT *)events->values[index];
148 			}
149 
150 			tag = (zbx_tag_t *)zbx_malloc(NULL, sizeof(zbx_tag_t));
151 			tag->tag = zbx_strdup(NULL, row[1]);
152 			tag->value = zbx_strdup(NULL, row[2]);
153 			zbx_vector_ptr_append(&event->tags, tag);
154 		}
155 		DBfree_result(result);
156 	}
157 
158 	if (0 != triggerids.values_num)	/* EVENT_OBJECT_TRIGGER */
159 	{
160 		zbx_vector_uint64_sort(&triggerids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
161 		zbx_vector_uint64_uniq(&triggerids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
162 
163 		sql_offset = 0;
164 		DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "triggerid", triggerids.values,
165 				triggerids.values_num);
166 
167 		result = DBselect(
168 				"select triggerid,description,expression,priority,comments,url,recovery_expression,"
169 					"recovery_mode,value,opdata"
170 				" from triggers"
171 				" where%s",
172 				sql);
173 
174 		while (NULL != (row = DBfetch(result)))
175 		{
176 			zbx_uint64_t	triggerid;
177 
178 			ZBX_STR2UINT64(triggerid, row[0]);
179 
180 			for (i = 0; i < events->values_num; i++)
181 			{
182 				DB_EVENT	*event = (DB_EVENT *)events->values[i];
183 
184 				if (EVENT_OBJECT_TRIGGER != event->object)
185 					continue;
186 
187 				if (triggerid == event->objectid)
188 				{
189 					event->trigger.triggerid = triggerid;
190 					event->trigger.description = zbx_strdup(NULL, row[1]);
191 					event->trigger.expression = zbx_strdup(NULL, row[2]);
192 					ZBX_STR2UCHAR(event->trigger.priority, row[3]);
193 					event->trigger.comments = zbx_strdup(NULL, row[4]);
194 					event->trigger.url = zbx_strdup(NULL, row[5]);
195 					event->trigger.recovery_expression = zbx_strdup(NULL, row[6]);
196 					ZBX_STR2UCHAR(event->trigger.recovery_mode, row[7]);
197 					ZBX_STR2UCHAR(event->trigger.value, row[8]);
198 					event->trigger.opdata = zbx_strdup(NULL, row[9]);
199 				}
200 			}
201 		}
202 		DBfree_result(result);
203 	}
204 
205 	zbx_free(sql);
206 
207 	zbx_vector_uint64_destroy(&trigger_eventids);
208 	zbx_vector_uint64_destroy(&triggerids);
209 }
210 
211 /******************************************************************************
212  *                                                                            *
213  * Function: zbx_db_trigger_clean                                             *
214  *                                                                            *
215  * Purpose: frees resources allocated to store trigger data                   *
216  *                                                                            *
217  * Parameters: trigger -                                                      *
218  *                                                                            *
219  ******************************************************************************/
zbx_db_trigger_clean(DB_TRIGGER * trigger)220 void	zbx_db_trigger_clean(DB_TRIGGER *trigger)
221 {
222 	zbx_free(trigger->description);
223 	zbx_free(trigger->expression);
224 	zbx_free(trigger->recovery_expression);
225 	zbx_free(trigger->comments);
226 	zbx_free(trigger->url);
227 	zbx_free(trigger->opdata);
228 }
229 
230 /******************************************************************************
231  *                                                                            *
232  * Function: zbx_free_event                                                   *
233  *                                                                            *
234  * Purpose: deallocate memory allocated in function 'get_db_events_info'      *
235  *                                                                            *
236  * Parameters: event - [IN] event data                                        *
237  *                                                                            *
238  ******************************************************************************/
zbx_db_free_event(DB_EVENT * event)239 void	zbx_db_free_event(DB_EVENT *event)
240 {
241 	if (EVENT_SOURCE_TRIGGERS == event->source)
242 	{
243 		zbx_vector_ptr_clear_ext(&event->tags, (zbx_clean_func_t)zbx_free_tag);
244 		zbx_vector_ptr_destroy(&event->tags);
245 	}
246 
247 	if (0 != event->trigger.triggerid)
248 		zbx_db_trigger_clean(&event->trigger);
249 
250 	zbx_free(event->name);
251 	zbx_free(event);
252 }
253 
254 /******************************************************************************
255  *                                                                            *
256  * Function: get_db_eventid_r_eventid_pairs                                   *
257  *                                                                            *
258  * Purpose: get recovery event IDs by event IDs then map them together also   *
259  *          additional create a separate array of recovery event IDs          *
260  *                                                                            *
261  * Parameters: eventids    - [IN] requested event IDs                         *
262  *             event_pairs - [OUT] the array of event ID and recovery event   *
263  *                                 pairs                                      *
264  *             r_eventids  - [OUT] array of recovery event IDs                *
265  *                                                                            *
266  ******************************************************************************/
zbx_db_get_eventid_r_eventid_pairs(zbx_vector_uint64_t * eventids,zbx_vector_uint64_pair_t * event_pairs,zbx_vector_uint64_t * r_eventids)267 void	zbx_db_get_eventid_r_eventid_pairs(zbx_vector_uint64_t *eventids, zbx_vector_uint64_pair_t *event_pairs,
268 		zbx_vector_uint64_t *r_eventids)
269 {
270 	DB_RESULT	result;
271 	DB_ROW		row;
272 	char		*filter = NULL;
273 	size_t		filter_alloc = 0, filter_offset = 0;
274 
275 	DBadd_condition_alloc(&filter, &filter_alloc, &filter_offset, "eventid", eventids->values,
276 			eventids->values_num);
277 
278 	result = DBselect("select eventid,r_eventid"
279 			" from event_recovery"
280 			" where%s order by eventid",
281 			filter);
282 
283 	while (NULL != (row = DBfetch(result)))
284 	{
285 		zbx_uint64_pair_t	r_event;
286 
287 		ZBX_STR2UINT64(r_event.first, row[0]);
288 		ZBX_STR2UINT64(r_event.second, row[1]);
289 
290 		zbx_vector_uint64_pair_append(event_pairs, r_event);
291 		zbx_vector_uint64_append(r_eventids, r_event.second);
292 	}
293 	DBfree_result(result);
294 
295 	zbx_free(filter);
296 }
297