1<?php
2
3// Pandora FMS - http://pandorafms.com
4// ==================================================
5// Copyright (c) 2005-2011 Artica Soluciones Tecnologicas
6// Please see http://pandorafms.org for full contribution list
7
8// This program is free software; you can redistribute it and/or
9// modify it under the terms of the  GNU Lesser General Public License
10// as published by the Free Software Foundation; version 2
11
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17/**
18 * @package Include
19 * @subpackage Modules
20 */
21
22include_once($config['homedir'] . "/include/functions_agents.php");
23include_once($config['homedir'] . '/include/functions_users.php');
24include_once($config['homedir'] . '/include/functions_tags.php');
25
26function modules_is_not_init($id_agent_module) {
27	$row = db_get_row('tagente_estado', 'id_agente_modulo', $id_agent_module);
28
29	if (!$row)
30		return true;
31
32	if ($row['estado'] == AGENT_MODULE_STATUS_NO_DATA || $row['estado'] == AGENT_MODULE_STATUS_NOT_INIT )
33		return true;
34	else
35		return false;
36}
37
38function modules_is_disable_agent($id_agent_module) {
39	$sql = "
40		SELECT disabled
41		FROM tagente
42		WHERE id_agente IN (
43			SELECT id_agente
44			FROM tagente_modulo
45			WHERE id_agente_modulo = " . (int)$id_agent_module . ")";
46
47	$disabled = db_get_value_sql($sql);
48
49	return (bool)$disabled;
50}
51
52function modules_is_disable_type_event($id_agent_module = false, $type_event = false) {
53	if ($id_agent_module === false) {
54		switch ($type_event) {
55			case EVENTS_GOING_UNKNOWN:
56				return true;
57				break;
58			case EVENTS_UNKNOWN:
59				return false;
60				break;
61			case EVENTS_ALERT_FIRED:
62				return false;
63				break;
64			case EVENTS_ALERT_RECOVERED:
65				return false;
66				break;
67			case EVENTS_ALERT_CEASED:
68				return false;
69				break;
70			case EVENTS_ALERT_MANUAL_VALIDATION:
71				return false;
72				break;
73			case EVENTS_RECON_HOST_DETECTED:
74				return false;
75				break;
76			case EVENTS_SYSTEM:
77				return false;
78				break;
79			case EVENTS_ERROR:
80				return false;
81				break;
82			case EVENTS_NEW_AGENT:
83				return false;
84				break;
85			case EVENTS_GOING_UP_WARNING:
86				return false;
87				break;
88			case EVENTS_GOING_UP_CRITICAL:
89				return false;
90				break;
91			case EVENTS_GOING_DOWN_WARNING:
92				return false;
93				break;
94			case EVENTS_GOING_DOWN_NORMAL:
95				return false;
96				break;
97			case EVENTS_GOING_DOWN_CRITICAL:
98				return false;
99				break;
100			case EVENTS_GOING_UP_NORMAL:
101				return false;
102				break;
103			case EVENTS_CONFIGURATION_CHANGE:
104				return false;
105				break;
106		}
107	}
108
109	$disabled_types_event = json_decode(
110		db_get_value('disabled_types_event', 'tagente_modulo', 'id_agente_modulo', $id_agent_module),
111		true);
112
113	if (isset($disabled_types_event[$type_event])) {
114		if ($disabled_types_event[$type_event]) {
115			return true;
116		}
117		else {
118			return false;
119		}
120	}
121	return true;
122}
123
124/**
125 * Copy a module defined in an agent to other agent.
126 *
127 * This function avoid duplicated by comparing module names.
128 *
129 * @param int Source agent module id.
130 * @param int Destiny agent id.
131 * @param string Forced name to the new module.
132 *
133 * @return New agent module id on success. Existing module id if it already exists.
134 * False on error.
135 */
136function modules_copy_agent_module_to_agent ($id_agent_module, $id_destiny_agent, $forced_name = false) {
137	global $config;
138
139	$module = modules_get_agentmodule ($id_agent_module);
140	if ($module === false)
141		return false;
142
143	if ($forced_name !== false)
144		$module['nombre'] = $forced_name;
145
146	$modules = agents_get_modules ($id_destiny_agent, false,
147		array ('nombre' => $module['nombre'], 'disabled' => false));
148
149	// The module already exist in the target
150	if (! empty ($modules))
151		return array_pop (array_keys ($modules));
152
153	$modulesDisabled = agents_get_modules ($id_destiny_agent, false,
154		array ('nombre' => $module['nombre'], 'disabled' => true));
155
156	// If the module exist but disabled, we enable it
157	if (!empty($modulesDisabled)) {
158		//the foreach have only one loop but extract the array index, and it's id_agente_modulo
159		foreach ($modulesDisabled as $id => $garbage) {
160			$id_module = $id;
161			modules_change_disabled($id_module, 0);
162		}
163
164		$id_new_module = $id_module;
165	}
166	else {
167		/* PHP copy arrays on assignment */
168		$new_module = $module;
169
170		/* Rewrite different values */
171		$new_module['ip_target'] = agents_get_address ($id_destiny_agent);
172		$new_module['policy_linked'] = 0;
173		$new_module['id_policy_module'] = 0;
174
175		/* Unset numeric indexes or SQL would fail */
176		$len = count ($new_module) / 2;
177		for ($i = 0; $i < $len; $i++)
178			unset ($new_module[$i]);
179
180		/* Unset original agent module id */
181		unset ($new_module['id_agente_modulo']);
182		unset ($new_module['id_agente']);
183
184		$id_new_module = modules_create_agent_module($id_destiny_agent,
185			$new_module['nombre'], $new_module);
186
187		if ($id_new_module === false) {
188			return false;
189		}
190
191	}
192
193	// If the module is synthetic we duplicate the operations too
194	if ($module['id_modulo'] == 5) {
195		$synth_ops = db_get_all_rows_field_filter('tmodule_synth',
196			'id_agent_module_target', $module['id_agente_modulo']);
197
198		if ($synth_ops === false) {
199			$synth_ops = array();
200		}
201
202		foreach ($synth_ops as $synth_op) {
203			unset($synth_op['id']);
204			$synth_op['id_agent_module_target'] = $id_new_module;
205			switch ($config['dbtype']) {
206				case "mysql":
207				case "postgresql":
208					db_process_sql_insert ('tmodule_synth',
209						$synth_op);
210					break;
211				case "oracle":
212					db_process_sql_insert ('tmodule_synth',
213						$synth_op, false);
214					break;
215			}
216		}
217	}
218
219	// Copy module tags
220	$source_tags = tags_get_module_tags($id_agent_module);
221
222	if ($source_tags ==  false)
223		$source_tags = array();
224
225	tags_insert_module_tag($id_new_module, $source_tags);
226
227	//Added the config data if necesary
228	enterprise_include_once('include/functions_config_agents.php');
229
230	$id_agente = modules_get_agentmodule_agent($id_agent_module);
231
232	if ($module['id_modulo'] == MODULE_DATA) {
233		if (enterprise_installed()) {
234			if (config_agents_has_remote_configuration($id_agente)) {
235				$result = enterprise_hook(
236					'config_agents_copy_agent_module_to_agent',
237					array($id_agent_module, $id_new_module));
238				if ($result === false)
239					return false;
240			}
241		}
242	}
243
244	return $id_new_module;
245}
246
247/**
248 * Enable/Disable a module
249 *
250 * @param mixed Agent module id to be disabled. Accepts an array with ids.
251 * @param integer new value for the field disabled. 0 to enable, 1 to disable
252 *
253 * @return True if the module was disabled. False if not.
254 */
255function modules_change_disabled($id_agent_module, $new_value = 1) {
256	$id_agent_module = (array) $id_agent_module;
257
258	$id_agent_module_changed = array();
259
260	foreach ($id_agent_module as $id_module) {
261		// If the module is already disabled/enabled ignore
262		$current_disabled = db_get_value('disabled', 'tagente_modulo',
263			'id_agente_modulo', $id_module);
264		if ($current_disabled == $new_value) {
265			continue;
266		}
267
268		$id_agent_changed[] = modules_get_agentmodule_agent($id_module);
269		$id_agent_module_changed[] = $id_module;
270	}
271
272	if (empty($id_agent_module_changed)) {
273		return NOERR;
274	}
275	else {
276		$result = db_process_sql_update('tagente_modulo',
277			array('disabled' => (int) $new_value),
278			array('id_agente_modulo' => $id_agent_module_changed));
279	}
280
281	if ($result) {
282		// Change the agent flag to update modules count
283		db_process_sql_update('tagente',
284			array('update_module_count' => 1),
285			array('id_agente' => $id_agent_changed));
286
287		return NOERR;
288	}
289	else {
290		return ERR_GENERIC;
291	}
292}
293
294/**
295 * Deletes a module from an agent.
296 *
297 * @param mixed Agent module id to be deleted. Accepts an array with ids.
298 *
299 * @return True if the module was deleted. False if not.
300 */
301function modules_delete_agent_module ($id_agent_module) {
302	if (empty($id_agent_module))
303		return false;
304
305	if (is_array($id_agent_module)) {
306		$id_agents = db_get_all_rows_sql(
307			sprintf('SELECT id_agente
308				FROM tagente_modulo
309				WHERE id_agente_modulo IN (%s)
310				GROUP BY id_agente',  implode(',', $id_agent_module)));
311
312		foreach($id_agents as $k => $v) {
313			$id_agents[$k] = $v['id_agente'];
314		}
315
316		// Update update flags to server side
317		db_process_sql (sprintf('UPDATE tagente
318			SET update_module_count=1, update_alert_count=1
319			WHERE id_agente IN (%s)', implode(',', $id_agents)));
320	}
321	else {
322		// Read module data
323		$id_agent = modules_get_agentmodule_agent($id_agent_module);
324
325		// Update update flags to server side
326		db_process_sql (sprintf('UPDATE tagente
327			SET update_module_count=1, update_alert_count=1
328			WHERE id_agente = %s', $id_agent));
329	}
330
331	$where = array ('id_agent_module' => $id_agent_module);
332
333	$enterprise_include = enterprise_include_once(
334		'include/functions_config_agents.php');
335
336	if ($enterprise_include !== ENTERPRISE_NOT_HOOK) {
337		if (is_array($id_agent_module)) {
338			foreach ($id_agent_module as $id_agent_module_item) {
339				config_agents_delete_module_in_conf(
340					modules_get_agentmodule_agent($id_agent_module_item),
341					modules_get_agentmodule_name($id_agent_module_item));
342			}
343		}
344		else {
345			config_agents_delete_module_in_conf(
346				modules_get_agentmodule_agent($id_agent_module),
347				modules_get_agentmodule_name($id_agent_module));
348		}
349	}
350
351	alerts_delete_alert_agent_module (0, $where);
352
353	db_process_sql_delete ('tgraph_source', $where);
354	db_process_sql_delete ('treport_content', $where);
355	db_process_sql_delete ('tevento',
356		array('id_agentmodule' => $id_agent_module));
357	$where = array ('id_agente_modulo' => $id_agent_module);
358	db_process_sql_delete ('tlayout_data', $where);
359	db_process_sql_delete ('tagente_estado', $where);
360	db_process_sql_update ('tagente_modulo',
361		array ('nombre' => 'delete_pending', 'delete_pending' => 1, 'disabled' => 1),
362		$where);
363	db_process_sql_delete('ttag_module', $where);
364
365	return true;
366}
367
368/**
369 * Updates a module from an agent.
370 *
371 * @param mixed Agent module id to be deleted. Accepts an array with ids.
372 * @param array Values to update.
373 * @param mixed Tag's module array or false.
374 *
375 * @return True if the module was updated. False if not.
376 */
377function modules_update_agent_module ($id, $values,
378	$onlyNoDeletePending = false, $tags = false) {
379
380	$update_tags = false;
381	$return_tag = true;
382	if ($tags !== false) {
383		$update_tags = true;
384		$return_tag = tags_update_module_tag($id, $tags, false, false);
385	}
386
387	if ($return_tag === false) {
388		return ERR_DB;
389	}
390
391	if (!is_array ($values) || empty ($values)) {
392		if ($update_tags) {
393			return true;
394		}
395		else {
396			return ERR_GENERIC;
397		}
398	}
399
400	if (isset ($values['nombre'])) {
401		if (empty ($values['nombre'])) {
402			return ERR_INCOMPLETE;
403		}
404
405		$id_agent = modules_get_agentmodule_agent($id);
406
407		$exists = (bool)db_get_value_filter('id_agente_modulo',
408			'tagente_modulo', array('nombre' => $values['nombre'], 'id_agente' => $id_agent, 'id_agente_modulo' => "<>$id"));
409
410		if ($exists) {
411			return ERR_EXIST;
412		}
413	}
414
415
416
417	$where = array();
418	$where['id_agente_modulo'] = $id;
419	if ($onlyNoDeletePending) {
420		$where['delete_pending'] = 0;
421	}
422
423	// Disable action requires a special function
424	if (isset($values['disabled'])) {
425		$result_disable = modules_change_disabled($id, $values['disabled']);
426
427		unset($values['disabled']);
428	}
429	else {
430		$result_disable = true;
431	}
432
433	$result = @db_process_sql_update ('tagente_modulo', $values, $where);
434
435	if ($result == false) {
436		if ($result_disable == ERR_GENERIC ){
437			return ERR_DB;
438		}
439		else{
440			return true;
441		}
442	}
443	else {
444		if ( ERR_GENERIC === $result_disable ){
445			return ERR_DB;
446		}
447		else{
448			return true;
449		}
450	}
451}
452
453/**
454 * Creates a module in an agent.
455 *
456 * @param int Agent id.
457 * @param int Module name id.
458 * @param array Extra values for the module.
459 * @param bool Disable the ACL checking, for default false.
460 * @param mixed Array with tag's ids or false.
461 *
462 * @return New module id if the module was created. False if not.
463 */
464function modules_create_agent_module ($id_agent, $name, $values = false, $disableACL = false,
465	$tags = false) {
466	global $config;
467
468	if (!$disableACL) {
469		if (empty ($id_agent) || ! users_access_to_agent ($id_agent, 'AW'))
470			return false;
471	}
472
473	if (empty ($name)) {
474		return ERR_INCOMPLETE;
475	}
476
477	// Check for non valid characters in module name
478	if (mb_ereg_match('[\xc2\xa1\xc2\xbf\xc3\xb7\xc2\xba\xc2\xaa]', io_safe_output($name)) !== false) {
479		return ERR_GENERIC;
480	}
481
482	if (! is_array ($values))
483		$values = array ();
484	$values['nombre'] = $name;
485	$values['id_agente'] = (int) $id_agent;
486
487	$exists = (bool)db_get_value_filter('id_agente_modulo', 'tagente_modulo', array('nombre' => $name, 'id_agente' => (int)$id_agent));
488
489	if ($exists) {
490		return ERR_EXIST;
491	}
492
493	// Encrypt passwords
494	if (isset ($values['plugin_pass'])) {
495		$values['plugin_pass'] = io_input_password($values['plugin_pass']);
496	}
497
498	// Encrypt SNMPv3 passwords
499	if (isset ($values['id_tipo_modulo']) && ($values['id_tipo_modulo'] >= 15 && $values['id_tipo_modulo'] <= 18) &&
500		isset ($values['tcp_send']) && ($values['tcp_send'] == 3) &&
501		isset ($values['custom_string_2'])) {
502		$values['custom_string_2'] = io_input_password($values['custom_string_2']);
503	}
504
505	$id_agent_module = db_process_sql_insert ('tagente_modulo', $values);
506
507	if ($id_agent_module === false)
508		return ERR_DB;
509
510	$return_tag = true;
511	if (($tags !== false) || (empty($tags)))
512		$return_tag = tags_insert_module_tag ($id_agent_module, $tags);
513
514	if ($return_tag === false) {
515		db_process_sql_delete ('tagente_modulo',
516			array ('id_agente_modulo' => $id_agent_module));
517
518		return ERR_DB;
519	}
520
521	if (isset ($values['id_tipo_modulo'])
522		&& ($values['id_tipo_modulo'] == 21 || $values['id_tipo_modulo'] == 22 || $values['id_tipo_modulo'] == 23)) {
523		// Async modules start in normal status
524		$status = AGENT_MODULE_STATUS_NORMAL;
525	}
526	else {
527		// Sync modules start in unknown status
528		$status = AGENT_MODULE_STATUS_NO_DATA;
529	}
530	switch ($config["dbtype"]) {
531		case "mysql":
532			$result = db_process_sql_insert ('tagente_estado',
533				array ('id_agente_modulo' => $id_agent_module,
534					'datos' => 0,
535					'timestamp' => '01-01-1970 00:00:00',
536					'estado' => $status,
537					'id_agente' => (int) $id_agent,
538					'utimestamp' => 0,
539					'status_changes' => 0,
540					'last_status' => $status,
541					'last_known_status' => $status
542				));
543			break;
544		case "postgresql":
545			$result = db_process_sql_insert ('tagente_estado',
546				array ('id_agente_modulo' => $id_agent_module,
547					'datos' => 0,
548					'timestamp' => null,
549					'estado' => $status,
550					'id_agente' => (int) $id_agent,
551					'utimestamp' => 0,
552					'status_changes' => 0,
553					'last_status' => $status,
554					'last_known_status' => $status
555				));
556			break;
557		case "oracle":
558			$result = db_process_sql_insert ('tagente_estado',
559				array ('id_agente_modulo' => $id_agent_module,
560					'datos' => 0,
561					'timestamp' => '#to_date(\'1970-01-01 00:00:00\', \'YYYY-MM-DD HH24:MI:SS\')',
562					'estado' => $status,
563					'id_agente' => (int) $id_agent,
564					'utimestamp' => 0,
565					'status_changes' => 0,
566					'last_status' => $status,
567					'last_known_status' => $status
568				));
569			break;
570	}
571
572	if ($result === false) {
573		db_process_sql_delete ('tagente_modulo',
574			array ('id_agente_modulo' => $id_agent_module));
575
576		return ERR_DB;
577	}
578
579	// Update module status count if the module is not created disabled
580	if (!isset ($values['disabled']) || $values['disabled'] == 0) {
581		if ($status == 0) {
582			db_process_sql ('UPDATE tagente SET total_count=total_count+1, normal_count=normal_count+1 WHERE id_agente=' . (int)$id_agent);
583		}
584		else {
585			db_process_sql ('UPDATE tagente SET total_count=total_count+1, notinit_count=notinit_count+1 WHERE id_agente=' . (int)$id_agent);
586		}
587	}
588
589	return $id_agent_module;
590}
591
592/**
593 * Gets all the agents that have a module with a name given.
594 *
595 * @param string Module name.
596 * @param int Group id of the agents. False will be any group.
597 * @param array Extra filter.
598 * @param mixed Fields to be returned. All agents field by default
599 * @param bool Flag to search agents in child groups.
600 *
601 * @return array All the agents which have a module with the name given.
602 */
603function modules_get_agents_with_module_name ($module_name, $id_group, $filter = false, $fields = 'tagente.*', $childGroups = false) {
604	if (empty ($module_name))
605		return false;
606
607	if (! is_array ($filter))
608		$filter = array ();
609	$filter[] = 'tagente_modulo.id_agente = tagente.id_agente';
610	$filter['tagente_modulo.nombre'] = $module_name;
611	$filter['tagente.id_agente'] = array_keys (agents_get_group_agents ($id_group, false, "none", false, $childGroups));
612
613	return db_get_all_rows_filter ('tagente, tagente_modulo',
614		$filter, $fields);
615}
616
617//
618// This are functions to format the data
619//
620
621/**
622 * Formats time data to tiemstamp format.
623 *
624 * @param numeric Numeric data.
625 *
626 * @return string HTML Code with data time with timestamp format.
627 */
628function modules_format_time($ts)
629{
630	return ui_print_timestamp ($ts, true, array("prominent" => "comparation"));
631}
632
633/**
634 * Formats module data.
635 *
636 * @param variant Numeric or string data.
637 *
638 * @return variant Module data formated.
639 */
640function modules_format_data($data)
641{
642	if (is_numeric ($data)) {
643		$data = format_numeric($data, 2);
644	}
645	else {
646		$data = io_safe_input ($data);
647	}
648	return $data;
649}
650
651/**
652 * Formats verbatim to string data.
653 *
654 * @param string String data.
655 *
656 * @return string HTML string data with verbatim format.
657 */
658function modules_format_verbatim($data) {
659	// We need to replace \n by <br> to create a "similar" output to
660	// information recolected in logs.
661	$data2 = preg_replace ("/\\n/", "<br>", $data);
662	return "<span style='font-size:10px;'>" . $data2 . "</span>";
663}
664
665/**
666 * Formats data time to timestamp format.
667 *
668 * @param int Data time.
669 *
670 * @return int Data time with timestamp format.
671 */
672function modules_format_timestamp($ts)
673{
674	global $config;
675
676	// This returns data with absolute user-defined timestamp format
677	// and numeric by data managed with 2 decimals, and not using Graph format
678	// (replacing 1000 by K and 1000000 by G, like version 2.x
679	return date ($config["date_format"], $ts);
680}
681
682/**
683 * Writes HTML code to perform delete module action for a particular module.
684 *
685 * @param int Id of the module.
686 *
687 * @return string HTML code to perform delete action.
688 */
689function modules_format_delete($id)
690{
691	global $period, $module_id, $config, $group;
692
693	$txt = "";
694
695	if (check_acl ($config['id_user'], $group, "AW") ==1) {
696		$txt = '<a href="index.php?sec=estado&sec2=operation/agentes/datos_agente&period='.$period.'&id='.$module_id.'&delete='.$id.'">' . html_print_image("images/cross.png", true, array("border" => '0')) . '</a>';
697	}
698	return $txt;
699}
700
701/**
702 * Writes HTML code to perform delete string module action for a particular module.
703 *
704 * @param int Id of the module.
705 *
706 * @return string HTML code to perform delete action.
707 */
708function modules_format_delete_string($id)
709{
710	global $period, $module_id, $config, $group;
711
712	$txt = "";
713
714	if (check_acl ($config['id_user'], $group, "AW") ==1) {
715		$txt = '<a href="index.php?sec=estado&sec2=operation/agentes/datos_agente&period='.$period.'&id='.$module_id.'&delete_string='.$id.'">' . html_print_image("images/cross.png", true, array("border" => '0')) . '</a>';
716	}
717	return $txt;
718}
719
720/**
721 * Writes HTML code to perform delete log4x module action for a particular module.
722 *
723 * @param int Id of the module.
724 *
725 * @return string HTML code to perform delete action.
726 */
727function modules_format_delete_log4x($id)
728{
729	global $period, $module_id, $config, $group;
730
731	$txt = "";
732
733	if (check_acl ($config['id_user'], $group, "AW") ==1) {
734		$txt = '<a href="index.php?sec=estado&sec2=operation/agentes/datos_agente&period='.$period.'&id='.$module_id.'&delete_log4x='.$id.'">' . html_print_image("images/cross.png", true, array("border" => '0')) . '</a>';
735	}
736
737	return $txt;
738}
739
740/**
741 * Get a single module information.
742 *
743 * @param int agentmodule id to get.
744 *
745 * @return array An array with module information
746 */
747function modules_get_agentmodule ($id_agentmodule) {
748	global $config;
749
750	switch ($config['dbtype']) {
751		case "mysql":
752		case "postgresql":
753			return db_get_row ('tagente_modulo', 'id_agente_modulo', (int) $id_agentmodule);
754			break;
755		case "oracle":
756			$fields = db_get_all_rows_filter('USER_TAB_COLUMNS',
757				'TABLE_NAME = \'TAGENTE_MODULO\' AND COLUMN_NAME <> \'MAX_CRITICAL\' AND COLUMN_NAME <> \'MIN_CRITICAL\' AND COLUMN_NAME <> \'POST_PROCESS\' AND COLUMN_NAME <> \'MAX_WARNING\' AND COLUMN_NAME <> \'MIN_WARNING\'', 'COLUMN_NAME');
758			foreach ($fields as $field) {
759				$fields_[] = $field['column_name'];
760			}
761			$fields = implode(',', $fields_);
762
763			$result = db_process_sql("
764				SELECT TO_NUMBER(MAX_CRITICAL) as max_critical,
765					TO_NUMBER(MIN_CRITICAL) as min_critical,
766					TO_NUMBER(MAX_WARNING) as max_warning,
767					TO_NUMBER(MIN_WARNING) as  min_warning,
768					TO_NUMBER(POST_PROCESS) as post_process,
769					" . $fields . "
770				FROM tagente_modulo
771				WHERE id_agente_modulo = " . $id_agentmodule);
772
773			return $result[0];
774			break;
775	}
776}
777
778function modules_get_table_data($id_agent_module) {
779	$id_type = db_get_value('id_tipo_modulo',
780		'tagente_modulo', 'id_agente_modulo', $id_agent_module);
781
782	$name_type = db_get_value('nombre', 'ttipo_modulo', 'id_tipo', $id_type);
783
784	$chunks = explode('_', $name_type);
785	$subtype = end($chunks);
786
787
788	switch ($subtype) {
789		case 'data':
790		case 'proc':
791		case 'icmp':
792		case 'tcp':
793		case 'snmp':
794		case 'inc':
795			// Numeric
796			return "tagente_datos";
797			break;
798		case 'log4x':
799			// Log4x
800			return "tagente_datos_log4x";
801			break;
802		case 'string':
803			// String
804			return "tagente_datos_string";
805			break;
806		default:
807			return null;
808			break;
809	}
810}
811
812function modules_get_raw_data($id_agent_module, $date_init, $date_end) {
813	$table = modules_get_table_data($id_agent_module);
814
815	$datelimit = $date_init - $date_end;
816	$search_in_history_db = db_search_in_history_db($datelimit);
817
818	$data = db_get_all_rows_sql('
819		SELECT *
820		FROM ' . $table . '
821		WHERE id_agente_modulo = ' . $id_agent_module . '
822			AND utimestamp >= ' . $date_init . '
823			AND utimestamp <= ' . $date_end, $search_in_history_db);
824
825	return $data;
826}
827
828function modules_get_agent_group($id_agent_module) {
829	$return = false;
830
831	$id_agent = modules_get_agentmodule_agent(
832		$id_agent_module);
833
834	if (!empty($id_agent)) {
835		$return = agents_get_agent_group($id_agent);
836	}
837
838	return $return;
839}
840
841/**
842 * Check the module exists in the DB.
843 *
844 * @param int $id_agentmodule The agent id.
845 * @param boolean $show_disabled Show the agent found althought it is disabled. By default false.
846 *
847 * @return boolean The result to check if the agent is in the DB.
848 */
849function modules_check_agentmodule_exists($id_agentmodule, $show_disabled = true) {
850	$module = db_get_row_filter('tagente_modulo',
851		array('id_agente_modulo' => $id_agentmodule, 'disabled' => !$show_disabled));
852
853	if (!empty($module)) {
854		if ($module['delete_pending'])
855			return false;
856		else
857			return true;
858	}
859	else {
860		return false;
861	}
862}
863
864/**
865 * Get a id of module from his name and the agent id
866 *
867 * @param string agentmodule name to get.
868 * @param int agent id.
869 *
870 * @return int the agentmodule id
871 */
872function modules_get_agentmodule_id ($agentmodule_name, $agent_id) {
873	return db_get_row_filter ('tagente_modulo',
874		array('nombre' => $agentmodule_name,
875			'id_agente' => $agent_id, 'delete_pending' => 0));
876}
877
878/**
879 * Get a if a module is init.
880 *
881 * @param int $agentmodule Id to get.
882 * @param bool $metaconsole Flag to extract the data for metaconsole, by default false.
883 * @param int $id_server Id of children console.
884 *
885 * @return bool true if is init and false if is not init
886 */
887function modules_get_agentmodule_is_init ($id_agentmodule, $metaconsole = false, $id_server = null) {
888
889	if ($metaconsole) {
890		$server = db_get_row('tmetaconsole_setup', 'id', $id_server);
891
892		if (metaconsole_connect($server) == NOERR) {
893			$result = db_get_row_filter ('tagente_estado',
894				array('id_agente_modulo' => $id_agentmodule),
895				'utimestamp');
896		}
897		metaconsole_restore_db();
898	}
899	else {
900		$result = db_get_row_filter ('tagente_estado',
901			array('id_agente_modulo' => $id_agentmodule),
902			'utimestamp');
903	}
904
905	return (bool)$result['utimestamp'];
906}
907
908/**
909 * Get the number of all agent modules in the database
910 *
911 * @param mixed Array of integers with agent(s) id or a single agent id. Default
912 * value will select all.
913 *
914 * @return int The number of agent modules
915 */
916function modules_get_agent_modules_count ($id_agent = 0) {
917	//Make sure we're all int's and filter out bad stuff
918	$id_agent = safe_int ($id_agent, 1);
919
920	if (empty ($id_agent)) {
921		//If the array proved empty or the agent is less than 1 (eg. -1)
922		$filter = '';
923	}
924	else {
925		$filter = sprintf (" WHERE id_agente IN (%s)", implode (",", (array) $id_agent));
926	}
927
928	return (int) db_get_sql ("SELECT COUNT(*)
929		FROM tagente_modulo" . $filter);
930}
931
932/**
933 * Get the name of a module type
934 *
935 * @param int $id_type Type id
936 *
937 * @return string The name of the given type.
938 */
939function modules_get_type_name ($id_type) {
940	return (string) db_get_value ('nombre',
941		'ttipo_modulo', 'id_tipo', (int) $id_type);
942}
943
944/**
945 * Get the id of a module type
946 *
947 * @param int $id_type Type id
948 *
949 * @return string The name of the given type.
950 */
951function modules_get_type_id($name_type) {
952	return (int) db_get_value ('id_tipo',
953		'ttipo_modulo', 'nombre', $name_type);
954}
955
956/**
957 * Know if a module type is a string or not
958 *
959 * @param int $id_type Type id
960 *
961 * @return bool true if string. false if not
962 */
963function modules_is_string_type ($id_type) {
964	$type_name = modules_get_type_name($id_type);
965
966	return (bool)preg_match('/_string$/', $type_name);
967}
968
969function modules_is_string($id_agentmodule) {
970	$id_type = db_get_value('id_tipo_modulo',
971		'tagente_modulo', 'id_agente_modulo',
972		(int) $id_agentmodule);
973
974	return modules_is_string_type($id_type);
975}
976
977/**
978 * Get the icon of a module type
979 *
980 * @param int $id_type Type id
981 *
982 * @return string The name of the icon.
983 */
984function modules_get_type_icon ($id_type) {
985	return (string) db_get_value ('icon', 'ttipo_modulo', 'id_tipo',
986		(int) $id_type);
987}
988
989/**
990 * Get agent id of an agent module.
991 *
992 * @param int $id_agentmodule Agent module id.
993 *
994 * @return int The id of the agent of given agent module
995 */
996function modules_get_agentmodule_agent ($id_agentmodule) {
997	return (int) db_get_value ('id_agente', 'tagente_modulo',
998		'id_agente_modulo', (int) $id_agentmodule);
999}
1000
1001/**
1002 * Get agent name of an agent module.
1003 *
1004 * @param int $id_agente_modulo Agent module id.
1005 *
1006 * @return string The name of the given agent module.
1007 */
1008function modules_get_agentmodule_agent_name ($id_agentmodule) {
1009	// Since this is a helper function we don't need to do casting
1010	return (string) agents_get_name (modules_get_agentmodule_agent ($id_agentmodule));
1011}
1012
1013/**
1014 * Get the module name of an agent module.
1015 *
1016 * @param int $id_agente_modulo Agent module id.
1017 *
1018 * @return string Name of the given agent module.
1019 */
1020function modules_get_agentmodule_name ($id_agente_modulo) {
1021	return (string) db_get_value ('nombre', 'tagente_modulo', 'id_agente_modulo', (int) $id_agente_modulo);
1022}
1023
1024/**
1025 * Get the module type of an agent module.
1026 *
1027 * @param int $id_agentmodule Agent module id.
1028 *
1029 * @return string Module type of the given agent module.
1030 */
1031function modules_get_agentmodule_type ($id_agentmodule, $metaconsole = false, $id_server = null) {
1032
1033	if ($metaconsole) {
1034		$server = db_get_row('tmetaconsole_setup', 'id', $id_server);
1035
1036		$return = db_get_value ('id_tipo_modulo',
1037			'tagente_modulo', 'id_agente_modulo', (int) $id_agentmodule);
1038
1039		metaconsole_restore_db();
1040	}
1041	else {
1042		$return = db_get_value ('id_tipo_modulo',
1043			'tagente_modulo', 'id_agente_modulo', (int) $id_agentmodule);
1044	}
1045
1046	return (int) $return;
1047}
1048
1049/**
1050 * Get the module kind (dataserver, networkserver...) of an agent module.
1051 *
1052 * @param int $id_agentmodule Agent module id.
1053 *
1054 * @return string Module kind of the given agent module.
1055 */
1056function modules_get_agentmodule_kind($id_agentmodule) {
1057	$id_modulo = (int) db_get_value ('id_modulo',
1058		'tagente_modulo', 'id_agente_modulo', (int) $id_agentmodule);
1059
1060	switch($id_modulo) {
1061		case MODULE_DATA:
1062			return 'dataserver';
1063			break;
1064		case MODULE_NETWORK:
1065		case MODULE_SNMP:
1066			return 'networkserver';
1067			break;
1068		case MODULE_PLUGIN:
1069			return 'pluginserver';
1070			break;
1071		case MODULE_PREDICTION:
1072			return 'predictionserver';
1073			break;
1074		case MODULE_WMI:
1075			return 'wmiserver';
1076			break;
1077		case MODULE_WEB:
1078			return 'webserver';
1079			break;
1080		default:
1081			return 'other';
1082			break;
1083	}
1084}
1085
1086/**
1087 * Get the unit of an agent module.
1088 *
1089 * @param int $id_agente_module Agent module id.
1090 *
1091 * @return string Module unit of the given agent module.
1092 */
1093function modules_get_unit ($id_agente_modulo) {
1094	return $unit = (string) db_get_value ('unit', 'tagente_modulo', 'id_agente_modulo', (int) $id_agente_modulo);
1095}
1096
1097function modules_get_interfaces($id_agent, $fields_param = false) {
1098	$return = array();
1099
1100	$fields = $fields_param;
1101	if ($fields !== false) {
1102		if (is_array($fields)) {
1103			$fields[] = 'id_tipo_modulo';
1104		}
1105	}
1106
1107	$modules = db_get_all_rows_filter('tagente_modulo',
1108		array('id_agente' => $id_agent), $fields);
1109
1110	if (empty($modules))
1111		$modules = array();
1112
1113	foreach ($modules as $module) {
1114		//18 = remote_snmp_proc
1115		//6 = remote_icmp_proc
1116		if ($module['id_tipo_modulo'] == 18) {
1117
1118			if ($fields_param !== false) {
1119				if (is_array($fields_param)) {
1120					if (in_array('id_tipo_modulo', $fields) !== false) {
1121						unset($module['id_tipo_modulo']);
1122					}
1123				}
1124			}
1125
1126			$return[] = $module;
1127		}
1128	}
1129
1130	return $return;
1131}
1132
1133/**
1134 * Get all the times a monitor went down during a period.
1135 *
1136 * @param int $id_agent_module Agent module of the monitor.
1137 * @param int $period Period timed to check from date
1138 * @param int $date Date to check (now by default)
1139 *
1140 * @return int The number of times a monitor went down.
1141 */
1142function modules_get_monitor_downs_in_period ($id_agent_module, $period, $date = 0) {
1143	global $config;
1144
1145	if ($date == 0) {
1146		$date = get_system_time ();
1147	}
1148	$datelimit = $date - $period;
1149
1150	switch ($config["dbtype"]) {
1151		case "mysql":
1152			$sql = sprintf ("SELECT COUNT(`id_agentmodule`)
1153				FROM `tevento`
1154				WHERE
1155					`event_type` = 'monitor_down'
1156					AND `id_agentmodule` = %d
1157					AND `utimestamp` > %d
1158					AND `utimestamp` <= %d",
1159				$id_agent_module, $datelimit, $date);
1160			break;
1161		case "postgresql":
1162			$sql = sprintf ("SELECT COUNT(\"id_agentmodule\")
1163				FROM \"tevento\"
1164				WHERE
1165					\"event_type\" = 'monitor_down'
1166					AND \"id_agentmodule\" = %d
1167					AND \"utimestamp\" > %d
1168					AND \"utimestamp\" <= %d",
1169				$id_agent_module, $datelimit, $date);
1170			break;
1171		case "oracle":
1172			$sql = sprintf ("SELECT COUNT(id_agentmodule)
1173				FROM tevento
1174				WHERE
1175					event_type = 'monitor_down'
1176					AND id_agentmodule = %d
1177					AND utimestamp > %d
1178					AND utimestamp <= %d",
1179				$id_agent_module, $datelimit, $date);
1180			break;
1181	}
1182
1183	return db_get_sql ($sql);
1184}
1185
1186/**
1187 * Get the last time a monitor went down during a period.
1188 *
1189 * @param int $id_agent_module Agent module of the monitor.
1190 * @param int $period Period timed to check from date
1191 * @param int $date Date to check (now by default)
1192 *
1193 * @return int The last time a monitor went down.
1194 */
1195function modules_get_last_down_timestamp_in_period ($id_agent_module, $period, $date = 0) {
1196	global $config;
1197
1198	if ($date == 0) {
1199		$date = get_system_time ();
1200	}
1201	$datelimit = $date - $period;
1202
1203	switch ($config["dbtype"]) {
1204		case "mysql":
1205			$sql = sprintf ("SELECT MAX(`timestamp`)
1206				FROM `tevento`
1207				WHERE event_type = 'monitor_down'
1208					AND `id_agentmodule` = %d
1209					AND `utimestamp` > %d
1210					AND `utimestamp` <= %d",
1211				$id_agent_module, $datelimit, $date);
1212			break;
1213		case "postgresql":
1214			$sql = sprintf ("SELECT MAX(\"timestamp\")
1215				FROM \"tevento\"
1216				WHERE event_type = 'monitor_down'
1217					AND \"id_agentmodule\" = %d
1218					AND \"utimestamp\" > %d
1219					AND \"utimestamp\" <= %d",
1220				$id_agent_module, $datelimit, $date);
1221			break;
1222		case "oracle":
1223			$sql = sprintf ("SELECT MAX(timestamp)
1224				FROM tevento
1225				WHERE event_type = 'monitor_down'
1226					AND id_agentmodule = %d
1227					AND utimestamp > %d
1228					AND utimestamp <= %d",
1229				$id_agent_module, $datelimit, $date);
1230			break;
1231	}
1232
1233	return db_get_sql ($sql);
1234}
1235
1236/**
1237 * Get all the monitors defined in an group.
1238 *
1239 * @param int $id_group Group id to get all the monitors.
1240 *
1241 * @return array An array with all the monitors defined in the group (tagente_modulo).
1242 */
1243function modules_get_monitors_in_group ($id_group) {
1244	global $config;
1245
1246	if ($id_group <= 0) {
1247		//We select all groups the user has access to if it's 0 or -1
1248		global $config;
1249		$id_group = array_keys (users_get_groups ($config['id_user']));
1250	}
1251
1252	if (is_array ($id_group)) {
1253		$id_group = implode (",",$id_group);
1254	}
1255
1256	switch ($config["dbtype"]) {
1257		case "mysql":
1258			$sql = sprintf ("SELECT `tagente_modulo`.*
1259				FROM `tagente_modulo`, `ttipo_modulo`, `tagente`
1260				WHERE `id_tipo_modulo` = `id_tipo`
1261					AND `tagente`.`id_agente` = `tagente_modulo`.`id_agente`
1262					AND `ttipo_modulo`.`nombre` LIKE '%%_proc'
1263					AND `tagente`.`id_grupo` IN (%s)
1264				ORDER BY `tagente`.`nombre`", $id_group);
1265			break;
1266		case "postgresql":
1267		case "oracle":
1268			$sql = sprintf ("SELECT tagente_modulo.*
1269				FROM tagente_modulo, ttipo_modulo, tagente
1270				WHERE id_tipo_modulo = id_tipo
1271					AND tagente.id_agente = tagente_modulo.id_agente
1272					AND ttipo_modulo.nombre LIKE '%%_proc'
1273					AND tagente.id_grupo IN (%s)
1274				ORDER BY tagente.nombre", $id_group);
1275			break;
1276	}
1277
1278	return db_get_all_rows_sql ($sql);
1279}
1280
1281/**
1282 * Get all the modules defined in an group.
1283 *
1284 * @param int $id_group Group id to get all the modules.
1285 *
1286 * @return array An array with all the modules defined in the group (tagente_modulo).
1287 */
1288function modules_get_modules_in_group ($id_group) {
1289	global $config;
1290
1291	if ($id_group <= 0) {
1292		//We select all groups the user has access to if it's 0 or -1
1293		global $config;
1294		$id_group = array_keys (users_get_groups ($config['id_user']));
1295	}
1296
1297	if (is_array ($id_group)) {
1298		$id_group = implode (",",$id_group);
1299	}
1300
1301	switch ($config["dbtype"]) {
1302		case "mysql":
1303			$sql = sprintf ("SELECT `tagente_modulo`.*
1304				FROM `tagente_modulo`, `ttipo_modulo`, `tagente`
1305				WHERE `id_tipo_modulo` = `id_tipo`
1306					AND `tagente`.`id_agente` = `tagente_modulo`.`id_agente`
1307					AND `tagente`.`id_grupo` IN (%s)
1308				ORDER BY `tagente`.`nombre`", $id_group);
1309			break;
1310		case "postgresql":
1311		case "oracle":
1312			$sql = sprintf ("SELECT tagente_modulo.*
1313				FROM tagente_modulo, ttipo_modulo, tagente
1314				WHERE id_tipo_modulo = id_tipo
1315					AND tagente.id_agente = tagente_modulo.id_agente
1316					AND tagente.id_grupo IN (%s)
1317				ORDER BY tagente.nombre", $id_group);
1318			break;
1319	}
1320
1321	return db_get_all_rows_sql ($sql);
1322}
1323
1324/**
1325 * Get all the monitors defined in an agent.
1326 *
1327 * @param int $id_agent Agent id to get all the monitors.
1328 *
1329 * @return array An array with all the monitors defined (tagente_modulo).
1330 */
1331function modules_get_monitors_in_agent ($id_agent) {
1332	global $config;
1333
1334	switch ($config["dbtype"]) {
1335		case "mysql":
1336			$sql = sprintf ("SELECT `tagente_modulo`.*
1337				FROM `tagente_modulo`, `ttipo_modulo`, `tagente`
1338				WHERE `id_tipo_modulo` = `id_tipo`
1339					AND `tagente`.`id_agente` = `tagente_modulo`.`id_agente`
1340					AND `ttipo_modulo`.`nombre` LIKE '%%_proc'
1341					AND `tagente`.`id_agente` = %d", $id_agent);
1342			break;
1343		case "postgresql":
1344		case "oracle":
1345			$sql = sprintf ("SELECT tagente_modulo.*
1346				FROM tagente_modulo, ttipo_modulo, tagente
1347				WHERE id_tipo_modulo = id_tipo
1348					AND tagente.id_agente = tagente_modulo.id_agente
1349					AND ttipo_modulo.nombre LIKE '%%_proc'
1350					AND tagente.id_agente = %d", $id_agent);
1351			break;
1352	}
1353
1354	return db_get_all_rows_sql ($sql);
1355}
1356
1357/**
1358 * Get all the monitors down during a period of time.
1359 *
1360 * @param array $monitors An array with all the monitors to check. Each
1361 * element of the array must be a dictionary.
1362 * @param int $period Period of time to check the monitors.
1363 * @param int $date Beginning date to check the monitors.
1364 *
1365 * @return array An array with all the monitors that went down in that
1366 * period of time.
1367 */
1368function modules_get_monitors_down ($monitors, $period = 0, $date = 0) {
1369	$monitors_down = array ();
1370
1371	if (empty ($monitors))
1372		return $monitors_down;
1373
1374	foreach ($monitors as $monitor) {
1375		$down = modules_get_monitor_downs_in_period ($monitor['id_agente_modulo'], $period, $date);
1376		if ($down > 0)
1377		array_push ($monitors_down, $monitor);
1378	}
1379
1380	return $monitors_down;
1381}
1382
1383/**
1384 * Get the module type name (type = generic_data, remote_snmp, ...)
1385 *
1386 * @param int $id_type Type id
1387 *
1388 * @return string Name of the given type.
1389 */
1390function modules_get_moduletype_name ($id_type) {
1391	return (string) db_get_value ('nombre', 'ttipo_modulo', 'id_tipo', (int) $id_type);
1392}
1393
1394/**
1395 * Get the module type description
1396 *
1397 * @param int $id_type Type id
1398 *
1399 * @return string Description of the given type.
1400 */
1401function modules_get_moduletype_description ($id_type) {
1402	return (string) db_get_value ('descripcion', 'ttipo_modulo', 'id_tipo', (int) $id_type);
1403}
1404
1405/**
1406 * Returns an array with all module types (default) or if "remote" or "agent"
1407 * is passed it will return only remote (ICMP, SNMP, TCP...) module types
1408 * otherwise the full list + the column you specify
1409 *
1410 * @param string Specifies which type to return (will return an array with id's)
1411 * @param string Which rows to select (defaults to nombre)
1412 *
1413 * @return array Either the full table or if a type is specified, an array with id's
1414 */
1415function modules_get_moduletypes ($type = "all", $rows = "nombre") {
1416	$return = array ();
1417	$rows = (array) $rows; //Cast as array
1418	$row_cnt = count ($rows);
1419	if ($type == "remote") {
1420		return array_merge (range (6,18), (array)100);
1421	}
1422	elseif ($type == "agent") {
1423		return array_merge (range (1,4), range (19,24));
1424	}
1425
1426	$sql = sprintf ("SELECT id_tipo, %s
1427		FROM ttipo_modulo", implode (",", $rows));
1428	$result = db_get_all_rows_sql ($sql);
1429	if ($result === false) {
1430		return $return;
1431	}
1432
1433	foreach ($result as $type) {
1434		if ($row_cnt > 1) {
1435			$return[$type["id_tipo"]] = $type;
1436		}
1437		else {
1438			$return[$type["id_tipo"]] = $type[reset ($rows)];
1439		}
1440	}
1441
1442	return $return;
1443}
1444
1445/**
1446 * Get the interval value of an agent module.
1447 *
1448 * If the module interval is not set, the agent interval is returned
1449 *
1450 * @param int Id agent module to get the interval value.
1451 *
1452 * @return int Module interval or agent interval if no module interval
1453 */
1454function modules_get_interval ($id_agent_module) {
1455	$interval = (int) db_get_value ('module_interval', 'tagente_modulo', 'id_agente_modulo', (int) $id_agent_module);
1456	if ($interval > 0)
1457		return $interval;
1458
1459	$id_agent = modules_give_agent_id_from_module_id ($id_agent_module);
1460	return (int) agents_get_interval ($id_agent);
1461}
1462
1463/**
1464 * Get module type icon.
1465 *
1466 * TODO: Create ui_print_moduletype_icon and print the full tag including hover etc.
1467 * @deprecated Use ui_print_moduletype_icon instead
1468 *
1469 * @param int Module type id
1470 *
1471 * @return string Icon filename of the given group
1472 */
1473function modules_show_icon_type ($id_type) {
1474	return (string) db_get_value ('icon', 'ttipo_modulo', 'id_tipo', $id_type);
1475}
1476
1477/**
1478 * Get agent id from an agent module.
1479 *
1480 * @param int Id of the agent module.
1481 *
1482 * @return int The agent id of the given module.
1483 */
1484function modules_give_agent_id_from_module_id ($id_agent_module) {
1485	return (int) db_get_value ('id_agente', 'tagente_modulo', 'id_agente_modulo', $id_agent_module);
1486}
1487
1488/**
1489 * Get the status of an agent module.
1490 *
1491 * @param int Id agent module to check.
1492 * @param bool $without_alerts The flag to check only the module, by default false.
1493 *
1494 * @return int Module status. Value 4 means that some alerts assigned to the
1495 * module were fired.
1496 */
1497function modules_get_agentmodule_status($id_agentmodule = 0, $without_alerts = false, $metaconsole = false, $id_server = null) {
1498	$current_timestamp = get_system_time ();
1499
1500	if ($metaconsole) {
1501		$server = db_get_row('tmetaconsole_setup', 'id', $id_server);
1502
1503		if (metaconsole_connect($server) == NOERR) {
1504			$status_row = db_get_row ("tagente_estado",
1505				"id_agente_modulo", $id_agentmodule);
1506
1507			if (!$without_alerts) {
1508				$times_fired = db_get_value ('SUM(times_fired)', 'talert_template_modules', 'id_agent_module', $id_agentmodule);
1509				if ($times_fired > 0) {
1510					switch($status_row['estado']) {
1511						case AGENT_STATUS_WARNING:
1512							return AGENT_MODULE_STATUS_WARNING_ALERT; // Alert fired in warning
1513							break;
1514						case AGENT_STATUS_CRITICAL:
1515							return AGENT_MODULE_STATUS_CRITICAL_ALERT; // Alert fired in critical
1516							break;
1517					}
1518				}
1519			}
1520		}
1521		metaconsole_restore_db();
1522	}
1523	else {
1524		$status_row = db_get_row ("tagente_estado",
1525			"id_agente_modulo", $id_agentmodule);
1526
1527		if (!$without_alerts) {
1528			$times_fired = db_get_value ('SUM(times_fired)',
1529				'talert_template_modules', 'id_agent_module', $id_agentmodule);
1530
1531			if ($times_fired > 0) {
1532
1533				switch($status_row['estado']) {
1534					case AGENT_STATUS_NORMAL:
1535						return AGENT_MODULE_STATUS_NORMAL_ALERT;
1536						break;
1537					case AGENT_STATUS_WARNING:
1538						return AGENT_MODULE_STATUS_WARNING_ALERT; // Alert fired in warning
1539						break;
1540					case AGENT_STATUS_CRITICAL:
1541						return AGENT_MODULE_STATUS_CRITICAL_ALERT; // Alert fired in critical
1542						break;
1543				}
1544			}
1545		}
1546	}
1547
1548	return $status_row['estado'];
1549}
1550
1551/**
1552 * Get the last status of an agent module.
1553 *
1554 * @param int Id agent module to check.
1555 *
1556 * @return int Module last status.
1557 */
1558function modules_get_agentmodule_last_status($id_agentmodule = 0) {
1559	$status_row = db_get_row ("tagente_estado", "id_agente_modulo", $id_agentmodule);
1560
1561	return $status_row['last_known_status'];
1562}
1563
1564/**
1565 * Get the current value of an agent module.
1566 *
1567 * @param int Agent module id.
1568 *
1569 * @return int a numerically formatted value
1570 */
1571function modules_get_last_value ($id_agentmodule) {
1572	return db_get_value ('datos', 'tagente_estado',
1573		'id_agente_modulo', $id_agentmodule);
1574}
1575
1576/**
1577 * Get the previous data to the timestamp provided.
1578 *
1579 * It's useful to know the first value of a module in an interval,
1580 * since it will be the last value in the table which has a timestamp
1581 * before the beginning of the interval. All this calculation is due
1582 * to the data compression algorithm.
1583 *
1584 * @param int Agent module id
1585 * @param int The timestamp to look backwards from and get the data.
1586 * @param int 1 if the module has a string type.
1587 *
1588 * @return mixed The row of tagente_datos of the last period. False if there were no data.
1589 */
1590function modules_get_previous_data ($id_agent_module, $utimestamp = 0, $string = 0) {
1591	if (empty ($utimestamp))
1592		$utimestamp = time ();
1593
1594	if ($string == 1) {
1595		$table = 'tagente_datos_string';
1596	}
1597	else {
1598		$table = 'tagente_datos';
1599	}
1600
1601	$sql = sprintf ('SELECT *
1602		FROM ' . $table . '
1603		WHERE id_agente_modulo = %d
1604			AND utimestamp <= %d
1605			AND utimestamp >= %d
1606		ORDER BY utimestamp DESC',
1607		$id_agent_module, $utimestamp, $utimestamp - SECONDS_2DAY);
1608
1609	$search_in_history_db = db_search_in_history_db($utimestamp);
1610
1611	return db_get_row_sql ($sql, $search_in_history_db);
1612}
1613
1614/**
1615 * Get the next data to the timestamp provided.
1616 *
1617 * @param int Agent module id
1618 * @param int The timestamp to look backwards from and get the data.
1619 * @param int 1 if the module has a string type.
1620 *
1621 * @return mixed The row of tagente_datos of the last period. False if there were no data.
1622 */
1623function modules_get_next_data ($id_agent_module, $utimestamp = 0, $string = 0) {
1624	if (empty ($utimestamp))
1625		$utimestamp = time ();
1626
1627	if ($string == 1) {
1628		$table = 'tagente_datos_string';
1629	}
1630	else {
1631		$table = 'tagente_datos';
1632	}
1633
1634	$interval = modules_get_interval ($id_agent_module);
1635	$sql = sprintf ('SELECT *
1636		FROM ' . $table . '
1637		WHERE id_agente_modulo = %d
1638			AND utimestamp <= %d
1639			AND utimestamp >= %d
1640		ORDER BY utimestamp ASC',
1641		$id_agent_module, $utimestamp + $interval, $utimestamp);
1642
1643	$search_in_history_db = db_search_in_history_db($utimestamp);
1644
1645	return db_get_row_sql ($sql, $search_in_history_db);
1646}
1647
1648/**
1649 * Get all the values of an agent module in a period of time.
1650 *
1651 * @param int Agent module id
1652 * @param int Period of time to check (in seconds)
1653 * @param int Top date to check the values. Default current time.
1654 *
1655 * @return array The module value and the timestamp
1656 */
1657function modules_get_agentmodule_data ($id_agent_module, $period,
1658	$date = 0, $trash=false, $conexion = false, $order = 'ASC') {
1659	global $config;
1660
1661	$module = db_get_row('tagente_modulo', 'id_agente_modulo',
1662		$id_agent_module);
1663
1664	if ($date < 1) {
1665		$date = get_system_time ();
1666	}
1667
1668	$datelimit = $date - $period;
1669	$search_in_history_db = db_search_in_history_db($datelimit);
1670
1671	switch ($module['id_tipo_modulo']) {
1672		//generic_data_string
1673		case 3:
1674		//remote_tcp_string
1675		case 10:
1676		//remote_snmp_string
1677		case 17:
1678		//async_string
1679		case 23:
1680			$sql = sprintf ("SELECT datos AS data, utimestamp
1681				FROM tagente_datos_string
1682				WHERE id_agente_modulo = %d
1683					AND utimestamp > %d AND utimestamp <= %d
1684				ORDER BY utimestamp %s",
1685				$id_agent_module, $datelimit, $date, $order);
1686			break;
1687		//log4x
1688		case 24:
1689			$sql = sprintf ("SELECT datos AS data, utimestamp
1690				FROM tagente_datos_log4x
1691				WHERE id_agente_modulo = %d
1692					AND utimestamp > %d AND utimestamp <= %d
1693				ORDER BY utimestamp %s",
1694				$id_agent_module, $datelimit, $date, $order);
1695			break;
1696		case 2:
1697		case 6:
1698		case 9:
1699		case 18:
1700		case 21:
1701		case 31:
1702			if ( $config["render_proc"] ) {
1703				$sql = sprintf ("
1704					SELECT IF(datos >= 1, '" . $config["render_proc_ok"] . "', '" .
1705					$config["render_proc_fail"] . "') as data, utimestamp
1706					FROM tagente_datos
1707					WHERE id_agente_modulo = %d
1708						AND utimestamp > %d AND utimestamp <= %d
1709					ORDER BY utimestamp %s",
1710					$id_agent_module, $datelimit, $date, $order);
1711			}
1712			else {
1713				$sql = sprintf ("
1714					SELECT datos AS data, utimestamp
1715					FROM tagente_datos
1716					WHERE id_agente_modulo = %d
1717						AND utimestamp > %d AND utimestamp <= %d
1718					ORDER BY utimestamp %s",
1719					$id_agent_module, $datelimit, $date, $order);
1720			}
1721			break;
1722		default:
1723			$sql = sprintf ("
1724				SELECT datos AS data, utimestamp
1725				FROM tagente_datos
1726				WHERE id_agente_modulo = %d
1727					AND utimestamp > %d AND utimestamp <= %d
1728				ORDER BY utimestamp %s",
1729				$id_agent_module, $datelimit, $date, $order);
1730			break;
1731	}
1732
1733	$values = db_get_all_rows_sql ($sql, $search_in_history_db, false, $conexion);
1734
1735	if ($values === false) {
1736		return array ();
1737	}
1738
1739	$module_name = modules_get_agentmodule_name ($id_agent_module);
1740	$agent_id = modules_get_agentmodule_agent ($id_agent_module);
1741	$agent_name = modules_get_agentmodule_agent_name ($id_agent_module);
1742	$module_type = modules_get_agentmodule_type ($id_agent_module);
1743
1744	foreach ($values as $key => $data) {
1745		$values[$key]["module_name"] = $module_name;
1746		$values[$key]["agent_id"] = $agent_id;
1747		$values[$key]["agent_name"] = $agent_name;
1748		$values[$key]["module_type"] = $module_type;
1749	}
1750
1751	if ($search_in_history_db) {
1752		$datos = array();
1753		foreach ($values as $key => $value) {
1754			$utimestamp[$key] = $value['utimestamp'];
1755		}
1756
1757		array_multisort($utimestamp, SORT_DESC, $values);
1758		foreach ($utimestamp as $key => $utimes) {
1759			$datos[$key] = array('utimestamp'=>$utimes,
1760									'data'=>$values[$key]["data"],
1761									'module_name'=>$values[$key]["module_name"],
1762									'agent_id'=>$values[$key]["agent_id"],
1763									'agent_name'=>$values[$key]["agent_name"]
1764								);
1765		}
1766		$values = $datos;
1767	}
1768	return $values;
1769}
1770
1771/**
1772 * This function gets the modulegroup for a given group
1773 *
1774 * @param int The group id
1775 *
1776 * @return int The modulegroup id
1777 */
1778function modules_get_agentmodule_modulegroup ($id_module) {
1779	return (int) db_get_value ('id_module_group', 'tagente_modulo', 'id_agente_modulo', (int) $id_module);
1780}
1781
1782/**
1783 * Gets all module groups. (General, Networking, System).
1784 *
1785 * Module groups are merely for sorting frontend
1786 *
1787 * @return array All module groups
1788 */
1789function modules_get_modulegroups () {
1790	$result = db_get_all_fields_in_table ("tmodule_group");
1791	$return = array ();
1792
1793	if (empty ($result)) {
1794		return $return;
1795	}
1796
1797	foreach ($result as $modulegroup) {
1798		$return[$modulegroup["id_mg"]] = $modulegroup["name"];
1799	}
1800
1801	return $return;
1802}
1803
1804/**
1805 * Gets a modulegroup name based on the id
1806 *
1807 * @param int The id of the modulegroup
1808 *
1809 * @return string The modulegroup name
1810 */
1811function modules_get_modulegroup_name ($modulegroup_id) {
1812	if ($modulegroup_id == 0)
1813		return false;
1814	else
1815		return (string) db_get_value ('name', 'tmodule_group', 'id_mg', (int) $modulegroup_id);
1816}
1817
1818/**
1819 * Gets a module status an modify the status and title reference variables
1820 *
1821 * @param mixed The module data (Necessary $module['datos'] and $module['estado']
1822 * @param int status reference variable
1823 * @param string title reference variable
1824 *
1825 */
1826function modules_get_status($id_agent_module, $db_status, $data, &$status, &$title) {
1827	$status = STATUS_MODULE_WARNING;
1828	$title = "";
1829
1830	// This module is initialized ? (has real data)
1831	//$module_init = db_get_value ('utimestamp', 'tagente_estado', 'id_agente_modulo', $id_agent_module);
1832	if ($db_status == AGENT_MODULE_STATUS_NO_DATA) {
1833		$status = STATUS_MODULE_NO_DATA;
1834		$title = __('NOT INIT');
1835	}
1836	elseif ($db_status == AGENT_MODULE_STATUS_CRITICAL_BAD) {
1837		$status = STATUS_MODULE_CRITICAL;
1838		$title = __('CRITICAL');
1839	}
1840	elseif ($db_status == AGENT_MODULE_STATUS_WARNING) {
1841		$status = STATUS_MODULE_WARNING;
1842		$title = __('WARNING');
1843	}
1844	elseif ($db_status == AGENT_MODULE_STATUS_NORMAL) {
1845		$status = STATUS_MODULE_OK;
1846		$title = __('NORMAL');
1847	}
1848	elseif ($db_status == AGENT_MODULE_STATUS_UNKNOWN) {
1849		$status = STATUS_AGENT_DOWN;
1850		$last_status =  modules_get_agentmodule_last_status($id_agent_module);
1851		switch($last_status) {
1852			case AGENT_STATUS_NORMAL:
1853				$title = __('UNKNOWN') . " - " . __('Last status') .
1854					" " . __('NORMAL');
1855				break;
1856			case AGENT_STATUS_CRITICAL:
1857				$title = __('UNKNOWN') . " - " . __('Last status') .
1858					" " . __('CRITICAL');
1859				break;
1860			case AGENT_STATUS_WARNING:
1861				$title = __('UNKNOWN') . " - " . __('Last status') .
1862					" " . __('WARNING');
1863				break;
1864		}
1865	}
1866
1867	if (is_numeric($data)) {
1868		$title .= ": " . format_for_graph($data);
1869	}
1870	else {
1871		$text = io_safe_output($data);
1872
1873		//Fixed the data from Selenium Plugin
1874		if ($text != strip_tags($text)) {
1875			$text = io_safe_input($text);
1876		}
1877
1878		$title .= ": " . substr($text ,0,42);
1879	}
1880}
1881
1882// Get unknown agents by using the status code in modules
1883
1884function modules_agents_unknown ($module_name) {
1885
1886	//TODO REVIEW ORACLE AND POSTGRES
1887	return db_get_sql ("SELECT COUNT( DISTINCT tagente.id_agente)
1888		FROM tagente_estado, tagente, tagente_modulo
1889		WHERE tagente.disabled = 0
1890			AND tagente_estado.utimestamp != 0
1891			AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo
1892			AND tagente_modulo.disabled = 0
1893			AND tagente_estado.id_agente = tagente.id_agente
1894			AND tagente_estado.estado = 3
1895			AND tagente_modulo.nombre = '$module_name'");
1896}
1897
1898// Get ok agents by using the status code in modules.
1899
1900function modules_agents_ok ($module_name) {
1901
1902	//!!!Query explanation!!!
1903	//An agent is OK if all its modules are OK
1904	//The status values are: 0 OK; 1 Critical; 2 Warning; 3 Unkown
1905	//This query grouped all modules by agents and select the MAX value for status which has the value 0
1906	//If MAX(estado) is 0 it means all modules has status 0 => OK
1907	//Then we count the agents of the group selected to know how many agents are in OK status
1908
1909	//TODO REVIEW ORACLE AND POSTGRES
1910	return db_get_sql ("SELECT COUNT(max_estado)
1911		FROM (
1912			SELECT MAX(tagente_estado.estado) as max_estado
1913			FROM tagente_estado, tagente, tagente_modulo
1914			WHERE tagente.disabled = 0
1915				AND tagente_estado.utimestamp != 0
1916				AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo
1917				AND tagente_modulo.disabled = 0
1918				AND tagente_estado.id_agente = tagente.id_agente
1919				AND tagente_modulo.nombre = '$module_name'
1920			GROUP BY tagente.id_agente HAVING max_estado = 0) AS S1");
1921}
1922
1923// Get critical agents by using the status code in modules.
1924
1925function modules_agents_critical ($module_name) {
1926
1927	//!!!Query explanation!!!
1928	//An agent is Warning when has at least one module in warning status and nothing more in critical status
1929	//The status values are: 0 OK; 1 Critical; 2 Warning; 3 Unkown
1930	//If estado = 1 it means at leas 1 module is in critical status so the agent is critical
1931	//Then we count the agents of the group selected to know how many agents are in critical status
1932
1933	//TODO REVIEW ORACLE AND POSTGRES
1934
1935	return db_get_sql ("SELECT COUNT( DISTINCT tagente_estado.id_agente)
1936		FROM tagente_estado, tagente, tagente_modulo
1937		WHERE tagente.disabled = 0 AND tagente_estado.utimestamp != 0
1938			AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo
1939			AND tagente_modulo.disabled = 0
1940			AND estado = 1
1941			AND tagente_estado.id_agente = tagente.id_agente
1942			AND tagente_modulo.nombre = '$module_name'");
1943}
1944
1945// Get warning agents by using the status code in modules.
1946
1947function modules_agents_warning ($module_name) {
1948
1949	//!!!Query explanation!!!
1950	//An agent is Warning when has at least one module in warning status and nothing more in critical status
1951	//The status values are: 0 OK; 1 Critical; 2 Warning; 3 Unkown
1952	//This query grouped all modules by agents and select the MIN value for status which has the value 0
1953	//If MIN(estado) is 2 it means at least one module is warning and there is no critical modules
1954	//Then we count the agents of the group selected to know how many agents are in warning status
1955
1956	//TODO REVIEW ORACLE AND POSTGRES
1957
1958	return db_get_sql ("SELECT COUNT(min_estado)
1959		FROM (SELECT MAX(tagente_estado.estado) as min_estado
1960			FROM tagente_estado, tagente, tagente_modulo
1961			WHERE tagente.disabled = 0 AND tagente_estado.utimestamp != 0
1962				AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo
1963				AND tagente_modulo.disabled = 0
1964				AND tagente_estado.id_agente = tagente.id_agente
1965				AND tagente_modulo.nombre = '$module_name'
1966			GROUP BY tagente.id_agente
1967				HAVING min_estado = 2) AS S1");
1968}
1969
1970// Get unknown agents by using the status code in modules
1971
1972function modules_group_agent_unknown ($module_group) {
1973
1974	return db_get_sql ("SELECT COUNT(DISTINCT tagente.id_agente)
1975		FROM tagente, tagente_modulo
1976		WHERE tagente.id_agente=tagente_modulo.id_agente
1977			AND critical_count=0 AND warning_count=0
1978			AND tagente.disabled = 0
1979			AND unknown_count>0 AND id_module_group = $module_group");
1980}
1981
1982// Get ok agents by using the status code in modules.
1983
1984function modules_group_agent_ok ($module_group) {
1985
1986	return db_get_sql ("SELECT COUNT(DISTINCT tagente.id_agente)
1987		FROM tagente, tagente_modulo
1988		WHERE tagente.id_agente=tagente_modulo.id_agente
1989			AND normal_count = total_count
1990			AND tagente.disabled = 0
1991			AND id_module_group = $module_group");
1992}
1993
1994// Get critical agents by using the status code in modules.
1995
1996function modules_group_agent_critical ($module_group) {
1997
1998	return db_get_sql ("SELECT COUNT(DISTINCT tagente.id_agente)
1999		FROM tagente, tagente_modulo
2000		WHERE tagente.id_agente=tagente_modulo.id_agente
2001			AND tagente.disabled = 0
2002			AND critical_count > 0 AND id_module_group = $module_group");
2003}
2004
2005// Get warning agents by using the status code in modules.
2006
2007function modules_group_agent_warning ($module_group) {
2008
2009	return db_get_sql ("SELECT COUNT(DISTINCT tagente.id_agente)
2010		FROM tagente, tagente_modulo
2011		WHERE tagente.id_agente=tagente_modulo.id_agente
2012			AND critical_count = 0 AND warning_count > 0
2013			AND tagente.disabled = 0
2014			AND id_module_group = $module_group");
2015}
2016
2017// Return a base64 encoded JSON document to store module macros inside the database
2018function modules_get_module_macros_json ($macro_names, $macro_values) {
2019	$module_macros = array ();
2020	for ($i = 0; $i < count($macro_names); $i++) {
2021		if (isset ($macro_values[$i])) {
2022			$module_macros[$macro_names[$i]] = $macro_values[$i];
2023		}
2024	}
2025
2026	return base64_encode(json_encode ($module_macros));
2027}
2028
2029/**
2030 * Returns the relations between modules.
2031 *
2032 * @param array Optional assoc array with parameters.
2033 * (int) id_agent
2034 * (int) id_module
2035 * (bool) disabled_update
2036 * (string) modules_type: The type of the two modules
2037 *
2038 * @return mixed Array with relations between modules. False if there were no data.
2039 */
2040function modules_get_relations ($params = array()) {
2041	$id_agent = 0;
2042	if (isset($params['id_agent'])) {
2043		$id_agent = $params['id_agent'];
2044	}
2045
2046	$id_module = 0;
2047	if (isset($params['id_module'])) {
2048		$id_module = $params['id_module'];
2049	}
2050
2051	$disabled_update = -1;
2052	if (isset($params['disabled_update'])) {
2053		$disabled_update = (int) $params['disabled_update'];
2054		if ($disabled_update > 1) {
2055			$disabled_update = 1;
2056		}
2057	}
2058
2059	$modules_type = "";
2060	if (isset($params['modules_type'])) {
2061		$modules_type = $params['modules_type'];
2062	}
2063
2064	$sql = "SELECT DISTINCT tmr.id, tmr.module_a, tmr.module_b,
2065				tmr.disable_update
2066			FROM tmodule_relationship tmr,
2067				tagente_modulo tam,
2068				tagente ta,
2069				ttipo_modulo ttm
2070			WHERE ";
2071
2072	$agent_filter = "";
2073	if ($id_agent > 0) {
2074		$agent_filter = sprintf("AND ta.id_agente = %d", $id_agent);
2075	}
2076	$module_a_filter = "";
2077	$module_b_filter = "";
2078	if ($id_module > 0) {
2079		$module_a_filter = sprintf("AND tmr.module_a = %d", $id_module);
2080		$module_b_filter = sprintf("AND tmr.module_b = %d", $id_module);
2081	}
2082	$disabled_update_filter = "";
2083	if ($disabled_update >= 0) {
2084		$disabled_update_filter = sprintf(
2085			"AND tmr.disable_update = %d", $disabled_update);
2086	}
2087	$modules_type_filter = "";
2088	if ($modules_type != "") {
2089		$modules_type_filter = sprintf(
2090			"AND (tam.id_tipo_modulo = ttm.id_tipo AND ttm.nombre = '%s')", $modules_type);
2091	}
2092
2093	$sql .= "( (tmr.module_a = tam.id_agente_modulo
2094					$module_a_filter)
2095				OR (tmr.module_b = tam.id_agente_modulo
2096					$module_b_filter) )
2097				AND tam.id_agente = ta.id_agente
2098					$agent_filter
2099				$disabled_update_filter
2100				$modules_type_filter";
2101
2102	return db_get_all_rows_sql($sql);
2103}
2104
2105/**
2106 * Check if a relation already exists.
2107 *
2108 * @param int First module id.
2109 * @param mixed (Optional) int The second module id. array The module ids filter.
2110 *
2111 * @return bool True if the relation exists, false otherwise.
2112 */
2113function modules_relation_exists ($id_module, $id_module_other = false) {
2114
2115	if ($id_module_other === false) {
2116
2117		$sql = sprintf("SELECT id
2118						FROM tmodule_relationship
2119						WHERE module_a = %d
2120							OR module_b = %d",
2121						$id_module, $id_module);
2122
2123	} elseif (is_array($id_module_other)) {
2124
2125		$ids_other = 0;
2126		if (!empty($id_module_other)) {
2127			$ids_other = implode(",", $id_module_other);
2128		}
2129		$sql = sprintf("SELECT id
2130						FROM tmodule_relationship
2131						WHERE (module_a = %d AND module_b IN (%s))
2132							OR (module_b = %d AND module_a IN (%s))",
2133						$id_module, $ids_other, $id_module, $ids_other);
2134	} else {
2135		$sql = sprintf("SELECT id
2136						FROM tmodule_relationship
2137						WHERE (module_a = %d AND module_b = %d)
2138							OR (module_b = %d AND module_a = %d)",
2139						$id_module, $id_module_other, $id_module, $id_module_other);
2140	}
2141
2142	return (bool) db_get_row_sql($sql);
2143}
2144
2145/**
2146 * Change the 'disabled_update' value of a relation row.
2147 *
2148 * @param int Relation id.
2149 *
2150 * @return bool True if the 'disabled_update' changes to 1, false otherwise.
2151 */
2152function modules_add_relation ($id_module_a, $id_module_b) {
2153	$result = false;
2154
2155	if (!modules_relation_exists($id_module_a, $id_module_b) && $id_module_a > 0 && $id_module_b > 0) {
2156		$values = array(
2157				'module_a' => $id_module_a,
2158				'module_b' => $id_module_b
2159			);
2160		$result = db_process_sql_insert('tmodule_relationship', $values);
2161	}
2162
2163	return $result;
2164}
2165
2166/**
2167 * Change the 'disabled_update' value of a relation row.
2168 *
2169 * @param int Relation id.
2170 *
2171 * @return bool True if the 'disabled_update' changes to 1, false otherwise.
2172 */
2173function modules_delete_relation ($id_relation) {
2174	$result = db_process_sql_delete('tmodule_relationship', array('id' => $id_relation));
2175
2176	return $result;
2177}
2178
2179/**
2180 * Change the 'disabled_update' value of a relation row.
2181 *
2182 * @param int Relation id.
2183 *
2184 * @return bool True if the 'disabled_update' changes to 1, false otherwise.
2185 */
2186function modules_change_relation_lock ($id_relation) {
2187	$old_value = (int) db_get_value('disable_update', 'tmodule_relationship', 'id', $id_relation);
2188	$new_value = $old_value === 1 ? 0 : 1;
2189
2190	$result = db_process_sql_update(
2191		'tmodule_relationship',
2192		array('disable_update' => $new_value),
2193		array('id' => $id_relation));
2194
2195	return ($result !== false ? $new_value : $old_value);
2196}
2197
2198
2199
2200function modules_get_count_datas($id_agent_module, $date_init, $date_end) {
2201	$interval = modules_get_interval ($id_agent_module);
2202
2203	// TODO REMOVE THE TIME IN PLANNED DOWNTIME
2204
2205	if (!is_numeric($date_init)) {
2206		$date_init = strtotime($date_init);
2207	}
2208
2209	if (!is_numeric($date_end)) {
2210		$date_end = strtotime($date_end);
2211	}
2212
2213
2214
2215	$first_date = modules_get_first_contact_date($id_agent_module);
2216
2217
2218
2219	if ($date_init < $first_date) {
2220		$date_init = $first_date;
2221	}
2222
2223	$diff = $date_end - $date_init;
2224
2225
2226	return ($diff / $interval);
2227}
2228
2229
2230function modules_get_first_contact_date($id_agent_module) {
2231	global $config;
2232
2233	// TODO REMOVE THE TIME IN PLANNED DOWNTIME
2234
2235	// TODO FOR OTHER KIND OF DATA
2236
2237	$first_date = db_get_value('utimestamp', 'tagente_datos',
2238		'id_agente_modulo', $id_agent_module,
2239		$config['history_db_enabled']);
2240
2241	return $first_date;
2242}
2243
2244/**
2245 * Get the unknown time status of a module in a period.
2246 * If there is more than 1 days between data, there is some unknown time modules
2247 *
2248 * @param int id_agent_module.
2249 * @param int ending interval timestamp
2250 * @param int interval duration
2251 *
2252 * @return int unknown seconds.
2253 */
2254function modules_get_unknown_time ($id_agent_module, $date, $period){
2255
2256	// TODO REMOVE THE TIME IN PLANNED DOWNTIME
2257
2258	if (empty($id_agent_module) || empty($date))
2259		return false;
2260
2261	// Set initial conditions
2262	$unknown_seconds = 0;
2263	$datelimit = $date - $period;
2264	$search_in_history_db = db_search_in_history_db($datelimit);
2265
2266	// Get interval data
2267	$sql = sprintf ('SELECT utimestamp
2268		FROM tagente_datos
2269		WHERE id_agente_modulo = %d
2270			AND utimestamp > %d AND utimestamp <= %d',
2271		$id_agent_module, $datelimit, $date);
2272	$sql .= ' ORDER BY utimestamp ASC';
2273	$interval_data = db_get_all_rows_sql ($sql, $search_in_history_db);
2274
2275	$previous_data = modules_get_previous_data ($id_agent_module, $datelimit);
2276
2277	// All alternatives on first data
2278	if ($previous_data === false && $interval_data === false) {
2279		return false;
2280	} else if($previous_data !== false && $interval_data === false) {
2281		if (($date - $previous_data['utimestamp']) <= SECONDS_1DAY) {
2282			return 0;
2283		}
2284		if (($previous_data['utimestamp'] + SECONDS_1DAY) >= $datelimit) {
2285			return $date - ($previous_data['utimestamp'] + SECONDS_1DAY);
2286		} else {
2287			return $period;
2288		}
2289	} else if ($previous_data === false && $interval_data !== false) {
2290		$first_data = array_shift ($interval_data);
2291		$unknown_seconds += $first_data['utimestamp'] - $datelimit;
2292		array_unshift ($interval_data, $first_data);
2293	} else {
2294		$first_data = array_shift ($interval_data);
2295		if (($previous_data['utimestamp'] + SECONDS_1DAY) >= $first_data['utimestamp']) {
2296			if (($previous_data['utimestamp'] + SECONDS_1DAY) >= $datelimit) {
2297				$unknown_seconds += $previous_data['utimestamp'] + SECONDS_1DAY - $first_data['utimestamp'];
2298			} else {
2299				$unknown_seconds += $first_data['utimestamp'] - $datetime;
2300			}
2301		}
2302		array_unshift ($interval_data, $first_data);
2303	}
2304
2305	// Put utimestamp like last data
2306	$last_data['utimestamp'] = $date;
2307	array_push ($interval_data, $last_data);
2308	$previous_data = array_shift ($previous_data);
2309
2310	// Check if all datas have data maximum one day before
2311	foreach ($interval_data as $data) {
2312		$previous_1day = $previous_data['utimestamp'] + SECONDS_1DAY;
2313		if ($previous_1day >= $data['utimestamp']) {
2314			$unknown_period += $previous_1day - $data['utimestamp'];
2315		}
2316		$previous_data = $data;
2317	}
2318
2319	return $unknown_seconds;
2320}
2321?>
2322