2012-07-24 Miguel de Dios <miguel.dedios@artica.es>

* lib/PandoraFMS/Core.pm, lib/PandoraFMS/Tools.pm,
	lib/PandoraFMS/PredictionServer.pm: cleaned source code style.
	
	* lib/PandoraFMS/DB.pm: added functions "get_agent_status",
		"get_agent_modules" and "get_agentmodule_status".




git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@6803 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
This commit is contained in:
mdtrooper 2012-07-24 13:23:27 +00:00
parent b063fc814c
commit 28bca04079
5 changed files with 541 additions and 361 deletions

View File

@ -1,3 +1,11 @@
2012-07-24 Miguel de Dios <miguel.dedios@artica.es>
* lib/PandoraFMS/Core.pm, lib/PandoraFMS/Tools.pm,
lib/PandoraFMS/PredictionServer.pm: cleaned source code style.
* lib/PandoraFMS/DB.pm: added functions "get_agent_status",
"get_agent_modules" and "get_agentmodule_status".
2012-07-16 Dario Rodriguez <dario.rodriguez@artica.es>
* lib/PandoraFMS/Core.pm: Updated statistic queries from php code

View File

@ -872,8 +872,12 @@ sub pandora_process_module ($$$$$$$$$;$) {
my ($pa_config, $data_object, $agent, $module, $module_type,
$timestamp, $utimestamp, $server_id, $dbh, $extra_macros) = @_;
logger($pa_config, "Processing module '" . safe_output($module->{'nombre'}) . "' for agent " . (defined ($agent) && $agent ne '' ? "'" . safe_output($agent->{'nombre'}) . "'" : 'ID ' . $module->{'id_agente'}) . ".", 10);
logger($pa_config,
"Processing module '" . safe_output($module->{'nombre'}) .
"' for agent " .
(defined ($agent) && $agent ne '' ? "'" . safe_output($agent->{'nombre'}) . "'" : 'ID ' . $module->{'id_agente'}) . ".",
1);
# Get agent information
if (! defined ($agent) || $agent eq '') {
$agent = get_db_single_row ($dbh, 'SELECT * FROM tagente WHERE id_agente = ?', $module->{'id_agente'});
@ -883,7 +887,7 @@ sub pandora_process_module ($$$$$$$$$;$) {
return;
}
}
# Get module type
if (! defined ($module_type) || $module_type eq '') {
$module_type = get_db_value ($dbh, 'SELECT nombre FROM ttipo_modulo WHERE id_tipo = ?', $module->{'id_tipo_modulo'});

View File

@ -20,7 +20,9 @@ package PandoraFMS::DB;
use strict;
use warnings;
use DBI;
use PandoraFMS::Tools;
use PandoraFMS::Tools;
#use Data::Dumper;
require Exporter;
@ -73,6 +75,9 @@ our @EXPORT = qw(
get_user_exists
is_agent_address
is_group_disabled
get_agent_status
get_agent_modules
get_agentmodule_status
);
##########################################################################
@ -81,7 +86,7 @@ our @EXPORT = qw(
my $RDBMS = '';
sub db_connect ($$$$$$) {
my ($rdbms, $db_name, $db_host, $db_port, $db_user, $db_pass) = @_;
if ($rdbms eq 'mysql') {
$RDBMS = 'mysql';
@ -91,12 +96,13 @@ sub db_connect ($$$$$$) {
# Enable auto reconnect
$dbh->{'mysql_auto_reconnect'} = 1;
# Enable character semantics
$dbh->{'mysql_enable_utf8'} = 1;
return $dbh;
} elsif ($rdbms eq 'postgresql') {
}
elsif ($rdbms eq 'postgresql') {
$RDBMS = 'postgresql';
# Connect to PostgreSQL
@ -188,55 +194,169 @@ sub get_os_id ($$) {
sub get_agent_group ($$) {
my ($dbh, $agent_id) = @_;
my $group_id = get_db_value ($dbh, "SELECT id_grupo FROM tagente WHERE id_agente = ?", $agent_id);
my $group_id = get_db_value ($dbh, "SELECT id_grupo
FROM tagente
WHERE id_agente = ?", $agent_id);
return 0 unless defined ($group_id);
return $group_id;
}
##########################################################################
########################################################################
## SUB get_agent_name (agent_id)
## Return agent name, given "agent_id"
##########################################################################
########################################################################
sub get_agent_name ($$) {
my ($dbh, $agent_id) = @_;
return get_db_value ($dbh, "SELECT nombre FROM tagente WHERE id_agente = ?", $agent_id);
return get_db_value ($dbh, "SELECT nombre
FROM tagente
WHERE id_agente = ?", $agent_id);
}
##########################################################################
########################################################################
## SUB agents_get_modules (agent_id, fields, filters)
## Return the list of modules, given "agent_id"
########################################################################
sub get_agent_modules ($$$$$) {
my ($pa_config, $dbh, $agent_id, $fields, $filters) = @_;
my $str_filter = '';
foreach my $key (keys $filters) {
$str_filter .= ' AND ' . $key . " = " . $filters->{$key};
}
my @rows = get_db_rows($dbh, "SELECT *
FROM tagente_modulo
WHERE id_agente = ?" . $str_filter, $agent_id);
return @rows;
}
########################################################################
## SUB get_agentmodule_status (agent_module_id)
## Return agent module status. given "agent_module_id"
########################################################################
sub get_agentmodule_status($$$) {
my ($pa_config, $dbh, $agent_module_id) = @_;
my $status = get_db_value($dbh, 'SELECT estado
FROM tagente_estado
WHERE id_agente_modulo = ?', $agent_module_id);
return $status;
}
########################################################################
## SUB get_get_status (agent_id)
## Return agent status, given "agent_id"
########################################################################
sub get_agent_status ($$$) {
my ($pa_config, $dbh, $agent_id) = @_;
my @modules = get_agent_modules ($pa_config, $dbh,
$agent_id, 'id_agente_modulo', {'disabled' => 0});
#logger($pa_config, Dumper(@modules), 5);
# The status are:
# 3 -> AGENT_MODULE_STATUS_UNKNOW
# 4 -> AGENT_MODULE_STATUS_CRITICAL_ALERT
# 1 -> AGENT_MODULE_STATUS_CRITICAL_BAD
# 2 -> AGENT_MODULE_STATUS_WARNING
# 0 -> AGENT_MODULE_STATUS_NORMAL
my $module_status = 3;
my $modules_async = 0;
foreach my $module (@modules) {
my $m_status = get_agentmodule_status($pa_config, $dbh,
$module->{'id_agente_modulo'});
#This is the order to check
# AGENT_MODULE_STATUS_CRITICAL_ALERT
# AGENT_MODULE_STATUS_CRITICAL_BAD
# AGENT_MODULE_STATUS_WARNING
# AGENT_MODULE_STATUS_UNKNOW
# AGENT_MODULE_STATUS_NORMAL
if ($m_status == 4) {
$module_status = 4;
}
elsif ($module_status != 4) {
if ($m_status == 1) {
$module_status = 1;
}
elsif ($module_status != 1) {
if ($m_status == 2) {
$module_status = 2;
}
else {
if ($m_status == 0) {
$module_status = 0;
}
}
}
}
my $module_type = get_db_value($dbh, 'SELECT id_tipo_modulo
FROM tagente_modulo
WHERE id_agente_modulo = ?', $module->{'id_agente_modulo'});
if (($module_type >= 21 && $module_type <= 23) ||
$module_type == 100) {
$modules_async++;
}
}
my $count_modules = scalar(@modules);
# If all the modules are asynchronous or keep alive, the group cannot be unknown
if ($modules_async < $count_modules) {
my $last_contact = get_db_value($dbh,
'SELECT (UNIX_TIMESTAMP(ultimo_contacto) + (intervalo * 2)) AS last_contact
FROM tagente WHERE id_agente = ?', $agent_id);
if ($last_contact < time ()) {
return 3;
}
}
return $module_status;
}
########################################################################
## SUB get_module_agent_id (agent_module_id)
## Return agent id, given "agent_module_id"
##########################################################################
########################################################################
sub get_module_agent_id ($$) {
my ($dbh, $agent_module_id) = @_;
return get_db_value ($dbh, "SELECT id_agente FROM tagente_modulo WHERE id_agente_modulo = ?", $agent_module_id);
}
##########################################################################
########################################################################
## SUB get_agent_address (id_agente)
## Return agent address, given "agent_id"
##########################################################################
########################################################################
sub get_agent_address ($$) {
my ($dbh, $agent_id) = @_;
return get_db_value ($dbh, "SELECT direccion FROM tagente WHERE id_agente = ?", $agent_id);
}
##########################################################################
########################################################################
## SUB get_module_name(module_id)
## Return the module name, given "module_id"
##########################################################################
########################################################################
sub get_module_name ($$) {
my ($dbh, $module_id) = @_;
return get_db_value ($dbh, "SELECT nombre FROM tagente_modulo WHERE id_agente_modulo = ?", $module_id);
}
##########################################################################
########################################################################
## Return module id given the module name and agent id.
##########################################################################
########################################################################
sub get_agent_module_id ($$$) {
my ($dbh, $module_name, $agent_id) = @_;
@ -269,7 +389,7 @@ sub get_template_module_id ($$$) {
##########################################################################
sub is_group_disabled ($$) {
my ($dbh, $group_id) = @_;
return get_db_value ($dbh, "SELECT disabled FROM tgrupo WHERE id_grupo = ?", $group_id);
}
@ -278,7 +398,7 @@ sub is_group_disabled ($$) {
##########################################################################
sub get_module_id ($$) {
my ($dbh, $module_name) = @_;
my $rc = get_db_value ($dbh, "SELECT id_tipo FROM ttipo_modulo WHERE nombre = ?", safe_input($module_name));
return defined ($rc) ? $rc : -1;
}
@ -288,7 +408,7 @@ sub get_module_id ($$) {
##########################################################################
sub get_user_disabled ($$) {
my ($dbh, $user_id) = @_;
my $rc = get_db_value ($dbh, "SELECT disabled FROM tusuario WHERE id_user = ?", safe_input($user_id));
return defined ($rc) ? $rc : -1;
}
@ -298,7 +418,7 @@ sub get_user_disabled ($$) {
##########################################################################
sub get_user_exists ($$) {
my ($dbh, $user_id) = @_;
my $rc = get_db_value ($dbh, "SELECT id_user FROM tusuario WHERE id_user = ?", safe_input($user_id));
return defined ($rc) ? 1 : -1;
}
@ -308,7 +428,7 @@ sub get_user_exists ($$) {
##########################################################################
sub get_plugin_id ($$) {
my ($dbh, $plugin_name) = @_;
my $rc = get_db_value ($dbh, "SELECT id FROM tplugin WHERE name = ?", safe_input($plugin_name));
return defined ($rc) ? $rc : -1;
}
@ -318,8 +438,8 @@ sub get_plugin_id ($$) {
##########################################################################
sub get_module_group_id ($$) {
my ($dbh, $module_group_name) = @_;
if(!defined($module_group_name) || $module_group_name eq '') {
if (!defined($module_group_name) || $module_group_name eq '') {
return 0;
}
@ -332,7 +452,7 @@ sub get_module_group_id ($$) {
##########################################################################
sub get_module_group_name ($$) {
my ($dbh, $module_group_id) = @_;
return get_db_value ($dbh, "SELECT name FROM tmodule_group WHERE id_mg = ?", $module_group_id);
}
@ -350,7 +470,7 @@ sub get_nc_profile_name ($$) {
##########################################################################
sub get_profile_id ($$) {
my ($dbh, $profile_name) = @_;
my $rc = get_db_value ($dbh, "SELECT id_perfil FROM tperfil WHERE name = ?", safe_input($profile_name));
return defined ($rc) ? $rc : -1;
}
@ -364,26 +484,27 @@ sub get_group_name ($$) {
return get_db_value ($dbh, "SELECT nombre FROM tgrupo WHERE id_grupo = ?", $group_id);
}
##########################################################################
########################################################################
## Get a single column returned by an SQL query as a hash reference.
##########################################################################
########################################################################
sub get_db_value ($$;@) {
my ($dbh, $query, @values) = @_;
my @rows;
# Cache statements
my $sth = $dbh->prepare_cached($query);
$sth->execute(@values);
# Save returned rows
while (my $row = $sth->fetchrow_arrayref()) {
$sth->finish();
return defined ($row->[0]) ? $row->[0] : undef;
}
my ($dbh, $query, @values) = @_;
#my @rows;
# Cache statements
my $sth = $dbh->prepare_cached($query);
$sth->execute(@values);
# Save returned rows
while (my $row = $sth->fetchrow_arrayref()) {
$sth->finish();
return undef;
return defined ($row->[0]) ? $row->[0] : undef;
}
$sth->finish();
return undef;
}
##########################################################################
@ -391,48 +512,50 @@ sub get_db_value ($$;@) {
## -1 on error.
##########################################################################
sub get_db_single_row ($$;@) {
my ($dbh, $query, @values) = @_;
my @rows;
# Cache statements
my $sth = $dbh->prepare_cached($query);
$sth->execute(@values);
# Save returned rows
while (my $row = $sth->fetchrow_hashref()) {
$sth->finish();
return {map { lc ($_) => $row->{$_} } keys (%{$row})} if ($RDBMS eq 'oracle');
return $row;
}
my ($dbh, $query, @values) = @_;
#my @rows;
# Cache statements
my $sth = $dbh->prepare_cached($query);
$sth->execute(@values);
# Save returned rows
while (my $row = $sth->fetchrow_hashref()) {
$sth->finish();
return undef;
return {map { lc ($_) => $row->{$_} } keys (%{$row})} if ($RDBMS eq 'oracle');
return $row;
}
$sth->finish();
return undef;
}
##########################################################################
## Get all rows returned by an SQL query as a hash reference array.
##########################################################################
sub get_db_rows ($$;@) {
my ($dbh, $query, @values) = @_;
my @rows;
# Cache statements
my $sth = $dbh->prepare_cached($query);
$sth->execute(@values);
# Save returned rows
while (my $row = $sth->fetchrow_hashref()) {
if ($RDBMS eq 'oracle') {
push (@rows, {map { lc ($_) => $row->{$_} } keys (%{$row})});
} else {
push (@rows, $row);
}
my ($dbh, $query, @values) = @_;
my @rows;
# Cache statements
my $sth = $dbh->prepare_cached($query);
$sth->execute(@values);
# Save returned rows
while (my $row = $sth->fetchrow_hashref()) {
if ($RDBMS eq 'oracle') {
push (@rows, {map { lc ($_) => $row->{$_} } keys (%{$row})});
}
$sth->finish();
return @rows;
else {
push (@rows, $row);
}
}
$sth->finish();
return @rows;
}
##########################################################################
@ -441,7 +564,7 @@ sub get_db_rows ($$;@) {
sub db_insert ($$$;@) {
my ($dbh, $index, $query, @values) = @_;
my $insert_id = undef;
# MySQL
if ($RDBMS eq 'mysql') {
$dbh->do($query, undef, @values);
@ -460,7 +583,7 @@ sub db_insert ($$$;@) {
$sth->bind_param_inout($#values + 2, \$insert_id, 99);
$sth->execute ();
}
return $insert_id;
}
@ -480,7 +603,7 @@ sub db_update ($$;@) {
##########################################################################
sub get_alert_template_module_id ($$$) {
my ($dbh, $id_module, $id_template) = @_;
my $rc = get_db_value ($dbh, "SELECT id FROM talert_template_modules WHERE id_agent_module = ? AND id_alert_template = ?", $id_module, $id_template);
return defined ($rc) ? $rc : -1;
}
@ -490,11 +613,11 @@ sub get_alert_template_module_id ($$$) {
##########################################################################
sub db_process_insert($$$$;@) {
my ($dbh, $index, $table, $parameters, @values) = @_;
my @columns_array = keys %$parameters;
my @values_array = values %$parameters;
if(!defined($table) || $#columns_array == -1) {
if (!defined($table) || $#columns_array == -1) {
return -1;
exit;
}
@ -502,20 +625,20 @@ sub db_process_insert($$$$;@) {
# Generate the '?' simbols to the Query like '(?,?,?,?,?)'
my $wildcards = '';
for (my $i=0; $i<=$#values_array; $i++) {
if(!defined($values_array[$i])) {
if (!defined($values_array[$i])) {
$values_array[$i] = '';
}
if($i > 0 && $i <= $#values_array) {
if ($i > 0 && $i <= $#values_array) {
$wildcards = $wildcards.',';
}
$wildcards = $wildcards.'?';
}
}
$wildcards = '('.$wildcards.')';
my $columns_string = join('`,`',@columns_array);
my $res = db_insert ($dbh, $index, "INSERT INTO $table (`".$columns_string."`) VALUES ".$wildcards, @values_array);
return $res;
}
@ -524,30 +647,30 @@ sub db_process_insert($$$$;@) {
##########################################################################
sub db_process_update($$$$$;@) {
my ($dbh, $table, $parameters, $where_column, $where_value, @values) = @_;
my @columns_array = keys %$parameters;
my @values_array = values %$parameters;
if(!defined($table) || $#columns_array == -1) {
if (!defined($table) || $#columns_array == -1) {
return -1;
exit;
}
my $fields = '';
for (my $i=0; $i<=$#values_array; $i++) {
if(!defined($values_array[$i])) {
if (!defined($values_array[$i])) {
$values_array[$i] = '';
}
if($i > 0 && $i <= $#values_array) {
if ($i > 0 && $i <= $#values_array) {
$fields = $fields.',';
}
$fields = $fields." `$columns_array[$i]` = ?";
}
}
push(@values_array, $where_value);
my $res = db_update ($dbh, "UPDATE $table SET$fields WHERE $where_column = ?", @values_array);
return $res;
}
@ -567,7 +690,7 @@ sub add_new_address_agent ($$$) {
my ($dbh, $addr_id, $agent_id) = @_;
db_do ($dbh, 'INSERT INTO taddress_agent (`id_a`, `id_agent`)
VALUES (?, ?)', $addr_id, $agent_id);
VALUES (?, ?)', $addr_id, $agent_id);
}
##########################################################################
@ -575,8 +698,12 @@ sub add_new_address_agent ($$$) {
##########################################################################
sub get_addr_id ($$) {
my ($dbh, $addr) = @_;
my $addr_id = get_db_value ($dbh, 'SELECT id_a FROM taddress WHERE ip = ?', $addr);
my $addr_id = get_db_value ($dbh,
'SELECT id_a
FROM taddress
WHERE ip = ?', $addr);
return (defined ($addr_id) ? $addr_id : -1);
}
@ -586,8 +713,12 @@ sub get_addr_id ($$) {
##########################################################################
sub get_agent_addr_id ($$$) {
my ($dbh, $addr_id, $agent_id) = @_;
my $agent_addr_id = get_db_value ($dbh, 'SELECT id_ag FROM taddress_agent WHERE id_a = ? AND id_agent = ?', $addr_id, $agent_id);
my $agent_addr_id = get_db_value ($dbh,
'SELECT id_ag
FROM taddress_agent
WHERE id_a = ?
AND id_agent = ?', $addr_id, $agent_id);
return (defined ($agent_addr_id) ? $agent_addr_id : -1);
}
@ -596,9 +727,9 @@ sub get_agent_addr_id ($$$) {
##########################################################################
sub db_do ($$;@) {
my ($dbh, $query, @values) = @_;
#DBI->trace( 3, '/tmp/dbitrace.log' );
$dbh->do($query, undef, @values);
}
@ -607,11 +738,12 @@ sub db_do ($$;@) {
##########################################################################
sub is_agent_address ($$$) {
my ($dbh, $id_agent, $id_addr) = @_;
my $id_ag = get_db_value ($dbh, 'SELECT id_ag FROM taddress_agent
WHERE id_a = ?
AND id_agent = ?', $id_addr, $id_agent);
my $id_ag = get_db_value ($dbh, 'SELECT id_ag
FROM taddress_agent
WHERE id_a = ?
AND id_agent = ?', $id_addr, $id_agent);
return (defined ($id_ag)) ? $id_ag : 0;
}
@ -623,7 +755,7 @@ sub db_reserved_word ($) {
# MySQL
return '`' . $reserved_word . '`' if ($RDBMS eq 'mysql');
# PostgreSQL
return '"' . $reserved_word . '"' if ($RDBMS eq 'postgresql' || $RDBMS eq 'oracle');
@ -671,8 +803,8 @@ sub db_concat ($$) {
my ($element1, $element2) = @_;
return " concat(" . $element1 . ", ' '," . $element2 . ") " if ($RDBMS eq 'mysql');
return " " . $element1 . " || ' ' || " . $element2 . " " if ($RDBMS eq 'oracle' or $RDBMS eq 'postgresql');
return " " . $element1 . " || ' ' || " . $element2 . " " if ($RDBMS eq 'oracle' or $RDBMS eq 'postgresql');
}
##########################################################################
@ -681,25 +813,25 @@ sub db_concat ($$) {
sub get_priority_name ($) {
my ($priority_id) = @_;
if($priority_id == 0) {
if ($priority_id == 0) {
return 'Maintenance';
}
elsif($priority_id == 1) {
elsif ($priority_id == 1) {
return 'Informational';
}
elsif($priority_id == 2) {
elsif ($priority_id == 2) {
return 'Normal';
}
elsif($priority_id == 3) {
elsif ($priority_id == 3) {
return 'Warning';
}
elsif($priority_id == 4) {
elsif ($priority_id == 4) {
return 'Critical';
}
elsif($priority_id == 5) {
elsif ($priority_id == 5) {
return 'Minor';
}
elsif($priority_id == 6) {
elsif ($priority_id == 6) {
return 'Major';
}

View File

@ -1,8 +1,8 @@
package PandoraFMS::PredictionServer;
##########################################################################
########################################################################
# Pandora FMS Prediction Server.
# Pandora FMS. the Flexible Monitoring System. http://www.pandorafms.org
##########################################################################
########################################################################
# Copyright (c) 2005-2009 Artica Soluciones Tecnologicas S.L
#
# This program is free software; you can redistribute it and/or
@ -36,6 +36,9 @@ use PandoraFMS::DB;
use PandoraFMS::Core;
use PandoraFMS::ProducerConsumerServer;
#For debug
#use Data::Dumper;
# Inherits from PandoraFMS::ProducerConsumerServer
our @ISA = qw(PandoraFMS::ProducerConsumerServer);
@ -45,106 +48,117 @@ my %PendingTasks :shared;
my $Sem :shared = Thread::Semaphore->new;
my $TaskSem :shared = Thread::Semaphore->new (0);
########################################################################################
########################################################################
# Prediction Server class constructor.
########################################################################################
########################################################################
sub new ($$;$) {
my ($class, $config, $dbh) = @_;
return undef unless $config->{'predictionserver'} == 1;
# Call the constructor of the parent class
my $self = $class->SUPER::new($config, 5, \&PandoraFMS::PredictionServer::data_producer, \&PandoraFMS::PredictionServer::data_consumer, $dbh);
bless $self, $class;
return $self;
bless $self, $class;
return $self;
}
###############################################################################
########################################################################
# Run.
###############################################################################
########################################################################
sub run ($) {
my $self = shift;
my $pa_config = $self->getConfig ();
print_message ($pa_config, " [*] Starting Pandora FMS Prediction Server.", 1);
$self->setNumThreads ($pa_config->{'prediction_threads'});
$self->SUPER::run (\@TaskQueue, \%PendingTasks, $Sem, $TaskSem);
}
###############################################################################
########################################################################
# Data producer.
###############################################################################
########################################################################
sub data_producer ($) {
my $self = shift;
my ($pa_config, $dbh) = ($self->getConfig (), $self->getDBH ());
my @tasks;
my @rows;
if ($pa_config->{'pandora_master'} != 1) {
@rows = get_db_rows ($dbh, 'SELECT tagente_modulo.id_agente_modulo, tagente_modulo.flag, last_execution_try
@rows = get_db_rows ($dbh, 'SELECT tagente_modulo.id_agente_modulo,
tagente_modulo.flag, last_execution_try
FROM tagente, tagente_modulo, tagente_estado
WHERE server_name = ?
AND tagente_modulo.id_agente = tagente.id_agente
AND tagente.disabled = 0
AND tagente_modulo.prediction_module != 0
AND tagente_modulo.disabled = 0
AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo
AND tagente_modulo.id_modulo = 5
AND (tagente_modulo.flag = 1
OR (tagente_estado.last_execution_try + tagente_estado.current_interval) < UNIX_TIMESTAMP())
ORDER BY last_execution_try ASC ', $pa_config->{'servername'});
} else {
@rows = get_db_rows ($dbh, 'SELECT DISTINCT(tagente_modulo.id_agente_modulo), tagente_modulo.flag, last_execution_try
FROM tagente, tagente_modulo, tagente_estado
WHERE ((server_name = ?) OR (server_name = ANY(SELECT name FROM tserver WHERE status = 0)))
AND tagente_modulo.id_agente = tagente.id_agente
AND tagente.disabled = 0
AND tagente_modulo.disabled = 0
AND tagente_modulo.prediction_module != 0
AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo
AND tagente_modulo.id_agente = tagente.id_agente
AND tagente.disabled = 0
AND tagente_modulo.prediction_module != 0
AND tagente_modulo.disabled = 0
AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo
AND tagente_modulo.id_modulo = 5
AND (tagente_modulo.flag = 1 OR (tagente_estado.last_execution_try + tagente_estado.current_interval) < UNIX_TIMESTAMP())
ORDER BY last_execution_try ASC', $pa_config->{'servername'});
AND (tagente_modulo.flag = 1
OR (tagente_estado.last_execution_try + tagente_estado.current_interval) < UNIX_TIMESTAMP())
ORDER BY last_execution_try ASC ', $pa_config->{'servername'});
}
else {
@rows = get_db_rows ($dbh, 'SELECT DISTINCT(tagente_modulo.id_agente_modulo),
tagente_modulo.flag, last_execution_try
FROM tagente, tagente_modulo, tagente_estado
WHERE ((server_name = ?)
OR (server_name = ANY(SELECT name
FROM tserver
WHERE status = 0)))
AND tagente_modulo.id_agente = tagente.id_agente
AND tagente.disabled = 0
AND tagente_modulo.disabled = 0
AND tagente_modulo.prediction_module != 0
AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo
AND tagente_modulo.id_modulo = 5
AND (tagente_modulo.flag = 1
OR (tagente_estado.last_execution_try + tagente_estado.current_interval) < UNIX_TIMESTAMP())
ORDER BY last_execution_try ASC', $pa_config->{'servername'});
}
foreach my $row (@rows) {
# Reset forced execution flag
if ($row->{'flag'} == 1) {
db_do ($dbh, 'UPDATE tagente_modulo SET flag = 0 WHERE id_agente_modulo = ?', $row->{'id_agente_modulo'});
}
push (@tasks, $row->{'id_agente_modulo'});
}
return @tasks;
}
###############################################################################
########################################################################
# Data consumer.
###############################################################################
########################################################################
sub data_consumer ($$) {
my ($self, $task) = @_;
exec_prediction_module ($self->getConfig (), $task, $self->getServerID (), $self->getDBH ());
}
##########################################################################
########################################################################
# Execute prediction module.
##########################################################################
########################################################################
sub exec_prediction_module ($$$$) {
my ($pa_config, $id_am, $server_id, $dbh) = @_;
# Get a full hash for agent_module record reference ($agent_module)
my $agent_module = get_db_single_row ($dbh, 'SELECT * FROM tagente_modulo WHERE id_agente_modulo = ?', $id_am);
my ($pa_config, $id_am, $server_id, $dbh) = @_;
# Get a full hash for agent_module record reference ($agent_module)
my $agent_module = get_db_single_row ($dbh, 'SELECT *
FROM tagente_modulo
WHERE id_agente_modulo = ?', $id_am);
return unless defined $agent_module;
# Service modules
if ($agent_module->{'prediction_module'} == 2) {
logger ($pa_config, "Executing service module " . $agent_module->{'nombre'}, 10);
logger ($pa_config, "Executing service module " . $agent_module->{'nombre'}, 5);
enterprise_hook ('exec_service_module', [$pa_config, $agent_module, $server_id, $dbh]);
logger ($pa_config, "End execution", 5);
return;
}
@ -154,122 +168,141 @@ sub exec_prediction_module ($$$$) {
enterprise_hook ('exec_synthetic_module', [$pa_config, $agent_module, $server_id, $dbh]);
return;
}
# Netflow modules
if ($agent_module->{'prediction_module'} == 4) {
logger ($pa_config, "Executing netflow module " . $agent_module->{'nombre'}, 10);
enterprise_hook ('exec_netflow_module', [$pa_config, $agent_module, $server_id, $dbh]);
return;
}
# Get a full hash for target agent_module record reference ($target_module)
my $target_module = get_db_single_row ($dbh, 'SELECT * FROM tagente_modulo WHERE id_agente_modulo = ?', $agent_module->{'prediction_module'});
# Get a full hash for target agent_module record reference ($target_module)
my $target_module = get_db_single_row ($dbh, 'SELECT * FROM tagente_modulo WHERE id_agente_modulo = ?', $agent_module->{'prediction_module'});
return unless defined $target_module;
# Prediction mode explanation
#
# 0 is for target type of generic_proc. It compares latest data with current data. Needs to get
# data on a "middle" interval, so if interval is 300, get data to compare with 150 before
# and 150 in the future. If current data is ABOVE or BELOW average +- typical_deviation
# this is a BAD value (0), if not is ok (1) and written in target module as is.
# more interval configured for this module, more "margin" has to compare data.
#
# 1 is for target type of generic_data. It get's data in the future, using the interval given in
# module. It gets average from current timestamp to INTERVAL in the future and gets average
# value. Typical deviation is not used here.
# Prediction mode explanation
#
# 0 is for target type of generic_proc. It compares latest data with current data. Needs to get
# data on a "middle" interval, so if interval is 300, get data to compare with 150 before
# and 150 in the future. If current data is ABOVE or BELOW average +- typical_deviation
# this is a BAD value (0), if not is ok (1) and written in target module as is.
# more interval configured for this module, more "margin" has to compare data.
#
# 1 is for target type of generic_data. It get's data in the future, using the interval given in
# module. It gets average from current timestamp to INTERVAL in the future and gets average
# value. Typical deviation is not used here.
# 0 proc, 1 data
my $prediction_mode = ($agent_module->{'id_tipo_modulo'} == 2) ? 0 : 1;
# Initialize another global sub variables.
my $prediction_mode = ($agent_module->{'id_tipo_modulo'} == 2) ? 0 : 1;
# Initialize another global sub variables.
my $module_data = 0; # 0 data for default
# Get current timestamp
my $utimestamp = time ();
my $timestamp = strftime ("%Y-%m-%d %H:%M:%S", localtime($utimestamp));
# Get different data from each week one month ago (4 values)
# $agent_module->{'module_interval'} uses a margin of interval to get average data from the past
my @week_data;
my @week_utimestamp;
for (my $i=0; $i<4; $i++){
$week_utimestamp[$i] = $utimestamp - (84600*7*($i+1));
# Adjust for proc prediction
if ($prediction_mode == 0) {
$week_utimestamp[$i] = $week_utimestamp[$i] - ($agent_module->{'module_interval'} / 2);
}
}
# Let's calculate statistical average using past data
# n = total of real data values
my ($n, $average, $temp1) = (0, 0, 0);
for (my $i=0; $i < 4; $i++){
my ($first_data, $last_data, $average_interval);
my $sum_data = 0;
$temp1 = $week_utimestamp[$i] + $agent_module->{'module_interval'};
# Get data for week $i in the past
$average_interval = get_db_value ($dbh, 'SELECT AVG(datos) FROM tagente_datos WHERE id_agente_modulo = ? AND utimestamp > ? AND utimestamp < ?', $target_module->{'id_agente_modulo'}, $week_utimestamp[$i], $temp1);
# Need to get data outside interval because no data.
if (!(defined($average_interval)) || ($average_interval == 0)) {
$last_data = get_db_value ($dbh, 'SELECT datos FROM tagente_datos WHERE id_agente_modulo = ? AND utimestamp > ? LIMIT 1', $target_module->{'id_agente_modulo'}, $week_utimestamp[$i]);
next unless defined ($last_data);
$first_data = get_db_value ($dbh, 'SELECT datos FROM tagente_datos WHERE id_agente_modulo = ? AND utimestamp < ? LIMIT 1', $target_module->{'id_agente_modulo'}, $temp1);
next unless defined ($first_data);
$sum_data++ if ($last_data != 0);
$sum_data++ if ($first_data != 0);
$week_data[$i] = ($sum_data > 0) ? (($last_data + $first_data) / $sum_data) : 0;
} else {
$week_data[$i] = $average_interval;
}
# It's possible that one of the week_data[i] values was not valid (NULL)
# so recheck it and relay on n=0 for "no data" values set to 0 in result
# Calculate total ammount of valida data for each data sample
if ((is_numeric($week_data[$i])) && ($week_data[$i] > 0)){
$n++;
# Average SUM
$average = $average + $week_data[$i];
}
}
# Real average value
$average = ($n > 0) ? ($average / $n) : 0;
# (PROC) Compare with current data
if ($prediction_mode == 0){
# Calculate typical deviation
my $typical_deviation = 0;
for (my $i=0; $i< $n; $i++){
if ((is_numeric($week_data[$i])) && ($week_data[$i] > 0)) {
$typical_deviation = $typical_deviation + (($week_data[$i] - $average)**2);
}
}
$typical_deviation = ($n > 1) ? sqrt ($typical_deviation / ($n-1)) : 0;
my $current_value = get_db_value ($dbh, 'SELECT datos FROM tagente_estado WHERE id_agente_modulo = ?', $target_module->{'id_agente_modulo'});
if ( ($current_value > ($average - $typical_deviation)) && ($current_value < ($average + $typical_deviation)) ){
$module_data = 1; # OK !!
} else {
$module_data = 0; # Out of predictions
}
} else {
# Prediction based on data
$module_data = $average;
}
# Get different data from each week one month ago (4 values)
# $agent_module->{'module_interval'} uses a margin of interval to get average data from the past
my @week_data;
my @week_utimestamp;
for (my $i=0; $i<4; $i++) {
$week_utimestamp[$i] = $utimestamp - (84600*7*($i+1));
# Adjust for proc prediction
if ($prediction_mode == 0) {
$week_utimestamp[$i] = $week_utimestamp[$i] - ($agent_module->{'module_interval'} / 2);
}
}
# Let's calculate statistical average using past data
# n = total of real data values
my ($n, $average, $temp1) = (0, 0, 0);
for (my $i=0; $i < 4; $i++) {
my ($first_data, $last_data, $average_interval);
my $sum_data = 0;
$temp1 = $week_utimestamp[$i] + $agent_module->{'module_interval'};
# Get data for week $i in the past
$average_interval = get_db_value ($dbh, 'SELECT AVG(datos)
FROM tagente_datos
WHERE id_agente_modulo = ?
AND utimestamp > ?
AND utimestamp < ?', $target_module->{'id_agente_modulo'}, $week_utimestamp[$i], $temp1);
# Need to get data outside interval because no data.
if (!(defined($average_interval)) || ($average_interval == 0)) {
$last_data = get_db_value ($dbh, 'SELECT datos
FROM tagente_datos
WHERE id_agente_modulo = ?
AND utimestamp > ?
LIMIT 1', $target_module->{'id_agente_modulo'}, $week_utimestamp[$i]);
next unless defined ($last_data);
$first_data = get_db_value ($dbh, 'SELECT datos
FROM tagente_datos
WHERE id_agente_modulo = ?
AND utimestamp < ?
LIMIT 1', $target_module->{'id_agente_modulo'}, $temp1);
next unless defined ($first_data);
$sum_data++ if ($last_data != 0);
$sum_data++ if ($first_data != 0);
$week_data[$i] = ($sum_data > 0) ? (($last_data + $first_data) / $sum_data) : 0;
}
else {
$week_data[$i] = $average_interval;
}
# It's possible that one of the week_data[i] values was not valid (NULL)
# so recheck it and relay on n=0 for "no data" values set to 0 in result
# Calculate total ammount of valida data for each data sample
if ((is_numeric($week_data[$i])) && ($week_data[$i] > 0)) {
$n++;
# Average SUM
$average = $average + $week_data[$i];
}
}
# Real average value
$average = ($n > 0) ? ($average / $n) : 0;
# (PROC) Compare with current data
if ($prediction_mode == 0) {
# Calculate typical deviation
my $typical_deviation = 0;
for (my $i=0; $i< $n; $i++) {
if ((is_numeric($week_data[$i])) && ($week_data[$i] > 0)) {
$typical_deviation = $typical_deviation + (($week_data[$i] - $average)**2);
}
}
$typical_deviation = ($n > 1) ? sqrt ($typical_deviation / ($n-1)) : 0;
my $current_value = get_db_value ($dbh, 'SELECT datos
FROM tagente_estado
WHERE id_agente_modulo = ?', $target_module->{'id_agente_modulo'});
if ( ($current_value > ($average - $typical_deviation)) && ($current_value < ($average + $typical_deviation)) ){
$module_data = 1; # OK !!
}
else {
$module_data = 0; # Out of predictions
}
}
else {
# Prediction based on data
$module_data = $average;
}
my %data = ("data" => $module_data);
pandora_process_module ($pa_config, \%data, '', $agent_module, '', $timestamp, $utimestamp, $server_id, $dbh);
my $agent_os_version = get_db_value ($dbh, 'SELECT os_version FROM tagente WHERE id_agente = ?', $agent_module->{'id_agente'});
my $agent_os_version = get_db_value ($dbh, 'SELECT os_version
FROM tagente
WHERE id_agente = ?', $agent_module->{'id_agente'});
if ($agent_os_version eq ''){
$agent_os_version = $pa_config->{'servername'}.'_Prediction';
}
pandora_update_agent ($pa_config, $timestamp, $agent_module->{'id_agente'}, $agent_os_version, $pa_config->{'version'}, -1, $dbh);
}

View File

@ -1,8 +1,8 @@
package PandoraFMS::Tools;
##########################################################################
########################################################################
# Tools Package
# Pandora FMS. the Flexible Monitoring System. http://www.pandorafms.org
##########################################################################
########################################################################
# Copyright (c) 2005-2011 Artica Soluciones Tecnologicas S.L
#
# This program is free software; you can redistribute it and/or
@ -21,7 +21,7 @@ use warnings;
use Time::Local;
use POSIX qw(setsid strftime);
use POSIX;
use PandoraFMS::Sendmail;
use PandoraFMS::Sendmail;
use HTML::Entities;
use Encode;
@ -68,33 +68,33 @@ our @EXPORT = qw(
safe_output
);
##########################################################################
########################################################################
## SUB pandora_trash_ascii
# Generate random ascii strings with variable lenght
##########################################################################
########################################################################
sub pandora_trash_ascii {
my $config_depth = $_[0];
my $a;
my $output;
for ($a=0;$a<$config_depth;$a++){
$output = $output.chr(int(rand(25)+97));
}
return $output
}
##########################################################################
########################################################################
## Convert the $value encode in html entity to clear char string.
##########################################################################
########################################################################
sub safe_input($) {
my $value = shift;
$value = encode_entities ($value, "'<>&");
#//Replace the character '\' for the equivalent html entitie
$value =~ s/\\/&#92;/gi;
#// First attempt to avoid SQL Injection based on SQL comments
#// Specific for MySQL.
$value =~ s/\/\*/&#47;&#42;/gi;
@ -110,15 +110,15 @@ sub safe_input($) {
for (my $i=0;$i<33;$i++) {
my $pattern = chr($i);
my $hex = ascii_to_html($i);
$value =~ s/$pattern/$hex/gi;
$value =~ s/$pattern/$hex/gi;
}
for (my $i=128;$i<191;$i++) {
my $pattern = chr($i);
my $hex = ascii_to_html($i);
$value =~ s/$pattern/$hex/gi;
$value =~ s/$pattern/$hex/gi;
}
#//Replace characteres for tildes and others
my $trans = get_html_entities();
@ -131,17 +131,17 @@ sub safe_input($) {
return $value;
}
##########################################################################
########################################################################
## Convert the html entities to value encode to rebuild char string.
##########################################################################
########################################################################
sub safe_output($) {
my $value = shift;
$value = decode_entities ($value);
#//Replace the character '\' for the equivalent html entitie
$value =~ s/&#92;/\\/gi;
#// First attempt to avoid SQL Injection based on SQL comments
#// Specific for MySQL.
$value =~ s/&#47;&#42;/\/\*/gi;
@ -151,21 +151,21 @@ sub safe_output($) {
$value =~ s/&#40;/\(/gi;
#//Replace ( for the html entitie
$value =~ s/&#41;/\)/gi;
$value =~ s/&#41;/\)/gi;
#//Replace some characteres for html entities
for (my $i=0;$i<33;$i++) {
my $pattern = chr($i);
my $hex = ascii_to_html($i);
$value =~ s/$hex/$pattern/gi;
$value =~ s/$hex/$pattern/gi;
}
for (my $i=128;$i<191;$i++) {
my $pattern = chr($i);
my $hex = ascii_to_html($i);
$value =~ s/$hex/$pattern/gi;
$value =~ s/$hex/$pattern/gi;
}
#//Replace characteres for tildes and others
my $trans = get_html_entities();
@ -213,10 +213,10 @@ sub get_html_entities {
return \%trans;
}
##########################################################################
########################################################################
# SUB ascii_to_html (string)
# Convert an ascii string to hexadecimal
##########################################################################
########################################################################
sub ascii_to_html($) {
my $ascii = shift;
@ -225,86 +225,86 @@ sub ascii_to_html($) {
}
##########################################################################
########################################################################
# SUB pandora_get_os (string)
# Detect OS using a string, and return id_os
##########################################################################
########################################################################
sub pandora_get_os ($) {
my $command = $_[0];
if (defined($command) && $command ne ""){
if ($command =~ m/Windows/i){
if (defined($command) && $command ne "") {
if ($command =~ m/Windows/i) {
return 9;
}
elsif ($command =~ m/Cisco/i){
elsif ($command =~ m/Cisco/i) {
return 7;
}
elsif ($command =~ m/SunOS/i){
elsif ($command =~ m/SunOS/i) {
return 2;
}
elsif ($command =~ m/Solaris/i){
elsif ($command =~ m/Solaris/i) {
return 2;
}
elsif ($command =~ m/AIX/i){
elsif ($command =~ m/AIX/i) {
return 3;
}
elsif ($command =~ m/HP\-UX/i){
elsif ($command =~ m/HP\-UX/i) {
return 5;
}
elsif ($command =~ m/Apple/i){
elsif ($command =~ m/Apple/i) {
return 8;
}
elsif ($command =~ m/Linux/i){
elsif ($command =~ m/Linux/i) {
return 1;
}
elsif ($command =~ m/Enterasys/i){
elsif ($command =~ m/Enterasys/i) {
return 11;
}
elsif ($command =~ m/3com/i){
elsif ($command =~ m/3com/i) {
return 11;
}
elsif ($command =~ m/Octopods/i){
elsif ($command =~ m/Octopods/i) {
return 13;
}
elsif ($command =~ m/embedded/i){
elsif ($command =~ m/embedded/i) {
return 14;
}
elsif ($command =~ m/android/i){
elsif ($command =~ m/android/i) {
return 15;
}
elsif ($command =~ m/BSD/i){
elsif ($command =~ m/BSD/i) {
return 4;
}
else {
return 10; # Unknown / Other
}
} else {
}
else {
return 10;
}
}
##########################################################################
########################################################################
# Sub daemonize ()
# Put program in background (for daemon mode)
##########################################################################
########################################################################
sub pandora_daemonize {
my $pa_config = $_[0];
open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!";
open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!";
chdir '/tmp' or die "Can't chdir to /tmp: $!";
defined(my $pid = fork) or die "Can't fork: $!";
open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!";
open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!";
chdir '/tmp' or die "Can't chdir to /tmp: $!";
defined(my $pid = fork) or die "Can't fork: $!";
exit if $pid;
setsid or die "Can't start a new session: $!";
setsid or die "Can't start a new session: $!";
# Store PID of this process in file presented by config token
if ($pa_config->{'PID'} ne ""){
if ($pa_config->{'PID'} ne "") {
if ( -e $pa_config->{'PID'} && open (FILE, $pa_config->{'PID'})) {
$pid = <FILE> + 0;
close FILE;
# check if pandora_server is running
if (kill (0, $pid)) {
die "[FATAL] pandora_server already running, pid: $pid.";
@ -325,14 +325,14 @@ sub pandora_daemonize {
# -------------------------------------------+
##########################################################################
########################################################################
# SUB pandora_sendmail
# Send a mail, connecting directly to MTA
# param1 - config hash
# param2 - Destination email addres
# param3 - Email subject
# param4 - Email Message body
##########################################################################
########################################################################
sub pandora_sendmail {
@ -340,39 +340,39 @@ sub pandora_sendmail {
my $to_address = $_[1];
my $subject = $_[2];
my $message = $_[3];
$subject = decode_entities ($subject);
$message = decode_entities ($message);
my %mail = ( To => $to_address,
Message => $message,
Subject => encode('MIME-Header', $subject),
'X-Mailer' => "Pandora FMS",
Smtp => $pa_config->{"mta_address"},
Port => $pa_config->{"mta_port"},
From => $pa_config->{"mta_from"},
my %mail = ( To => $to_address,
Message => $message,
Subject => encode('MIME-Header', $subject),
'X-Mailer' => "Pandora FMS",
Smtp => $pa_config->{"mta_address"},
Port => $pa_config->{"mta_port"},
From => $pa_config->{"mta_from"},
);
# Check if message has non-ascii chars.
# non-ascii chars should be encoded in UTF-8.
if ($message =~ /[^[:ascii:]]/o) {
$mail{Message} = encode("UTF-8", $mail{Message});
$mail{'Content-Type'} = 'text/plain; charset="UTF-8"';
}
if ($pa_config->{"mta_user"} ne ""){
$mail{auth} = {user=>$pa_config->{"mta_user"}, password=>$pa_config->{"mta_pass"}, method=>$pa_config->{"mta_auth"}, required=>1 };
}
if (sendmail %mail) {
return;
} else {
}
else {
logger ($pa_config, "[ERROR] Sending email to $to_address with subject $subject", 1);
if (defined($Mail::Sendmail::error)){
logger ($pa_config, "ERROR Code: $Mail::Sendmail::error", 5);
}
}
}
##########################################################################
@ -394,7 +394,8 @@ sub is_numeric {
my $NUMBER = qr{ ($SIGN?) ($DIGITS) }xms;
if ( $val !~ /^${NUMBER}$/ ) {
return 0; #Non-numeric
} else {
}
else {
return 1; #Numeric
}
}
@ -429,16 +430,17 @@ sub md5check {
if ($buf =~ /$buf2/ ) {
#print "MD5 Correct";
return 1;
} else {
}
else {
#print "MD5 Incorrect";
return 0;
}
}
##########################################################################
########################################################################
# SUB logger (pa_config, message, level)
# Log to file
##########################################################################
########################################################################
sub logger ($$;$) {
my ($pa_config, $message, $level) = @_;
@ -451,15 +453,15 @@ sub logger ($$;$) {
if (-e $file && (stat($file))[7] > $pa_config->{'max_log_size'}) {
rename ($file, $file.'.old');
}
open (FILE, ">> $file") or die "[FATAL] Could not open logfile '$file'";
print FILE strftime ("%Y-%m-%d %H:%M:%S", localtime()) . " " . $pa_config->{'servername'} . $pa_config->{'servermode'} . " [V". $level ."] " . $message . "\n";
close (FILE);
}
##########################################################################
########################################################################
# limpia_cadena (string) - Purge a string for any forbidden characters (esc, etc)
##########################################################################
########################################################################
sub limpia_cadena {
my $micadena;
$micadena = $_[0];
@ -467,14 +469,15 @@ sub limpia_cadena {
$micadena =~ s/[^\-\:\;\.\,\_\s\a\*\=\(\)a-zA-Z0-9]//g;
$micadena =~ s/[\n\l\f]//g;
return $micadena;
} else {
}
else {
return "";
}
}
##########################################################################
########################################################################
# clean_blank (string) - Purge a string for any blank spaces in it
##########################################################################
########################################################################
sub clean_blank {
my $input = $_[0];
$input =~ s/\s//g;
@ -512,9 +515,9 @@ sub float_equal {
##########################################################################
sub enterprise_load ($) {
my $pa_config = shift;
# Check dependencies
# Already loaded
#return 1 if (is_loaded ('PandoraFMS::Enterprise'));
@ -553,12 +556,12 @@ sub enterprise_hook ($$) {
return $output;
}
##########################################################################
########################################################################
# Prints a message to STDOUT at the given log level.
##########################################################################
########################################################################
sub print_message ($$$) {
my ($pa_config, $message, $log_level) = @_;
print STDOUT $message . "\n" if ($pa_config->{'verbosity'} >= $log_level);
}
@ -568,32 +571,32 @@ sub print_message ($$$) {
##########################################################################
sub get_tag_value ($$$) {
my ($hash_ref, $tag, $def_value) = @_;
return $def_value unless defined ($hash_ref->{$tag}) and ref ($hash_ref->{$tag});
# Return the first found value
foreach my $value (@{$hash_ref->{$tag}}) {
# If the tag is defined but has no value a ref to an empty hash is returned by XML::Simple
return $value unless ref ($value);
}
return $def_value;
}
###############################################################################
########################################################################
# Initialize some variables needed by the MD5 algorithm.
# See http://en.wikipedia.org/wiki/MD5#Pseudocode.
###############################################################################
########################################################################
my (@R, @K);
sub md5_init () {
# R specifies the per-round shift amounts
@R = (7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21);
# Use binary integer part of the sines of integers (radians) as constants
for (my $i = 0; $i < 64; $i++) {
$K[$i] = floor(abs(sin($i + 1)) * MOD232);