506 lines
15 KiB
C
506 lines
15 KiB
C
/*****************************************************************************
|
|
*
|
|
* STATUSDATA.C - External status data for Nagios CGIs
|
|
*
|
|
*
|
|
* License:
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
/*********** COMMON HEADER FILES ***********/
|
|
|
|
#include "../include/config.h"
|
|
#include "../include/common.h"
|
|
#include "../include/objects.h"
|
|
#include "../include/statusdata.h"
|
|
#include "../xdata/xsddefault.h" /* default routines */
|
|
|
|
#ifdef NSCGI
|
|
#include "../include/cgiutils.h"
|
|
#else
|
|
#include "../include/nagios.h"
|
|
#include "../include/broker.h"
|
|
#endif
|
|
|
|
|
|
#ifdef NSCGI
|
|
hoststatus *hoststatus_list = NULL;
|
|
hoststatus *hoststatus_list_tail = NULL;
|
|
servicestatus *servicestatus_list = NULL;
|
|
servicestatus *servicestatus_list_tail = NULL;
|
|
|
|
hoststatus **hoststatus_hashlist = NULL;
|
|
servicestatus **servicestatus_hashlist = NULL;
|
|
|
|
extern int use_pending_states;
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef NSCORE
|
|
|
|
/******************************************************************/
|
|
/****************** TOP-LEVEL OUTPUT FUNCTIONS ********************/
|
|
/******************************************************************/
|
|
|
|
/* initializes status data at program start */
|
|
int initialize_status_data(const char *cfgfile) {
|
|
return xsddefault_initialize_status_data(cfgfile);
|
|
}
|
|
|
|
|
|
/* update all status data (aggregated dump) */
|
|
int update_all_status_data(void) {
|
|
int result = OK;
|
|
|
|
#ifdef USE_EVENT_BROKER
|
|
/* send data to event broker */
|
|
broker_aggregated_status_data(NEBTYPE_AGGREGATEDSTATUS_STARTDUMP, NEBFLAG_NONE, NEBATTR_NONE, NULL);
|
|
#endif
|
|
|
|
result = xsddefault_save_status_data();
|
|
|
|
#ifdef USE_EVENT_BROKER
|
|
/* send data to event broker */
|
|
broker_aggregated_status_data(NEBTYPE_AGGREGATEDSTATUS_ENDDUMP, NEBFLAG_NONE, NEBATTR_NONE, NULL);
|
|
#endif
|
|
return result;
|
|
}
|
|
|
|
|
|
/* cleans up status data before program termination */
|
|
int cleanup_status_data(int delete_status_data) {
|
|
return xsddefault_cleanup_status_data(delete_status_data);
|
|
}
|
|
|
|
|
|
|
|
/* updates program status info */
|
|
int update_program_status(int aggregated_dump) {
|
|
|
|
#ifdef USE_EVENT_BROKER
|
|
/* send data to event broker (non-aggregated dumps only) */
|
|
if(aggregated_dump == FALSE)
|
|
broker_program_status(NEBTYPE_PROGRAMSTATUS_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, NULL);
|
|
#endif
|
|
|
|
return OK;
|
|
}
|
|
|
|
|
|
|
|
/* updates host status info */
|
|
int update_host_status(host *hst, int aggregated_dump) {
|
|
|
|
#ifdef USE_EVENT_BROKER
|
|
/* send data to event broker (non-aggregated dumps only) */
|
|
if(aggregated_dump == FALSE)
|
|
broker_host_status(NEBTYPE_HOSTSTATUS_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, hst, NULL);
|
|
#endif
|
|
|
|
return OK;
|
|
}
|
|
|
|
|
|
|
|
/* updates service status info */
|
|
int update_service_status(service *svc, int aggregated_dump) {
|
|
|
|
#ifdef USE_EVENT_BROKER
|
|
/* send data to event broker (non-aggregated dumps only) */
|
|
if(aggregated_dump == FALSE)
|
|
broker_service_status(NEBTYPE_SERVICESTATUS_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, svc, NULL);
|
|
#endif
|
|
|
|
return OK;
|
|
}
|
|
|
|
|
|
|
|
/* updates contact status info */
|
|
int update_contact_status(contact *cntct, int aggregated_dump) {
|
|
|
|
#ifdef USE_EVENT_BROKER
|
|
/* send data to event broker (non-aggregated dumps only) */
|
|
if(aggregated_dump == FALSE)
|
|
broker_contact_status(NEBTYPE_CONTACTSTATUS_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, cntct, NULL);
|
|
#endif
|
|
|
|
return OK;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef NSCGI
|
|
|
|
/******************************************************************/
|
|
/******************* TOP-LEVEL INPUT FUNCTIONS ********************/
|
|
/******************************************************************/
|
|
|
|
|
|
/* reads in all status data */
|
|
int read_status_data(const char *status_file_name, int options) {
|
|
return xsddefault_read_status_data(status_file_name, options);
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************/
|
|
/****************** CHAINED HASH FUNCTIONS ************************/
|
|
/******************************************************************/
|
|
|
|
/* adds hoststatus to hash list in memory */
|
|
int add_hoststatus_to_hashlist(hoststatus *new_hoststatus) {
|
|
hoststatus *temp_hoststatus = NULL;
|
|
hoststatus *lastpointer = NULL;
|
|
int hashslot = 0;
|
|
int i = 0;
|
|
|
|
/* initialize hash list */
|
|
if(hoststatus_hashlist == NULL) {
|
|
|
|
hoststatus_hashlist = (hoststatus **)malloc(sizeof(hoststatus *) * HOSTSTATUS_HASHSLOTS);
|
|
if(hoststatus_hashlist == NULL)
|
|
return 0;
|
|
|
|
for(i = 0; i < HOSTSTATUS_HASHSLOTS; i++)
|
|
hoststatus_hashlist[i] = NULL;
|
|
}
|
|
|
|
if(!new_hoststatus)
|
|
return 0;
|
|
|
|
hashslot = hashfunc(new_hoststatus->host_name, NULL, HOSTSTATUS_HASHSLOTS);
|
|
lastpointer = NULL;
|
|
for(temp_hoststatus = hoststatus_hashlist[hashslot]; temp_hoststatus && compare_hashdata(temp_hoststatus->host_name, NULL, new_hoststatus->host_name, NULL) < 0; temp_hoststatus = temp_hoststatus->nexthash)
|
|
lastpointer = temp_hoststatus;
|
|
|
|
if(!temp_hoststatus || (compare_hashdata(temp_hoststatus->host_name, NULL, new_hoststatus->host_name, NULL) != 0)) {
|
|
if(lastpointer)
|
|
lastpointer->nexthash = new_hoststatus;
|
|
else
|
|
hoststatus_hashlist[hashslot] = new_hoststatus;
|
|
new_hoststatus->nexthash = temp_hoststatus;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* else already exists */
|
|
return 0;
|
|
}
|
|
|
|
|
|
int add_servicestatus_to_hashlist(servicestatus *new_servicestatus) {
|
|
servicestatus *temp_servicestatus = NULL, *lastpointer = NULL;
|
|
int hashslot = 0;
|
|
int i = 0;
|
|
|
|
/* initialize hash list */
|
|
if(servicestatus_hashlist == NULL) {
|
|
|
|
servicestatus_hashlist = (servicestatus **)malloc(sizeof(servicestatus *) * SERVICESTATUS_HASHSLOTS);
|
|
if(servicestatus_hashlist == NULL)
|
|
return 0;
|
|
|
|
for(i = 0; i < SERVICESTATUS_HASHSLOTS; i++)
|
|
servicestatus_hashlist[i] = NULL;
|
|
}
|
|
|
|
if(!new_servicestatus)
|
|
return 0;
|
|
|
|
hashslot = hashfunc(new_servicestatus->host_name, new_servicestatus->description, SERVICESTATUS_HASHSLOTS);
|
|
lastpointer = NULL;
|
|
for(temp_servicestatus = servicestatus_hashlist[hashslot]; temp_servicestatus && compare_hashdata(temp_servicestatus->host_name, temp_servicestatus->description, new_servicestatus->host_name, new_servicestatus->description) < 0; temp_servicestatus = temp_servicestatus->nexthash)
|
|
lastpointer = temp_servicestatus;
|
|
|
|
if(!temp_servicestatus || (compare_hashdata(temp_servicestatus->host_name, temp_servicestatus->description, new_servicestatus->host_name, new_servicestatus->description) != 0)) {
|
|
if(lastpointer)
|
|
lastpointer->nexthash = new_servicestatus;
|
|
else
|
|
servicestatus_hashlist[hashslot] = new_servicestatus;
|
|
new_servicestatus->nexthash = temp_servicestatus;
|
|
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* else already exists */
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************/
|
|
/********************** ADDITION FUNCTIONS ************************/
|
|
/******************************************************************/
|
|
|
|
|
|
/* adds a host status entry to the list in memory */
|
|
int add_host_status(hoststatus *new_hoststatus) {
|
|
char date_string[MAX_DATETIME_LENGTH];
|
|
|
|
/* make sure we have what we need */
|
|
if(new_hoststatus == NULL)
|
|
return ERROR;
|
|
if(new_hoststatus->host_name == NULL)
|
|
return ERROR;
|
|
|
|
/* massage host status a bit */
|
|
if(new_hoststatus != NULL) {
|
|
switch(new_hoststatus->status) {
|
|
case 0:
|
|
new_hoststatus->status = SD_HOST_UP;
|
|
break;
|
|
case 1:
|
|
new_hoststatus->status = SD_HOST_DOWN;
|
|
break;
|
|
case 2:
|
|
new_hoststatus->status = SD_HOST_UNREACHABLE;
|
|
break;
|
|
default:
|
|
new_hoststatus->status = SD_HOST_UP;
|
|
break;
|
|
}
|
|
if(new_hoststatus->has_been_checked == FALSE) {
|
|
if(use_pending_states == TRUE)
|
|
new_hoststatus->status = HOST_PENDING;
|
|
my_free(new_hoststatus->plugin_output);
|
|
if(new_hoststatus->should_be_scheduled == TRUE) {
|
|
get_time_string(&new_hoststatus->next_check, date_string, sizeof(date_string), LONG_DATE_TIME);
|
|
asprintf(&new_hoststatus->plugin_output, "Host check scheduled for %s", date_string);
|
|
}
|
|
else {
|
|
/* passive-only hosts that have just been scheduled for a forced check */
|
|
if(new_hoststatus->checks_enabled == FALSE && new_hoststatus->next_check != (time_t)0L && (new_hoststatus->check_options & CHECK_OPTION_FORCE_EXECUTION)) {
|
|
get_time_string(&new_hoststatus->next_check, date_string, sizeof(date_string), LONG_DATE_TIME);
|
|
asprintf(&new_hoststatus->plugin_output, "Forced host check scheduled for %s", date_string);
|
|
}
|
|
/* passive-only hosts not scheduled to be checked */
|
|
else
|
|
new_hoststatus->plugin_output = (char *)strdup("Host is not scheduled to be checked...");
|
|
}
|
|
}
|
|
}
|
|
|
|
new_hoststatus->next = NULL;
|
|
new_hoststatus->nexthash = NULL;
|
|
|
|
/* add new hoststatus to hoststatus chained hash list */
|
|
if(!add_hoststatus_to_hashlist(new_hoststatus))
|
|
return ERROR;
|
|
|
|
/* object cache file is already sorted, so just add new items to end of list */
|
|
if(hoststatus_list == NULL) {
|
|
hoststatus_list = new_hoststatus;
|
|
hoststatus_list_tail = new_hoststatus;
|
|
}
|
|
else {
|
|
hoststatus_list_tail->next = new_hoststatus;
|
|
hoststatus_list_tail = new_hoststatus;
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
|
|
/* adds a service status entry to the list in memory */
|
|
int add_service_status(servicestatus *new_svcstatus) {
|
|
char date_string[MAX_DATETIME_LENGTH];
|
|
|
|
/* make sure we have what we need */
|
|
if(new_svcstatus == NULL)
|
|
return ERROR;
|
|
if(new_svcstatus->host_name == NULL || new_svcstatus->description == NULL)
|
|
return ERROR;
|
|
|
|
|
|
/* massage service status a bit */
|
|
if(new_svcstatus != NULL) {
|
|
switch(new_svcstatus->status) {
|
|
case 0:
|
|
new_svcstatus->status = SERVICE_OK;
|
|
break;
|
|
case 1:
|
|
new_svcstatus->status = SERVICE_WARNING;
|
|
break;
|
|
case 2:
|
|
new_svcstatus->status = SERVICE_CRITICAL;
|
|
break;
|
|
case 3:
|
|
new_svcstatus->status = SERVICE_UNKNOWN;
|
|
break;
|
|
default:
|
|
new_svcstatus->status = SERVICE_OK;
|
|
break;
|
|
}
|
|
if(new_svcstatus->has_been_checked == FALSE) {
|
|
if(use_pending_states == TRUE)
|
|
new_svcstatus->status = SERVICE_PENDING;
|
|
my_free(new_svcstatus->plugin_output);
|
|
if(new_svcstatus->should_be_scheduled == TRUE) {
|
|
get_time_string(&new_svcstatus->next_check, date_string, sizeof(date_string), LONG_DATE_TIME);
|
|
asprintf(&new_svcstatus->plugin_output, "Service check scheduled for %s", date_string);
|
|
}
|
|
else {
|
|
/* passive-only services that have just been scheduled for a forced check */
|
|
if(new_svcstatus->checks_enabled == FALSE && new_svcstatus->next_check != (time_t)0L && (new_svcstatus->check_options & CHECK_OPTION_FORCE_EXECUTION)) {
|
|
get_time_string(&new_svcstatus->next_check, date_string, sizeof(date_string), LONG_DATE_TIME);
|
|
asprintf(&new_svcstatus->plugin_output, "Forced service check scheduled for %s", date_string);
|
|
}
|
|
/* passive-only services not scheduled to be checked */
|
|
else
|
|
new_svcstatus->plugin_output = (char *)strdup("Service is not scheduled to be checked...");
|
|
}
|
|
}
|
|
}
|
|
|
|
new_svcstatus->next = NULL;
|
|
new_svcstatus->nexthash = NULL;
|
|
|
|
/* add new servicestatus to servicestatus chained hash list */
|
|
if(!add_servicestatus_to_hashlist(new_svcstatus))
|
|
return ERROR;
|
|
|
|
/* object cache file is already sorted, so just add new items to end of list */
|
|
if(servicestatus_list == NULL) {
|
|
servicestatus_list = new_svcstatus;
|
|
servicestatus_list_tail = new_svcstatus;
|
|
}
|
|
else {
|
|
servicestatus_list_tail->next = new_svcstatus;
|
|
servicestatus_list_tail = new_svcstatus;
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************/
|
|
/*********************** CLEANUP FUNCTIONS ************************/
|
|
/******************************************************************/
|
|
|
|
|
|
/* free all memory for status data */
|
|
void free_status_data(void) {
|
|
hoststatus *this_hoststatus = NULL;
|
|
hoststatus *next_hoststatus = NULL;
|
|
servicestatus *this_svcstatus = NULL;
|
|
servicestatus *next_svcstatus = NULL;
|
|
|
|
/* free memory for the host status list */
|
|
for(this_hoststatus = hoststatus_list; this_hoststatus != NULL; this_hoststatus = next_hoststatus) {
|
|
next_hoststatus = this_hoststatus->next;
|
|
my_free(this_hoststatus->host_name);
|
|
my_free(this_hoststatus->plugin_output);
|
|
my_free(this_hoststatus->long_plugin_output);
|
|
my_free(this_hoststatus->perf_data);
|
|
my_free(this_hoststatus);
|
|
}
|
|
|
|
/* free memory for the service status list */
|
|
for(this_svcstatus = servicestatus_list; this_svcstatus != NULL; this_svcstatus = next_svcstatus) {
|
|
next_svcstatus = this_svcstatus->next;
|
|
my_free(this_svcstatus->host_name);
|
|
my_free(this_svcstatus->description);
|
|
my_free(this_svcstatus->plugin_output);
|
|
my_free(this_svcstatus->long_plugin_output);
|
|
my_free(this_svcstatus->perf_data);
|
|
my_free(this_svcstatus);
|
|
}
|
|
|
|
/* free hash lists reset list pointers */
|
|
my_free(hoststatus_hashlist);
|
|
my_free(servicestatus_hashlist);
|
|
hoststatus_list = NULL;
|
|
servicestatus_list = NULL;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************/
|
|
/************************ SEARCH FUNCTIONS ************************/
|
|
/******************************************************************/
|
|
|
|
|
|
/* find a host status entry */
|
|
hoststatus *find_hoststatus(char *host_name) {
|
|
hoststatus *temp_hoststatus = NULL;
|
|
|
|
if(host_name == NULL || hoststatus_hashlist == NULL)
|
|
return NULL;
|
|
|
|
for(temp_hoststatus = hoststatus_hashlist[hashfunc(host_name, NULL, HOSTSTATUS_HASHSLOTS)]; temp_hoststatus && compare_hashdata(temp_hoststatus->host_name, NULL, host_name, NULL) < 0; temp_hoststatus = temp_hoststatus->nexthash);
|
|
|
|
if(temp_hoststatus && (compare_hashdata(temp_hoststatus->host_name, NULL, host_name, NULL) == 0))
|
|
return temp_hoststatus;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/* find a service status entry */
|
|
servicestatus *find_servicestatus(char *host_name, char *svc_desc) {
|
|
servicestatus *temp_servicestatus = NULL;
|
|
|
|
if(host_name == NULL || svc_desc == NULL || servicestatus_hashlist == NULL)
|
|
return NULL;
|
|
|
|
for(temp_servicestatus = servicestatus_hashlist[hashfunc(host_name, svc_desc, SERVICESTATUS_HASHSLOTS)]; temp_servicestatus && compare_hashdata(temp_servicestatus->host_name, temp_servicestatus->description, host_name, svc_desc) < 0; temp_servicestatus = temp_servicestatus->nexthash);
|
|
|
|
if(temp_servicestatus && (compare_hashdata(temp_servicestatus->host_name, temp_servicestatus->description, host_name, svc_desc) == 0))
|
|
return temp_servicestatus;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************/
|
|
/*********************** UTILITY FUNCTIONS ************************/
|
|
/******************************************************************/
|
|
|
|
|
|
/* gets the total number of services of a certain state for a specific host */
|
|
int get_servicestatus_count(char *host_name, int type) {
|
|
servicestatus *temp_status = NULL;
|
|
int count = 0;
|
|
|
|
if(host_name == NULL)
|
|
return 0;
|
|
|
|
for(temp_status = servicestatus_list; temp_status != NULL; temp_status = temp_status->next) {
|
|
if(temp_status->status & type) {
|
|
if(!strcmp(host_name, temp_status->host_name))
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
#endif
|