2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
#!/usr/bin/perl
# **********************************************************************
2010-10-15 12:56:56 +02:00
# Pandora FMS Generic Unix/Perl Agent
2011-06-28 14:13:26 +02:00
# (c) 2009-2011 Artica Soluciones Tecnológicas
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
# with the help of many people. Please see http://pandorafms.org
# This code is licensed under GPL 2.0 license.
# **********************************************************************
2010-02-22 20:32:10 +01:00
=head1 NAME
pandora_agent - Pandora FMS Agent
=head1 VERSION
2012-12-17 17:33:15 +01:00
Version 5.0
2010-02-22 20:32:10 +01:00
=head1 USAGE
2011-06-21 13:06:47 +02:00
<< pandora_agent F<pandora home> >>
2010-02-22 20:32:10 +01:00
=cut
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
use strict;
use warnings;
use POSIX qw(strftime floor);
use Sys::Hostname;
use File::Basename;
use File::Copy;
2010-10-08 11:58:18 +02:00
use IO::Socket;
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
2012-08-01 18:35:40 +02:00
2010-09-17 15:03:24 +02:00
# Agent XML data
my $Xml;
# Semaphore used to acces $Xml
my $Sem = undef;
# Semaphore used to control the number of threads
my $ThreadSem = undef;
2014-06-03 11:36:52 +02:00
use constant AGENT_VERSION => '5.1BETA1';
2014-06-03 01:45:28 +02:00
use constant AGENT_BUILD => '140603';
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
2010-05-18 20:07:32 +02:00
# Commands to retrieve total memory information in kB
use constant TOTALMEMORY_CMDS => {
2010-11-15 11:32:23 +01:00
linux => 'cat /proc/meminfo | grep MemTotal: | awk \'{ print $2 }\'',
2011-07-29 11:15:37 +02:00
solaris => '/usr/sbin/prtconf | awk \'/Memory/ { print $3 * 1024 }\'',
2010-10-06 03:49:48 +02:00
hpux => 'swapinfo -t | grep memory | awk \'{print $2}\'',
2011-07-29 11:15:37 +02:00
freebsd => '/sbin/sysctl hw.physmem | awk \'{print $2 / 1024}\'',
2010-05-18 20:07:32 +02:00
};
# Commands to retrieve free memory information in kB
use constant FREEMEMORY_CMDS => {
2010-11-15 11:32:23 +01:00
linux => 'cat /proc/meminfo | grep MemFree: | awk \'{ print $2 }\'',
2010-06-08 18:52:51 +02:00
solaris => 'vmstat 1 2 | tail -1 | awk \'{ print $5 }\'',
2010-10-06 03:49:48 +02:00
hpux => 'swapinfo -t | grep memory | awk \'{print $4}\'',
2011-07-29 11:15:37 +02:00
freebsd => '/sbin/sysctl -n vm.stats.vm.v_page_size vm.stats.vm.v_free_count | tr "\n" " " | awk \'{ print $1 * $2 / 1024 }\'',
2010-05-18 20:07:32 +02:00
};
# Commands to retrieve cpu information
use constant CPUUSAGE_CMDS => {
2010-06-08 18:52:51 +02:00
linux => 'vmstat 1 2 | tail -1 | awk \'{ print $13 }\'',
solaris => 'vmstat 1 2 | tail -1 | awk \'{ print $21 }\'',
2010-10-06 03:49:48 +02:00
hpux => 'vmstat 1 2 | tail -1 | awk \'{ print $16 }\'',
freebsd => 'vmstat -n 0 1 2 | tail -1 | awk \'{ print $15 }\''
2010-05-18 20:07:32 +02:00
};
# Commands to retrieve process information
use constant PROC_CMDS => {
2010-06-08 18:52:51 +02:00
# cpu usage, memory usage, command name
linux => 'ps aux | awk \'NR > 1 {ps = ""; for (i = 11; i <= NF; ++i) {ps = (ps " " $i) }; print $3, $6, ps}\'',
solaris => 'prstat 1 1 | awk \'NR > 1 {split ($10, ps, "/"); cpu = substr ($9, 1, length ($9) - 1); mem = substr ($3, 1, length ($3) - 1); print cpu, mem, ps[1]}\'',
hpux => 'ps -elf | awk \'NR > 1 {ps = ""; for (i = 15; i <= NF; ++i) {ps = (ps " " $i) }; print 0, $10, ps}\'',
2010-10-06 03:49:48 +02:00
aix => 'ps aux | awk \'NR > 1 {print $3, $6, $11}\'',
2011-07-29 11:15:37 +02:00
freebsd => 'ps axww -o %cpu= -o %mem= -o command= | sed -e "s/^ *//"',
2010-05-18 20:07:32 +02:00
};
# Commands to retrieve partition information in kB
use constant PART_CMDS => {
2010-06-08 18:52:51 +02:00
# total, available, mount point
2010-06-30 17:51:45 +02:00
linux => 'df -P | awk \'NR > 1 {print $2, $4, $6}\'',
2010-06-08 18:52:51 +02:00
solaris => 'df -k | awk \'NR > 1 {print $2, $4, $6}\'',
hpux => 'df -P | awk \'NR > 1 {print $2, $4, $6}\'',
2010-10-06 03:49:48 +02:00
aix => 'df -kP | awk \'NR > 1 {print $2, $4, $6}\'',
freebsd => 'df -k | awk \'NR > 1 {print $2, $4, $6}\''
2010-05-18 20:07:32 +02:00
};
2012-02-28 16:48:26 +01:00
# Commands to call df with POSIX output format
use constant DF_CMDS => {
# total, available, mount point
linux => 'df -P',
solaris => 'df -k',
hpux => 'df -P',
aix => 'df -kP',
freebsd => 'df -k'
};
2010-05-18 20:07:32 +02:00
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
# OS and OS version
my $OS = $^O;
2010-11-04 20:34:04 +01:00
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
my $OS_VERSION;
# Used to calculate the MD5 checksum of a string
use constant MOD232 => 2**32;
# Directory where pandora_agent.conf is located
my $ConfDir = '';
# Pandora FMS agent configuration file
my $ConfFile = 'pandora_agent.conf';
2011-11-15 14:33:16 +01:00
# Broker agent configuration files
2011-12-19 16:40:22 +01:00
my @BrokerPid;
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
# Configuration tokens
2013-03-11 13:10:56 +01:00
my %DefaultConf = (
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
'server_ip' => 'localhost',
'server_path' => '/var/spool/pandora/data_in',
2011-03-17 14:49:15 +01:00
'logfile' =>'/var/log/pandora/pandora_agent.log',
2009-11-17 19:16:10 +01:00
'temporal' => '/var/spool/pandora',
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
'interval' => 300,
'debug' => 0,
'agent_name' => hostname (),
'description' => '',
'group' => '',
2012-06-21 15:12:57 +02:00
'encoding' => 'UTF-8',
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
'server_port' => 41121,
'transfer_mode' => 'tentacle',
'server_pwd' => '',
'server_ssl' => 'no',
'server_opts' => '',
'delayed_startup' => 0,
2010-07-30 14:25:23 +02:00
'pandora_nice' => 10,
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
'cron_mode' => 0,
'remote_config' => 0,
'secondary_mode' => 'never',
'secondary_server_ip' => 'localhost',
'secondary_server_path' => '/var/spool/pandora/data_in',
'secondary_server_port' => 41121,
'secondary_transfer_mode' => 'tentacle',
2012-04-24 11:31:27 +02:00
'secondary_server_pwd' => '',
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
'secondary_server_ssl' => 'no',
'secondary_server_opts' => '',
2010-01-12 18:29:03 +01:00
'autotime' => 0,
2012-02-28 16:48:26 +01:00
'temporal_min_size' => 1,
2010-06-18 14:36:19 +02:00
'timezone_offset' => 0,
2010-12-27 11:18:20 +01:00
'pandora_exec' => 'pandora_agent_exec',
2010-10-08 11:58:18 +02:00
'agent_threads' => 1,
2010-11-15 11:32:23 +01:00
'udp_server_port' => 41122,
'udp_server_auth_address' => '0.0.0.0',
2011-04-11 18:35:45 +02:00
'udp_server' => 0,
'proxy_mode' => 0,
2011-04-12 17:09:25 +02:00
'proxy_max_connection' => 10,
2011-06-09 10:48:11 +02:00
'proxy_timeout' => 1,
2012-01-03 18:18:45 +01:00
'intensive_interval' => 0,
'timestamp' => 0,
2012-02-28 16:48:26 +01:00
'xml_buffer' => 0,
2012-11-15 16:53:45 +01:00
'custom_id' => '',
'url_address' => '',
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
);
2013-03-11 13:10:56 +01:00
my %Conf = %DefaultConf;
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
# Modules
my @Modules;
# Logfile file handle
my $LogFileFH;
# Agent name MD5;
my $AgentMD5;
# Remote configuration file name
my $RemoteConfFile;
# Remote md5 file name
my $RemoteMD5File;
2010-05-18 20:07:32 +02:00
# Process data
my %Procs = (
'__utimestamp__' => 0
);
# Partition data
my %Parts = (
'__utimestamp__' => 0
);
2010-07-19 19:27:59 +02:00
# Collections
my %Collections;
2012-11-15 16:53:45 +01:00
# Custom fields
my %Customfields;
2010-11-04 20:34:04 +01:00
# $DevNull
my $DevNull = '/dev/null';
# Shell command separator
my $CmdSep = ';';
2011-04-12 17:09:25 +02:00
# PID of tentacle proxy, used in proxy mode
my $tentacle_pid = undef;
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
################################################################################
# Print usage information and exit.
################################################################################
sub print_usage () {
print "\nUsage: $0 <Pandora home>\n\n";
print "\tPandora home is the directory where pandora_agent.conf is located,\n";
print "\tby default /etc/pandora.\n\n";
exit 1;
}
################################################################################
# Print an error message and exit.
################################################################################
sub error ($) {
my $msg = shift;
print ("[ERROR] $msg\n\n");
2012-04-18 16:13:41 +02:00
`logger -i -t pandora_agent_daemon [ERROR] $msg 2>/dev/null`;
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
exit 1;
}
2012-05-30 18:51:23 +02:00
################################################################################
# Check a regular expression. Returns 1 if its valid, 0 otherwise.
################################################################################
sub valid_regexp ($) {
my $regexp = shift;
eval {
'' =~ /$regexp/;
};
# Something went wrong
return 0 if ($@);
return 1;
}
2010-08-11 18:14:49 +02:00
################################################################################
# Recursively delete files and directories.
################################################################################
sub rmrf {
my $path = shift;
local *DIR;
if (-d $path) {
opendir (DIR, $path) || return;
while (defined (my $file_name = readdir(DIR))) {
next if ($file_name eq '.' || $file_name eq '..');
rmrf ("$path/$file_name");
}
closedir (DIR);
rmdir ($path);
} else {
unlink ($path);
}
}
################################################################################
# Recursively set file permissions.
################################################################################
sub chmodr {
my ($perm, $path) = @_;
local *DIR;
if (-d $path) {
opendir (DIR, $path) || return;
while (defined (my $file_name = readdir(DIR))) {
next if ($file_name eq '.' || $file_name eq '..');
chmodr ($perm, "$path/$file_name");
}
closedir (DIR);
}
chmod ($perm, $path);
}
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
################################################################################
# Open the agent logfile and start logging.
################################################################################
2011-11-15 14:33:16 +01:00
sub start_log (;$) {
my $quiet = shift;
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
# Get the logfile
my $log_file_name = read_config ('logfile');
$log_file_name = '/var/log/pandora/pandora_agent.log' unless defined ($log_file_name);
# Open it
open ($LogFileFH, "> $log_file_name") or error ("Could not open log file '$log_file_name' for writing: $!.");
2011-11-15 14:33:16 +01:00
if (! defined ($quiet)) {
print "Logging to $log_file_name\n";
}
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
}
################################################################################
# Close the agent logfile and stop logging.
################################################################################
sub stop_log () {
close ($LogFileFH);
}
################################################################################
# Log a message to the agent logfile.
################################################################################
sub log_message ($$;$) {
my ($source, $msg, $dest) = @_;
if (defined ($dest)) {
print $dest strftime ('%Y/%m/%d %H:%M:%S', localtime ()) . " - [$source] - $msg\n";
} else {
2012-04-18 16:13:41 +02:00
#Trying to write into log file to test its writable
syswrite ($LogFileFH, "");
#If no error, the file is writable
if (!$!) {
print $LogFileFH strftime ('%Y/%m/%d %H:%M:%S', localtime ()) . " - [$source] - $msg\n";
} else {
#If error then log into syslog!
`logger -i -t pandora_agent_daemon [ERROR] $msg 2>/dev/null`;
}
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
}
}
################################################################################
2011-06-01 12:34:05 +02:00
# Parse configuration file (modules, plugins and collections)
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
################################################################################
2011-06-01 12:34:05 +02:00
sub parse_conf_modules($) {
my ($param) = @_;
2013-05-23 19:20:21 +02:00
# Mark the start of a module definition
my $module_begin = 0;
# Skeleton for modules
my $module = {};
2009-12-03 19:35:08 +01:00
2011-06-01 12:34:05 +02:00
foreach my $line (@{$param}) {
2011-06-09 10:48:11 +02:00
next if ($line =~ m/^\s*#/) or ($line =~ m/^\s*$/);
2011-06-01 12:34:05 +02:00
# Module definition
if ($line =~ /^\s*module_begin\s*$/) {
2013-05-23 19:20:21 +02:00
$module_begin = 1;
init_module ($module);
2011-06-01 12:34:05 +02:00
} elsif ($line =~ /^\s*module_name\s+(.+)$/) {
$module->{'name'} = $1;
} elsif ($line =~ /^\s*module_description\s+(.+)$/) {
$module->{'description'} = $1;
} elsif ($line =~ /^\s*module_type\s+(\S+)\s*$/) {
$module->{'type'} = $1;
2011-06-21 13:06:47 +02:00
}elsif ($line =~ /^\s*module_precondition\s+(.*)$/) {
my $action = $1;
2012-01-03 18:18:45 +01:00
2011-06-21 13:06:47 +02:00
# Numeric comparison
2011-09-02 08:05:47 +02:00
if ($action =~ /^\s*([<>!=]+)\s+(\d+(?:\.\d*)?)\s+(.*)$/) {
2011-06-21 13:06:47 +02:00
push (@{$module->{'precondition'}}, {'operator' => $1, 'value_1' => $2, 'command' => $3});
# Interval
2011-09-02 08:05:47 +02:00
} elsif ($action =~ /^\s*[(]\s*(\d+(?:\.\d*)?)\s*,\s*(\d+(?:\.\d*)?)\s*[)]\s+(.*)$/) {
2011-06-21 13:06:47 +02:00
push (@{$module->{'precondition'}}, {'operator' => '()', 'value_1' => $1, 'value_2' => $2, 'command' => $3});
# Regular expression
} elsif ($action =~ /^\s*=~\s+(\S*)\s+(.*)$/) {
2012-05-30 18:51:23 +02:00
if (valid_regexp ($1)) {
push (@{$module->{'precondition'}}, {'operator' => '=~', 'value_1' => $1, 'command' => $2});
} else {
log_message ('setup', "Invalid regular expression in module precondition: $line");
}
2011-06-21 13:06:47 +02:00
}
2011-06-01 12:34:05 +02:00
} elsif ($line =~ /^\s*module_exec\s+(.+)$/) {
$module->{'func'} = \&module_exec;
$module->{'params'} = $1;
} elsif ($line =~ /^\s*module_cpuusage\s+(.*)$/) {
$module->{'func'} = \&module_cpuusage;
$module->{'params'} = $1;
} elsif ($line =~ /^\s*module_freememory\s+(.*)$/) {
$module->{'func'} = \&module_freememory;
$module->{'params'} = $1;
} elsif ($line =~ /^\s*module_freepercentmemory\s+(.*)$/) {
$module->{'func'} = \&module_freepercentmemory;
$module->{'params'} = $1;
} elsif ($line =~ /^\s*(module_proc|module_service)\s+(.+)$/) {
$module->{'func'} = \&module_proc;
$module->{'params'} = $2;
} elsif ($line =~ /^\s*module_cpuproc\s+(.+)$/) {
$module->{'func'} = \&module_cpuproc;
$module->{'params'} = $1;
} elsif ($line =~ /^\s*module_memproc\s+(.+)$/) {
$module->{'func'} = \&module_memproc;
$module->{'params'} = $1;
} elsif ($line =~ /^\s*module_freedisk\s+(.*)$/) {
$module->{'func'} = \&module_freedisk;
$module->{'params'} = $1;
} elsif ($line =~ /^\s*module_freepercentdisk\s+(.*)$/) {
$module->{'func'} = \&module_freepercentdisk;
$module->{'params'} = $1;
} elsif ($line =~ /^\s*module_occupiedpercentdisk\s+(.*)$/) {
$module->{'func'} = \&module_occupiedpercentdisk;
$module->{'params'} = $1;
} elsif ($line =~ /^\s*module_max\s+(.*)\s*$/) {
$module->{'max'} = $1;
} elsif ($line =~ /^\s*module_min\s+(.*)\s*$/) {
$module->{'min'} = $1;
} elsif ($line =~ /^\s*module_postprocess\s+(.*)\s*$/) {
$module->{'post_process'} = $1;
} elsif ($line =~ /^\s*module_interval\s+(\d+)\s*$/) {
$module->{'interval'} = $1;
} elsif ($line =~ /^\s*module_timeout\s+(\d+)\s*$/) {
$module->{'timeout'} = $1;
} elsif ($line =~ /^\s*module_save\s+(\w+)$/) {
$module->{'save'} = $1;
} elsif ($line =~ /^\s*module_condition\s+(.*)$/) {
my $action = $1;
# Numeric comparison
2011-09-02 08:05:47 +02:00
if ($action =~ /^\s*([<>!=]+)\s+(\d+(?:\.\d*)?)\s+(.*)$/) {
2011-06-01 12:34:05 +02:00
push (@{$module->{'conditions'}}, {'operator' => $1, 'value_1' => $2, 'command' => $3});
# Interval
2011-09-02 08:05:47 +02:00
} elsif ($action =~ /^\s*[(]\s*(\d+(?:\.\d*)?)\s*,\s*(\d+(?:\.\d*)?)\s*[)]\s+(.*)$/) {
2011-06-01 12:34:05 +02:00
push (@{$module->{'conditions'}}, {'operator' => '()', 'value_1' => $1, 'value_2' => $2, 'command' => $3});
# Regular expression
} elsif ($action =~ /^\s*=~\s+(\S*)\s+(.*)$/) {
2012-05-30 18:51:23 +02:00
if (valid_regexp ($1)) {
push (@{$module->{'conditions'}}, {'operator' => '=~', 'value_1' => $1, 'command' => $2});
} else {
log_message ('setup', "Invalid regular expression in module condition: $line");
}
2011-06-01 12:34:05 +02:00
}
2012-01-03 18:18:45 +01:00
} elsif ($line =~ /^\s*module_intensive_condition\s+(.*)$/) {
my $action = $1;
$module->{'is_intensive'} = 1;
# Numeric comparison
if ($action =~ /^\s*([<>!=]+)\s+(\d+(?:\.\d*)?)\s*$/) {
push (@{$module->{'intensive_conditions'}}, {'operator' => $1, 'value_1' => $2});
# Interval
} elsif ($action =~ /^\s*[(]\s*(\d+(?:\.\d*)?)\s*,\s*(\d+(?:\.\d*)?)\s*[)]\s*$/) {
push (@{$module->{'intensive_conditions'}}, {'operator' => '()', 'value_1' => $1, 'value_2' => $2});
# Regular expression
} elsif ($action =~ /^\s*=~\s+(\S*)\s*$/) {
2012-05-30 18:51:23 +02:00
if (valid_regexp ($1)) {
push (@{$module->{'intensive_conditions'}}, {'operator' => '=~', 'value_1' => $1});
} else {
log_message ('setup', "Invalid regular expression in intensive condition: $line");
}
2012-01-03 18:18:45 +01:00
}
2011-06-01 12:34:05 +02:00
} elsif ($line =~ /^\s*module_crontab\s+(((\*|(\d+(-\d+){0,1}))\s*){5}).*$/) {
$module->{'cron'} = $1;
} elsif ($line =~ /^\s*module_cron_interval\s+(\d+).*$/) {
$module->{'cron_interval'} = $1;
} elsif ($line =~ /^\s*module_end\s*$/) {
2013-05-23 19:20:21 +02:00
$module_begin = 0;
# Check for invalid modules
2013-11-12 13:28:28 +01:00
next unless (($module->{'name'} ne '' && $module->{'func'} != 0) || $module->{'func'} == \&module_plugin);
2012-01-03 18:18:45 +01:00
# Set the intensive interval
if ($module->{'is_intensive'} == 1) {
$module->{'intensive_interval'} = $module->{'interval'};
} else {
$module->{'intensive_interval'} = $module->{'interval'} * ($Conf{'interval'} / $Conf{'intensive_interval'});
}
# Make the module run the first time
$module->{'counter'} = $module->{'intensive_interval'};
2013-04-12 15:29:23 +02:00
2013-05-23 19:20:21 +02:00
# Replace macros
replace_macros ($module);
push (@Modules, {%{$module}});
# Plugin
} elsif ($line =~ /^\s*module_plugin\s+(.+)$/) {
# Single line plugin definition
if ($module_begin == 0) {
# Set default values for the module configuration
init_module ($module);
# Configure the plugin
2013-11-12 13:28:28 +01:00
$module->{'func'} = \&module_plugin;
2013-05-23 19:20:21 +02:00
$module->{'params'} = $1;
# Set the intensive interval
if ($module->{'is_intensive'} == 1) {
$module->{'intensive_interval'} = $module->{'interval'};
} else {
$module->{'intensive_interval'} = $module->{'interval'} * ($Conf{'interval'} / $Conf{'intensive_interval'});
2013-04-12 15:29:23 +02:00
}
2013-05-23 19:20:21 +02:00
# Make the module run the first time
$module->{'counter'} = $module->{'intensive_interval'};
2013-04-12 15:29:23 +02:00
2013-05-23 19:20:21 +02:00
push (@Modules, {%{$module}});
} else {
2013-11-12 13:28:28 +01:00
$module->{'func'} = \&module_plugin;
2013-05-23 19:20:21 +02:00
$module->{'params'} = $1;
2013-04-12 15:29:23 +02:00
}
2011-06-01 12:34:05 +02:00
# Module proc command redefinition
} elsif ($line =~ /^\s*module_proc_cmd\s+(.+)$/) {
PROC_CMDS->{$OS} = $1;
# Module freedisk command redefinition
} elsif ($line =~ /^\s*module_freedisk_cmd\s+(.+)$/) {
PART_CMDS->{$OS} = $1;
# Collection
} elsif ($line =~ /^\s*file_collection\s+(.+)$/) {
my $collection = $1;
2011-08-10 17:22:46 +02:00
# Prevent path traversal attacks
if ($collection !~ m/(\.\.)|\//) {
$Collections{$collection} = 0;
}
2011-07-14 18:03:06 +02:00
# Min critical
} elsif ($line =~ /^\s*module_min_critical\s+(.*)\s*$/) {
$module->{'min_critical'} = $1;
# Max critical
} elsif ($line =~ /^\s*module_max_critical\s+(.*)\s*$/) {
$module->{'max_critical'} = $1;
# Min warning
} elsif ($line =~ /^\s*module_min_warning\s+(.*)\s*$/) {
$module->{'min_warning'} = $1;
# Max warning
} elsif ($line =~ /^\s*module_max_warning\s+(.*)\s*$/) {
$module->{'max_warning'} = $1;
# Disabled
} elsif ($line =~ /^\s*module_disabled\s+(.*)\s*$/) {
$module->{'disabled'} = $1;
# Min ff event
} elsif ($line =~ /^\s*module_min_ff_event\s+(.*)\s*$/) {
$module->{'min_ff_event'} = $1;
2012-05-10 18:27:15 +02:00
# Unit
2012-11-13 13:24:36 +01:00
} elsif ($line =~ /^\s*module_unit\s+(.*)\s*$/) {
2012-05-10 18:27:15 +02:00
$module->{'unit'} = $1;
2012-11-13 13:24:36 +01:00
# Module_group
} elsif ($line =~ /^\s*module_group\s+(\S+)\s*$/) {
$module->{'module_group'} = $1;
# Custom id
} elsif ($line =~ /^\s*module_custom_id\s+(.*)\s*$/) {
$module->{'custom_id'} = $1;
# Str warning
} elsif ($line =~ /^\s*module_str_warning\s+(.*)\s*$/) {
$module->{'str_warning'} = $1;
# Str critical
} elsif ($line =~ /^\s*module_str_critical\s+(.*)\s*$/) {
$module->{'str_critical'} = $1;
# Critical instructions
} elsif ($line =~ /^\s*module_critical_instructions\s+(.*)\s*$/) {
$module->{'critical_instructions'} = $1;
# Warning instructions
} elsif ($line =~ /^\s*module_warning_instructions\s+(.*)\s*$/) {
$module->{'warning_instructions'} = $1;
# Unknown instructions
} elsif ($line =~ /^\s*module_unknown_instructions\s+(.*)\s*$/) {
$module->{'unknown_instructions'} = $1;
# Tags
} elsif ($line =~ /^\s*module_tags\s+(.*)\s*$/) {
$module->{'tags'} = $1;
# Critical inverse
} elsif ($line =~ /^\s*module_critical_inverse\s+(\S+)\s*$/) {
$module->{'critical_inverse'} = $1;
# Warning inverse
} elsif ($line =~ /^\s*module_warning_inverse\s+(\S+)\s*$/) {
$module->{'warning_inverse'} = $1;
# Quiet
} elsif ($line =~ /^\s*module_quiet\s+(\S+)\s*$/) {
$module->{'quiet'} = $1;
# FF interval
} elsif ($line =~ /^\s*module_ff_interval\s+(\S+)\s*$/) {
$module->{'module_ff_interval'} = $1;
2012-08-01 18:35:40 +02:00
# Macros
2012-11-13 13:24:36 +01:00
} elsif ($line =~ /^\s*module_macro(\S+)\s+(.*)\s*$/) {
2012-08-01 18:35:40 +02:00
$module->{'macros'}{$1} = $2;
2011-06-01 12:34:05 +02:00
}
}
2011-06-09 10:48:11 +02:00
return;
2011-06-01 12:34:05 +02:00
}
2011-06-27 17:18:34 +02:00
################################################################################
2011-11-15 14:33:16 +01:00
# Create configuration file for broker agents.
2011-06-27 17:18:34 +02:00
################################################################################
2011-11-15 14:33:16 +01:00
sub write_broker_conf($){
my ($broker_agent) = @_;
2011-06-27 17:18:34 +02:00
my $content = '';
open (CONF_FILE, "$ConfDir/$ConfFile") or error ("Could not open file '$ConfDir/$ConfFile': $!.");
2011-11-15 14:33:16 +01:00
open (BROKER_FILE, ">$ConfDir/${broker_agent}.conf") or error ("Could not write configuration file: $!");
2011-06-27 17:18:34 +02:00
2011-07-08 13:46:38 +02:00
while (my $line = <CONF_FILE>){
2011-11-15 14:33:16 +01:00
# Skip broker definitions
if ($line =~ m/^\s*broker_agent/) {
2011-07-08 13:46:38 +02:00
next;
}
2011-11-15 14:33:16 +01:00
# Change the agent name
if ($line =~ m/^\s*#*\s*agent_name\s+/) {
$line = "agent_name $broker_agent\n";
}
# Change the logfile
elsif ($line =~ m/^\s*logfile\s+(.*)/) {
$line = 'logfile ' . dirname ($1) . "/$broker_agent.log\n";
2011-07-08 13:46:38 +02:00
}
2011-11-15 14:33:16 +01:00
2011-07-08 13:46:38 +02:00
print BROKER_FILE $line;
}
2011-06-27 17:18:34 +02:00
close (BROKER_FILE);
close (CONF_FILE);
}
2011-06-01 12:34:05 +02:00
################################################################################
2011-06-09 10:48:11 +02:00
# Read configuration file. Exit on error.
2011-06-01 12:34:05 +02:00
################################################################################
2011-06-09 10:48:11 +02:00
sub read_config (;$) {
my $token = shift;
2011-11-15 14:33:16 +01:00
my @found_tokens;
2011-06-09 10:48:11 +02:00
my $module;
2011-06-27 17:18:34 +02:00
2011-06-09 10:48:11 +02:00
error ("File '$ConfDir/$ConfFile' not found.") unless (-e "$ConfDir/$ConfFile");
open (CONF_FILE, "$ConfDir/$ConfFile") or error ("Could not open file '$ConfDir/$ConfFile': $!.");
my @file = <CONF_FILE>;
2011-06-27 17:18:34 +02:00
close(CONF_FILE);
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
2011-06-27 17:18:34 +02:00
foreach my $line (@file){
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
# Skip comments and empty lines
next if ($line =~ m/^\s*#/) or ($line =~ m/^\s*$/);
2012-11-15 16:53:45 +01:00
2012-08-28 06:42:28 +02:00
# Replace CRLF with LF
$line =~ s/\r\n/\n/g;
2011-11-15 14:33:16 +01:00
2012-11-15 16:53:45 +01:00
# Store the custom fields
if (($line =~ m/^(custom_field\d+_name)\s+(.*)/) or ($line =~ m/^(custom_field\d+_value)\s+(.*)/)) {
$Customfields{$1} = $2;
next;
}
2011-11-15 14:33:16 +01:00
# Token search
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
if (defined ($token)) {
2011-11-15 14:33:16 +01:00
if ($line =~ /^\s*(\S+)\s+(.*)$/ && $1 eq $token) {
# Multiple value token
if (wantarray ()) {
push (@found_tokens, $2);
}
# Single value token
else {
return $2;
}
}
2011-07-14 12:31:40 +02:00
next;
}
2011-11-15 14:33:16 +01:00
next if ($line =~ /^module\s*\w*/);
#Configuration token
if ($line =~ /^\s*(\S+)\s+(.*)$/) {
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
log_message ('setup', "$1 is $2");
$Conf{$1} = $2;
2010-05-18 20:07:32 +02:00
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
# Remove trailing spaces
$Conf{$1} =~ s/\s*$//;
2011-11-15 14:33:16 +01:00
}
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
}
2011-06-27 17:18:34 +02:00
2011-11-15 14:33:16 +01:00
# Token search
2010-10-04 19:22:28 +02:00
if (defined ($token)) {
2011-11-15 14:33:16 +01:00
# Multiple value token
if (wantarray ()) {
return @found_tokens;
}
# Single value token not found.
2010-10-04 19:22:28 +02:00
return undef;
2011-06-09 10:48:11 +02:00
}
2012-02-23 14:01:32 +01:00
# Set the intensive interval
if ($Conf{'intensive_interval'} == 0) {
$Conf{'intensive_interval'} = $Conf{'interval'};
}
2011-06-09 10:48:11 +02:00
2013-09-19 14:07:31 +02:00
# Search for includes after all other variables have been set
foreach my $line (@file) {
# Skip comments and empty lines
next if ($line =~ m/^\s*#/) or ($line =~ m/^\s*$/);
# Replace CRLF with LF
$line =~ s/\r\n/\n/g;
# Additional configuration file
if ($line =~ /^include\s+(.*)\s*/) {
$Conf{'include'} = $Conf{'include'} ? "$Conf{'include'} $1" : $1;
foreach my $file_name (glob("$1")) {
open (FILE, "$file_name") or next;
log_message ('setup', "reading $file_name");
my @file_conf = <FILE>;
parse_conf_modules(\@file_conf);
close (FILE);
}
next;
}
}
2011-11-15 14:33:16 +01:00
# Module, plugin and collection definitions
parse_conf_modules(\@file);
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
# Update the agent MD5 since agent_name may have changed
2010-10-04 19:22:28 +02:00
$AgentMD5 = md5 ($Conf{'agent_name'});
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
$RemoteConfFile = "$AgentMD5.conf";
$RemoteMD5File = "$AgentMD5.md5";
2010-09-17 15:03:24 +02:00
# Set the maximun number of threads
$ThreadSem = Thread::Semaphore->new ($Conf{'agent_threads'}) if defined ($Sem);
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
2010-10-08 16:04:23 +02:00
# Set tentacle client options
if ($Conf{'transfer_mode'} eq 'tentacle') {
$Conf{'server_opts'} = '-x \'' . $Conf{'server_pwd'} . '\' ' . $Conf{'server_opts'} if ($Conf{'server_pwd'} ne '');
$Conf{'server_opts'} = '-c ' . $Conf{'server_opts'} if ($Conf{'server_ssl'} eq 'yes');
}
2011-03-17 14:49:15 +01:00
# Set tentacle client options for secondary server
if ($Conf{'secondary_transfer_mode'} eq 'tentacle') {
$Conf{'secondary_server_opts'} = '-x \'' . $Conf{'secondary_server_pwd'} . '\' ' . $Conf{'secondary_server_opts'} if ($Conf{'secondary_server_pwd'} ne '');
$Conf{'secondary_server_opts'} = '-c ' . $Conf{'secondary_server_opts'} if ($Conf{'secondary_server_ssl'} eq 'yes');
}
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
}
2011-06-27 17:18:34 +02:00
#################################################################################
## Remove any trailing / from directory names.
#################################################################################
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
sub fix_directory ($) {
my $dir = shift;
my $char = chop ($dir);
return $dir if ($char eq '/');
return $dir . $char;
}
2011-06-27 17:18:34 +02:00
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
################################################################################
# Sends a file to the server.
################################################################################
#sub send_file ($;$) {
sub send_file {
my ($file, $secondary) = @_;
my $output;
if ($Conf{'transfer_mode'} eq 'tentacle') {
2013-06-13 17:10:53 +02:00
$output = `tentacle_client -v -a $Conf{'server_ip'} -p $Conf{'server_port'} $Conf{'server_opts'} "$file" 2>&1 >$DevNull`;
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
} elsif ($Conf{'transfer_mode'} eq 'ssh') {
2013-06-13 17:10:53 +02:00
$output = `scp -P $Conf{'server_port'} "$file" pandora@"$Conf{'server_ip'}:$Conf{'server_path'}" 2>&1 >$DevNull`;
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
} elsif ($Conf{'transfer_mode'} eq 'ftp') {
2010-11-15 11:32:23 +01:00
my $base = basename ($file);
my $dir = dirname ($file);
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
2010-11-04 20:34:04 +01:00
$output = `ftp -n $Conf{'server_ip'} $Conf{'server_port'} 2>&1 >$DevNull <<FEOF1
2010-11-15 11:32:23 +01:00
quote USER pandora
quote PASS $Conf{'server_pwd'}
lcd "$dir"
cd "$Conf{'server_path'}"
put "$base"
quit
FEOF1`
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
} elsif ($Conf{'transfer_mode'} eq 'local') {
2013-06-13 17:10:53 +02:00
$output = `cp "$file" "$Conf{'server_path'}/" 2>&1 >$DevNull`;
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
}
# Get the errorlevel
my $rc = $? >> 8;
if ($rc != 0) {
log_message ('error', "Error sending file '$file': $output");
}
return $rc unless (defined ($secondary));
# Send the file to the secondary server
return $rc unless ($Conf{'secondary_mode'} eq 'always' || ($Conf{'secondary_mode'} eq 'on_error' && $rc != 0));
swap_servers ();
$rc = send_file ($file);
swap_servers ();
return $rc;
}
2012-02-28 16:48:26 +01:00
################################################################################
# Send buffered XML files.
################################################################################
sub send_buffered_xml_files () {
# Read XML files from the temporal directory
opendir(TEMPORAL, $Conf{'temporal'}) or return;
while (my $xml_file = readdir(TEMPORAL)) {
2012-04-19 14:19:30 +02:00
# Skip non data files and symlinks
next if ($xml_file !~ m/\.data$/ || -l "$Conf{'temporal'}/$xml_file");
2012-02-28 16:48:26 +01:00
2013-03-11 06:41:51 +01:00
my $rc = send_file ("$Conf{'temporal'}/$xml_file", 1);
unlink ("$Conf{'temporal'}/$xml_file") if ($rc == 0);
2012-02-28 16:48:26 +01:00
}
}
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
################################################################################
# Swap primary and secondary servers.
################################################################################
sub swap_servers () {
($Conf{'server_ip'}, $Conf{'secondary_server_ip'}) = ($Conf{'secondary_server_ip'}, $Conf{'server_ip'});
($Conf{'server_path'}, $Conf{'secondary_server_path'}) = ($Conf{'secondary_server_path'}, $Conf{'server_path'});
($Conf{'server_port'}, $Conf{'secondary_server_port'}) = ($Conf{'secondary_server_port'}, $Conf{'server_port'});
2013-02-12 03:38:48 +01:00
($Conf{'transfer_mode'}, $Conf{'secondary_transfer_mode'}) = ($Conf{'secondary_transfer_mode'}, $Conf{'transfer_mode'});
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
($Conf{'server_pwd'}, $Conf{'secondary_server_pwd'}) = ($Conf{'secondary_server_pwd'}, $Conf{'server_pwd'});
($Conf{'server_ssl'}, $Conf{'secondary_server_ssl'}) = ($Conf{'secondary_server_ssl'}, $Conf{'server_ssl'});
($Conf{'server_opts'}, $Conf{'secondary_server_opts'}) = ($Conf{'secondary_server_opts'}, $Conf{'server_opts'});
}
################################################################################
# Receive a file from the server.
################################################################################
sub recv_file ($) {
my $file = shift;
my $output;
if ($Conf{'transfer_mode'} eq 'tentacle') {
2010-11-04 20:34:04 +01:00
$output = `cd "$Conf{'temporal'}"$CmdSep tentacle_client -v -g -a $Conf{'server_ip'} -p $Conf{'server_port'} $Conf{'server_opts'} $file 2>&1 >$DevNull`
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
} elsif ($Conf{'transfer_mode'} eq 'ssh') {
2010-11-04 20:34:04 +01:00
$output = `scp -P $Conf{'server_port'} pandora@"$Conf{'server_ip'}:$Conf{'server_path'}/$file" $Conf{'temporal'} 2>&1 >$DevNull`;
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
} elsif ($Conf{'transfer_mode'} eq 'ftp') {
2010-11-15 11:32:23 +01:00
my $base = basename ($file);
my $dir = dirname ($file);
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
2010-11-04 20:34:04 +01:00
$output = `ftp -n $Conf{'server_ip'} $Conf{'server_port'} 2>&1 >$DevNull <<FEOF1
2010-11-15 11:32:23 +01:00
quote USER pandora
quote PASS $Conf{'server_pwd'}
lcd "$Conf{'temporal'}"
cd "$Conf{'server_path'}"
get "$file"
quit
FEOF1`
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
} elsif ($Conf{'transfer_mode'} eq 'local') {
2010-11-04 20:34:04 +01:00
$output = `cp $Conf{'server_path'}/$file $Conf{'temporal'} 2>&1 >$DevNull`;
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
}
# Get the errorlevel
my $rc = $? >> 8;
if ($rc != 0) {
2010-07-19 19:27:59 +02:00
log_message ('error', "Error retrieving file: $output");
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
}
return $rc;
}
################################################################################
# Check the server for a remote configuration.
################################################################################
sub check_remote_config () {
2010-07-19 19:27:59 +02:00
return unless ($Conf{'remote_config'} eq '1');
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
# Calculate the configuration file MD5 digest
open (CONF_FILE, "$ConfDir/$ConfFile") or error ("Could not open file '$ConfDir/$ConfFile': $!.");
2010-11-15 11:32:23 +01:00
binmode(CONF_FILE);
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
my $conf_md5 = md5 (join ('', <CONF_FILE>));
2010-11-15 11:32:23 +01:00
close (CONF_FILE);
2012-03-01 11:38:10 +01:00
# Remove temporary files if they exist as symlink to avoid symlink attack
2012-03-02 07:43:14 +01:00
for my $file ("$Conf{'temporal'}/$RemoteMD5File", "$Conf{'temporal'}/$RemoteConfFile") {
2012-03-01 11:38:10 +01:00
error ("File '$file' already exists as a symlink and could not be removed: $!") if (-l $file && ! unlink($file));
}
2010-11-15 11:32:23 +01:00
# Get the remote MD5 file
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
if (recv_file ($RemoteMD5File) != 0) {
open (MD5_FILE, "> $Conf{'temporal'}/$RemoteMD5File") || error ("Could not open file '$ConfDir/$RemoteMD5File' for writing: $!.");
print MD5_FILE $conf_md5;
close (MD5_FILE);
copy ("$ConfDir/$ConfFile", "$Conf{'temporal'}/$RemoteConfFile");
send_file ("$Conf{'temporal'}/$RemoteConfFile");
send_file ("$Conf{'temporal'}/$RemoteMD5File");
log_message ('remote config', 'Uploading configuration for the first time.');
unlink ("$Conf{'temporal'}/$RemoteConfFile");
unlink ("$Conf{'temporal'}/$RemoteMD5File");
return;
}
open (MD5_FILE, "< $Conf{'temporal'}/$RemoteMD5File") || error ("Could not open file '$ConfDir/$RemoteMD5File' for writing: $!.");
my $remote_conf_md5 = <MD5_FILE>;
close (MD5_FILE);
# No changes
return if ($remote_conf_md5 eq $conf_md5);
# Get the new configuration file
return if (recv_file ($RemoteConfFile) != 0);
log_message ('remote config', 'Configuration has changed!');
2013-04-17 20:01:49 +02:00
# Save the new configuration
move ("$Conf{'temporal'}/$RemoteConfFile", "$ConfDir/$ConfFile");
2010-07-19 19:27:59 +02:00
# Empty modules, plugins and collections
2009-12-03 19:35:08 +01:00
@Modules = ();
2010-07-19 19:27:59 +02:00
%Collections = ();
2013-04-17 20:01:49 +02:00
%Conf = %DefaultConf;
2009-12-03 19:35:08 +01:00
2013-04-17 20:01:49 +02:00
# Reload the new configuration
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
read_config ();
# Log file may have changed
stop_log ();
2011-11-15 14:33:16 +01:00
start_log ('quiet');
2010-07-30 14:25:23 +02:00
#Set nice of the pandora_agent
my $PID = $$;
`renice "$Conf{'pandora_nice'}" "$PID"`;
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
}
2011-04-11 18:35:45 +02:00
################################################################################
# SUB launch_tentacle_proxy
# Launchs tentacle server in proxy mode.
################################################################################
sub launch_tentacle_proxy () {
2011-04-12 17:09:25 +02:00
# Check if proxy server ip is right.
if ($Conf{'server_ip'} ne "localhost") {
2011-04-11 18:35:45 +02:00
2011-04-12 17:09:25 +02:00
#Create a new process and launch tentacle.
$tentacle_pid = fork();
if ($tentacle_pid == 0) {
2011-04-11 18:35:45 +02:00
2011-04-12 17:09:25 +02:00
#Execute tentacle server as a daemon
my $new_process = "tentacle_server -b ".$Conf{'server_ip'}." -g ".$Conf{'server_port'}." -c ".$Conf{'proxy_max_connection'}." -t ".$Conf{'proxy_timeout'};
log_message ('setup', 'Proxy mode enabled');
2013-08-13 19:01:17 +02:00
exec ($new_process);
2011-04-12 17:09:25 +02:00
}
} else {
2013-08-13 19:01:17 +02:00
log_message ('error', 'You can not proxy to localhost');
exit 1;
2011-04-11 18:35:45 +02:00
}
}
2010-07-19 19:27:59 +02:00
################################################################################
2010-07-21 13:32:08 +02:00
# Delete old collections and download new collections.
2010-07-19 19:27:59 +02:00
################################################################################
sub check_collections () {
2010-07-21 13:32:08 +02:00
# Delete old collections
opendir (DIR, "$ConfDir/collections") || return;
while (defined (my $file_name = readdir(DIR))) {
next if ($file_name eq '.' || $file_name eq '..');
# Do not delete md5 files associated to a collection
$file_name =~ s/\.md5$//;
2010-08-11 18:14:49 +02:00
if (! defined ($Collections{$file_name})) {
rmrf ("$ConfDir/collections/$file_name");
unlink ("$ConfDir/collections/$file_name.md5");
}
2010-07-21 13:32:08 +02:00
}
closedir (DIR);
# Download new collections
2010-07-19 19:27:59 +02:00
while (my ($collection, $in_path) = each (%Collections)) {
my $collection_file = $collection . ".zip";
my $collection_md5_file = $collection . ".md5";
# Add the collection directory to the PATH
if ($in_path == 0) {
$Collections{$collection} = 1;
$ENV{'PATH'} .= ":$ConfDir/collections/$collection";
}
# Get remote md5
2012-03-01 11:38:10 +01:00
error ("File '$Conf{'temporal'}/$collection_md5_file' already exists as a symlink and could not be removed: $!.") if (-l "$Conf{'temporal'}/$collection_md5_file" && !unlink("$Conf{'temporal'}/$collection_md5_file"));
2010-07-19 19:27:59 +02:00
next unless (recv_file ($collection_md5_file) == 0);
open (MD5_FILE, "< $Conf{'temporal'}/$collection_md5_file") || error ("Could not open file '$Conf{'temporal'}/$collection_md5_file' for reading: $!.");
my $remote_collection_md5 = <MD5_FILE>;
close (MD5_FILE);
unlink ("$Conf{'temporal'}/$collection_md5_file");
# Read local md5
my $local_collection_md5 = '';
if (defined (open (MD5_FILE, "< $ConfDir/collections/$collection_md5_file"))) {
$local_collection_md5 = <MD5_FILE>;
close MD5_FILE;
}
# Check for changes
$local_collection_md5 = $remote_collection_md5 unless defined ($local_collection_md5);
next if ($local_collection_md5 eq $remote_collection_md5);
# Download and unzip
next unless (recv_file ($collection_file) == 0);
2010-07-21 13:32:08 +02:00
rmrf ("$ConfDir/collections/$collection");
2010-11-04 20:34:04 +01:00
`unzip -d "$ConfDir/collections/$collection" "$Conf{'temporal'}/$collection_file" 2>$DevNull`;
2010-07-19 19:27:59 +02:00
unlink ("$Conf{'temporal'}/$collection_file");
2010-08-11 18:14:49 +02:00
# Save the new md5
open (MD5_FILE, "> $ConfDir/collections/$collection_md5_file") || error ("Could not open file '$ConfDir/collections/$collection_md5_file' for writing: $!.");
print MD5_FILE "$remote_collection_md5";
close (MD5_FILE);
# Set proper file permissions
chmodr (0750, "$ConfDir/collections/$collection");
2010-07-19 19:27:59 +02:00
}
}
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
###############################################################################
# MD5 leftrotate function. See http://en.wikipedia.org/wiki/MD5#Pseudocode.
###############################################################################
sub leftrotate ($$) {
my ($x, $c) = @_;
2009-12-03 19:35:08 +01:00
return (0xFFFFFFFF & ($x << $c)) | ($x >> (32 - $c));
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
}
###############################################################################
# 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);
}
}
###############################################################################
# Return the MD5 checksum of the given string.
# Pseudocode from http://en.wikipedia.org/wiki/MD5#Pseudocode.
###############################################################################
sub md5 ($) {
my $str = shift;
# Note: All variables are unsigned 32 bits and wrap modulo 2^32 when calculating
# Initialize variables
my $h0 = 0x67452301;
my $h1 = 0xEFCDAB89;
my $h2 = 0x98BADCFE;
my $h3 = 0x10325476;
# Pre-processing
my $msg = unpack ("B*", pack ("A*", $str));
my $bit_len = length ($msg);
# Append "1" bit to message
$msg .= '1';
# Append "0" bits until message length in bits ≡ 448 (mod 512)
$msg .= '0' while ((length ($msg) % 512) != 448);
# Append bit /* bit, not byte */ length of unpadded message as 64-bit little-endian integer to message
$msg .= unpack ("B64", pack ("VV", $bit_len));
# Process the message in successive 512-bit chunks
for (my $i = 0; $i < length ($msg); $i += 512) {
my @w;
my $chunk = substr ($msg, $i, 512);
# Break chunk into sixteen 32-bit little-endian words w[i], 0 <= i <= 15
for (my $j = 0; $j < length ($chunk); $j += 32) {
push (@w, unpack ("V", pack ("B32", substr ($chunk, $j, 32))));
}
# Initialize hash value for this chunk
my $a = $h0;
my $b = $h1;
my $c = $h2;
my $d = $h3;
my $f;
my $g;
# Main loop
for (my $y = 0; $y < 64; $y++) {
if ($y <= 15) {
$f = $d ^ ($b & ($c ^ $d));
$g = $y;
}
elsif ($y <= 31) {
$f = $c ^ ($d & ($b ^ $c));
$g = (5 * $y + 1) % 16;
}
elsif ($y <= 47) {
$f = $b ^ $c ^ $d;
$g = (3 * $y + 5) % 16;
}
else {
2009-12-03 19:35:08 +01:00
$f = $c ^ ($b | (0xFFFFFFFF & (~ $d)));
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
$g = (7 * $y) % 16;
}
my $temp = $d;
$d = $c;
$c = $b;
$b = ($b + leftrotate (($a + $f + $K[$y] + $w[$g]) % MOD232, $R[$y])) % MOD232;
$a = $temp;
}
# Add this chunk's hash to result so far
$h0 = ($h0 + $a) % MOD232;
$h1 = ($h1 + $b) % MOD232;
$h2 = ($h2 + $c) % MOD232;
$h3 = ($h3 + $d) % MOD232;
}
# Digest := h0 append h1 append h2 append h3 #(expressed as little-endian)
return unpack ("H*", pack ("V", $h0)) . unpack ("H*", pack ("V", $h1)) . unpack ("H*", pack ("V", $h2)) . unpack ("H*", pack ("V", $h3));
}
################################################################################
# Try to guess the OS version.
################################################################################
sub guess_os_version ($) {
my $os = shift;
2010-06-09 14:24:15 +02:00
my $os_version;
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
# Linux
2010-06-09 14:24:15 +02:00
if ($os eq 'linux') {
2010-11-04 20:34:04 +01:00
$os_version = `lsb_release -sd 2>$DevNull`;
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
# AIX
2010-06-09 14:24:15 +02:00
} elsif ($os eq 'aix') {
$os_version = "$2.$1" if (`uname -rv` =~ /\s*(\d)\s+(\d)\s*/);
2010-11-04 20:34:04 +01:00
# Windows
} elsif ($os =~ /win/i) {
$os_version = `ver`;
$DevNull = '/Nul';
$CmdSep = '\&';
$OS = "windows";
2010-06-09 14:24:15 +02:00
# Solaris, HP-UX, BSD and others
} else {
$os_version = `uname -r`;
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
}
2010-06-09 14:24:15 +02:00
# Something went wrong
return '' unless defined ($os_version);
# Remove any trailing new lines
chomp ($os_version);
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
2010-06-09 14:24:15 +02:00
return $os_version;
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
}
2010-05-18 20:07:32 +02:00
################################################################################
# Execute the given module.
################################################################################
sub exec_module ($) {
my $module = shift;
# Need something to execute
2011-02-03 10:44:04 +01:00
if ($module->{'func'} == 0) {
$ThreadSem->up () if (defined ($ThreadSem) && $Conf{'agent_threads'} > 1);
return;
}
2010-05-18 20:07:32 +02:00
# Check module interval
2012-01-03 18:18:45 +01:00
if (++($module->{'counter'}) < $module->{'intensive_interval'}) {
2011-02-03 10:44:04 +01:00
$ThreadSem->up () if (defined ($ThreadSem) && $Conf{'agent_threads'} > 1);
return;
}
2010-05-18 20:07:32 +02:00
2010-06-25 14:38:32 +02:00
# Check module cron
2011-02-03 10:44:04 +01:00
if (check_module_cron ($module) != 1) {
$ThreadSem->up () if (defined ($ThreadSem) && $Conf{'agent_threads'} > 1);
return;
}
2012-01-03 18:18:45 +01:00
# Check module preconditions
if (evaluate_module_preconditions ($module) == 0) {
return;
}
2010-06-25 14:38:32 +02:00
2010-05-18 20:07:32 +02:00
# Reset module counter
$module->{'counter'} = 0;
# Temporarily disable strict refs
no strict 'refs';
# Run
2010-06-23 20:01:38 +02:00
my @value = &{$module->{'func'}}($module);
2012-01-03 18:18:45 +01:00
if (defined ($value[0])) {
# Evaluate intensive conditions
if ($module->{'is_intensive'} == 1) {
my $intensive_match = evaluate_module_intensive_conditions ($module, $value[0]);
if ($intensive_match == $module->{'intensive_match'} && $module->{'timestamp'} + $module->{'interval'} * $Conf{'interval'} > time ()) {
$ThreadSem->up () if (defined ($ThreadSem) && $Conf{'agent_threads'} > 1);
return;
}
# Update the time reference
$module->{'timestamp'} = time () if ($module->{'timestamp'} + $module->{'interval'} * $Conf{'interval'} <= time ());
# Update the intensive match status
$module->{'intensive_match'} = $intensive_match;
}
# Evaluate module conditions
evaluate_module_conditions ($module, $value[0]);
# Write the module XML
write_module_xml ($module, @value);
}
2010-06-23 20:01:38 +02:00
# Save the module value if needed (only works for the first returned value)
if ($module->{'save'} ne '') {
if (defined ($value[0])) {
$ENV{$module->{'save'}} = $value[0] ;
} else {
$ENV{$module->{'save'}} = '';
}
}
2010-09-17 15:03:24 +02:00
$ThreadSem->up () if (defined ($ThreadSem) && $Conf{'agent_threads'} > 1);
2010-05-18 20:07:32 +02:00
}
################################################################################
# Load process information.
################################################################################
sub load_procs () {
my $utimestamp = time ();
# Do we know hoy to get process information in this OS?
return unless defined (PROC_CMDS->{$OS});
# Update at most once every interval
return if ($Procs{'__utimestamp__'} > ($utimestamp - $Conf{'interval'}));
# Get process information
2010-06-08 18:52:51 +02:00
my $cmd = PROC_CMDS->{$OS};
2010-05-18 20:07:32 +02:00
my @procs = `$cmd`;
return undef unless ($? eq 0);
2011-09-13 05:06:39 +02:00
# Clear past process infomation
%Procs = ();
2010-05-18 20:07:32 +02:00
# Parse process information
foreach my $proc (@procs) {
chomp ($proc);
my @proc_info = split (/\s+/, $proc);
2010-06-08 18:52:51 +02:00
next unless ($#proc_info >= 2);
# Process command
my $proc_cmd = join (' ', @proc_info[2..$#proc_info]);
2010-05-18 20:07:32 +02:00
# Process command
$Procs{$proc_cmd} = ();
# Process CPU usage
2010-06-08 18:52:51 +02:00
$Procs{$proc_cmd}{'cpu'} = $proc_info[0];
2010-05-18 20:07:32 +02:00
# Process virtual size
2010-06-08 18:52:51 +02:00
$Procs{$proc_cmd}{'size'} = $proc_info[1];
2010-05-18 20:07:32 +02:00
}
$Procs{'__utimestamp__'} = $utimestamp;
}
################################################################################
# Load partition information.
################################################################################
sub load_parts () {
my $utimestamp = time ();
# Do we know hoy to get partition information in this OS?
return unless defined (PART_CMDS->{$OS});
# Update at most once every interval
return if ($Parts{'__utimestamp__'} > ($utimestamp - $Conf{'interval'}));
# Get partition information
2010-06-08 18:52:51 +02:00
my $cmd = PART_CMDS->{$OS};
2010-05-18 20:07:32 +02:00
my @parts = `$cmd`;
return undef unless ($? eq 0);
# Parse partition information
foreach my $part (@parts) {
chomp ($part);
my @part_info = split (/\s+/, $part);
2010-06-08 18:52:51 +02:00
next unless ($#part_info >= 2);
my $part = join (' ', @part_info[2..$#part_info]);
2010-05-18 20:07:32 +02:00
# Mount point
2010-06-08 18:52:51 +02:00
$Parts{$part} = ();
2010-05-18 20:07:32 +02:00
# Total space in kB
2010-06-08 18:52:51 +02:00
$Parts{$part}{'total'} = $part_info[0];
2010-05-18 20:07:32 +02:00
# Available space in kB
2010-06-08 18:52:51 +02:00
$Parts{$part}{'avail'} = $part_info[1];
2010-05-18 20:07:32 +02:00
}
$Parts{'__utimestamp__'} = $utimestamp;
}
################################################################################
# Execute the given command.
################################################################################
sub module_exec ($) {
my $module = shift;
2010-06-18 14:36:19 +02:00
my @data;
2011-06-21 13:06:47 +02:00
my $exe;
2010-05-18 20:07:32 +02:00
# Check module parameters
return () unless ($module->{'params'} ne '');
2012-08-01 18:35:40 +02:00
my $params = $module->{'params'};
2010-05-18 20:07:32 +02:00
# Execute the command
2010-06-18 14:36:19 +02:00
if ($module->{'timeout'} == 0) {
2012-08-01 18:35:40 +02:00
@data = `$params 2> $DevNull`;
2013-03-11 12:51:32 +01:00
log_message ('debug', "Executing module " . $module->{'name'} . " ($params 2> $DevNull)") if ($Conf{'debug'} eq '1');
2010-06-18 14:36:19 +02:00
} else {
2012-08-01 18:35:40 +02:00
my $cmd = quotemeta ($params);
2010-11-04 20:34:04 +01:00
@data = `$Conf{'pandora_exec'} $module->{'timeout'} $cmd 2> $DevNull`;
2013-03-11 12:51:32 +01:00
log_message ('debug', "Executing module " . $module->{'name'} . ' (' . $Conf{'pandora_exec'} . ' ' . $module->{'timeout'} . " $cmd 2> $DevNull)") if ($Conf{'debug'} eq '1');
2010-06-18 14:36:19 +02:00
}
2010-05-18 20:07:32 +02:00
# Something went wrong or no data
return () unless ($? eq 0 && defined ($data[0]));
return @data;
}
################################################################################
# Get the status of a process. 1 running, 0 not running.
################################################################################
sub module_proc ($) {
my $module = shift;
# Check module parameters
return () unless ($module->{'params'} ne '');
# Data collection layer
load_procs ();
return (1) if defined ($Procs{$module->{'params'}});
return (0);
}
################################################################################
# Get the CPU usage of a process.
################################################################################
sub module_cpuproc ($) {
my $module = shift;
# Check module parameters
return () unless ($module->{'params'} ne '');
2011-09-13 05:06:39 +02:00
# Data collection layer
load_procs ();
2010-05-18 20:07:32 +02:00
return () unless defined ($Procs{$module->{'params'}}) and defined ($Procs{$module->{'params'}}{'cpu'});
return ($Procs{$module->{'params'}}{'cpu'});
}
################################################################################
# Get the memory usage of a process in Mbytes.
################################################################################
sub module_memproc ($) {
my $module = shift;
# Check module parameters
return () unless ($module->{'params'} ne '');
# Data collection layer
load_procs ();
return () unless defined ($Procs{$module->{'params'}}) and defined ($Procs{$module->{'params'}}{'size'});
return (sprintf ("%d", $Procs{$module->{'params'}}{'size'} / 1024));
}
################################################################################
# Get the free space in a partition in Mbytes.
################################################################################
sub module_freedisk ($) {
my $module = shift;
# Check module parameters
return () unless ($module->{'params'} ne '');
# Data collection layer
load_parts ();
return () unless defined ($Parts{$module->{'params'}}) and defined ($Parts{$module->{'params'}}{'avail'});
my $avail = sprintf("%d", $Parts{$module->{'params'}}{'avail'} / 1024);
return ($avail);
}
################################################################################
# Get the free space in a partition in %.
################################################################################
sub module_freepercentdisk ($) {
my $module = shift;
# Check module parameters
return () unless ($module->{'params'} ne '');
# Data collection layer
load_parts ();
return () unless defined ($Parts{$module->{'params'}}) and defined ($Parts{$module->{'params'}}{'avail'});
my $availp = sprintf("%d", $Parts{$module->{'params'}}{'avail'} * 100 / $Parts{$module->{'params'}}{'total'});
return ($availp);
}
2011-03-09 11:16:01 +01:00
################################################################################
2011-03-09 16:40:16 +01:00
# Get the occupied space in a partition in %.
2011-03-09 11:16:01 +01:00
################################################################################
2011-03-09 16:40:16 +01:00
sub module_occupiedpercentdisk ($) {
2011-03-09 11:16:01 +01:00
my $module = shift;
# Check module parameters
return () unless ($module->{'params'} ne '');
# Data collection layer
load_parts ();
return () unless defined ($Parts{$module->{'params'}}) and defined ($Parts{$module->{'params'}}{'avail'});
2011-03-09 16:40:16 +01:00
my $occupiedp = sprintf("%d", ($Parts{$module->{'params'}}{'total'} - $Parts{$module->{'params'}}{'avail'}) * 100 / $Parts{$module->{'params'}}{'total'});
return ($occupiedp);
2011-03-09 11:16:01 +01:00
}
2010-05-18 20:07:32 +02:00
################################################################################
# Get the CPU usage %.
################################################################################
sub module_cpuusage ($) {
my $module = shift;
# Do we know hoy to get CPU usage in this OS?
return unless defined (CPUUSAGE_CMDS->{$OS});
# Get CPU usage
2010-06-08 18:52:51 +02:00
my $cmd = CPUUSAGE_CMDS->{$OS};
2010-11-04 20:34:04 +01:00
my @data = `$cmd 2> $DevNull`;
2010-05-18 20:07:32 +02:00
# Something went wrong or no data
return () unless ($? eq 0 && defined ($data[0]));
return ($data[0]);
}
################################################################################
# Get the free space in a partition in Mbytes.
################################################################################
sub module_freememory ($) {
my $module = shift;
# Do we know hoy to get memory information in this OS?
return () unless defined (FREEMEMORY_CMDS->{$OS});
# Get available memory
2010-06-08 18:52:51 +02:00
my $cmd = FREEMEMORY_CMDS->{$OS};
2010-11-04 20:34:04 +01:00
my @data = `$cmd 2> $DevNull`;
2010-05-18 20:07:32 +02:00
# Something went wrong or no data
return () unless ($? eq 0 && defined ($data[0]));
return (sprintf ("%d", $data[0] / 1024));
}
################################################################################
# Get the free space in a partition in %.
################################################################################
sub module_freepercentmemory ($) {
my $module = shift;
# Do we know hoy to get memory information in this OS?
return unless defined (TOTALMEMORY_CMDS->{$OS});
# Get CPU usage
2010-06-08 18:52:51 +02:00
my $cmd = TOTALMEMORY_CMDS->{$OS};
2010-11-04 20:34:04 +01:00
my @data = `$cmd 2> $DevNull`;
2010-05-18 20:07:32 +02:00
# Something went wrong or no data
return () unless ($? eq 0 && defined ($data[0]));
# Get total memory in MB
my $total = sprintf ("%d", $data[0] / 1024);
# Get available memory in MB
my ($avail) = module_freememory ($module);
return () unless defined ($avail);
return sprintf (("%d", $avail * 100 / $total));
}
2011-06-21 13:06:47 +02:00
################################################################################
# Evaluate and execute module preconditions.
################################################################################
sub evaluate_module_preconditions ($) {
my ($module) = @_;
# Evaluate preconditions
2012-01-03 18:18:45 +01:00
foreach my $precondition (@{$module->{'precondition'}}) {
my $data = `$precondition->{'command'} 2> $DevNull`;
return 0 if (evaluate_condition ($precondition, $data) == 0);
}
return 1;
}
################################################################################
# Evaluate a module condition. Returns 1 if the condition matches, 0 otherwise.
################################################################################
sub evaluate_condition ($$) {
my ($condition, $data) = @_;
{
no warnings;
if (($condition->{'operator'} eq '>' && $data > $condition->{'value_1'}) ||
($condition->{'operator'} eq '<' && $data < $condition->{'value_1'}) ||
($condition->{'operator'} eq '=' && $data == $condition->{'value_1'}) ||
($condition->{'operator'} eq '!=' && $data != $condition->{'value_1'}) ||
($condition->{'operator'} eq '=~' && $data =~ /$condition->{'value_1'}/) ||
($condition->{'operator'} eq '()' && $data > $condition->{'value_1'} && $data < $condition->{'value_2'})) {
return 1;
2011-06-21 13:06:47 +02:00
}
2011-12-14 12:43:24 +01:00
}
2012-01-03 18:18:45 +01:00
return 0;
2011-06-21 13:06:47 +02:00
}
2010-06-23 20:01:38 +02:00
################################################################################
# Evaluate and execute module conditions.
################################################################################
sub evaluate_module_conditions ($$) {
my ($module, $data) = @_;
# Evaluate conditions
foreach my $condition (@{$module->{'conditions'}}) {
2012-01-03 18:18:45 +01:00
if (evaluate_condition ($condition, $data) == 1) {
2010-11-04 20:34:04 +01:00
`$condition->{'command'} 2> $DevNull`;
2010-06-23 20:01:38 +02:00
}
}
}
2012-01-03 18:18:45 +01:00
################################################################################
# Evaluate intensive conditions.
################################################################################
sub evaluate_module_intensive_conditions ($$) {
my ($module, $data) = @_;
# Evaluate conditions
foreach my $condition (@{$module->{'intensive_conditions'}}) {
return 0 if (evaluate_condition ($condition, $data) == 0);
}
return 1;
}
2010-06-25 14:38:32 +02:00
################################################################################
# Checks the module's cron string. Returns 1 if the module should be run, 0 if
# not.
################################################################################
sub check_module_cron ($) {
my $module = shift;
# No cron string defined
2010-07-08 17:04:43 +02:00
return 1 unless ($module->{'cron'} ne '');
2010-06-25 14:38:32 +02:00
# Check if the module was already executed
2013-04-03 13:52:44 +02:00
return 0 unless (time() >= $module->{'cron_utimestamp'});
2010-06-25 14:38:32 +02:00
# Get cron configuration
my @cron_params = split (/\s/, $module->{'cron'});
# Get current time
my $current_time = time();
my @time = localtime($current_time);
# Minutes, hours, day of the month, month and day of the week
my @time_params = @time[1, 2, 3, 4, 6];
# Fix month (localtime retuns 0..11 and we need 1..12)
$time_params[3] += 1;
# Check cron parameters
for (my $i = 0; $i < 5; $i++) {
2010-06-30 21:13:41 +02:00
# Wildcard
next if ($cron_params[$i] eq '*');
# Get interval
my ($bottom, $top) = split (/-/, $cron_params[$i]);
$top = $bottom unless defined ($top);
# Check interval
if ($bottom <= $top) {
return 0 if ($time_params[$i] < $bottom || $time_params[$i] > $top);
} else {
return 0 if ($time_params[$i] < $bottom && $time_params[$i] > $top);
}
2010-06-25 14:38:32 +02:00
}
# Do not check in the next minute, hour, day or month.
my $offset = 0;
2010-06-30 21:13:41 +02:00
if ($module->{'cron_interval'} >= 0) {
$offset = $module->{'cron_interval'};
} elsif($cron_params[0] ne '*') {
2010-06-25 14:38:32 +02:00
# 1 minute
$offset = 60;
} elsif($cron_params[1] ne '*') {
# 1 hour
$offset = 3600;
} elsif($cron_params[2] ne '*' || $cron_params[4] ne '*') {
# 1 day
$offset = 86400;
} elsif($cron_params[3] ne '*') {
# 31 days
$offset = 2678400;
}
$module->{'cron_utimestamp'} = $current_time + $offset;
return 1;
}
2010-09-17 15:03:24 +02:00
################################################################################
# Write module data in XML format.
################################################################################
sub write_module_xml ($@) {
my ($module, @data) = @_;
# No data
return unless (defined $data[0]);
2013-11-12 13:28:28 +01:00
# Is it a plugin?
if ($module->{'func'} == \&module_plugin) {
$Sem->down () if (defined ($Sem));
$Xml .= $data[0];
$Sem->up () if (defined ($Sem));
return;
}
2010-09-17 15:03:24 +02:00
# Critical section
$Sem->down () if (defined ($Sem));
2012-11-13 13:24:36 +01:00
$Xml .= "<module>\n" .
2010-11-15 11:32:23 +01:00
" <name><![CDATA[" . $module->{'name'} . "]]></name>\n" .
" <description><![CDATA[" . $module->{'description'} . "]]></description>\n" .
" <type>" . $module->{'type'} . "</type>\n";
2010-09-17 15:03:24 +02:00
2011-03-01 15:45:32 +01:00
# Interval
2012-01-03 18:18:45 +01:00
$Xml .= " <module_interval>" . $module->{'interval'} . "</module_interval>\n";
2011-03-01 15:45:32 +01:00
# Min
$Xml .= " <min>" . $module->{'min'} . "</min>\n" if (defined ($module->{'min'}));
# Max
$Xml .= " <max>" . $module->{'max'} . "</max>\n" if (defined ($module->{'max'}));
# Post process
$Xml .= " <post_process>" . $module->{'post_process'} . "</post_process>\n" if (defined ($module->{'post_process'}));
2010-09-20 17:03:06 +02:00
2011-07-14 18:03:06 +02:00
# Min critical
$Xml .= " <min_critical>" . $module->{'min_critical'} . "</min_critical>\n" if (defined ($module->{'min_critical'}));
# Max critical
$Xml .= " <max_critical>" . $module->{'max_critical'} . "</max_critical>\n" if (defined ($module->{'max_critical'}));
# Min warning
$Xml .= " <min_warning>" . $module->{'min_warning'} . "</min_warning>\n" if (defined ($module->{'min_warning'}));
# Max warning
$Xml .= " <max_warning>" . $module->{'max_warning'} . "</max_warning>\n" if (defined ($module->{'max_warning'}));
# Disabled
$Xml .= " <disabled>" . $module->{'disabled'} . "</disabled>\n" if (defined ($module->{'disabled'}));
# Min ff event
$Xml .= " <min_ff_event>" . $module->{'min_ff_event'} . "</min_ff_event>\n" if (defined ($module->{'min_ff_event'}));
2012-05-10 18:27:15 +02:00
# Unit
2012-11-13 13:24:36 +01:00
$Xml .= " <unit><![CDATA[" . $module->{'unit'} . "]]></unit>\n" if (defined ($module->{'unit'}));
# Module group
$Xml .= " <module_group>" . $module->{'module_group'} . "</module_group>\n" if (defined ($module->{'module_group'}));
# Custom ID
$Xml .= " <custom_id><![CDATA[" . $module->{'custom_id'} . "]]></custom_id>\n" if (defined ($module->{'custom_id'}));
# Str warning
$Xml .= " <str_warning><![CDATA[" . $module->{'str_warning'} . "]]></str_warning>\n" if (defined ($module->{'str_warning'}));
# Str critical
$Xml .= " <str_critical><![CDATA[" . $module->{'str_critical'} . "]]></str_critical>\n" if (defined ($module->{'str_critical'}));
# Critical instructions
$Xml .= " <critical_instructions><![CDATA[" . $module->{'critical_instructions'} . "]]></critical_instructions>\n" if (defined ($module->{'critical_instructions'}));
# Warning instructions
$Xml .= " <warning_instructions><![CDATA[" . $module->{'warning_instructions'} . "]]></warning_instructions>\n" if (defined ($module->{'warning_instructions'}));
# Unknown instructions
$Xml .= " <unknown_instructions><![CDATA[" . $module->{'unknown_instructions'} . "]]></unknown_instructions>\n" if (defined ($module->{'unknown_instructions'}));
# Tags
$Xml .= " <tags><![CDATA[" . $module->{'tags'} . "]]></tags>\n" if (defined ($module->{'tags'}));
2011-07-14 18:03:06 +02:00
2012-11-13 13:24:36 +01:00
# Critical inverse
$Xml .= " <critical_inverse>" . $module->{'critical_inverse'} . "</critical_inverse>\n" if (defined ($module->{'critical_inverse'}));
# Warning inverse
$Xml .= " <warning_inverse>" . $module->{'warning_inverse'} . "</warning_inverse>\n" if (defined ($module->{'warning_inverse'}));
# Quiet
$Xml .= " <quiet>" . $module->{'quiet'} . "</quiet>\n" if (defined ($module->{'quiet'}));
# Module FF interval
$Xml .= " <module_ff_interval>" . $module->{'module_ff_interval'} . "</module_ff_interval>\n" if (defined ($module->{'module_ff_interval'}));
2010-09-17 15:03:24 +02:00
# Data list
if ($#data > 0) {
2010-11-15 11:32:23 +01:00
$Xml .= " <datalist>\n";
2010-09-17 15:03:24 +02:00
foreach my $data_item (@data) {
chomp ($data_item);
2010-11-15 11:32:23 +01:00
$Xml .= " <data><value><![CDATA[$data_item]]></value></data>\n";
2010-09-17 15:03:24 +02:00
}
2010-11-15 11:32:23 +01:00
$Xml .= " </datalist>\n";
2010-09-17 15:03:24 +02:00
# Single data
} else {
chomp ($data[0]);
2010-11-15 11:32:23 +01:00
$Xml .= " <data><![CDATA[$data[0]]]></data>\n";
2010-09-17 15:03:24 +02:00
}
2012-11-13 13:24:36 +01:00
$Xml .= "</module>\n";
2010-09-17 15:03:24 +02:00
$Sem->up () if (defined ($Sem));
}
2010-10-08 11:58:18 +02:00
################################################################################
# Receive a UDP server signal to restart agent
################################################################################
sub udp_server_signal () {
2010-11-15 11:32:23 +01:00
log_message ('udp server', 'Received signal to restart the agent.');
2010-10-08 11:58:18 +02:00
}
################################################################################
# Basic UDP server to restart agent on UDP signal received
################################################################################
sub udp_server ($$) {
2010-11-15 11:32:23 +01:00
my $udp_port = shift;
my $udp_auth_address = shift;
my $parent_pid = getppid();
2010-10-08 11:58:18 +02:00
2010-11-15 11:32:23 +01:00
my($sock, $oldmsg, $newmsg, $hisaddr, $hishost, $MAXLEN);
$MAXLEN = 1024;
2010-10-08 11:58:18 +02:00
2010-11-15 11:32:23 +01:00
log_message ('udp server', 'Starting UDP server listening on '.$udp_auth_address.":".$udp_port);
$sock = IO::Socket::INET->new(LocalPort => $udp_port, Proto => 'udp') or die "socket: $@";
2010-10-08 11:58:18 +02:00
2010-11-15 11:32:23 +01:00
while ($sock->recv($newmsg, $MAXLEN)) {
my($port, $ipaddr) = sockaddr_in($sock->peername);
$hishost = gethostbyaddr($ipaddr, AF_INET);
2010-10-08 11:58:18 +02:00
2010-11-15 11:32:23 +01:00
log_message ('udp server', 'Received signal from '.$hishost);
2010-10-08 11:58:18 +02:00
2010-11-15 11:32:23 +01:00
if (($udp_auth_address eq "0.0.0.0") || ($hishost eq $udp_auth_address)){
if ($newmsg =~ /REFRESH AGENT/){
# Send signal to restart agent
kill 'SIGINT' , $parent_pid;
}
}
}
2010-10-08 11:58:18 +02:00
}
2010-09-17 15:03:24 +02:00
################################################################################
# Execute the given plugin.
################################################################################
2013-11-12 13:28:28 +01:00
sub module_plugin ($) {
2010-09-17 15:03:24 +02:00
my $plugin = shift;
2013-05-23 19:20:21 +02:00
my $command = $plugin->{'params'};
# Empty plugin
2013-11-12 13:28:28 +01:00
return () if ($command eq '');
2013-05-23 19:20:21 +02:00
# Execute the plugin
my $output = `$command 2>$DevNull`;
2010-09-17 15:03:24 +02:00
# Do not save the output if there was an error
2011-02-03 10:44:04 +01:00
if ($? != 0) {
2013-11-12 13:28:28 +01:00
return ();
2011-02-03 10:44:04 +01:00
}
2010-09-17 15:03:24 +02:00
2013-11-12 13:28:28 +01:00
return ($output);
2010-09-17 15:03:24 +02:00
}
2011-04-12 17:09:25 +02:00
################################################################################
# TERM Handler
################################################################################
sub kill_signal_handler (){
# Kill tentacle server if it was launched
if (defined ($tentacle_pid)) {
print "kill -9 $tentacle_pid\n";
`kill -9 $tentacle_pid`;
}
exit (0);
}
2012-02-28 16:48:26 +01:00
################################################################################
# Get the free disk space in the temporal directory (in bytes).
################################################################################
sub temporal_freedisk () {
# Call df
return 0 unless defined (DF_CMDS->{$OS});
my $cmd = DF_CMDS->{$OS} . ' ' . $Conf{'temporal'} . ' | awk \'NR > 1 {print $4}\'';
my $temporal_freedisk = `$cmd`;
# Check for errors
return 0 unless ($? eq 0);
# Convert to bytes
return 1024 * int ($temporal_freedisk);
}
2013-05-23 19:20:21 +02:00
################################################################################
# Replace module macros.
################################################################################
sub replace_macros ($) {
my $module = shift;
# Replace macros
foreach my $token (keys (%{$module})) {
# No need to skip macros for now, since it's a hash ref and only array refs
# are searched for macros.
#if ($token eq 'macros') {
# next;
#}
# No defined value for conf token
if (! defined ($module->{$token})) {
next;
}
# Simple configuration token
if(ref($module->{$token}) eq ''){
while (my ($macro, $subst) = each (%{$module->{'macros'}})) {
eval {
$module->{$token} =~ s/$macro/$subst/g;
};
}
}
# Hash array
elsif (ref($module->{$token}) eq 'ARRAY'){
for (my $i = 0; $i <= $#{$module->{$token}}; $i++) {
# Array of configuration tokens
foreach my $key (keys (%{$module->{$token}->[$i]})) {
# Each configuration token is a hash
while (my ($macro, $subst) = each (%{$module->{'macros'}})) {
eval {
$module->{$token}->[$i]->{$key} =~ s/$macro/$subst/g;
}
}
}
}
}
}
}
################################################################################
# Initialize a module with default values.
################################################################################
sub init_module ($) {
my $module = shift;
$module->{'name'} = '';
$module->{'type'} = 'generic_data';
$module->{'description'} = '';
$module->{'func'} = 0;
$module->{'params'} = '';
$module->{'interval'} = 1;
$module->{'timeout'} = 0;
$module->{'counter'} = 0;
$module->{'max'} = undef;
$module->{'min'} = undef;
$module->{'post_process'} = undef;
$module->{'min_critical'} = undef;
$module->{'max_critical'} = undef;
$module->{'min_warning'} = undef;
$module->{'max_warning'} = undef;
$module->{'disabled'} = undef;
$module->{'min_ff_event'} = undef;
$module->{'save'} = '';
$module->{'conditions'} = [];
$module->{'cron'} = '';
$module->{'cron_utimestamp'} = 0;
$module->{'cron_interval'} = -1;
$module->{'precondition'} = [];
$module->{'is_intensive'} = 0;
$module->{'intensive_conditions'} = [];
$module->{'intensive_match'} = 0;
$module->{'timestamp'} = 0;
$module->{'unit'} = undef;
$module->{'module_group'} = undef;
$module->{'custom_id'} = undef;
$module->{'str_warning'} = undef;
$module->{'str_critical'} = undef;
$module->{'critical_instructions'} = undef;
$module->{'warning_instructions'} = undef;
$module->{'unknown_instructions'} = undef;
$module->{'tags'} = undef;
$module->{'critical_inverse'} = undef;
$module->{'warning_inverse'} = undef;
$module->{'quiet'} = undef;
$module->{'module_ff_interval'} = undef;
$module->{'macros'} = {};
}
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
################################################################################
# Main.
################################################################################
2011-04-12 17:09:25 +02:00
#Handler TERM signal.
$SIG{'TERM'} = \&kill_signal_handler;
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
# Check command line arguments
print_usage unless ($#ARGV == 0);
2009-11-19 01:34:27 +01:00
$ConfDir = fix_directory ($ARGV[0]);
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
error ("Directory '$ConfDir' does not exist.") unless (-d "$ConfDir");
2011-07-14 12:31:40 +02:00
#Pandora home path
$ENV{'PANDORA_HOME'}=$ConfDir;
2011-11-15 14:33:16 +01:00
# Get user to run as
my $pandora_user = read_config ('pandora_user');
if (defined ($pandora_user)) {
# Change the EUID
my $pandora_user_uid = getpwnam ($pandora_user);
if (!defined ($pandora_user_uid)) {
error ("Cannot get uid for user $pandora_user. Does the user exist and can we read /etc/passwd?");
2011-07-08 13:46:38 +02:00
}
2011-11-15 14:33:16 +01:00
$> = $pandora_user_uid;
if ($> != $pandora_user_uid) {
error ("Cannot run as $pandora_user: Insufficient permissions.");
}
}
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
2011-11-15 14:33:16 +01:00
# Guess the OS version
$OS_VERSION = guess_os_version ($OS);
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
2011-11-15 14:33:16 +01:00
# Initialize MD5 variables
md5_init ();
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
2011-11-15 14:33:16 +01:00
# Start logging
start_log ();
log_message ('log', 'Running as user ' . getpwuid ($>));
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
2011-11-15 14:33:16 +01:00
# Read configuration file
read_config ();
$ENV{'PANDORA_AGENT'}=$Conf{'agent_name'};
2011-07-14 12:31:40 +02:00
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
# Fix directory names
$Conf{'temporal'} = fix_directory ($Conf{'temporal'});
2009-11-19 01:34:27 +01:00
error ("Temporal directory '" . $Conf{'temporal'} . "' does not exist.") unless (-d "$Conf{'temporal'}");
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
$Conf{'server_path'} = fix_directory ($Conf{'server_path'});
$Conf{'secondary_server_path'} = fix_directory ($Conf{'secondary_server_path'});
2012-08-15 04:06:52 +02:00
# Load thread support if agent_threads is greater than 1.
if ($Conf{'agent_threads'} > 1) {
eval {
local $SIG{__DIE__};
require threads;
require threads::shared;
require Thread::Semaphore;
};
if (!$@) {
$Sem = Thread::Semaphore->new;
threads::shared::share (\$Xml);
threads::shared::share (\$Sem);
log_message ('log', 'Using thread library.');
} else {
log_message ('log', 'Thread library is not available. agent_threads is set to 1 (disabled).');
$Conf{'agent_threads'} = 1;
}
} else {
log_message ('log', 'Thread is disabled.');
}
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
# Startup delay
log_message ('log', 'Sleeping for ' . $Conf{'delayed_startup'} . ' seconds.') if ($Conf{'delayed_startup'} > 0);
sleep ($Conf{'delayed_startup'});
2010-07-30 14:25:23 +02:00
#Set nice of the pandora_agent
my $PID = $$;
`renice "$Conf{'pandora_nice'}" "$PID"`;
2011-04-12 17:09:25 +02:00
#Launch tentacle server in proxy mode if configured
2011-04-13 10:15:16 +02:00
if ($Conf{'proxy_mode'}) {
#Check if user is root
2012-04-18 16:13:41 +02:00
if ($> != 0) {
2011-04-13 10:15:16 +02:00
launch_tentacle_proxy();
} else {
2013-09-13 16:01:49 +02:00
log_message ('error', 'Proxy mode can not be launched as root');
2013-08-13 19:01:17 +02:00
exit 1;
2011-04-13 10:15:16 +02:00
}
2011-04-12 17:09:25 +02:00
}
2011-04-11 18:35:45 +02:00
2010-08-11 18:14:49 +02:00
# Add the plugins directory to the PATH
$ENV{'PATH'} .= ":$ConfDir/plugins";
2010-10-08 11:58:18 +02:00
# Start UDP server if configured
if ($Conf{'udp_server'} == 1){
2010-11-15 11:32:23 +01:00
my $pid = fork();
2010-10-08 11:58:18 +02:00
2010-11-15 11:32:23 +01:00
if ($pid == 0){
udp_server ($Conf{'udp_server_port'}, $Conf{'udp_server_auth_address'});
exit;
}
2010-10-08 11:58:18 +02:00
}
2011-11-15 14:33:16 +01:00
# Must be set to 0 if the agent is a broker agent
my $main_agent = -1;
2013-04-03 13:52:44 +02:00
# base time to start eatch iteration with the same interval.
my $iter_base_time = time();
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
# Loop
while (1) {
2011-04-12 17:09:25 +02:00
# Ignore signals from UDP and Tentacle server while processing execution
if ($Conf{'udp_server'} == 1 || $Conf{'proxy_mode'}){
2010-11-15 11:32:23 +01:00
$SIG{'INT'} = 'DEFAULT';
}
2010-10-08 11:58:18 +02:00
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
# Check for a new configuration
2009-11-19 01:34:27 +01:00
check_remote_config () unless ($Conf{'debug'} eq '1');
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
2010-07-19 19:27:59 +02:00
# Check file collections
check_collections () unless ($Conf{'debug'} eq '1');
2011-11-15 14:33:16 +01:00
# Launch broker agents
2011-12-19 16:45:38 +01:00
@BrokerPid = ();
2011-11-15 14:33:16 +01:00
my @broker_agents = read_config ('broker_agent');
foreach my $broker_agent (@broker_agents) {
# Create broker conf file if it does not exist
if (! -e "$ConfDir/${broker_agent}.conf") {
write_broker_conf($broker_agent);
}
$main_agent = fork ();
# Broker agent
if ($main_agent == 0) {
# Set the configuration file
$ConfFile = "${broker_agent}.conf";
# Log to a new file
stop_log ();
start_log ('quiet');
# Read configuration file
2011-12-16 14:38:22 +01:00
@Modules = ();
%Collections = ();
2013-03-11 13:10:56 +01:00
%Conf = %DefaultConf;
2011-11-15 14:33:16 +01:00
read_config ();
# Check for a new configuration
check_remote_config () unless ($Conf{'debug'} eq '1');
# Check file collections
check_collections () unless ($Conf{'debug'} eq '1');
# Execute
last;
2011-12-19 16:40:22 +01:00
} else {
push (@BrokerPid, $main_agent);
2011-11-15 14:33:16 +01:00
}
}
2011-06-28 11:47:10 +02:00
my $address;
2011-06-28 10:10:31 +02:00
2011-06-28 11:47:10 +02:00
if(defined($Conf{'address'})) {
# Check if address is auto to get the local ip
if ($Conf{'address'} eq 'auto') {
2011-06-28 14:13:26 +02:00
# Tested on Ubuntu, debian, Suse, Solaris 10 and AIX 5.1
2013-07-10 12:08:52 +02:00
my @address_list = `ifconfig -a | grep -v '127.0.0' | grep '[0-9]*\\.[0-9]*\\.[0-9]*' | awk '{ print \$2 }' | awk -F':' '{ print \$2 }'`;
2013-04-17 12:44:32 +02:00
for (my $i = 0; $i <= $#address_list; $i++) {
chomp($address_list[$i]);
if ($i > 0) {
$address .= ',';
}
$address .= $address_list[$i];
}
2011-06-28 10:10:31 +02:00
}
else {
2011-06-28 11:47:10 +02:00
$address = $Conf{'address'};
2011-06-28 10:10:31 +02:00
}
}
2012-01-03 18:18:45 +01:00
# Clear the XML
$Xml = "";
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
2012-11-15 16:53:45 +01:00
# Custom fields
my @customfieldskeys = keys(%Customfields);
if ($#customfieldskeys > -1) {
$Xml .= "<custom_fields>\n";
foreach my $customfieldkey (@customfieldskeys) {
if($customfieldkey =~ m/^(custom_field\d+_)name/) {
if(defined($Customfields{$1."value"})) {
$Xml .= " <field>\n";
$Xml .= " <name><![CDATA[". $Customfields{$1."name"} ."]]></name>\n";
$Xml .= " <value><![CDATA[". $Customfields{$1."value"} ."]]></value>\n";
$Xml .= " </field>\n";
}
}
}
$Xml .= "</custom_fields>\n";
}
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
# Execute modules
foreach my $module (@Modules) {
2010-09-17 15:03:24 +02:00
# Execute the module in a separate thread
if (defined ($ThreadSem) && $Conf{'agent_threads'} > 1) {
$ThreadSem->down ();
2013-11-12 13:28:28 +01:00
my $thr = threads->create (\&exec_module, $module);
2010-09-17 15:03:24 +02:00
if (! defined ($thr)) {
$ThreadSem->up ();
} else {
2011-02-10 12:00:16 +01:00
$thr->detach();
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
}
2010-09-17 15:03:24 +02:00
# Execute the module
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
} else {
2013-11-12 13:28:28 +01:00
exec_module($module);
2010-09-17 15:03:24 +02:00
}
}
2009-11-19 01:34:27 +01:00
2010-09-17 15:03:24 +02:00
# Wait for all the threads
2011-02-10 12:00:16 +01:00
$ThreadSem->down ($Conf{'agent_threads'}) if (defined ($ThreadSem) && $Conf{'agent_threads'} > 1);
$ThreadSem->up ($Conf{'agent_threads'}) if (defined ($ThreadSem) && $Conf{'agent_threads'} > 1);
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
2012-01-03 18:18:45 +01:00
if ($Xml ne "" || $Conf{'timestamp'} + $Conf{'interval'} <= time ()) {
# Update the time reference
$Conf{'timestamp'} = time () if ($Conf{'timestamp'} + $Conf{'interval'} <= time ());
# Compose the XML
my $xml_header = "<?xml version='1.0' encoding='" . $Conf{'encoding'} . "'?>\n" .
"<agent_data description='" . $Conf{'description'} ."' group='" . $Conf{'group'} .
"' os_name='$OS' os_version='$OS_VERSION' interval='" . $Conf{'interval'} .
"' version='" . AGENT_VERSION . '(Build ' . AGENT_BUILD . ')' . ($Conf{'autotime'} eq '1' ? '' : "' timestamp='" . strftime ('%Y/%m/%d %H:%M:%S', localtime ())) .
2012-11-15 16:53:45 +01:00
"' agent_name='" . $Conf{'agent_name'} . "' timezone_offset='". $Conf{'timezone_offset'} .
"' custom_id='" . $Conf{'custom_id'} . "' url_address='". $Conf{'url_address'};
2012-01-03 18:18:45 +01:00
if (defined ($Conf{'address'})) {
$xml_header .= "' address='" .$address;
}
if (defined ($Conf{'parent_agent_name'})) {
$xml_header .= "' parent_agent_name='" .$Conf{'parent_agent_name'};
}
# Check the gis mode (exec or manual). If exec script is defined, we execute it and get the coordenates
if (defined ($Conf{'gis_exec'}) && (-e $Conf{'gis_exec'})) {
my $coord_str = `$Conf{'gis_exec'}`;
chomp($coord_str);
my @coords = split(',',$coord_str);
# Check if lat and long are numeric
if (defined($coords[0]) && defined($coords[1]) && ($coords[0] =~ /^-?(\d+)\.(\d+)$|^-?(\d+)$/) && ($coords[1] =~ /^-?(\d+)\.(\d+)$|^-?(\d+)$/)) {
my $lat = $coords[0];
my $long = $coords[1];
$xml_header .= "' longitude='" .$long . "' latitude='" .$lat;
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
2012-01-03 18:18:45 +01:00
if (defined ($coords[2])) {
my $alt = $coords[2];
$xml_header .= "' altitude='" .$alt;
}
if (defined ($Conf{'position_description'})) {
$xml_header .= "' position_description='" .$Conf{'position_description'};
}
}
}
elsif (defined ($Conf{'longitude'}) && defined ($Conf{'latitude'})) {
$xml_header .= "' longitude='" .$Conf{'longitude'} . "' latitude='" .$Conf{'latitude'};
if (defined ($Conf{'altitude'})) {
$xml_header .= "' altitude='" .$Conf{'altitude'};
}
if (defined ($Conf{'position_description'})) {
$xml_header .= "' position_description='" .$Conf{'position_description'};
}
}
$xml_header .= "'>\n";
$Xml = $xml_header . $Xml . "</agent_data>";
# Save XML data file
my $temp_file = $Conf{'temporal'} . '/' . $Conf{'agent_name'} . '.' . time () . '.data';
2012-03-01 11:38:10 +01:00
error ("File '$temp_file' already exists as a symlink and could not be removed: $!") if (-l $temp_file && !unlink($temp_file));
2012-01-03 18:18:45 +01:00
open (TEMP_FILE, "> $temp_file") || error ("Could not write XML data file: $!");
print TEMP_FILE $Xml;
close (TEMP_FILE);
# Debug mode
if ($Conf{'debug'} eq '1') {
log_message ('debug', "Wrote XML data file '$temp_file'");
log_message ('debug', "Wrote XML data file '$temp_file'", *STDOUT);
last;
}
# Send the XML data file
2012-02-28 16:48:26 +01:00
my $rc = send_file ($temp_file, 1);
if ($rc == 0 || $Conf{'xml_buffer'} == 0 || temporal_freedisk () < $Conf{'temporal_min_size'}) {
unlink ($temp_file);
}
2012-01-03 18:18:45 +01:00
2012-02-28 16:48:26 +01:00
# Send buffered XML data files
if ($Conf{'xml_buffer'} == 1) {
send_buffered_xml_files ();
}
2012-01-03 18:18:45 +01:00
}
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
2010-11-15 11:32:23 +01:00
# Enable signal capture to break the Sleep interval on UDP signal
2012-01-03 18:18:45 +01:00
if ($Conf{'udp_server'} == 1) {
2010-11-15 11:32:23 +01:00
$SIG{'INT'} = \&udp_server_signal;
}
2010-10-08 11:58:18 +02:00
2011-11-15 14:33:16 +01:00
# Sleep if main agent
if ($main_agent != 0) {
2011-12-19 16:40:22 +01:00
foreach my $broker_pid (@BrokerPid) {
waitpid ($broker_pid, 0);
}
2012-01-03 18:18:45 +01:00
# Cron mode
last if ($Conf{'cron_mode'} == 1);
2013-04-03 13:52:44 +02:00
$iter_base_time += $Conf{'intensive_interval'};
my $now = time();
my $interval_remain = $iter_base_time - $now;
if ($interval_remain >= 0) {
sleep ($interval_remain);
} else {
# don't sleep if iteraion took more than "intensive_interval" seconds
$iter_base_time = $now; # use current time as base time
}
2011-11-15 14:33:16 +01:00
}
# Finish if broker agent
else {
2011-12-19 12:26:05 +01:00
exit (0);
2011-11-15 14:33:16 +01:00
}
2009-09-14 Ramon Novoa <rnovoa@artica.es>
* unix, unix/pandora_agent_installer,
unix/plugins, unix/pandora_agent,
unix/pandora_agent_daemon, unix/AUTHORS,
unix/pandora_agent.conf, unix/COPYING,
unix/pandora_agent.spec, unix/tentacle_client,
unix/README: Added to repository. Generic Pandora FMS Unix agent
written in PERL. The skeleton files where copied from the linux
subdirectory.
git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1940 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
2009-09-14 17:57:00 +02:00
}
2010-02-22 20:32:10 +01:00
__END__
=head1 EXIT STATUS
=over
=item 0 on Success
=item 1 on Error
=back
=head1 CONFIGURATION
By default pandora_agent uses F</etc/pandora> as B<home configuration directory>. There is the F<pandora_agent.conf> file with all the configuration of the agent.
=head1 DEPENDENCIES
=head1 LICENSE
This is released under the GNU Lesser General Public License.
=head1 SEE ALSO
=head1 COPYRIGHT
Copyright (c) 2005-2010 Artica Soluciones Tecnologicas S.L
=cut