Logo Search packages:      
Sourcecode: nagios2 version File versions  Download package

statusdata.c

/*****************************************************************************
 *
 * STATUSDATA.C - External status data for Nagios CGIs
 *
 * Copyright (c) 2000-2005 Ethan Galstad (nagios@nagios.org)
 * Last Modified:   07-25-2005
 *
 * 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"

#ifdef NSCORE
#include "../include/nagios.h"
#include "../include/broker.h"
#endif
#ifdef NSCGI
#include "../include/cgiutils.h"
#endif

/**** IMPLEMENTATION SPECIFIC HEADER FILES ****/

#ifdef USE_XSDDEFAULT
#include "../xdata/xsddefault.h"          /* default routines */
#endif


#ifdef NSCORE
extern int      aggregate_status_updates;
#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;
#endif



#ifdef NSCORE

/******************************************************************/
/****************** TOP-LEVEL OUTPUT FUNCTIONS ********************/
/******************************************************************/

/* initializes status data at program start */
int initialize_status_data(char *config_file){
      int result=OK;

      /**** IMPLEMENTATION-SPECIFIC CALLS ****/
#ifdef USE_XSDDEFAULT
      result=xsddefault_initialize_status_data(config_file);
#endif

      return result;
        }


/* update all status data (aggregated dump) */
int update_all_status_data(void){
      int result;

#ifdef USE_EVENT_BROKER
      /* send data to event broker */
      broker_aggregated_status_data(NEBTYPE_AGGREGATEDSTATUS_STARTDUMP,NEBFLAG_NONE,NEBATTR_NONE,NULL);
#endif

      /**** IMPLEMENTATION-SPECIFIC CALLS ****/
#ifdef USE_XSDDEFAULT
      result=xsddefault_save_status_data();
#endif

#ifdef USE_EVENT_BROKER
      /* send data to event broker */
      broker_aggregated_status_data(NEBTYPE_AGGREGATEDSTATUS_ENDDUMP,NEBFLAG_NONE,NEBATTR_NONE,NULL);
#endif

      if(result!=OK)
            return ERROR;

      return OK;
        }


/* cleans up status data before program termination */
int cleanup_status_data(char *config_file,int delete_status_data){
      int result=OK;

      /**** IMPLEMENTATION-SPECIFIC CALLS ****/
#ifdef USE_XSDDEFAULT
      result=xsddefault_cleanup_status_data(config_file,delete_status_data);
#endif

      return result;
        }



/* 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

      /* currently a noop if aggregated updates is TRUE */

      /* update all status data if we're not aggregating updates */
      if(aggregate_status_updates==FALSE)
            update_all_status_data();

      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

      /* currently a noop if aggregated updates is TRUE */

      /* update all status data if we're not aggregating updates */
      if(aggregate_status_updates==FALSE)
            update_all_status_data();

      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

      /* currently a noop if aggregated updates is TRUE */

      /* update all status data if we're not aggregating updates */
      if(aggregate_status_updates==FALSE)
            update_all_status_data();

      return OK;
        }

#endif





#ifdef NSCGI

/******************************************************************/
/******************* TOP-LEVEL INPUT FUNCTIONS ********************/
/******************************************************************/


/* reads in all status data */
int read_status_data(char *config_file,int options){
      int result=OK;

      /**** IMPLEMENTATION-SPECIFIC CALLS ****/
#ifdef USE_XSDDEFAULT
      result=xsddefault_read_status_data(config_file,options);
#endif
#ifdef USE_XSDDB
      result=xsddb_read_status_data(config_file,options);
#endif

      return result;
        }



/******************************************************************/
/****************** CHAINED HASH FUNCTIONS ************************/
/******************************************************************/

/* adds hoststatus to hash list in memory */
int add_hoststatus_to_hashlist(hoststatus *new_hoststatus){
      hoststatus *temp_hoststatus, *lastpointer;
      int hashslot;

      /* initialize hash list */
      if(hoststatus_hashlist==NULL){
            int i;

            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=hashfunc1(new_hoststatus->host_name,HOSTSTATUS_HASHSLOTS);
      lastpointer=NULL;
      for(temp_hoststatus=hoststatus_hashlist[hashslot];temp_hoststatus && compare_hashdata1(temp_hoststatus->host_name,new_hoststatus->host_name)<0;temp_hoststatus=temp_hoststatus->nexthash)
            lastpointer=temp_hoststatus;

      if(!temp_hoststatus || (compare_hashdata1(temp_hoststatus->host_name,new_hoststatus->host_name)!=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, *lastpointer;
      int hashslot;

      /* initialize hash list */
      if(servicestatus_hashlist==NULL){
            int i;

            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=hashfunc2(new_servicestatus->host_name,new_servicestatus->description,SERVICESTATUS_HASHSLOTS);
      lastpointer=NULL;
      for(temp_servicestatus=servicestatus_hashlist[hashslot];temp_servicestatus && compare_hashdata2(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_hashdata2(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 temp_buffer[MAX_INPUT_BUFFER];
      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=HOST_UP;
                  break;
            case 1:
                  new_hoststatus->status=HOST_DOWN;
                  break;
            case 2:
                  new_hoststatus->status=HOST_UNREACHABLE;
                  break;
            default:
                  new_hoststatus->status=HOST_UP;
                  break;
                    }
            if(new_hoststatus->has_been_checked==FALSE){
                  new_hoststatus->status=HOST_PENDING;
                  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);
                        snprintf(temp_buffer,sizeof(temp_buffer)-1,"Host check scheduled for %s",date_string);
                        temp_buffer[sizeof(temp_buffer)-1]='\x0';
                        new_hoststatus->plugin_output=strdup(temp_buffer);
                          }
                  else
                        new_hoststatus->plugin_output=strdup("Host has not been checked yet");
                    }
              }

      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 temp_buffer[MAX_INPUT_BUFFER];
      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){
                  new_svcstatus->status=SERVICE_PENDING;
                  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);
                        snprintf(temp_buffer,sizeof(temp_buffer)-1,"Service check scheduled for %s",date_string);
                        temp_buffer[sizeof(temp_buffer)-1]='\x0';
                        new_svcstatus->plugin_output=strdup(temp_buffer);
                          }
                  else
                        new_svcstatus->plugin_output=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;
      hoststatus *next_hoststatus;
      servicestatus *this_svcstatus;
      servicestatus *next_svcstatus;

      /* free memory for the host status list */
      for(this_hoststatus=hoststatus_list;this_hoststatus!=NULL;this_hoststatus=next_hoststatus){
            next_hoststatus=this_hoststatus->next;
            free(this_hoststatus->host_name);
            free(this_hoststatus->plugin_output);
            free(this_hoststatus->perf_data);
            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;
            free(this_svcstatus->host_name);
            free(this_svcstatus->description);
            free(this_svcstatus->plugin_output);
            free(this_svcstatus->perf_data);
            free(this_svcstatus);
              }

      /* free hash lists reset list pointers */
      free(hoststatus_hashlist);
      free(servicestatus_hashlist);
      hoststatus_hashlist=NULL;
      servicestatus_hashlist=NULL;
      hoststatus_list=NULL;
      servicestatus_list=NULL;

      return;
        }




/******************************************************************/
/************************ SEARCH FUNCTIONS ************************/
/******************************************************************/


/* find a host status entry */
hoststatus *find_hoststatus(char *host_name){
      hoststatus *temp_hoststatus;

      if(host_name==NULL || hoststatus_hashlist==NULL)
            return NULL;

      for(temp_hoststatus=hoststatus_hashlist[hashfunc1(host_name,HOSTSTATUS_HASHSLOTS)];temp_hoststatus && compare_hashdata1(temp_hoststatus->host_name,host_name)<0;temp_hoststatus=temp_hoststatus->nexthash);

      if(temp_hoststatus && (compare_hashdata1(temp_hoststatus->host_name,host_name)==0))
            return temp_hoststatus;

      return NULL;
        }


/* find a service status entry */
servicestatus *find_servicestatus(char *host_name,char *svc_desc){
      servicestatus *temp_servicestatus;

      if(host_name==NULL || svc_desc==NULL || servicestatus_hashlist==NULL)
            return NULL;

      for(temp_servicestatus=servicestatus_hashlist[hashfunc2(host_name,svc_desc,SERVICESTATUS_HASHSLOTS)];temp_servicestatus && compare_hashdata2(temp_servicestatus->host_name,temp_servicestatus->description,host_name,svc_desc)<0;temp_servicestatus=temp_servicestatus->nexthash);

      if(temp_servicestatus && (compare_hashdata2(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;
      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


Generated by  Doxygen 1.6.0   Back to index