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 <assert.h>
21 
22 #include "common.h"
23 #include "log.h"
24 
25 #include "db.h"
26 #include "zbxjson.h"
27 #include "zbxtasks.h"
28 
29 /******************************************************************************
30  *                                                                            *
31  * Function: tm_remote_command_clear                                          *
32  *                                                                            *
33  * Purpose: frees remote command task resources                               *
34  *                                                                            *
35  * Parameters: data - [IN] the remote command task data                       *
36  *                                                                            *
37  ******************************************************************************/
tm_remote_command_clear(zbx_tm_remote_command_t * data)38 static void	tm_remote_command_clear(zbx_tm_remote_command_t *data)
39 {
40 	zbx_free(data->command);
41 	zbx_free(data->username);
42 	zbx_free(data->password);
43 	zbx_free(data->publickey);
44 	zbx_free(data->privatekey);
45 }
46 
47 /******************************************************************************
48  *                                                                            *
49  * Function: tm_remote_command_result_clear                                   *
50  *                                                                            *
51  * Purpose: frees remote command result task resources                        *
52  *                                                                            *
53  * Parameters: data - [IN] the remote command result task data                *
54  *                                                                            *
55  ******************************************************************************/
tm_remote_command_result_clear(zbx_tm_remote_command_result_t * data)56 static void	tm_remote_command_result_clear(zbx_tm_remote_command_result_t *data)
57 {
58 	zbx_free(data->info);
59 }
60 
61 /******************************************************************************
62  *                                                                            *
63  * Function: tm_data_result_clear                                             *
64  *                                                                            *
65  * Purpose: frees data result task resources                                  *
66  *                                                                            *
67  * Parameters: data - [IN] the data result task data                          *
68  *                                                                            *
69  ******************************************************************************/
tm_data_result_clear(zbx_tm_data_result_t * data)70 static void	tm_data_result_clear(zbx_tm_data_result_t *data)
71 {
72 	zbx_free(data->info);
73 }
74 
75 /******************************************************************************
76  *                                                                            *
77  * Function: tm_data_clear                                                    *
78  *                                                                            *
79  * Purpose: frees data task resources                                         *
80  *                                                                            *
81  * Parameters: data - [IN] the data task                                      *
82  *                                                                            *
83  ******************************************************************************/
tm_data_clear(zbx_tm_data_t * data)84 static void	tm_data_clear(zbx_tm_data_t *data)
85 {
86 	zbx_free(data->data);
87 }
88 
89 /******************************************************************************
90  *                                                                            *
91  * Function: zbx_tm_task_clear                                                *
92  *                                                                            *
93  * Purpose: frees task resources                                              *
94  *                                                                            *
95  * Parameters: task - [IN]                                                    *
96  *                                                                            *
97  ******************************************************************************/
zbx_tm_task_clear(zbx_tm_task_t * task)98 void	zbx_tm_task_clear(zbx_tm_task_t *task)
99 {
100 	if (NULL != task->data)
101 	{
102 		switch (task->type)
103 		{
104 			case ZBX_TM_TASK_REMOTE_COMMAND:
105 				tm_remote_command_clear((zbx_tm_remote_command_t *)task->data);
106 				break;
107 			case ZBX_TM_TASK_REMOTE_COMMAND_RESULT:
108 				tm_remote_command_result_clear((zbx_tm_remote_command_result_t *)task->data);
109 				break;
110 			case ZBX_TM_TASK_CHECK_NOW:
111 				/* nothing to clear */
112 				break;
113 			case ZBX_TM_TASK_DATA:
114 				tm_data_clear((zbx_tm_data_t *)task->data);
115 				break;
116 			case ZBX_TM_TASK_DATA_RESULT:
117 				tm_data_result_clear((zbx_tm_data_result_t *)task->data);
118 				break;
119 			default:
120 				THIS_SHOULD_NEVER_HAPPEN;
121 		}
122 	}
123 
124 	zbx_free(task->data);
125 	task->type = ZBX_TM_TASK_UNDEFINED;
126 }
127 
128 /******************************************************************************
129  *                                                                            *
130  * Function: zbx_tm_task_free                                                 *
131  *                                                                            *
132  * Purpose: frees task and its resources                                      *
133  *                                                                            *
134  * Parameters: task - [IN] the task to free                                   *
135  *                                                                            *
136  ******************************************************************************/
zbx_tm_task_free(zbx_tm_task_t * task)137 void	zbx_tm_task_free(zbx_tm_task_t *task)
138 {
139 	zbx_tm_task_clear(task);
140 	zbx_free(task);
141 }
142 
143 /******************************************************************************
144  *                                                                            *
145  * Function: zbx_tm_remote_command_create                                     *
146  *                                                                            *
147  * Purpose: create a remote command task data                                 *
148  *                                                                            *
149  * Parameters: command_type  - [IN] the remote command type (ZBX_SCRIPT_TYPE_)*
150  *             command       - [IN] the command to execute                    *
151  *             execute_on    - [IN] the execution target (ZBX_SCRIPT_EXECUTE_)*
152  *             port          - [IN] the target port                           *
153  *             authtype      - [IN] the authentication type                   *
154  *             username      - [IN] the username (can be NULL)                *
155  *             password      - [IN] the password (can be NULL)                *
156  *             publickey     - [IN] the public key (can be NULL)              *
157  *             privatekey    - [IN] the private key (can be NULL)             *
158  *             parent_taskid - [IN] the parent task identifier                *
159  *             hostid        - [IN] the target host identifier                *
160  *             alertid       - [IN] the alert identifier                      *
161  *                                                                            *
162  * Return value: The created remote command data.                             *
163  *                                                                            *
164  ******************************************************************************/
zbx_tm_remote_command_create(int command_type,const char * command,int execute_on,int port,int authtype,const char * username,const char * password,const char * publickey,const char * privatekey,zbx_uint64_t parent_taskid,zbx_uint64_t hostid,zbx_uint64_t alertid)165 zbx_tm_remote_command_t	*zbx_tm_remote_command_create(int command_type, const char *command, int execute_on, int port,
166 		int authtype, const char *username, const char *password, const char *publickey, const char *privatekey,
167 		zbx_uint64_t parent_taskid, zbx_uint64_t hostid, zbx_uint64_t alertid)
168 {
169 	zbx_tm_remote_command_t	*data;
170 
171 	data = (zbx_tm_remote_command_t *)zbx_malloc(NULL, sizeof(zbx_tm_remote_command_t));
172 	data->command_type = command_type;
173 	data->command = zbx_strdup(NULL, ZBX_NULL2EMPTY_STR(command));
174 	data->execute_on = execute_on;
175 	data->port = port;
176 	data->authtype = authtype;
177 	data->username = zbx_strdup(NULL, ZBX_NULL2EMPTY_STR(username));
178 	data->password = zbx_strdup(NULL, ZBX_NULL2EMPTY_STR(password));
179 	data->publickey = zbx_strdup(NULL, ZBX_NULL2EMPTY_STR(publickey));
180 	data->privatekey = zbx_strdup(NULL, ZBX_NULL2EMPTY_STR(privatekey));
181 	data->parent_taskid = parent_taskid;
182 	data->hostid = hostid;
183 	data->alertid = alertid;
184 
185 	return data;
186 }
187 
188 /******************************************************************************
189  *                                                                            *
190  * Function: zbx_tm_remote_command_result_create                              *
191  *                                                                            *
192  * Purpose: create a remote command result task data                          *
193  *                                                                            *
194  * Parameters: parent_taskid - [IN] the parent task identifier                *
195  *             status        - [IN] the remote command execution status       *
196  *             info          - [IN] the remote command execution result       *
197  *                                                                            *
198  * Return value: The created remote command result data.                      *
199  *                                                                            *
200  ******************************************************************************/
zbx_tm_remote_command_result_create(zbx_uint64_t parent_taskid,int status,const char * info)201 zbx_tm_remote_command_result_t	*zbx_tm_remote_command_result_create(zbx_uint64_t parent_taskid, int status,
202 		const char *info)
203 {
204 	zbx_tm_remote_command_result_t	*data;
205 
206 	data = (zbx_tm_remote_command_result_t *)zbx_malloc(NULL, sizeof(zbx_tm_remote_command_result_t));
207 	data->status = status;
208 	data->parent_taskid = parent_taskid;
209 	data->info = zbx_strdup(NULL, ZBX_NULL2EMPTY_STR(info));
210 
211 	return data;
212 }
213 
214 /******************************************************************************
215  *                                                                            *
216  * Function: zbx_tm_check_now_create                                          *
217  *                                                                            *
218  * Purpose: create a check now task data                                      *
219  *                                                                            *
220  * Parameters: itemid - [IN] the item identifier                              *
221  *                                                                            *
222  * Return value: The created check now data.                                  *
223  *                                                                            *
224  ******************************************************************************/
zbx_tm_check_now_create(zbx_uint64_t itemid)225 zbx_tm_check_now_t	*zbx_tm_check_now_create(zbx_uint64_t itemid)
226 {
227 	zbx_tm_check_now_t	*data;
228 
229 	data = (zbx_tm_check_now_t *)zbx_malloc(NULL, sizeof(zbx_tm_check_now_t));
230 	data->itemid = itemid;
231 
232 	return data;
233 }
234 
235 /******************************************************************************
236  *                                                                            *
237  * Function: zbx_tm_data_create                                               *
238  *                                                                            *
239  * Purpose: create a data task                                                *
240  *                                                                            *
241  * Parameters: parent_taskid - [IN] parent task identifier                    *
242  *             str           - [IN] data depending on type                    *
243  *             len           - [IN] length of data                            *
244  *             type          - [IN] type of data task                         *
245  *                                                                            *
246  * Return value: The created data task.                                       *
247  *                                                                            *
248  ******************************************************************************/
zbx_tm_data_create(zbx_uint64_t parent_taskid,const char * str,int len,int type)249 zbx_tm_data_t	*zbx_tm_data_create(zbx_uint64_t parent_taskid, const char *str, int len, int type)
250 {
251 	zbx_tm_data_t	*data;
252 
253 	data = (zbx_tm_data_t *)zbx_malloc(NULL, sizeof(zbx_tm_data_t));
254 	data->data = zbx_malloc(NULL, len + 1);
255 	memcpy(data->data, str, len);
256 	data->data[len] = '\0';
257 	data->parent_taskid = parent_taskid;
258 	data->type = type;
259 
260 	return data;
261 }
262 
263 /******************************************************************************
264  *                                                                            *
265  * Function: zbx_tm_data_result_create                                        *
266  *                                                                            *
267  * Purpose: create a data result task data                                    *
268  *                                                                            *
269  * Parameters: parent_taskid - [IN] the parent task identifier                *
270  *             status        - [IN] the data task execution status            *
271  *             info          - [IN] the data task execution result            *
272  *                                                                            *
273  * Return value: The created data task result.                                *
274  *                                                                            *
275  ******************************************************************************/
zbx_tm_data_result_create(zbx_uint64_t parent_taskid,int status,const char * info)276 zbx_tm_data_result_t	*zbx_tm_data_result_create(zbx_uint64_t parent_taskid, int status, const char *info)
277 {
278 	zbx_tm_data_result_t	*data;
279 
280 	data = (zbx_tm_data_result_t *)zbx_malloc(NULL, sizeof(zbx_tm_data_result_t));
281 	data->status = status;
282 	data->parent_taskid = parent_taskid;
283 	data->info = zbx_strdup(NULL, ZBX_NULL2EMPTY_STR(info));
284 
285 	return data;
286 }
287 
288 /******************************************************************************
289  *                                                                            *
290  * Function: zbx_tm_task_create                                               *
291  *                                                                            *
292  * Purpose: create a new task                                                 *
293  *                                                                            *
294  * Parameters: taskid       - [IN] the task identifier                        *
295  *             type         - [IN] the task type (see ZBX_TM_TASK_*)          *
296  *             status       - [IN] the task status (see ZBX_TM_STATUS_*)      *
297  *             clock        - [IN] the task creation time                     *
298  *             ttl          - [IN] the task expiration period in seconds      *
299  *             proxy_hostid - [IN] the destination proxy identifier (or 0)    *
300  *                                                                            *
301  * Return value: The created task.                                            *
302  *                                                                            *
303  ******************************************************************************/
zbx_tm_task_create(zbx_uint64_t taskid,unsigned char type,unsigned char status,int clock,int ttl,zbx_uint64_t proxy_hostid)304 zbx_tm_task_t	*zbx_tm_task_create(zbx_uint64_t taskid, unsigned char type, unsigned char status, int clock, int ttl,
305 		zbx_uint64_t proxy_hostid)
306 {
307 	zbx_tm_task_t	*task;
308 
309 	task = (zbx_tm_task_t *)zbx_malloc(NULL, sizeof(zbx_tm_task_t));
310 
311 	task->taskid = taskid;
312 	task->type = type;
313 	task->status = status;
314 	task->clock = clock;
315 	task->ttl = ttl;
316 	task->proxy_hostid = proxy_hostid;
317 	task->data = NULL;
318 
319 	return task;
320 }
321 
322 /******************************************************************************
323  *                                                                            *
324  * Function: tm_save_remote_command_tasks                                     *
325  *                                                                            *
326  * Purpose: saves remote command task data in database                        *
327  *                                                                            *
328  * Parameters: tasks     - [IN] the tasks                                     *
329  *             tasks_num - [IN] the number of tasks to process                *
330  *                                                                            *
331  * Return value: SUCCEED - the data was saved successfully                    *
332  *               FAIL    - otherwise                                          *
333  *                                                                            *
334  * Comments: The tasks array can contain mixture of task types.               *
335  *                                                                            *
336  ******************************************************************************/
tm_save_remote_command_tasks(zbx_tm_task_t ** tasks,int tasks_num)337 static int	tm_save_remote_command_tasks(zbx_tm_task_t **tasks, int tasks_num)
338 {
339 	int			i, ret;
340 	zbx_db_insert_t		db_insert;
341 	zbx_tm_remote_command_t	*data;
342 
343 	zbx_db_insert_prepare(&db_insert, "task_remote_command", "taskid", "command_type", "execute_on", "port",
344 			"authtype", "username", "password", "publickey", "privatekey", "command", "alertid",
345 			"parent_taskid", "hostid", NULL);
346 
347 	for (i = 0; i < tasks_num; i++)
348 	{
349 		zbx_tm_task_t	*task = tasks[i];
350 
351 		switch (task->type)
352 		{
353 			case ZBX_TM_TASK_REMOTE_COMMAND:
354 				data = (zbx_tm_remote_command_t *)task->data;
355 				zbx_db_insert_add_values(&db_insert, task->taskid, data->command_type, data->execute_on,
356 						data->port, data->authtype, data->username, data->password,
357 						data->publickey, data->privatekey, data->command, data->alertid,
358 						data->parent_taskid, data->hostid);
359 		}
360 	}
361 
362 	ret = zbx_db_insert_execute(&db_insert);
363 	zbx_db_insert_clean(&db_insert);
364 
365 	return ret;
366 }
367 
368 /******************************************************************************
369  *                                                                            *
370  * Function: tm_save_remote_command_result_tasks                              *
371  *                                                                            *
372  * Purpose: saves remote command result task data in database                 *
373  *                                                                            *
374  * Parameters: tasks     - [IN] the tasks                                     *
375  *             tasks_num - [IN] the number of tasks to process                *
376  *                                                                            *
377  * Return value: SUCCEED - the data was saved successfully                    *
378  *               FAIL    - otherwise                                          *
379  *                                                                            *
380  * Comments: The tasks array can contain mixture of task types.               *
381  *                                                                            *
382  ******************************************************************************/
tm_save_remote_command_result_tasks(zbx_tm_task_t ** tasks,int tasks_num)383 static int	tm_save_remote_command_result_tasks(zbx_tm_task_t **tasks, int tasks_num)
384 {
385 	int				i, ret;
386 	zbx_db_insert_t			db_insert;
387 	zbx_tm_remote_command_result_t	*data;
388 
389 	zbx_db_insert_prepare(&db_insert, "task_remote_command_result", "taskid", "status", "parent_taskid", "info",
390 			NULL);
391 
392 	for (i = 0; i < tasks_num; i++)
393 	{
394 		zbx_tm_task_t	*task = tasks[i];
395 
396 		switch (task->type)
397 		{
398 			case ZBX_TM_TASK_REMOTE_COMMAND_RESULT:
399 				data = (zbx_tm_remote_command_result_t *)task->data;
400 				zbx_db_insert_add_values(&db_insert, task->taskid, data->status, data->parent_taskid,
401 						data->info);
402 		}
403 	}
404 
405 	ret = zbx_db_insert_execute(&db_insert);
406 	zbx_db_insert_clean(&db_insert);
407 
408 	return ret;
409 }
410 
411 /******************************************************************************
412  *                                                                            *
413  * Function: tm_save_check_now_tasks                                          *
414  *                                                                            *
415  * Purpose: saves remote command task data in database                        *
416  *                                                                            *
417  * Parameters: tasks     - [IN] the tasks                                     *
418  *             tasks_num - [IN] the number of tasks to process                *
419  *                                                                            *
420  * Return value: SUCCEED - the data was saved successfully                    *
421  *               FAIL    - otherwise                                          *
422  *                                                                            *
423  * Comments: The tasks array can contain mixture of task types.               *
424  *                                                                            *
425  ******************************************************************************/
tm_save_check_now_tasks(zbx_tm_task_t ** tasks,int tasks_num)426 static int	tm_save_check_now_tasks(zbx_tm_task_t **tasks, int tasks_num)
427 {
428 	int			i, ret;
429 	zbx_db_insert_t		db_insert;
430 	zbx_tm_check_now_t	*data;
431 
432 	zbx_db_insert_prepare(&db_insert, "task_check_now", "taskid", "itemid", NULL);
433 
434 	for (i = 0; i < tasks_num; i++)
435 	{
436 		const zbx_tm_task_t	*task = tasks[i];
437 
438 		switch (task->type)
439 		{
440 			case ZBX_TM_TASK_CHECK_NOW:
441 				data = (zbx_tm_check_now_t *)task->data;
442 				zbx_db_insert_add_values(&db_insert, task->taskid, data->itemid);
443 		}
444 	}
445 
446 	ret = zbx_db_insert_execute(&db_insert);
447 	zbx_db_insert_clean(&db_insert);
448 
449 	return ret;
450 }
451 
452 /******************************************************************************
453  *                                                                            *
454  * Function: tm_save_data_tasks                                               *
455  *                                                                            *
456  * Purpose: saves data task in database                                       *
457  *                                                                            *
458  * Parameters: tasks     - [IN] the tasks                                     *
459  *             tasks_num - [IN] the number of tasks to process                *
460  *                                                                            *
461  * Return value: SUCCEED - the data was saved successfully                    *
462  *               FAIL    - otherwise                                          *
463  *                                                                            *
464  * Comments: The tasks array can contain mixture of task types.               *
465  *                                                                            *
466  ******************************************************************************/
tm_save_data_tasks(zbx_tm_task_t ** tasks,int tasks_num)467 static int	tm_save_data_tasks(zbx_tm_task_t **tasks, int tasks_num)
468 {
469 	int		i, ret;
470 	zbx_db_insert_t	db_insert;
471 	zbx_tm_data_t	*data;
472 
473 	zbx_db_insert_prepare(&db_insert, "task_data", "taskid", "type", "data", "parent_taskid", NULL);
474 
475 	for (i = 0; i < tasks_num; i++)
476 	{
477 		const zbx_tm_task_t	*task = tasks[i];
478 
479 		switch (task->type)
480 		{
481 			case ZBX_TM_TASK_DATA:
482 				data = (zbx_tm_data_t *)task->data;
483 				zbx_db_insert_add_values(&db_insert, task->taskid, data->type, data->data,
484 						data->parent_taskid);
485 		}
486 	}
487 
488 	ret = zbx_db_insert_execute(&db_insert);
489 	zbx_db_insert_clean(&db_insert);
490 
491 	return ret;
492 }
493 
494 /******************************************************************************
495  *                                                                            *
496  * Function: tm_save_data_result_tasks                                        *
497  *                                                                            *
498  * Purpose: saves data task result in database                                *
499  *                                                                            *
500  * Parameters: tasks     - [IN] the tasks                                     *
501  *             tasks_num - [IN] the number of tasks to process                *
502  *                                                                            *
503  * Return value: SUCCEED - the data was saved successfully                    *
504  *               FAIL    - otherwise                                          *
505  *                                                                            *
506  * Comments: The tasks array can contain mixture of task types.               *
507  *                                                                            *
508  ******************************************************************************/
tm_save_data_result_tasks(zbx_tm_task_t ** tasks,int tasks_num)509 static int	tm_save_data_result_tasks(zbx_tm_task_t **tasks, int tasks_num)
510 {
511 	int			i, ret;
512 	zbx_db_insert_t		db_insert;
513 	zbx_tm_data_result_t	*data;
514 
515 	zbx_db_insert_prepare(&db_insert, "task_result", "taskid", "status", "parent_taskid", "info", NULL);
516 
517 	for (i = 0; i < tasks_num; i++)
518 	{
519 		const zbx_tm_task_t	*task = tasks[i];
520 
521 		switch (task->type)
522 		{
523 			case ZBX_TM_TASK_DATA_RESULT:
524 				data = (zbx_tm_data_result_t *)task->data;
525 				zbx_db_insert_add_values(&db_insert, task->taskid, data->status, data->parent_taskid,
526 						data->info);
527 		}
528 	}
529 
530 	ret = zbx_db_insert_execute(&db_insert);
531 	zbx_db_insert_clean(&db_insert);
532 
533 	return ret;
534 }
535 
536 /******************************************************************************
537  *                                                                            *
538  * Function: tm_save_tasks                                                    *
539  *                                                                            *
540  * Purpose: saves tasks into database                                         *
541  *                                                                            *
542  * Parameters: tasks     - [IN] the tasks                                     *
543  *             tasks_num - [IN] the number of tasks to process                *
544  *                                                                            *
545  * Return value: SUCCEED - the tasks were saved successfully                  *
546  *               FAIL    - otherwise                                          *
547  *                                                                            *
548  ******************************************************************************/
tm_save_tasks(zbx_tm_task_t ** tasks,int tasks_num)549 static int	tm_save_tasks(zbx_tm_task_t **tasks, int tasks_num)
550 {
551 	int		i, ret, remote_command_num = 0, remote_command_result_num = 0, check_now_num = 0, ids_num = 0,
552 			data_num = 0, data_result_num = 0;
553 	zbx_uint64_t	taskid;
554 	zbx_db_insert_t	db_insert;
555 
556 	for (i = 0; i < tasks_num; i++)
557 	{
558 		if (0 == tasks[i]->taskid)
559 			ids_num++;
560 	}
561 
562 	if (0 != ids_num)
563 		taskid = DBget_maxid_num("task", ids_num);
564 
565 	for (i = 0; i < tasks_num; i++)
566 	{
567 		switch (tasks[i]->type)
568 		{
569 			case ZBX_TM_TASK_REMOTE_COMMAND:
570 				remote_command_num++;
571 				break;
572 			case ZBX_TM_TASK_REMOTE_COMMAND_RESULT:
573 				remote_command_result_num++;
574 				break;
575 			case ZBX_TM_TASK_CHECK_NOW:
576 				check_now_num++;
577 				break;
578 			case ZBX_TM_TASK_DATA:
579 				data_num++;
580 				break;
581 			case ZBX_TM_TASK_DATA_RESULT:
582 				data_result_num++;
583 				break;
584 			default:
585 				THIS_SHOULD_NEVER_HAPPEN;
586 				continue;
587 		}
588 
589 		if (0 == tasks[i]->taskid)
590 			tasks[i]->taskid = taskid++;
591 	}
592 
593 	zbx_db_insert_prepare(&db_insert, "task", "taskid", "type", "status", "clock", "ttl", "proxy_hostid", NULL);
594 
595 	for (i = 0; i < tasks_num; i++)
596 	{
597 		if (0 == tasks[i]->taskid)
598 			continue;
599 
600 		zbx_db_insert_add_values(&db_insert, tasks[i]->taskid, (int)tasks[i]->type, (int)tasks[i]->status,
601 				tasks[i]->clock, tasks[i]->ttl, tasks[i]->proxy_hostid);
602 	}
603 
604 	ret = zbx_db_insert_execute(&db_insert);
605 	zbx_db_insert_clean(&db_insert);
606 
607 	if (SUCCEED == ret && 0 != remote_command_num)
608 		ret = tm_save_remote_command_tasks(tasks, tasks_num);
609 
610 	if (SUCCEED == ret && 0 != remote_command_result_num)
611 		ret = tm_save_remote_command_result_tasks(tasks, tasks_num);
612 
613 	if (SUCCEED == ret && 0 != check_now_num)
614 		ret = tm_save_check_now_tasks(tasks, tasks_num);
615 
616 	if (SUCCEED == ret && 0 != data_num)
617 		ret = tm_save_data_tasks(tasks, tasks_num);
618 
619 	if (SUCCEED == ret && 0 != data_result_num)
620 		ret = tm_save_data_result_tasks(tasks, tasks_num);
621 
622 	return ret;
623 }
624 
625 /******************************************************************************
626  *                                                                            *
627  * Function: zbx_tm_save_tasks                                                *
628  *                                                                            *
629  * Purpose: saves tasks and their data into database                          *
630  *                                                                            *
631  * Parameters: tasks - [IN] the tasks                                         *
632  *                                                                            *
633  ******************************************************************************/
zbx_tm_save_tasks(zbx_vector_ptr_t * tasks)634 void	zbx_tm_save_tasks(zbx_vector_ptr_t *tasks)
635 {
636 	zabbix_log(LOG_LEVEL_DEBUG, "In %s() tasks_num:%d", __func__, tasks->values_num);
637 
638 	tm_save_tasks((zbx_tm_task_t **)tasks->values, tasks->values_num);
639 
640 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
641 }
642 
643 /******************************************************************************
644  *                                                                            *
645  * Function: zbx_tm_save_task                                                 *
646  *                                                                            *
647  * Purpose: saves task and its data into database                             *
648  *                                                                            *
649  * Parameters: task - [IN] the task                                           *
650  *                                                                            *
651  * Return value: SUCCEED - the task was saved successfully                    *
652  *               FAIL    - otherwise                                          *
653  *                                                                            *
654  ******************************************************************************/
zbx_tm_save_task(zbx_tm_task_t * task)655 int	zbx_tm_save_task(zbx_tm_task_t *task)
656 {
657 	int	ret;
658 
659 	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
660 
661 	ret = tm_save_tasks(&task, 1);
662 
663 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
664 
665 	return ret;
666 }
667 
668 /******************************************************************************
669  *                                                                            *
670  * Function: zbx_tm_update_task_status                                        *
671  *                                                                            *
672  * Purpose: update status of the specified tasks in database                  *
673  *                                                                            *
674  * Parameters: tasks  - [IN] the tasks                                        *
675  *             status - [IN] the new status                                   *
676  *                                                                            *
677  ******************************************************************************/
zbx_tm_update_task_status(zbx_vector_ptr_t * tasks,int status)678 void	zbx_tm_update_task_status(zbx_vector_ptr_t *tasks, int status)
679 {
680 	zbx_vector_uint64_t	taskids;
681 	int			i;
682 	char			*sql = NULL;
683 	size_t			sql_alloc = 0, sql_offset = 0;
684 
685 	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
686 
687 	zbx_vector_uint64_create(&taskids);
688 
689 	for (i = 0; i < tasks->values_num; i++)
690 	{
691 		zbx_tm_task_t	*task = (zbx_tm_task_t *)tasks->values[i];
692 		zbx_vector_uint64_append(&taskids, task->taskid);
693 	}
694 
695 	zbx_vector_uint64_sort(&taskids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
696 
697 	zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update task set status=%d where", status);
698 	DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "taskid", taskids.values, taskids.values_num);
699 	DBexecute("%s", sql);
700 	zbx_free(sql);
701 
702 	zbx_vector_uint64_destroy(&taskids);
703 
704 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
705 }
706 
707 /******************************************************************************
708  *                                                                            *
709  * Function: tm_json_serialize_task                                           *
710  *                                                                            *
711  * Purpose: serializes common task data in json format                        *
712  *                                                                            *
713  * Parameters: json - [OUT] the json data                                     *
714  *             data - [IN] the task to serialize                              *
715  *                                                                            *
716  ******************************************************************************/
tm_json_serialize_task(struct zbx_json * json,const zbx_tm_task_t * task)717 static void	tm_json_serialize_task(struct zbx_json *json, const zbx_tm_task_t *task)
718 {
719 	zbx_json_addint64(json, ZBX_PROTO_TAG_TYPE, task->type);
720 	zbx_json_addint64(json, ZBX_PROTO_TAG_CLOCK, task->clock);
721 	zbx_json_addint64(json, ZBX_PROTO_TAG_TTL, task->ttl);
722 }
723 
724 /******************************************************************************
725  *                                                                            *
726  * Function: tm_json_serialize_remote_command                                 *
727  *                                                                            *
728  * Purpose: serializes remote command data in json format                     *
729  *                                                                            *
730  * Parameters: json - [OUT] the json data                                     *
731  *             data - [IN] the remote command to serialize                    *
732  *                                                                            *
733  ******************************************************************************/
tm_json_serialize_remote_command(struct zbx_json * json,const zbx_tm_remote_command_t * data)734 static void	tm_json_serialize_remote_command(struct zbx_json *json, const zbx_tm_remote_command_t *data)
735 {
736 	zbx_json_addint64(json, ZBX_PROTO_TAG_COMMANDTYPE, data->command_type);
737 	zbx_json_addstring(json, ZBX_PROTO_TAG_COMMAND, data->command, ZBX_JSON_TYPE_STRING);
738 	zbx_json_addint64(json, ZBX_PROTO_TAG_EXECUTE_ON, data->execute_on);
739 	zbx_json_addint64(json, ZBX_PROTO_TAG_PORT, data->port);
740 	zbx_json_addint64(json, ZBX_PROTO_TAG_AUTHTYPE, data->authtype);
741 	zbx_json_addstring(json, ZBX_PROTO_TAG_USERNAME, data->username, ZBX_JSON_TYPE_STRING);
742 	zbx_json_addstring(json, ZBX_PROTO_TAG_PASSWORD, data->password, ZBX_JSON_TYPE_STRING);
743 	zbx_json_addstring(json, ZBX_PROTO_TAG_PUBLICKEY, data->publickey, ZBX_JSON_TYPE_STRING);
744 	zbx_json_addstring(json, ZBX_PROTO_TAG_PRIVATEKEY, data->privatekey, ZBX_JSON_TYPE_STRING);
745 	zbx_json_adduint64(json, ZBX_PROTO_TAG_ALERTID, data->alertid);
746 	zbx_json_adduint64(json, ZBX_PROTO_TAG_PARENT_TASKID, data->parent_taskid);
747 	zbx_json_adduint64(json, ZBX_PROTO_TAG_HOSTID, data->hostid);
748 }
749 
750 /******************************************************************************
751  *                                                                            *
752  * Function: tm_json_serialize_remote_command_result                          *
753  *                                                                            *
754  * Purpose: serializes remote command result data in json format              *
755  *                                                                            *
756  * Parameters: json - [OUT] the json data                                     *
757  *             data - [IN] the remote command result to serialize             *
758  *                                                                            *
759  ******************************************************************************/
tm_json_serialize_remote_command_result(struct zbx_json * json,const zbx_tm_remote_command_result_t * data)760 static void	tm_json_serialize_remote_command_result(struct zbx_json *json,
761 		const zbx_tm_remote_command_result_t *data)
762 {
763 	zbx_json_addint64(json, ZBX_PROTO_TAG_STATUS, data->status);
764 	zbx_json_addstring(json, ZBX_PROTO_TAG_INFO, data->info, ZBX_JSON_TYPE_STRING);
765 	zbx_json_adduint64(json, ZBX_PROTO_TAG_PARENT_TASKID, data->parent_taskid);
766 }
767 
768 /******************************************************************************
769  *                                                                            *
770  * Function: tm_json_serialize_check_now                                      *
771  *                                                                            *
772  * Purpose: serializes check now data in json format                          *
773  *                                                                            *
774  * Parameters: json - [OUT] the json data                                     *
775  *             data - [IN] the check now to serialize                         *
776  *                                                                            *
777  ******************************************************************************/
tm_json_serialize_check_now(struct zbx_json * json,const zbx_tm_check_now_t * data)778 static void	tm_json_serialize_check_now(struct zbx_json *json, const zbx_tm_check_now_t *data)
779 {
780 	zbx_json_addint64(json, ZBX_PROTO_TAG_ITEMID, data->itemid);
781 }
782 
783 /******************************************************************************
784  *                                                                            *
785  * Function: tm_json_serialize_data                                           *
786  *                                                                            *
787  * Purpose: serializes data task in json format                               *
788  *                                                                            *
789  * Parameters: json - [OUT] the json data                                     *
790  *             data - [IN] the data task to serialize                         *
791  *                                                                            *
792  ******************************************************************************/
tm_json_serialize_data(struct zbx_json * json,const zbx_tm_data_t * data)793 static void	tm_json_serialize_data(struct zbx_json *json, const zbx_tm_data_t *data)
794 {
795 	zbx_json_adduint64(json, ZBX_PROTO_TAG_DATA_TYPE, data->type);
796 	zbx_json_adduint64(json, ZBX_PROTO_TAG_PARENT_TASKID, data->parent_taskid);
797 	zbx_json_addstring(json, ZBX_PROTO_TAG_DATA, data->data, ZBX_JSON_TYPE_STRING);
798 }
799 
800 /******************************************************************************
801  *                                                                            *
802  * Function: tm_json_serialize_data_result                                    *
803  *                                                                            *
804  * Purpose: serializes data task result in json format                        *
805  *                                                                            *
806  * Parameters: json - [OUT] the json data                                     *
807  *             data - [IN] the data task result to serialize                  *
808  *                                                                            *
809  ******************************************************************************/
tm_json_serialize_data_result(struct zbx_json * json,const zbx_tm_data_result_t * data)810 static void	tm_json_serialize_data_result(struct zbx_json *json, const zbx_tm_data_result_t *data)
811 {
812 	zbx_json_addint64(json, ZBX_PROTO_TAG_STATUS, data->status);
813 	zbx_json_addstring(json, ZBX_PROTO_TAG_INFO, data->info, ZBX_JSON_TYPE_STRING);
814 	zbx_json_adduint64(json, ZBX_PROTO_TAG_PARENT_TASKID, data->parent_taskid);
815 }
816 
817 /******************************************************************************
818  *                                                                            *
819  * Function: zbx_tm_json_serialize_tasks                                      *
820  *                                                                            *
821  * Purpose: serializes remote command data in json format                     *
822  *                                                                            *
823  * Parameters: json  - [OUT] the json data                                    *
824  *             tasks - [IN] the tasks to serialize                            *
825  *                                                                            *
826  ******************************************************************************/
zbx_tm_json_serialize_tasks(struct zbx_json * json,const zbx_vector_ptr_t * tasks)827 void	zbx_tm_json_serialize_tasks(struct zbx_json *json, const zbx_vector_ptr_t *tasks)
828 {
829 	int	i;
830 
831 	zbx_json_addarray(json, ZBX_PROTO_TAG_TASKS);
832 
833 	for (i = 0; i < tasks->values_num; i++)
834 	{
835 		const zbx_tm_task_t	*task = (const zbx_tm_task_t *)tasks->values[i];
836 
837 		zbx_json_addobject(json, NULL);
838 		tm_json_serialize_task(json, task);
839 
840 		switch (task->type)
841 		{
842 			case ZBX_TM_TASK_REMOTE_COMMAND:
843 				tm_json_serialize_remote_command(json, (zbx_tm_remote_command_t *)task->data);
844 				break;
845 			case ZBX_TM_TASK_REMOTE_COMMAND_RESULT:
846 				tm_json_serialize_remote_command_result(json, (zbx_tm_remote_command_result_t *)task->data);
847 				break;
848 			case ZBX_TM_TASK_CHECK_NOW:
849 				tm_json_serialize_check_now(json, (zbx_tm_check_now_t *)task->data);
850 				break;
851 			case ZBX_TM_TASK_DATA:
852 				tm_json_serialize_data(json, (zbx_tm_data_t *)task->data);
853 				break;
854 			case ZBX_TM_TASK_DATA_RESULT:
855 				tm_json_serialize_data_result(json, (zbx_tm_data_result_t *)task->data);
856 				break;
857 			default:
858 				THIS_SHOULD_NEVER_HAPPEN;
859 				break;
860 		}
861 
862 		zbx_json_close(json);
863 	}
864 
865 	zbx_json_close(json);
866 }
867 
868 /******************************************************************************
869  *                                                                            *
870  * Function: tm_json_deserialize_remote_command                               *
871  *                                                                            *
872  * Purpose: deserializes remote command from json data                        *
873  *                                                                            *
874  * Parameters: jp - [IN] the json data                                        *
875  *                                                                            *
876  * Return value: The deserialized remote command data or NULL if              *
877  *               deserialization failed.                                      *
878  *                                                                            *
879  ******************************************************************************/
tm_json_deserialize_remote_command(const struct zbx_json_parse * jp)880 static zbx_tm_remote_command_t	*tm_json_deserialize_remote_command(const struct zbx_json_parse *jp)
881 {
882 	char			value[MAX_STRING_LEN];
883 	int			commandtype, execute_on, port, authtype;
884 	zbx_uint64_t		alertid, parent_taskid, hostid;
885 	char			*username = NULL, *password = NULL, *publickey = NULL, *privatekey = NULL,
886 				*command = NULL;
887 	size_t			username_alloc = 0, password_alloc = 0, publickey_alloc = 0, privatekey_alloc = 0,
888 				command_alloc = 0;
889 	zbx_tm_remote_command_t	*data = NULL;
890 
891 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_COMMANDTYPE, value, sizeof(value), NULL))
892 		goto out;
893 
894 	commandtype = atoi(value);
895 
896 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_EXECUTE_ON, value, sizeof(value), NULL))
897 		goto out;
898 
899 	execute_on = atoi(value);
900 
901 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_PORT, value, sizeof(value), NULL))
902 		goto out;
903 
904 	port = atoi(value);
905 
906 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_AUTHTYPE, value, sizeof(value), NULL))
907 		goto out;
908 
909 	authtype = atoi(value);
910 
911 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_ALERTID, value, sizeof(value), NULL) ||
912 			SUCCEED != is_uint64(value, &alertid))
913 	{
914 		goto out;
915 	}
916 
917 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_PARENT_TASKID, value, sizeof(value), NULL) ||
918 			SUCCEED != is_uint64(value, &parent_taskid))
919 	{
920 		goto out;
921 	}
922 
923 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_HOSTID, value, sizeof(value), NULL) ||
924 			SUCCEED != is_uint64(value, &hostid))
925 	{
926 		goto out;
927 	}
928 
929 	if (SUCCEED != zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_USERNAME, &username, &username_alloc, NULL))
930 		goto out;
931 
932 	if (SUCCEED != zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_PASSWORD, &password, &password_alloc, NULL))
933 		goto out;
934 
935 	if (SUCCEED != zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_PUBLICKEY, &publickey, &publickey_alloc, NULL))
936 		goto out;
937 
938 	if (SUCCEED != zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_PRIVATEKEY, &privatekey, &privatekey_alloc, NULL))
939 		goto out;
940 
941 	if (SUCCEED != zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_COMMAND, &command, &command_alloc, NULL))
942 		goto out;
943 
944 	data = zbx_tm_remote_command_create(commandtype, command, execute_on, port, authtype, username, password,
945 			publickey, privatekey, parent_taskid, hostid, alertid);
946 out:
947 	zbx_free(command);
948 	zbx_free(privatekey);
949 	zbx_free(publickey);
950 	zbx_free(password);
951 	zbx_free(username);
952 
953 	return data;
954 }
955 
956 /******************************************************************************
957  *                                                                            *
958  * Function: tm_json_deserialize_remote_command_result                        *
959  *                                                                            *
960  * Purpose: deserializes remote command result from json data                 *
961  *                                                                            *
962  * Parameters: jp - [IN] the json data                                        *
963  *                                                                            *
964  * Return value: The deserialized remote command result data or NULL if       *
965  *               deserialization failed.                                      *
966  *                                                                            *
967  ******************************************************************************/
tm_json_deserialize_remote_command_result(const struct zbx_json_parse * jp)968 static zbx_tm_remote_command_result_t	*tm_json_deserialize_remote_command_result(const struct zbx_json_parse *jp)
969 {
970 	char				value[MAX_STRING_LEN];
971 	int				status;
972 	zbx_uint64_t			parent_taskid;
973 	char				*info = NULL;
974 	size_t				info_alloc = 0;
975 	zbx_tm_remote_command_result_t	*data = NULL;
976 
977 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_STATUS, value, sizeof(value), NULL))
978 		goto out;
979 
980 	status = atoi(value);
981 
982 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_PARENT_TASKID, value, sizeof(value), NULL) ||
983 			SUCCEED != is_uint64(value, &parent_taskid))
984 	{
985 		goto out;
986 	}
987 
988 	if (SUCCEED != zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_INFO, &info, &info_alloc, NULL))
989 		goto out;
990 
991 	data = zbx_tm_remote_command_result_create(parent_taskid, status, info);
992 out:
993 	zbx_free(info);
994 
995 	return data;
996 }
997 
998 /******************************************************************************
999  *                                                                            *
1000  * Function: tm_json_deserialize_check_now                                    *
1001  *                                                                            *
1002  * Purpose: deserializes check now from json data                             *
1003  *                                                                            *
1004  * Parameters: jp - [IN] the json data                                        *
1005  *                                                                            *
1006  * Return value: The deserialized check now data or NULL if deserialization   *
1007  *               failed.                                                      *
1008  *                                                                            *
1009  ******************************************************************************/
tm_json_deserialize_check_now(const struct zbx_json_parse * jp)1010 static zbx_tm_check_now_t	*tm_json_deserialize_check_now(const struct zbx_json_parse *jp)
1011 {
1012 	char		value[MAX_ID_LEN + 1];
1013 	zbx_uint64_t	itemid;
1014 
1015 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_ITEMID, value, sizeof(value), NULL) ||
1016 			SUCCEED != is_uint64(value, &itemid))
1017 	{
1018 		return NULL;
1019 	}
1020 
1021 	return zbx_tm_check_now_create(itemid);
1022 }
1023 
1024 /******************************************************************************
1025  *                                                                            *
1026  * Function: tm_json_deserialize_data                                         *
1027  *                                                                            *
1028  * Purpose: deserializes data task from json                                  *
1029  *                                                                            *
1030  * Parameters: jp - [IN] the json                                             *
1031  *                                                                            *
1032  * Return value: The deserialized data task or NULL if deserialization        *
1033  *               failed.                                                      *
1034  *                                                                            *
1035  ******************************************************************************/
tm_json_deserialize_data(const struct zbx_json_parse * jp)1036 static zbx_tm_data_t	*tm_json_deserialize_data(const struct zbx_json_parse *jp)
1037 {
1038 	char		*str = NULL, value[MAX_ID_LEN + 1];
1039 	size_t		str_alloc = 0;
1040 	zbx_tm_data_t	*data = NULL;
1041 	zbx_uint64_t	parent_taskid;
1042 	int		type;
1043 
1044 	if (SUCCEED != zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_DATA, &str, &str_alloc, NULL))
1045 		goto out;
1046 
1047 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_PARENT_TASKID, value, sizeof(value), NULL) ||
1048 			SUCCEED != is_uint64(value, &parent_taskid))
1049 	{
1050 		goto out;
1051 	}
1052 
1053 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_DATA_TYPE, value, sizeof(value), NULL))
1054 	{
1055 		goto out;
1056 	}
1057 	type = atoi(value);
1058 
1059 	data = zbx_tm_data_create(parent_taskid, str, strlen(str), type);
1060 out:
1061 	zbx_free(str);
1062 
1063 	return data;
1064 }
1065 
1066 /******************************************************************************
1067  *                                                                            *
1068  * Function: tm_json_deserialize_data_result                                  *
1069  *                                                                            *
1070  * Purpose: deserializes data task result from json                           *
1071  *                                                                            *
1072  * Parameters: jp - [IN] the json                                             *
1073  *                                                                            *
1074  * Return value: The deserialized data task result or NULL if deserialization *
1075  *               failed.                                                      *
1076  *                                                                            *
1077  ******************************************************************************/
tm_json_deserialize_data_result(const struct zbx_json_parse * jp)1078 static zbx_tm_data_result_t	*tm_json_deserialize_data_result(const struct zbx_json_parse *jp)
1079 {
1080 	char			value[MAX_STRING_LEN];
1081 	int			status;
1082 	zbx_uint64_t		parent_taskid;
1083 	char			*info = NULL;
1084 	size_t			info_alloc = 0;
1085 	zbx_tm_data_result_t	*data = NULL;
1086 
1087 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_STATUS, value, sizeof(value), NULL))
1088 		goto out;
1089 
1090 	status = atoi(value);
1091 
1092 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_PARENT_TASKID, value, sizeof(value), NULL) ||
1093 			SUCCEED != is_uint64(value, &parent_taskid))
1094 	{
1095 		goto out;
1096 	}
1097 
1098 	if (SUCCEED != zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_INFO, &info, &info_alloc, NULL))
1099 		goto out;
1100 
1101 	data = zbx_tm_data_result_create(parent_taskid, status, info);
1102 out:
1103 	zbx_free(info);
1104 
1105 	return data;
1106 }
1107 
1108 /******************************************************************************
1109  *                                                                            *
1110  * Function: tm_json_deserialize_task                                         *
1111  *                                                                            *
1112  * Purpose: deserializes common task data from json data                      *
1113  *                                                                            *
1114  * Parameters: jp - [IN] the json data                                        *
1115  *                                                                            *
1116  * Return value: The deserialized task data or NULL if deserialization failed.*
1117  *                                                                            *
1118  ******************************************************************************/
tm_json_deserialize_task(const struct zbx_json_parse * jp)1119 static zbx_tm_task_t	*tm_json_deserialize_task(const struct zbx_json_parse *jp)
1120 {
1121 	char	value[MAX_STRING_LEN];
1122 	int	type, clock, ttl;
1123 
1124 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_TYPE, value, sizeof(value), NULL))
1125 		return NULL;
1126 
1127 	ZBX_STR2UCHAR(type, value);
1128 
1129 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_CLOCK, value, sizeof(value), NULL))
1130 		return NULL;
1131 
1132 	clock = atoi(value);
1133 
1134 	if (SUCCEED != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_TTL, value, sizeof(value), NULL))
1135 		return NULL;
1136 
1137 	ttl = atoi(value);
1138 
1139 	return zbx_tm_task_create(0, type, ZBX_TM_STATUS_NEW, clock, ttl, 0);
1140 }
1141 
1142 /******************************************************************************
1143  *                                                                            *
1144  * Function: zbx_tm_json_deserialize_tasks                                    *
1145  *                                                                            *
1146  * Purpose: deserializes tasks from json data                                 *
1147  *                                                                            *
1148  * Parameters: jp    - [IN] the json data                                     *
1149  *             tasks - [OUT] the deserialized tasks                           *
1150  *                                                                            *
1151  ******************************************************************************/
zbx_tm_json_deserialize_tasks(const struct zbx_json_parse * jp,zbx_vector_ptr_t * tasks)1152 void	zbx_tm_json_deserialize_tasks(const struct zbx_json_parse *jp, zbx_vector_ptr_t *tasks)
1153 {
1154 	const char		*pnext = NULL;
1155 	struct zbx_json_parse	jp_task;
1156 
1157 	while (NULL != (pnext = zbx_json_next(jp, pnext)))
1158 	{
1159 		zbx_tm_task_t	*task;
1160 
1161 		if (SUCCEED != zbx_json_brackets_open(pnext, &jp_task))
1162 		{
1163 			zabbix_log(LOG_LEVEL_DEBUG, "Cannot deserialize task record: %s", jp->start);
1164 			continue;
1165 		}
1166 
1167 		task = tm_json_deserialize_task(&jp_task);
1168 
1169 		if (NULL == task)
1170 		{
1171 			zabbix_log(LOG_LEVEL_DEBUG, "Cannot deserialize task at: %s", jp_task.start);
1172 			continue;
1173 		}
1174 
1175 		switch (task->type)
1176 		{
1177 			case ZBX_TM_TASK_REMOTE_COMMAND:
1178 				task->data = tm_json_deserialize_remote_command(&jp_task);
1179 				break;
1180 			case ZBX_TM_TASK_REMOTE_COMMAND_RESULT:
1181 				task->data = tm_json_deserialize_remote_command_result(&jp_task);
1182 				break;
1183 			case ZBX_TM_TASK_CHECK_NOW:
1184 				task->data = tm_json_deserialize_check_now(&jp_task);
1185 				break;
1186 			case ZBX_TM_TASK_DATA:
1187 				task->data = tm_json_deserialize_data(&jp_task);
1188 				break;
1189 			case ZBX_TM_TASK_DATA_RESULT:
1190 				task->data = tm_json_deserialize_data_result(&jp_task);
1191 				break;
1192 			default:
1193 				THIS_SHOULD_NEVER_HAPPEN;
1194 				break;
1195 		}
1196 
1197 		if (NULL == task->data)
1198 		{
1199 			zabbix_log(LOG_LEVEL_DEBUG, "Cannot deserialize task data at: %s", jp_task.start);
1200 			zbx_tm_task_free(task);
1201 			continue;
1202 		}
1203 
1204 		zbx_vector_ptr_append(tasks, task);
1205 	}
1206 }
1207 
1208 /******************************************************************************
1209  *                                                                            *
1210  * Function: zbx_create_task_data                                             *
1211  *                                                                            *
1212  * Purpose: insert task and its data in database                              *
1213  *                                                                            *
1214  * Parameters: data         - [IN] task data                                  *
1215  *             len          - [IN] length of data                             *
1216  *             proxy_hostid - [IN] proxy identifier                           *
1217  *                                                                            *
1218  * Return value: The created data task id or 0 on failure.                    *
1219  *                                                                            *
1220  ******************************************************************************/
zbx_create_task_data(const char * data,int len,zbx_uint64_t proxy_hostid)1221 static zbx_uint64_t	zbx_create_task_data(const char *data, int len, zbx_uint64_t proxy_hostid)
1222 {
1223 	zbx_tm_task_t	*task;
1224 	zbx_uint64_t	taskid;
1225 
1226 	taskid = DBget_maxid("task");
1227 
1228 	task = zbx_tm_task_create(taskid, ZBX_TM_TASK_DATA, ZBX_TM_STATUS_NEW, time(NULL), ZBX_DATA_TTL, proxy_hostid);
1229 
1230 	task->data = zbx_tm_data_create(task->taskid, data, len, ZBX_TM_DATA_TYPE_TEST_ITEM);
1231 
1232 	DBbegin();
1233 
1234 	if (FAIL == zbx_tm_save_task(task))
1235 		taskid = 0;
1236 
1237 	DBcommit();
1238 
1239 	zbx_tm_task_free(task);
1240 
1241 	return taskid;
1242 }
1243 
1244 /******************************************************************************
1245  *                                                                            *
1246  * Function: zbx_tm_task_result_wait                                          *
1247  *                                                                            *
1248  * Purpose: wait for task result                                              *
1249  *                                                                            *
1250  * Parameters: taskid - [IN] task identifier                                  *
1251  *             info   - [OUT] task result or error reason                     *
1252  *                                                                            *
1253  * Return value: SUCCEED - if task was executed without errors                *
1254  *               FAIL    - otherwise                                          *
1255  *                                                                            *
1256  ******************************************************************************/
zbx_tm_task_result_wait(zbx_uint64_t taskid,char ** info)1257 static int	zbx_tm_task_result_wait(zbx_uint64_t taskid, char **info)
1258 {
1259 	DB_RESULT	result;
1260 	DB_ROW		row;
1261 	int		ret, time_start;
1262 
1263 	for (time_start = time(NULL); ZBX_DATA_TTL > time(NULL) - time_start; sleep(1))
1264 	{
1265 		result = DBselect("select status,info"
1266 				" from task_result"
1267 				" where parent_taskid=" ZBX_FS_UI64,
1268 				taskid);
1269 
1270 		if (NULL != (row = DBfetch(result)))
1271 		{
1272 			*info = zbx_strdup(NULL, row[1]);
1273 
1274 			if (SUCCEED != (ret = atoi(row[0])))
1275 				ret = FAIL;
1276 
1277 			DBfree_result(result);
1278 			return ret;
1279 		}
1280 
1281 		DBfree_result(result);
1282 	}
1283 
1284 	*info = zbx_strdup(NULL, "Timeout while waiting for result.");
1285 
1286 	return FAIL;
1287 }
1288 
1289 /******************************************************************************
1290  *                                                                            *
1291  * Function: zbx_tm_execute_task_data                                         *
1292  *                                                                            *
1293  * Purpose: wait for task result                                              *
1294  *                                                                            *
1295  * Parameters: data         - [IN] task data                                  *
1296  *             len          - [IN] length of data                             *
1297  *             proxy_hostid - [IN] proxy identifier                           *
1298  *             info         - [OUT] task result or error reason               *
1299  *                                                                            *
1300  * Return value: SUCCEED - if task was executed without errors                *
1301  *               FAIL    - otherwise                                          *
1302  *                                                                            *
1303  ******************************************************************************/
zbx_tm_execute_task_data(const char * data,int len,zbx_uint64_t proxy_hostid,char ** info)1304 int	zbx_tm_execute_task_data(const char *data, int len, zbx_uint64_t proxy_hostid, char **info)
1305 {
1306 	zbx_uint64_t	taskid;
1307 
1308 	if (0 == (taskid = zbx_create_task_data(data, len, proxy_hostid)))
1309 	{
1310 		*info = zbx_strdup(NULL, "Cannot create task.");
1311 		return FAIL;
1312 	}
1313 
1314 	return zbx_tm_task_result_wait(taskid, info);
1315 }
1316