1798 lines
45 KiB
C++
1798 lines
45 KiB
C++
/* Defines a parent class for a Pandora module.
|
|
|
|
Copyright (C) 2006 Artica ST.
|
|
Written by Esteban Sanchez.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
with this program; if not, write to the Free Software Foundation,
|
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include "pandora_module.h"
|
|
#include "../pandora_strutils.h"
|
|
#include "../pandora.h"
|
|
|
|
#include <iostream>
|
|
#include <sstream>
|
|
|
|
#define BUFSIZE 4096
|
|
|
|
using namespace Pandora;
|
|
using namespace Pandora_Modules;
|
|
using namespace Pandora_Strutils;
|
|
|
|
/**
|
|
* Creates a Pandora_Module.
|
|
*
|
|
* Initializes all attributes. The default interval is set to 1 loop.
|
|
*
|
|
* @param name Module name.
|
|
*/
|
|
Pandora_Module::Pandora_Module (string name) {
|
|
this->module_name = name;
|
|
this->executions = 0;
|
|
this->module_interval = 1;
|
|
this->module_timeout = 15000;
|
|
this->max = 0;
|
|
this->min = 0;
|
|
this->post_process = "";
|
|
this->has_limits = false;
|
|
this->has_min = false;
|
|
this->has_max = false;
|
|
this->async = false;
|
|
this->data_list = NULL;
|
|
this->inventory_list = NULL;
|
|
this->precondition_list = NULL;
|
|
this->condition_list = NULL;
|
|
this->cron = NULL;
|
|
this->min_critical = "";
|
|
this->max_critical = "";
|
|
this->min_warning = "";
|
|
this->max_warning = "";
|
|
this->disabled = "";
|
|
this->min_ff_event = "";
|
|
this->intensive_condition_list = NULL;
|
|
this->intensive_interval = 1;
|
|
this->timestamp = 0;
|
|
this->intensive_match = 0;
|
|
this->unit = "";
|
|
this->module_group = "";
|
|
this->custom_id = "";
|
|
this->str_warning = "";
|
|
this->str_critical = "";
|
|
this->critical_instructions = "";
|
|
this->warning_instructions = "";
|
|
this->unknown_instructions = "";
|
|
this->tags = "";
|
|
this->critical_inverse = "";
|
|
this->warning_inverse = "";
|
|
this->quiet = "";
|
|
this->module_ff_interval = "";
|
|
this->module_alert_template = "";
|
|
this->module_crontab = "";
|
|
}
|
|
|
|
/**
|
|
* Virtual destructor of Pandora_Module.
|
|
*
|
|
* Should be redefined by child classes.
|
|
*/
|
|
Pandora_Module::~Pandora_Module () {
|
|
Condition *cond = NULL;
|
|
Condition *precond = NULL;
|
|
list<Condition *>::iterator iter;
|
|
list<Condition *>::iterator iter_pre;
|
|
|
|
/* Clean data lists */
|
|
this->cleanDataList ();
|
|
|
|
/* Clean precondition list */
|
|
if (this->precondition_list != NULL && this->precondition_list->size () > 0) {
|
|
iter_pre = this->precondition_list->begin ();
|
|
for (iter_pre = this->precondition_list->begin ();
|
|
iter_pre != this->precondition_list->end ();
|
|
iter_pre++) {
|
|
/* Free regular expressions */
|
|
precond = *iter_pre;
|
|
if (precond->string_value != "") {
|
|
regfree (&(precond->regexp));
|
|
}
|
|
delete (*iter_pre);
|
|
}
|
|
delete (this->precondition_list);
|
|
this->precondition_list = NULL;
|
|
}
|
|
|
|
/* Clean condition list */
|
|
if (this->condition_list != NULL && this->condition_list->size () > 0) {
|
|
iter = this->condition_list->begin ();
|
|
for (iter = this->condition_list->begin ();
|
|
iter != this->condition_list->end ();
|
|
iter++) {
|
|
/* Free regular expressions */
|
|
cond = *iter;
|
|
if (cond->string_value != "") {
|
|
regfree (&(cond->regexp));
|
|
}
|
|
delete (*iter);
|
|
}
|
|
delete (this->condition_list);
|
|
this->condition_list = NULL;
|
|
}
|
|
|
|
/* Clean intensive_condition list */
|
|
if (this->intensive_condition_list != NULL && this->intensive_condition_list->size () > 0) {
|
|
iter = this->intensive_condition_list->begin ();
|
|
for (iter = this->intensive_condition_list->begin ();
|
|
iter != this->intensive_condition_list->end ();
|
|
iter++) {
|
|
/* Free regular expressions */
|
|
cond = *iter;
|
|
if (cond->string_value != "") {
|
|
regfree (&(cond->regexp));
|
|
}
|
|
delete (*iter);
|
|
}
|
|
delete (this->intensive_condition_list);
|
|
this->intensive_condition_list = NULL;
|
|
}
|
|
|
|
/* Clean the module cron */
|
|
if (this->cron != NULL) {
|
|
delete (this->cron);
|
|
this->cron = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
Pandora_Module::cleanDataList () {
|
|
Pandora_Data *data;
|
|
list<Pandora_Data *>::iterator iter;
|
|
|
|
if (this->data_list) {
|
|
if (this->data_list->size () > 0) {
|
|
iter = this->data_list->begin ();
|
|
for (iter = this->data_list->begin ();
|
|
iter != this->data_list->end ();
|
|
iter++) {
|
|
data = *iter;
|
|
delete data;
|
|
}
|
|
}
|
|
delete this->data_list;
|
|
this->data_list = NULL;
|
|
}
|
|
if (this->inventory_list) {
|
|
if (this->inventory_list->size () > 0) {
|
|
iter = this->inventory_list->begin ();
|
|
for (iter = this->inventory_list->begin ();
|
|
iter != this->inventory_list->end ();
|
|
iter++) {
|
|
data = *iter;
|
|
delete data;
|
|
}
|
|
}
|
|
delete this->inventory_list;
|
|
this->inventory_list = NULL;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the Module_Type from a string type.
|
|
*
|
|
* @param type String type.
|
|
*
|
|
* @return The Module_Type which represents the type.
|
|
*/
|
|
Module_Type
|
|
Pandora_Module::parseModuleTypeFromString (string type) {
|
|
if (type == module_generic_data_str || type == "") {
|
|
return TYPE_GENERIC_DATA;
|
|
} else if (type == module_generic_data_inc_str) {
|
|
return TYPE_GENERIC_DATA_INC;
|
|
} else if (type == module_generic_data_string_str) {
|
|
return TYPE_GENERIC_DATA_STRING;
|
|
} else if (type == module_generic_proc_str) {
|
|
return TYPE_GENERIC_PROC;
|
|
} else if (type == module_async_data_str) {
|
|
return TYPE_ASYNC_DATA;
|
|
} else if (type == module_async_proc_str) {
|
|
return TYPE_ASYNC_PROC;
|
|
} else if (type == module_async_string_str) {
|
|
return TYPE_ASYNC_STRING;
|
|
} else if (type == module_log_str) {
|
|
return TYPE_LOG;
|
|
} else if (type == module_generic_data_inc_abs_str) {
|
|
return TYPE_GENERIC_DATA_INC_ABS;
|
|
} else {
|
|
return TYPE_0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the Module_Kind from a string Kind.
|
|
*
|
|
* @param kind String Kind.
|
|
*
|
|
* @return The Module_Kind which represents the Kind.
|
|
*/
|
|
Module_Kind
|
|
Pandora_Module::parseModuleKindFromString (string kind) {
|
|
if (kind == module_exec_str) {
|
|
return MODULE_EXEC;
|
|
} else if (kind == module_proc_str) {
|
|
return MODULE_PROC;
|
|
} else if (kind == module_service_str) {
|
|
return MODULE_SERVICE;
|
|
} else if (kind == module_freedisk_str) {
|
|
return MODULE_FREEDISK;
|
|
} else if (kind == module_freedisk_percent_str) {
|
|
return MODULE_FREEDISK_PERCENT;
|
|
} else if (kind == module_freememory_str) {
|
|
return MODULE_FREEMEMORY;
|
|
} else if (kind == module_freememory_percent_str) {
|
|
return MODULE_FREEMEMORY_PERCENT;
|
|
} else if (kind == module_cpuusage_str) {
|
|
return MODULE_CPUUSAGE;
|
|
} else if (kind == module_inventory_str) {
|
|
return MODULE_INVENTORY;
|
|
} else if (kind == module_logevent_str) {
|
|
return MODULE_LOGEVENT;
|
|
} else if (kind == module_wmiquery_str) {
|
|
return MODULE_WMIQUERY;
|
|
} else if (kind == module_perfcounter_str) {
|
|
return MODULE_PERFCOUNTER;
|
|
} else if (kind == module_tcpcheck_str) {
|
|
return MODULE_TCPCHECK;
|
|
} else if (kind == module_regexp_str) {
|
|
return MODULE_REGEXP;
|
|
} else if (kind == module_plugin_str) {
|
|
return MODULE_PLUGIN;
|
|
} else if (kind == module_ping_str) {
|
|
return MODULE_PING;
|
|
} else if (kind == module_snmpget_str) {
|
|
return MODULE_SNMPGET;
|
|
} else {
|
|
return MODULE_0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the name of the module.
|
|
*
|
|
* @return The name of the module.
|
|
*/
|
|
string
|
|
Pandora_Module::getName () const {
|
|
return this->module_name;
|
|
}
|
|
|
|
/**
|
|
* Get the description of the module.
|
|
*
|
|
* @return The module description.
|
|
*/
|
|
string
|
|
Pandora_Module::getDescription () const {
|
|
return this->module_description;
|
|
}
|
|
|
|
/**
|
|
* Get the module type in a human readable string.
|
|
*
|
|
* @return The module type..
|
|
*/
|
|
string
|
|
Pandora_Module::getTypeString () const {
|
|
return this->module_type_str;
|
|
}
|
|
|
|
/**
|
|
* Get the module type in a integer value.
|
|
*
|
|
* @return The module type in a integer value.
|
|
*/
|
|
Module_Type
|
|
Pandora_Module::getTypeInt () const {
|
|
return this->module_type;
|
|
}
|
|
|
|
/**
|
|
* Get the kind of the module in a integer_value.
|
|
*
|
|
* @return The module kind in a integer value.
|
|
*/
|
|
Module_Kind
|
|
Pandora_Module::getModuleKind () const {
|
|
return this->module_kind;
|
|
}
|
|
|
|
/**
|
|
* Get the output of the module.
|
|
*
|
|
* @return The module output in a string value.
|
|
*/
|
|
string
|
|
Pandora_Module::getLatestOutput () const {
|
|
return this->latest_output;
|
|
}
|
|
|
|
/**
|
|
* Get the type of the module in a integer_value.
|
|
*
|
|
* @return The module type in a integer value.
|
|
*/
|
|
Module_Type
|
|
Pandora_Module::getModuleType () const {
|
|
return this->module_type;
|
|
}
|
|
|
|
/**
|
|
* Get the module output.
|
|
*
|
|
* After running the module, this function will return the output,
|
|
* based on the module_type and the interval.
|
|
*
|
|
* @return The output in a string.
|
|
*
|
|
* @exception Output_Error Throwed if the module_type is not correct.
|
|
* @exception Value_Error Throwed when the output is not in
|
|
* the interval range.
|
|
*/
|
|
string
|
|
Pandora_Module::getDataOutput (Pandora_Data *data) {
|
|
double value;
|
|
|
|
if (this->module_type == TYPE_GENERIC_DATA_STRING ||
|
|
this->module_type == TYPE_ASYNC_STRING || this->module_type == TYPE_LOG) {
|
|
return data->getValue ();
|
|
}
|
|
|
|
try {
|
|
value = Pandora_Strutils::strtodouble (data->getValue ());
|
|
} catch (Pandora_Strutils::Invalid_Conversion e) {
|
|
pandoraLog ("Output error on module %s",
|
|
this->module_name.c_str ());
|
|
throw Output_Error ();
|
|
}
|
|
|
|
if (this->has_limits) {
|
|
if (value > this->max || value < this->min) {
|
|
pandoraLog ("The returned value was not in the interval on module %s",
|
|
this->module_name.c_str ());
|
|
throw Value_Error ();
|
|
}
|
|
}
|
|
|
|
return trim (data->getValue ());
|
|
}
|
|
|
|
/**
|
|
* Export the module output to en environment variable.
|
|
*/
|
|
void
|
|
Pandora_Module::exportDataOutput () {
|
|
Pandora_Data *pandora_data = NULL;
|
|
string putenv_str, module_data;
|
|
|
|
/* putenv expects a string of the form name=value */
|
|
putenv_str = this->save + "=";
|
|
|
|
/* No data */
|
|
if ( (!this->has_output) || this->data_list == NULL) {
|
|
putenv (putenv_str.c_str ());
|
|
return;
|
|
}
|
|
|
|
/* Get the module data */
|
|
pandora_data = data_list->front ();
|
|
if (pandora_data == NULL) {
|
|
putenv (putenv_str.c_str ());
|
|
return;
|
|
}
|
|
module_data = pandora_data->getValue ();
|
|
putenv_str += module_data;
|
|
|
|
/* Save it as an environment variable */
|
|
putenv (putenv_str.c_str ());
|
|
}
|
|
|
|
/**
|
|
* Set the output of the module.
|
|
*
|
|
* If the function is called more than once before calling getXML, the
|
|
* output will be accumulated and added to a <datalist> tag.
|
|
*
|
|
* @param output Output to add.
|
|
*/
|
|
void
|
|
Pandora_Module::setOutput (string output) {
|
|
Pandora_Data *data;
|
|
|
|
if (this->data_list == NULL)
|
|
this->data_list = new list<Pandora_Data *> ();
|
|
data = new Pandora_Data (output, this->module_name);
|
|
this->data_list->push_back (data);
|
|
this->latest_output = output;
|
|
}
|
|
|
|
|
|
/**
|
|
* Set the output of the module.
|
|
*
|
|
* If the function is called more than once before calling getXML, the
|
|
* output will be accumulated and added to a <datalist> tag.
|
|
*
|
|
* @param output Output to add.
|
|
* @param system_time Timestamp.
|
|
*/
|
|
void
|
|
Pandora_Module::setOutput (string output, SYSTEMTIME *system_time) {
|
|
Pandora_Data *data;
|
|
|
|
if (this->data_list == NULL)
|
|
this->data_list = new list<Pandora_Data *> ();
|
|
data = new Pandora_Data (output, system_time, this->module_name);
|
|
this->data_list->push_back (data);
|
|
}
|
|
|
|
/**
|
|
* Set no output for the module.
|
|
*/
|
|
void
|
|
Pandora_Module::setNoOutput () {
|
|
this->cleanDataList ();
|
|
this->has_output = false;
|
|
}
|
|
|
|
/**
|
|
* Run the module and generates the output.
|
|
*
|
|
* It is used by the child classes to check the execution interval
|
|
* value and increment the executions variable.
|
|
*
|
|
* @exception Interval_Not_Fulfilled Throwed when the execution
|
|
* interval value indicates that the module doesn't have
|
|
* to execute.
|
|
*/
|
|
void
|
|
Pandora_Module::run () {
|
|
/* Check the interval */
|
|
if (this->executions % this->intensive_interval != 0) {
|
|
pandoraDebug ("%s: Interval is not fulfilled", this->module_name.c_str ());
|
|
this->executions++;
|
|
has_output = false;
|
|
throw Interval_Not_Fulfilled ();
|
|
}
|
|
|
|
/* Increment the executions after check. This is done to execute the
|
|
first time */
|
|
this->executions++;
|
|
has_output = true;
|
|
}
|
|
|
|
/**
|
|
* Get the XML output of the value.
|
|
*
|
|
* The output is a element of the TinyXML library. A sample output of
|
|
* a module is:
|
|
* @verbatim
|
|
<module>
|
|
<name>Conexiones abiertas</name>
|
|
<type>generic_data</type>
|
|
<data>5</data>
|
|
<description>Conexiones abiertas</description>
|
|
</module>
|
|
@endverbatim
|
|
*
|
|
* @return A pointer to the TiXmlElement if successful which has to be
|
|
* freed by the caller. NULL if the XML could not be created.
|
|
*/
|
|
string
|
|
Pandora_Module::getXml () {
|
|
ostringstream module_interval, min, max;
|
|
string module_xml, data_clean, interval_str;
|
|
Pandora_Data *data;
|
|
|
|
pandoraDebug ("%s getXML begin", module_name.c_str ());
|
|
|
|
/* No data */
|
|
if (!this->has_output || this->data_list == NULL) {
|
|
return "";
|
|
}
|
|
|
|
/* Log module */
|
|
if (this->module_type == TYPE_LOG) {
|
|
module_xml = "<log_module>\n\t<source><![CDATA[";
|
|
module_xml += this->module_name;
|
|
module_xml += "]]></source>\n\t<data><![CDATA[";
|
|
|
|
if (this->data_list && this->data_list->size () > 1) {
|
|
list<Pandora_Data *>::iterator iter;
|
|
|
|
iter = this->data_list->begin ();
|
|
for (iter = this->data_list->begin ();
|
|
iter != this->data_list->end ();
|
|
iter++) {
|
|
data = *iter;
|
|
|
|
try {
|
|
data_clean = strreplace (this->getDataOutput (data),
|
|
"%", "%%" );
|
|
} catch (Module_Exception e) {
|
|
continue;
|
|
}
|
|
|
|
module_xml += data_clean;
|
|
}
|
|
} else {
|
|
data = data_list->front ();
|
|
try {
|
|
data_clean = strreplace (this->getDataOutput (data), "%", "%%" );
|
|
module_xml += data_clean;
|
|
|
|
} catch (Module_Exception e) {
|
|
}
|
|
}
|
|
module_xml += "]]></data></log_module>";
|
|
|
|
/* Clean up */
|
|
this->cleanDataList ();
|
|
|
|
pandoraDebug ("%s getXML end", module_name.c_str ());
|
|
return module_xml;
|
|
}
|
|
|
|
/* Compose the module XML */
|
|
module_xml = "<module>\n\t<name><![CDATA[";
|
|
module_xml += this->module_name;
|
|
module_xml += "]]></name>\n\t<type><![CDATA[";
|
|
module_xml += this->module_type_str;
|
|
module_xml += "]]></type>\n";
|
|
|
|
/* Description */
|
|
if (this->module_description != "") {
|
|
module_xml += "\t<description><![CDATA[";
|
|
module_xml += this->module_description;
|
|
module_xml += "]]></description>\n";
|
|
}
|
|
|
|
/* Interval */
|
|
module_interval << this->module_interval;
|
|
module_xml += "\t<module_interval><![CDATA[";
|
|
module_xml += module_interval.str ();
|
|
module_xml += "]]></module_interval>\n";
|
|
|
|
/* Min */
|
|
if (this->has_min) {
|
|
min << this->min;
|
|
module_xml += "\t<min><![CDATA[";
|
|
module_xml += min.str ();
|
|
module_xml += "]]></min>\n";
|
|
}
|
|
|
|
/* Max */
|
|
if (this->has_max) {
|
|
max << this->max;
|
|
module_xml += "\t<max><![CDATA[";
|
|
module_xml += max.str ();
|
|
module_xml += "]]></max>\n";
|
|
}
|
|
|
|
/* Post process */
|
|
if (this->post_process != "") {
|
|
module_xml += "\t<post_process><![CDATA[";
|
|
module_xml += this->post_process;
|
|
module_xml += "]]></post_process>\n";
|
|
}
|
|
|
|
/* Min critical */
|
|
if (this->min_critical != "") {
|
|
module_xml += "\t<min_critical><![CDATA[";
|
|
module_xml += this->min_critical;
|
|
module_xml += "]]></min_critical>\n";
|
|
}
|
|
|
|
/* Max critical */
|
|
if (this->max_critical != "") {
|
|
module_xml += "\t<max_critical><![CDATA[";
|
|
module_xml += this->max_critical;
|
|
module_xml += "]]></max_critical>\n";
|
|
}
|
|
|
|
/* Min warning */
|
|
if (this->min_warning != "") {
|
|
module_xml += "\t<min_warning><![CDATA[";
|
|
module_xml += this->min_warning;
|
|
module_xml += "]]></min_warning>\n";
|
|
}
|
|
|
|
/* Max warning */
|
|
if (this->max_warning != "") {
|
|
module_xml += "\t<max_warning><![CDATA[";
|
|
module_xml += this->max_warning;
|
|
module_xml += "]]></max_warning>\n";
|
|
}
|
|
|
|
/* Disabled */
|
|
if (this->disabled != "") {
|
|
module_xml += "\t<disabled><![CDATA[";
|
|
module_xml += this->disabled;
|
|
module_xml += "]]></disabled>\n";
|
|
}
|
|
|
|
/* Min ff event */
|
|
if (this->min_ff_event != "") {
|
|
module_xml += "\t<min_ff_event><![CDATA[";
|
|
module_xml += this->min_ff_event;
|
|
module_xml += "]]></min_ff_event>\n";
|
|
}
|
|
|
|
/* Unit */
|
|
if (this->unit != "") {
|
|
module_xml += "\t<unit><![CDATA[";
|
|
module_xml += this->unit;
|
|
module_xml += "]]></unit>\n";
|
|
}
|
|
|
|
/* Module group */
|
|
if (this->module_group != "") {
|
|
module_xml += "\t<module_group>";
|
|
module_xml += this->module_group;
|
|
module_xml += "</module_group>\n";
|
|
}
|
|
|
|
/* Custom ID */
|
|
if (this->custom_id != "") {
|
|
module_xml += "\t<custom_id>";
|
|
module_xml += this->custom_id;
|
|
module_xml += "</custom_id>\n";
|
|
}
|
|
|
|
/* Str warning */
|
|
if (this->str_warning != "") {
|
|
module_xml += "\t<str_warning>";
|
|
module_xml += this->str_warning;
|
|
module_xml += "</str_warning>\n";
|
|
}
|
|
|
|
/* Str critical */
|
|
if (this->str_critical != "") {
|
|
module_xml += "\t<str_critical>";
|
|
module_xml += this->str_critical;
|
|
module_xml += "</str_critical>\n";
|
|
}
|
|
|
|
/* Critical instructions */
|
|
if (this->critical_instructions != "") {
|
|
module_xml += "\t<critical_instructions>";
|
|
module_xml += this->critical_instructions;
|
|
module_xml += "</critical_instructions>\n";
|
|
}
|
|
|
|
/* Warning instructions */
|
|
if (this->warning_instructions != "") {
|
|
module_xml += "\t<warning_instructions>";
|
|
module_xml += this->warning_instructions;
|
|
module_xml += "</warning_instructions>\n";
|
|
}
|
|
|
|
/* Unknown instructions */
|
|
if (this->unknown_instructions != "") {
|
|
module_xml += "\t<unknown_instructions>";
|
|
module_xml += this->unknown_instructions;
|
|
module_xml += "</unknown_instructions>\n";
|
|
}
|
|
|
|
/* Tags */
|
|
if (this->tags != "") {
|
|
module_xml += "\t<tags>";
|
|
module_xml += this->tags;
|
|
module_xml += "</tags>\n";
|
|
}
|
|
|
|
/* Critical inverse */
|
|
if (this->critical_inverse != "") {
|
|
module_xml += "\t<critical_inverse>";
|
|
module_xml += this->critical_inverse;
|
|
module_xml += "</critical_inverse>\n";
|
|
}
|
|
|
|
/* Warning inverse */
|
|
if (this->warning_inverse != "") {
|
|
module_xml += "\t<warning_inverse>";
|
|
module_xml += this->warning_inverse;
|
|
module_xml += "</warning_inverse>\n";
|
|
}
|
|
|
|
/* Quiet */
|
|
if (this->quiet != "") {
|
|
module_xml += "\t<quiet>";
|
|
module_xml += this->quiet;
|
|
module_xml += "</quiet>\n";
|
|
}
|
|
|
|
/* Module FF interval */
|
|
if (this->module_ff_interval != "") {
|
|
module_xml += "\t<module_ff_interval>";
|
|
module_xml += this->module_ff_interval;
|
|
module_xml += "</module_ff_interval>\n";
|
|
}
|
|
|
|
/* Module Alert template */
|
|
if (this->module_alert_template != "") {
|
|
module_xml += "\t<alert_template>";
|
|
module_xml += this->module_alert_template;
|
|
module_xml += "</alert_template>\n";
|
|
}
|
|
|
|
/* Module Crontab */
|
|
if (this->module_crontab != "") {
|
|
module_xml += "\t<crontab>";
|
|
module_xml += this->module_crontab;
|
|
module_xml += "</crontab>\n";
|
|
}
|
|
|
|
/* Write module data */
|
|
if (this->data_list && this->data_list->size () > 1) {
|
|
list<Pandora_Data *>::iterator iter;
|
|
|
|
module_xml += "\t<datalist>\n";
|
|
|
|
iter = this->data_list->begin ();
|
|
for (iter = this->data_list->begin ();
|
|
iter != this->data_list->end ();
|
|
iter++) {
|
|
data = *iter;
|
|
|
|
try {
|
|
data_clean = strreplace (this->getDataOutput (data),
|
|
"%", "%%" );
|
|
} catch (Module_Exception e) {
|
|
continue;
|
|
}
|
|
|
|
module_xml += "\t\t<data>\n\t\t\t<value><![CDATA[";
|
|
module_xml += data_clean;
|
|
module_xml += "]]></value>\n\t\t\t<timestamp><![CDATA[";
|
|
module_xml += data->getTimestamp ();
|
|
module_xml += "]]></timestamp>\n\t\t</data>\n";
|
|
}
|
|
|
|
module_xml += "\t</datalist>\n";
|
|
} else {
|
|
data = data_list->front ();
|
|
try {
|
|
data_clean = strreplace (this->getDataOutput (data), "%", "%%" );
|
|
module_xml += "\t<data><![CDATA[";
|
|
module_xml += data_clean;
|
|
module_xml += "]]></data>\n";
|
|
} catch (Module_Exception e) {
|
|
}
|
|
}
|
|
|
|
/* Close the module tag */
|
|
module_xml += "</module>\n";
|
|
|
|
/* Clean up */
|
|
this->cleanDataList ();
|
|
|
|
pandoraDebug ("%s getXML end", module_name.c_str ());
|
|
return module_xml;
|
|
}
|
|
|
|
/**
|
|
* Set the max value the module can have.
|
|
*
|
|
* The range is closed, so the value is included.
|
|
*
|
|
* @param value Max value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setMax (int value) {
|
|
this->has_limits = true;
|
|
this->has_max = true;
|
|
this->max = value;
|
|
}
|
|
|
|
/**
|
|
* Set the min value the module can have.
|
|
*
|
|
* The range is closed, so the value is included.
|
|
*
|
|
* @param value Min value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setMin (int value) {
|
|
this->has_limits = true;
|
|
this->has_min = true;
|
|
this->min = value;
|
|
}
|
|
|
|
/**
|
|
* Set the post process value for the module.
|
|
*
|
|
* @param value Post process value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setPostProcess (string value) {
|
|
this->post_process = value;
|
|
}
|
|
|
|
/**
|
|
* Set the min critical value for the module.
|
|
*
|
|
* @param value Min critical value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setMinCritical (string value) {
|
|
this->min_critical = value;
|
|
}
|
|
|
|
/**
|
|
* Set the max critical value for the module.
|
|
*
|
|
* @param value Max critical value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setMaxCritical (string value) {
|
|
this->max_critical = value;
|
|
}
|
|
|
|
/**
|
|
* Set the min warning value for the module.
|
|
*
|
|
* @param value Min warning value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setMinWarning (string value) {
|
|
this->min_warning = value;
|
|
}
|
|
|
|
/**
|
|
* Set the max warning value for the module.
|
|
*
|
|
* @param value Max warning value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setMaxWarning (string value) {
|
|
this->max_warning = value;
|
|
}
|
|
|
|
/**
|
|
* Set the disabled value for the module.
|
|
*
|
|
* @param value Disabled value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setDisabled (string value) {
|
|
this->disabled = value;
|
|
}
|
|
|
|
/**
|
|
* Set the min ff event value for the module.
|
|
*
|
|
* @param value Min ff event value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setMinFFEvent (string value) {
|
|
this->min_ff_event = value;
|
|
}
|
|
|
|
/**
|
|
* Set the unit value for the module.
|
|
*
|
|
* @param value unit value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setUnit (string value) {
|
|
this->unit = value;
|
|
}
|
|
|
|
/**
|
|
* Set the module group for the module.
|
|
*
|
|
* @param value module group value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setModuleGroup (string value) {
|
|
this->module_group = value;
|
|
}
|
|
|
|
/**
|
|
* Set the custom id for the module.
|
|
*
|
|
* @param value custom id value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setCustomId (string value) {
|
|
this->custom_id = value;
|
|
}
|
|
|
|
/**
|
|
* Set the str warning for the module.
|
|
*
|
|
* @param value str warning value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setStrWarning (string value) {
|
|
this->str_warning = value;
|
|
}
|
|
|
|
/**
|
|
* Set the str critical for the module.
|
|
*
|
|
* @param value str critical value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setStrCritical (string value) {
|
|
this->str_critical = value;
|
|
}
|
|
|
|
/**
|
|
* Set the critical instructions for the module.
|
|
*
|
|
* @param value critical instructions value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setCriticalInstructions (string value) {
|
|
this->critical_instructions = value;
|
|
}
|
|
|
|
/**
|
|
* Set the warning instructions for the module.
|
|
*
|
|
* @param value warning instructions value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setWarningInstructions (string value) {
|
|
this->warning_instructions = value;
|
|
}
|
|
|
|
/**
|
|
* Set the unknown instructions for the module.
|
|
*
|
|
* @param value unknown instructions value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setUnknownInstructions (string value) {
|
|
this->unknown_instructions = value;
|
|
}
|
|
|
|
/**
|
|
* Set the tags for the module.
|
|
*
|
|
* @param value tags value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setTags (string value) {
|
|
this->tags = value;
|
|
}
|
|
|
|
/**
|
|
* Set the critical inverse for the module.
|
|
*
|
|
* @param value critical inverse value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setCriticalInverse (string value) {
|
|
this->critical_inverse = value;
|
|
}
|
|
|
|
/**
|
|
* Set the warning inverse for the module.
|
|
*
|
|
* @param value warning inverse value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setWarningInverse (string value) {
|
|
this->warning_inverse = value;
|
|
}
|
|
|
|
/**
|
|
* Set the quiet for the module.
|
|
*
|
|
* @param value quiet value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setQuiet (string value) {
|
|
this->quiet = value;
|
|
}
|
|
|
|
/**
|
|
* Set the module FF interval for the module.
|
|
*
|
|
* @param value module FF interval value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setModuleFFInterval (string value) {
|
|
this->module_ff_interval = value;
|
|
}
|
|
|
|
/**
|
|
* Set the module Alert template for the module.
|
|
*
|
|
* @param value module Alert template value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setModuleAlertTemplate (string value) {
|
|
this->module_alert_template = value;
|
|
}
|
|
|
|
/**
|
|
* Set the module Crontab for the module.
|
|
*
|
|
* @param value module Crontab value to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setModuleCrontab (string value) {
|
|
this->module_crontab = value;
|
|
}
|
|
|
|
/**
|
|
* Set the async flag to the module.
|
|
*
|
|
* If a module is set to be async, it would try to works only when the
|
|
* events happen. Note that not all the modules can work in async mode.
|
|
*
|
|
* @param async Flag to set.
|
|
*/
|
|
void
|
|
Pandora_Module::setAsync (bool async) {
|
|
this->async = async;
|
|
}
|
|
|
|
/**
|
|
* Set the module type from a string type.
|
|
*
|
|
* @param type String type.
|
|
*/
|
|
void
|
|
Pandora_Module::setType (string type) {
|
|
this->module_type_str = type;
|
|
this->module_type = parseModuleTypeFromString (type);
|
|
}
|
|
|
|
/**
|
|
* Set the module kind from a string kind.
|
|
*
|
|
* @param kind String kind.
|
|
*/
|
|
void
|
|
Pandora_Module::setKind (string kind) {
|
|
this->module_kind_str = kind;
|
|
this->module_kind = parseModuleKindFromString (kind);
|
|
}
|
|
|
|
/**
|
|
* Set the interval execution.
|
|
*
|
|
* @param interval Interval between executions.
|
|
*/
|
|
void
|
|
Pandora_Module::setInterval (int interval) {
|
|
this->module_interval = interval;
|
|
}
|
|
|
|
/**
|
|
* Set the intensive interval.
|
|
*
|
|
* @param intensive_interval Intensive interval.
|
|
*/
|
|
void
|
|
Pandora_Module::setIntensiveInterval (int intensive_interval) {
|
|
this->intensive_interval = intensive_interval;
|
|
}
|
|
|
|
/**
|
|
* Set the execution timeout.
|
|
*
|
|
* @param timeout Execution timeout.
|
|
*/
|
|
void
|
|
Pandora_Module::setTimeout (int timeout) {
|
|
|
|
if (timeout < 0) {
|
|
return;
|
|
}
|
|
|
|
/* WaitForSingleObject expects milliseconds */
|
|
this->module_timeout = timeout * 1000;
|
|
}
|
|
|
|
/**
|
|
* Get the execution interval.
|
|
*
|
|
* @return The execution interval.
|
|
*/
|
|
int
|
|
Pandora_Module::getInterval () {
|
|
return this->module_interval;
|
|
}
|
|
|
|
/**
|
|
* Get the intensive interval.
|
|
*
|
|
* @return The intensive interval.
|
|
*/
|
|
int
|
|
Pandora_Module::getIntensiveInterval () {
|
|
return this->intensive_interval;
|
|
}
|
|
|
|
/**
|
|
* Get the execution timeout.
|
|
*
|
|
* @return The execution timeout.
|
|
*/
|
|
int
|
|
Pandora_Module::getTimeout () {
|
|
return this->module_timeout;
|
|
}
|
|
|
|
/**
|
|
* Set the module description.
|
|
*
|
|
* @param description Description of the module.
|
|
*/
|
|
void
|
|
Pandora_Module::setDescription (string description) {
|
|
this->module_description = description;
|
|
}
|
|
|
|
/**
|
|
* Set the name of the environment variable where the module data will be saved.
|
|
*
|
|
* @param save Name of the environment variable.
|
|
*/
|
|
void
|
|
Pandora_Module::setSave (string save) {
|
|
this->save = save;
|
|
}
|
|
|
|
/**
|
|
* Get the name of the environment variable where the module data will be saved.
|
|
*
|
|
* @return The name of the environment variable.
|
|
*/
|
|
string
|
|
Pandora_Module::getSave () {
|
|
return this->save;
|
|
}
|
|
|
|
/**
|
|
* Adds a new condition to a condition list.
|
|
*
|
|
* @param condition Condition string.
|
|
* @param condition_list Pointer to the condition list.
|
|
*/
|
|
void
|
|
Pandora_Module::addGenericCondition (string condition, list<Condition *> **condition_list) {
|
|
Condition *cond;
|
|
char operation[256], string_value[1024], command[1024];
|
|
|
|
/* Create the condition list if it does not exist */
|
|
if (*condition_list == NULL) {
|
|
*condition_list = new list<Condition *> ();
|
|
}
|
|
|
|
/* Create the new condition */
|
|
cond = new Condition;
|
|
if (cond == NULL) {
|
|
return;
|
|
}
|
|
cond->value_1 = 0;
|
|
cond->value_2 = 0;
|
|
|
|
/* Numeric comparison */
|
|
if (sscanf (condition.c_str (), "%255s %lf %1023[^\n]s", operation, &(cond->value_1), command) == 3) {
|
|
cond->operation = operation;
|
|
cond->command = command;
|
|
cond->command = command;
|
|
cond->command = "cmd.exe /c \"" + cond->command + "\"";
|
|
(*condition_list)->push_back (cond);
|
|
/* Regular expression */
|
|
} else if (sscanf (condition.c_str (), "=~ %1023s %1023[^\n]s", string_value, command) == 2) {
|
|
cond->operation = "=~";
|
|
cond->string_value = string_value;
|
|
cond->command = command;
|
|
cond->command = "cmd.exe /c \"" + cond->command + "\"";
|
|
if (regcomp (&(cond->regexp), string_value, REG_EXTENDED) != 0) {
|
|
pandoraDebug ("Invalid regular expression %s", string_value);
|
|
delete (cond);
|
|
return;
|
|
}
|
|
(*condition_list)->push_back (cond);
|
|
/* Interval */
|
|
} else if (sscanf (condition.c_str (), "(%lf , %lf) %1023[^\n]s", &(cond->value_1), &(cond->value_2), command) == 3) {
|
|
cond->operation = "()";
|
|
cond->command = command;
|
|
cond->command = "cmd.exe /c \"" + cond->command + "\"";
|
|
(*condition_list)->push_back (cond);
|
|
} else {
|
|
pandoraLog ("Invalid condition: %s", condition.c_str ());
|
|
delete (cond);
|
|
return;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* Adds a new module condition.
|
|
*
|
|
* @param condition Condition string.
|
|
*/
|
|
void
|
|
Pandora_Module::addCondition (string condition) {
|
|
addGenericCondition (condition, &(this->condition_list));
|
|
}
|
|
|
|
/**
|
|
* Adds a new module pre-condition.
|
|
*
|
|
* @param condition Condition string.
|
|
*/
|
|
void
|
|
Pandora_Module::addPreCondition (string condition) {
|
|
addGenericCondition (condition, &(this->precondition_list));
|
|
}
|
|
|
|
/**
|
|
* Adds a new module intensive condition.
|
|
*
|
|
* @param condition Condition string.
|
|
*/
|
|
void
|
|
Pandora_Module::addIntensiveCondition (string condition) {
|
|
Condition *cond;
|
|
char operation[256], string_value[1024], command[1024];
|
|
|
|
/* Create the condition list if it does not exist */
|
|
if (this->intensive_condition_list == NULL) {
|
|
this->intensive_condition_list = new list<Condition *> ();
|
|
}
|
|
|
|
/* Create the new condition */
|
|
cond = new Condition;
|
|
if (cond == NULL) {
|
|
return;
|
|
}
|
|
cond->value_1 = 0;
|
|
cond->value_2 = 0;
|
|
|
|
/* Numeric comparison */
|
|
if (sscanf (condition.c_str (), "%255s %lf", operation, &(cond->value_1)) == 2) {
|
|
cond->operation = operation;
|
|
(this->intensive_condition_list)->push_back (cond);
|
|
/* Regular expression */
|
|
} else if (sscanf (condition.c_str (), "=~ %1023s", string_value) == 1) {
|
|
cond->operation = "=~";
|
|
cond->string_value = string_value;
|
|
if (regcomp (&(cond->regexp), string_value, REG_EXTENDED) != 0) {
|
|
pandoraDebug ("Invalid regular expression %s", string_value);
|
|
delete (cond);
|
|
return;
|
|
}
|
|
(this->intensive_condition_list)->push_back (cond);
|
|
/* Interval */
|
|
} else if (sscanf (condition.c_str (), "(%lf , %lf)", &(cond->value_1), &(cond->value_2)) == 2) {
|
|
cond->operation = "()";
|
|
(this->intensive_condition_list)->push_back (cond);
|
|
} else {
|
|
pandoraDebug ("Invalid intensive condition: %s", condition.c_str ());
|
|
delete (cond);
|
|
return;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Evaluates and executes module preconditions.
|
|
*/
|
|
int
|
|
Pandora_Module::evaluatePreconditions () {
|
|
STARTUPINFO si;
|
|
PROCESS_INFORMATION pi;
|
|
DWORD retval, dwRet;
|
|
SECURITY_ATTRIBUTES attributes;
|
|
HANDLE out, new_stdout, out_read, job;
|
|
string working_dir;
|
|
Condition *precond = NULL;
|
|
double double_output;
|
|
list<Condition *>::iterator iter;
|
|
unsigned char run;
|
|
string output;
|
|
|
|
if (this->precondition_list != NULL && this->precondition_list->size () > 0) {
|
|
|
|
iter = this->precondition_list->begin ();
|
|
for (iter = this->precondition_list->begin ();
|
|
iter != this->precondition_list->end ();
|
|
iter++) {
|
|
|
|
precond = *iter;
|
|
run = 0;
|
|
|
|
|
|
/* Set the bInheritHandle flag so pipe handles are inherited. */
|
|
attributes.nLength = sizeof (SECURITY_ATTRIBUTES);
|
|
attributes.bInheritHandle = TRUE;
|
|
attributes.lpSecurityDescriptor = NULL;
|
|
|
|
/* Create a job to kill the child tree if it become zombie */
|
|
/* CAUTION: In order to compile this, WINVER should be defined to 0x0500.
|
|
This may need no change, since it was redefined by the
|
|
program, but if needed, the macro is defined
|
|
in <windef.h> */
|
|
job = CreateJobObject (&attributes, this->module_name.c_str ());
|
|
if (job == NULL) {
|
|
pandoraLog ("evaluatePreconditions: CreateJobObject failed. Err: %d", GetLastError ());
|
|
return 0;
|
|
}
|
|
|
|
/* Get the handle to the current STDOUT. */
|
|
out = GetStdHandle (STD_OUTPUT_HANDLE);
|
|
|
|
if (! CreatePipe (&out_read, &new_stdout, &attributes, 0)) {
|
|
pandoraLog ("evaluatePreconditions: CreatePipe failed. Err: %d", GetLastError ());
|
|
return 0;
|
|
}
|
|
|
|
/* Ensure the read handle to the pipe for STDOUT is not inherited */
|
|
SetHandleInformation (out_read, HANDLE_FLAG_INHERIT, 0);
|
|
|
|
/* Set up members of the STARTUPINFO structure. */
|
|
ZeroMemory (&si, sizeof (si));
|
|
GetStartupInfo (&si);
|
|
|
|
si.cb = sizeof (si);
|
|
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
|
|
si.wShowWindow = SW_HIDE;
|
|
si.hStdError = new_stdout;
|
|
si.hStdOutput = new_stdout;
|
|
|
|
/* Set up members of the PROCESS_INFORMATION structure. */
|
|
ZeroMemory (&pi, sizeof (pi));
|
|
pandoraDebug ("Executing pre-condition: %s", precond->command.c_str ());
|
|
|
|
/* Set the working directory of the process. It's "utils" directory
|
|
to find the GNU W32 tools */
|
|
working_dir = getPandoraInstallDir () + "util\\";
|
|
|
|
/* Create the child process. */
|
|
if (! CreateProcess (NULL, (CHAR *) precond->command.c_str (), NULL,
|
|
NULL, TRUE, CREATE_SUSPENDED | CREATE_NO_WINDOW, NULL,
|
|
working_dir.c_str (), &si, &pi)) {
|
|
pandoraLog ("evaluatePreconditions: %s CreateProcess failed. Err: %d",
|
|
this->module_name.c_str (), GetLastError ());
|
|
} else {
|
|
char buffer[BUFSIZE + 1];
|
|
unsigned long read, avail;
|
|
|
|
if (! AssignProcessToJobObject (job, pi.hProcess)) {
|
|
pandoraLog ("evaluatePreconditions: could not assign proccess to job (error %d)",
|
|
GetLastError ());
|
|
}
|
|
ResumeThread (pi.hThread);
|
|
|
|
/*string output;*/
|
|
output = "";
|
|
int tickbase = GetTickCount();
|
|
while ( (dwRet = WaitForSingleObject (pi.hProcess, 500)) != WAIT_ABANDONED ) {
|
|
PeekNamedPipe (out_read, buffer, BUFSIZE, &read, &avail, NULL);
|
|
if (avail > 0) {
|
|
ReadFile (out_read, buffer, BUFSIZE, &read, NULL);
|
|
buffer[read] = '\0';
|
|
output += (char *) buffer;
|
|
}
|
|
|
|
try {
|
|
double_output = Pandora_Strutils::strtodouble (output);
|
|
} catch (Pandora_Strutils::Invalid_Conversion e) {
|
|
double_output = 0;
|
|
}
|
|
|
|
if (dwRet == WAIT_OBJECT_0) {
|
|
break;
|
|
} else if(this->getTimeout() < GetTickCount() - tickbase) {
|
|
/* STILL_ACTIVE */
|
|
TerminateProcess(pi.hThread, STILL_ACTIVE);
|
|
pandoraLog ("evaluatePreconditions: %s timed out (retcode: %d)", this->module_name.c_str (), STILL_ACTIVE);
|
|
break;
|
|
}
|
|
}
|
|
|
|
GetExitCodeProcess (pi.hProcess, &retval);
|
|
|
|
if (retval != 0) {
|
|
if (! TerminateJobObject (job, 0)) {
|
|
pandoraLog ("evaluatePreconditions: TerminateJobObject failed. (error %d)",
|
|
GetLastError ());
|
|
}
|
|
if (retval != STILL_ACTIVE) {
|
|
pandoraLog ("evaluatePreconditions: %s did not executed well (retcode: %d)",
|
|
this->module_name.c_str (), retval);
|
|
}
|
|
/* Close job, process and thread handles. */
|
|
CloseHandle (job);
|
|
CloseHandle (pi.hProcess);
|
|
CloseHandle (pi.hThread);
|
|
CloseHandle (new_stdout);
|
|
CloseHandle (out_read);
|
|
return 0;
|
|
}
|
|
|
|
/* Close job, process and thread handles. */
|
|
CloseHandle (job);
|
|
CloseHandle (pi.hProcess);
|
|
CloseHandle (pi.hThread);
|
|
}
|
|
|
|
CloseHandle (new_stdout);
|
|
CloseHandle (out_read);
|
|
|
|
if (evaluateCondition (output, double_output, precond) == 0) {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* Evaluates and executes module conditions.
|
|
*/
|
|
void
|
|
Pandora_Module::evaluateConditions () {
|
|
unsigned char run;
|
|
double double_value;
|
|
string string_value;
|
|
Condition *cond = NULL;
|
|
list<Condition *>::iterator iter;
|
|
PROCESS_INFORMATION pi;
|
|
STARTUPINFO si;
|
|
Pandora_Data *pandora_data = NULL;
|
|
regex_t regex;
|
|
|
|
/* No data */
|
|
if ( (!this->has_output) || this->data_list == NULL) {
|
|
return;
|
|
}
|
|
|
|
/* Get the module data */
|
|
pandora_data = data_list->front ();
|
|
|
|
/* Get the string value of the data */
|
|
string_value = pandora_data->getValue ();
|
|
|
|
/* Get the double value of the data */
|
|
try {
|
|
double_value = Pandora_Strutils::strtodouble (string_value);
|
|
} catch (Pandora_Strutils::Invalid_Conversion e) {
|
|
double_value = 0;
|
|
}
|
|
|
|
if (this->condition_list != NULL && this->condition_list->size () > 0) {
|
|
iter = this->condition_list->begin ();
|
|
for (iter = this->condition_list->begin ();
|
|
iter != this->condition_list->end ();
|
|
iter++) {
|
|
cond = *iter;
|
|
run = 0;
|
|
|
|
if (evaluateCondition (string_value, double_value, cond) == 1) {
|
|
/* Run the condition command */
|
|
ZeroMemory (&si, sizeof (si));
|
|
ZeroMemory (&pi, sizeof (pi));
|
|
if (CreateProcess (NULL , (CHAR *)cond->command.c_str (), NULL, NULL, FALSE,
|
|
CREATE_NO_WINDOW, NULL, NULL, &si, &pi) == 0) {
|
|
return;
|
|
}
|
|
WaitForSingleObject(pi.hProcess, this->module_timeout);
|
|
CloseHandle (pi.hProcess);
|
|
CloseHandle (pi.hThread);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Evaluates and executes intensive module conditions.
|
|
*/
|
|
int
|
|
Pandora_Module::evaluateIntensiveConditions () {
|
|
double double_value;
|
|
string string_value;
|
|
Condition *cond = NULL;
|
|
list<Condition *>::iterator iter;
|
|
PROCESS_INFORMATION pi;
|
|
STARTUPINFO si;
|
|
Pandora_Data *pandora_data = NULL;
|
|
regex_t regex;
|
|
|
|
/* Not an intensive module */
|
|
if (this->intensive_condition_list == NULL || this->intensive_condition_list->size () <= 0) {
|
|
return 1;
|
|
}
|
|
|
|
/* No data */
|
|
if ( (!this->has_output) || this->data_list == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
/* Get the module data */
|
|
pandora_data = data_list->front ();
|
|
|
|
/* Get the string value of the data */
|
|
string_value = pandora_data->getValue ();
|
|
|
|
/* Get the double value of the data */
|
|
try {
|
|
double_value = Pandora_Strutils::strtodouble (string_value);
|
|
} catch (Pandora_Strutils::Invalid_Conversion e) {
|
|
double_value = 0;
|
|
}
|
|
|
|
iter = this->intensive_condition_list->begin ();
|
|
for (iter = this->intensive_condition_list->begin ();
|
|
iter != this->intensive_condition_list->end ();
|
|
iter++) {
|
|
cond = *iter;
|
|
if (evaluateCondition (string_value, double_value, cond) == 0) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* Checks the module cron. Returns 1 if the module should run, 0 if not.
|
|
*
|
|
* @return 1 if the module should run, 0 if not.
|
|
*/
|
|
int
|
|
Pandora_Module::checkCron (int module_interval, int agent_interval) {
|
|
int i, time_params[5];
|
|
time_t current_time, offset;
|
|
struct tm *time_struct;
|
|
Cron *cron = this->cron;
|
|
|
|
// No cron
|
|
if (cron == NULL) {
|
|
return 1;
|
|
}
|
|
|
|
// Get current time
|
|
current_time = time (NULL);
|
|
|
|
// Check if the module was already executed
|
|
if (current_time <= cron->utimestamp) {
|
|
return 0;
|
|
}
|
|
|
|
// Break current time
|
|
time_struct = localtime(¤t_time);
|
|
if (time_struct == NULL) {
|
|
return 1;
|
|
}
|
|
|
|
time_params[0] = time_struct->tm_min;
|
|
time_params[1] = time_struct->tm_hour;
|
|
time_params[2] = time_struct->tm_mday;
|
|
time_params[3] = time_struct->tm_mon;
|
|
time_params[4] = time_struct->tm_wday;
|
|
|
|
// Fix month (localtime retuns 0..11 and we need 1..12)
|
|
time_params[3] += 1;
|
|
|
|
// Check cron parameters
|
|
for (i = 0; i < 5; i++) {
|
|
|
|
// Wildcard
|
|
if (cron->params[i][0] < 0) {
|
|
continue;
|
|
}
|
|
|
|
// Check if next execution will overflow the cron (only minutes overflow)
|
|
// If overflow, execute the module
|
|
bool overflow_cron = false;
|
|
if (i == 0) {
|
|
int start_cron_seconds = cron->params[i][0]*60;
|
|
int current_exec_seconds = time_params[i]*60;
|
|
int next_exec_seconds = time_params[i]*60 + module_interval*agent_interval;
|
|
if (current_exec_seconds > start_cron_seconds && current_exec_seconds > next_exec_seconds) {
|
|
start_cron_seconds += 3600;
|
|
}
|
|
if ((current_exec_seconds <= start_cron_seconds) && (start_cron_seconds <= next_exec_seconds)) {
|
|
overflow_cron = true;
|
|
}
|
|
}
|
|
|
|
// Check interval
|
|
if (cron->params[i][0] <= cron->params[i][1]) {
|
|
if ((time_params[i] < cron->params[i][0] || time_params[i] > cron->params[i][1]) && !overflow_cron) {
|
|
return 0;
|
|
}
|
|
} else {
|
|
if ((time_params[i] < cron->params[i][0] && time_params[i] > cron->params[i][1]) && !overflow_cron) {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Do not check in the next minute, hour, day or month.
|
|
offset = 0;
|
|
if (cron->interval >= 0) {
|
|
offset = cron->interval;
|
|
} else if(cron->params[0][0] >= 0) {
|
|
// 1 minute
|
|
offset = 60;
|
|
} else if(cron->params[1][0] >= 0) {
|
|
// 1 hour
|
|
offset = 3600;
|
|
} else if(cron->params[2][0] >=0 || cron->params[4][0] >= 0) {
|
|
// 1 day
|
|
offset = 86400;
|
|
} else if(cron->params[3][0] >= 0) {
|
|
// 31 days
|
|
offset = 2678400;
|
|
}
|
|
|
|
cron->utimestamp = current_time + offset;
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* Sets the module cron from a string.
|
|
*
|
|
* @return 1 if the module should run, 0 if not.
|
|
*/
|
|
void
|
|
Pandora_Module::setCron (string cron_string) {
|
|
int i, value;
|
|
char cron_params[5][256], bottom[256], top[256];
|
|
|
|
/* Create the new cron if necessary */
|
|
if (this->cron == NULL) {
|
|
this->cron = new Cron ();
|
|
}
|
|
|
|
/* Parse the cron string */
|
|
if (sscanf (cron_string.c_str (), "%255s %255s %255s %255s %255s", cron_params[0], cron_params[1], cron_params[2], cron_params[3], cron_params[4]) != 5) {
|
|
pandoraDebug ("Invalid cron string: %s", cron_string.c_str ());
|
|
return;
|
|
}
|
|
|
|
/* Fill the cron structure */
|
|
this->cron->utimestamp = 0;
|
|
this->cron->interval = -1;
|
|
for (i = 0; i < 5; i++) {
|
|
|
|
/* Wildcard */
|
|
if (cron_params[i][0] == '*') {
|
|
this->cron->params[i][0] = -1;
|
|
|
|
/* Interval */
|
|
} else if (sscanf (cron_params[i], "%255[^-]-%255s", bottom, top) == 2) {
|
|
value = atoi (bottom);
|
|
this->cron->params[i][0] = value;
|
|
value = atoi (top);
|
|
this->cron->params[i][1] = value;
|
|
|
|
/* Single value */
|
|
} else {
|
|
value = atoi (cron_params[i]);
|
|
this->cron->params[i][0] = value;
|
|
this->cron->params[i][1] = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the interval of the module cron.
|
|
*
|
|
* @param interval Module cron interval in seconds.
|
|
*/
|
|
void
|
|
Pandora_Module::setCronInterval (int interval) {
|
|
if (this->cron == NULL) {
|
|
this->cron = new Cron ();
|
|
}
|
|
|
|
this->cron->interval = interval;
|
|
}
|
|
|
|
/**
|
|
* Evaluate a single condition. Returns 1 if the condition matches, 0
|
|
* otherwise.
|
|
*
|
|
* @param string_value String value.
|
|
* @param double_value Double value.
|
|
* @param condition Pointer to the condition.
|
|
*/
|
|
int Pandora_Module::evaluateCondition (string string_value, double double_value, Condition *condition) {
|
|
if ((condition->operation == ">" && double_value > condition->value_1) ||
|
|
(condition->operation == "<" && double_value < condition->value_1) ||
|
|
(condition->operation == "=" && double_value == condition->value_1) ||
|
|
(condition->operation == "!=" && double_value != condition->value_1) ||
|
|
(condition->operation == "=~" && regexec (&(condition->regexp), string_value.c_str(), 0, NULL, 0) == 0) ||
|
|
(condition->operation == "()" && double_value > condition->value_1 && double_value < condition->value_2)) {
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Checks if a module has data.
|
|
*
|
|
* @return 1 if the module has data, 0 otherwise.
|
|
*/
|
|
int Pandora_Module::hasOutput () {
|
|
if (this->has_output == 1) {
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Sets the module timestamp.
|
|
*
|
|
* @param timestamp Module timestamp in seconds.
|
|
*/
|
|
void
|
|
Pandora_Module::setTimestamp (time_t timestamp) {
|
|
this->timestamp = timestamp;
|
|
}
|
|
|
|
/**
|
|
* Gets the module timestamp.
|
|
*
|
|
* @return Module timestamp in seconds.
|
|
*/
|
|
time_t
|
|
Pandora_Module::getTimestamp () {
|
|
return this->timestamp;
|
|
}
|
|
|
|
/**
|
|
* Sets the value of intensive_match.
|
|
*
|
|
* @param intensive_match 0 or 1.
|
|
*/
|
|
void
|
|
Pandora_Module::setIntensiveMatch (unsigned char intensive_match) {
|
|
this->intensive_match = intensive_match;
|
|
}
|
|
|
|
/**
|
|
* Gets the value of intensive_match.
|
|
*
|
|
* @return The value of intensive match.
|
|
*/
|
|
unsigned char
|
|
Pandora_Module::getIntensiveMatch () {
|
|
return this->intensive_match;
|
|
}
|
|
|
|
bool
|
|
Pandora_Module::getAsync () {
|
|
return this->async;
|
|
}
|
|
|
|
|