/***************************************************************************** * * STATUSDATA.C - External status data for NetSaint CGIs * * Copyright (c) 2000-2001 Ethan Galstad (netsaint@netsaint.org) * Last Modified: 09-19-2001 * * License: * * 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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA. * *****************************************************************************/ /*********** COMMON HEADER FILES ***********/ #include "config.h" #include "common.h" #include "objects.h" #include "statusdata.h" #ifdef NSCORE #include "../base/netsaint.h" #endif #ifdef NSCGI #include "../cgi/cgiutils.h" #endif /**** IMPLEMENTATION SPECIFIC HEADER FILES ****/ #ifdef USE_XSDDEFAULT #include "../xdata/xsddefault.h" /* default routines */ #endif #ifdef USE_XSDDB #include "../xdata/xsddb.h" /* database routines */ #endif #ifdef NSCGI hoststatus *hoststatus_list=NULL; servicestatus *servicestatus_list=NULL; time_t program_start; int daemon_mode; int program_mode; time_t last_mode_change; time_t last_command_check; time_t last_log_rotation; int execute_service_checks; int accept_passive_service_checks; int enable_event_handlers; int obsess_over_services; int enable_flap_detection; int netsaint_pid; #endif #ifdef NSCORE extern time_t program_start; extern int netsaint_pid; extern int daemon_mode; extern int program_mode; extern time_t last_mode_change; extern time_t last_command_check; extern time_t last_log_rotation; extern int execute_service_checks; extern int accept_passive_service_checks; extern int enable_event_handlers; extern int obsess_over_services; extern int enable_flap_detection; extern int aggregate_status_updates; extern host *host_list; extern service *service_list; #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 #ifdef USE_XSDDB result=xsddb_initialize_status_data(config_file); #endif return result; } /* update all status data (aggregated dump) */ int update_all_status_data(void){ host *temp_host; service *temp_service; int result=OK; /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XSDDEFAULT result=xsddefault_begin_aggregated_dump(); #endif #ifdef USE_XSDDB result=xsddb_begin_aggregated_dump(); #endif if(result!=OK) return ERROR; /* update program info */ if(update_program_status(TRUE)==ERROR) return ERROR; /* update all host data */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(update_host_status(temp_host,TRUE)==ERROR) return ERROR; } /* update all service data */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(update_service_status(temp_service,TRUE)==ERROR) return ERROR; } /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XSDDEFAULT result=xsddefault_end_aggregated_dump(); #endif #ifdef USE_XSDDB result=xsddb_end_aggregated_dump(); #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 #ifdef USE_XSDDB result=xsddb_cleanup_status_data(config_file,delete_status_data); #endif return result; } /* updates program status info */ int update_program_status(int aggregated_dump){ int result=OK; /* don't update status if we're only dumping status data occasionally and this is not part of an aggregated dump */ if(aggregate_status_updates==TRUE && aggregated_dump==FALSE) return OK; /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XSDDEFAULT result=xsddefault_update_program_status(program_start,(int)getpid(),daemon_mode,program_mode,last_mode_change,last_command_check,last_log_rotation,execute_service_checks,accept_passive_service_checks,enable_event_handlers,obsess_over_services,enable_flap_detection,aggregated_dump); #endif #ifdef USE_XSDDB result=xsddb_update_program_status(program_start,(int)getpid(),daemon_mode,program_mode,last_mode_change,last_command_check,last_log_rotation,execute_service_checks,accept_passive_service_checks,enable_event_handlers,obsess_over_services,enable_flap_detection,aggregated_dump); #endif return result; } /* updates host status info */ int update_host_status(host *hst,int aggregated_dump){ int result=OK; char *status_string=""; time_t current_time; /* don't update status if we're only dumping status data occasionally and this is not part of an aggregated dump */ if(aggregate_status_updates==TRUE && aggregated_dump==FALSE) return OK; time(¤t_time); switch(hst->status){ case HOST_DOWN: status_string="DOWN"; break; case HOST_UNREACHABLE: status_string="UNREACHABLE"; break; case HOST_UP: status_string="UP"; break; default: status_string="?"; } /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XSDDEFAULT result=xsddefault_update_host_status(hst->name,status_string,current_time,hst->last_check,hst->last_state_change,hst->problem_has_been_acknowledged,hst->time_up,hst->time_down,hst->time_unreachable,hst->last_host_notification,hst->current_notification_number,hst->notifications_enabled,hst->event_handler_enabled,hst->checks_enabled,hst->flap_detection_enabled,hst->is_flapping,hst->percent_state_change,hst->scheduled_downtime_depth,hst->plugin_output,aggregated_dump); #endif #ifdef USE_XSDDB result=xsddb_update_host_status(hst->name,status_string,current_time,hst->last_check,hst->last_state_change,hst->problem_has_been_acknowledged,hst->time_up,hst->time_down,hst->time_unreachable,hst->last_host_notification,hst->current_notification_number,hst->notifications_enabled,hst->event_handler_enabled,hst->checks_enabled,hst->flap_detection_enabled,hst->is_flapping,hst->percent_state_change,hst->scheduled_downtime_depth,hst->plugin_output,aggregated_dump); #endif return result; } /* updates service status info */ int update_service_status(service *svc,int aggregated_dump){ int result=OK; host *hst; char *status_string=""; char *last_hard_state_string=""; time_t current_time; /* don't update status if we're only dumping status data occasionally and this is not part of an aggregated dump */ if(aggregate_status_updates==TRUE && aggregated_dump==FALSE) return OK; time(¤t_time); /* find the host associated with this service */ hst=find_host(svc->host_name,NULL); if(hst==NULL) return ERROR; /* update host status info if necessary */ if(aggregated_dump==FALSE) update_host_status(hst,FALSE); /* get the service state string */ if(svc->current_state==STATE_OK){ if(svc->last_state==STATE_OK) status_string="OK"; else status_string="RECOVERY"; } else if(svc->current_state==STATE_CRITICAL) status_string="CRITICAL"; else if(svc->current_state==STATE_WARNING) status_string="WARNING"; else status_string="UNKNOWN"; /* get the last hard state string */ switch(svc->last_hard_state){ case STATE_OK: last_hard_state_string="OK"; break; case STATE_WARNING: last_hard_state_string="WARNING"; break; case STATE_UNKNOWN: last_hard_state_string="UNKNOWN"; break; case STATE_CRITICAL: last_hard_state_string="CRITICAL"; break; default: last_hard_state_string="?"; } /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XSDDEFAULT result=xsddefault_update_service_status(svc->host_name,svc->description,status_string,current_time,svc->current_attempt,svc->max_attempts,svc->state_type,svc->last_check,svc->next_check,svc->should_be_scheduled,svc->check_type,svc->checks_enabled,svc->accept_passive_service_checks,svc->event_handler_enabled,svc->last_state_change,svc->problem_has_been_acknowledged,last_hard_state_string,svc->time_ok,svc->time_warning,svc->time_unknown,svc->time_critical,svc->last_notification,svc->current_notification_number,svc->notifications_enabled,svc->latency,svc->execution_time,svc->flap_detection_enabled,svc->is_flapping,svc->percent_state_change,svc->scheduled_downtime_depth,svc->plugin_output,aggregated_dump); #endif #ifdef USE_XSDDB result=xsddb_update_service_status(svc->host_name,svc->description,status_string,current_time,svc->current_attempt,svc->max_attempts,svc->state_type,svc->last_check,svc->next_check,svc->should_be_scheduled,svc->check_type,svc->checks_enabled,svc->accept_passive_service_checks,svc->event_handler_enabled,svc->last_state_change,svc->problem_has_been_acknowledged,last_hard_state_string,svc->time_ok,svc->time_warning,svc->time_unknown,svc->time_critical,svc->last_notification,svc->current_notification_number,svc->notifications_enabled,svc->latency,svc->execution_time,svc->flap_detection_enabled,svc->is_flapping,svc->percent_state_change,svc->scheduled_downtime_depth,svc->plugin_output,aggregated_dump); #endif return result; } #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; } /******************************************************************/ /********************** ADDITION FUNCTIONS ************************/ /******************************************************************/ /* sets program status variables */ int add_program_status(time_t _program_start,int _netsaint_pid, int _daemon_mode,int _program_mode,time_t _last_mode_change,time_t _last_command_check,time_t _last_log_rotation,int _execute_service_checks,int _accept_passive_service_checks,int _enable_event_handlers,int _obsess_over_services, int _enable_flap_detection){ /* make sure values are in range */ if(_daemon_mode<0 || _daemon_mode>1) return ERROR; if(_execute_service_checks<0 || _execute_service_checks>1) return ERROR; if(_accept_passive_service_checks<0 || _accept_passive_service_checks>1) return ERROR; if(_enable_event_handlers<0 || _enable_event_handlers>1) return ERROR; if(_obsess_over_services<0 || _obsess_over_services>1) return ERROR; if(_enable_flap_detection<0 || _enable_flap_detection>1) return ERROR; if(_program_mode!=ACTIVE_MODE && _program_mode!=STANDBY_MODE) return ERROR; /* set program variables */ program_start=_program_start; netsaint_pid=_netsaint_pid; daemon_mode=(_daemon_mode>0)?TRUE:FALSE; program_mode=_program_mode; last_mode_change=_last_mode_change; last_command_check=_last_command_check; last_log_rotation=_last_log_rotation; execute_service_checks=(_execute_service_checks>0)?TRUE:FALSE; accept_passive_service_checks=(_accept_passive_service_checks>0)?TRUE:FALSE; enable_event_handlers=(_enable_event_handlers>0)?TRUE:FALSE; obsess_over_services=(_obsess_over_services>0)?TRUE:FALSE; enable_flap_detection=(_enable_flap_detection>0)?TRUE:FALSE; return OK; } /* adds a host status entry to the list in memory */ int add_host_status(char *host_name,char *status_string,time_t last_update,time_t last_check,time_t last_state_change,int problem_has_been_acknowledged,unsigned long time_up, unsigned long time_down, unsigned long time_unreachable,time_t last_notification,int current_notification_number,int notifications_enabled,int event_handler_enabled,int checks_enabled,int flap_detection_enabled, int is_flapping, double percent_state_change, int scheduled_downtime_depth, char *plugin_output){ hoststatus *new_hoststatus=NULL; hoststatus *last_hoststatus=NULL; hoststatus *temp_hoststatus=NULL; int status; /* make sure we have what we need */ if(host_name==NULL) return ERROR; if(!strcmp(host_name,"")) return ERROR; if(plugin_output==NULL) return ERROR; if(status_string==NULL) return ERROR; if(problem_has_been_acknowledged<0 || problem_has_been_acknowledged>1) return ERROR; if(current_notification_number<0) return ERROR; if(notifications_enabled<0 || notifications_enabled>1) return ERROR; if(event_handler_enabled<0 || event_handler_enabled>1) return ERROR; if(checks_enabled<0 || checks_enabled>1) return ERROR; if(flap_detection_enabled<0 || flap_detection_enabled>1) return ERROR; if(is_flapping<0 || is_flapping>1) return ERROR; if(!strcmp(status_string,"DOWN")) status=HOST_DOWN; else if(!strcmp(status_string,"UNREACHABLE")) status=HOST_UNREACHABLE; else if(!strcmp(status_string,"PENDING")) status=HOST_PENDING; else if(!strcmp(status_string,"UP")) status=HOST_UP; else return ERROR; /* allocate memory for new host status */ new_hoststatus=(hoststatus *)malloc(sizeof(hoststatus)); if(new_hoststatus==NULL) return ERROR; /* host name */ new_hoststatus->host_name=(char *)malloc(strlen(host_name)+1); if(new_hoststatus->host_name==NULL){ free(new_hoststatus); return ERROR; } strcpy(new_hoststatus->host_name,host_name); /* host status */ new_hoststatus->status=status; /* time this status data was last updated */ new_hoststatus->last_update=last_update; /* time this host was last checked */ new_hoststatus->last_check=last_check; /* time this host last changed state */ new_hoststatus->last_state_change=last_state_change; /* has this host problem been acknowleged? */ new_hoststatus->problem_has_been_acknowledged=(problem_has_been_acknowledged>0)?TRUE:FALSE; /* time up, down and unreachable */ new_hoststatus->time_up=time_up; new_hoststatus->time_down=time_down; new_hoststatus->time_unreachable=time_unreachable; /* last notification time for this host */ new_hoststatus->last_notification=last_notification; /* current notification number */ new_hoststatus->current_notification_number=current_notification_number; /* notifications enabled option */ new_hoststatus->notifications_enabled=(notifications_enabled>0)?TRUE:FALSE; /* event handler enabled option */ new_hoststatus->event_handler_enabled=(event_handler_enabled>0)?TRUE:FALSE; /* checks enabled option */ new_hoststatus->checks_enabled=(checks_enabled>0)?TRUE:FALSE; /* flap detection enabled option */ new_hoststatus->flap_detection_enabled=(flap_detection_enabled>0)?TRUE:FALSE; /* flapping indicator */ new_hoststatus->is_flapping=(is_flapping>0)?TRUE:FALSE; /* percent state change */ new_hoststatus->percent_state_change=percent_state_change; /* scheduled downtime depth */ new_hoststatus->scheduled_downtime_depth=scheduled_downtime_depth; /* plugin output */ new_hoststatus->information=(char *)malloc(strlen(plugin_output)+1); if(new_hoststatus->information==NULL){ free(new_hoststatus->host_name); free(new_hoststatus); return ERROR; } strcpy(new_hoststatus->information,plugin_output); /* add new host status to list, sorted by host name */ last_hoststatus=hoststatus_list; for(temp_hoststatus=hoststatus_list;temp_hoststatus!=NULL;temp_hoststatus=temp_hoststatus->next){ if(strcmp(new_hoststatus->host_name,temp_hoststatus->host_name)<0){ new_hoststatus->next=temp_hoststatus; if(temp_hoststatus==hoststatus_list) hoststatus_list=new_hoststatus; else last_hoststatus->next=new_hoststatus; break; } else last_hoststatus=temp_hoststatus; } if(hoststatus_list==NULL){ new_hoststatus->next=NULL; hoststatus_list=new_hoststatus; } else if(temp_hoststatus==NULL){ new_hoststatus->next=NULL; last_hoststatus->next=new_hoststatus; } return OK; } /* adds a service status entry to the list in memory */ int add_service_status(char *host_name,char *svc_description,char *status_string,time_t last_update,int current_attempt,int max_attempts,int state_type,time_t last_check,time_t next_check,int check_type,int checks_enabled,int accept_passive_checks,int event_handler_enabled,time_t last_state_change,int problem_has_been_acknowledged,char *last_hard_state_string,unsigned long time_ok,unsigned long time_warning,unsigned long time_unknown,unsigned long time_critical,time_t last_notification,int current_notification_number,int notifications_enabled, int latency, int execution_time, int flap_detection_enabled, int is_flapping, double percent_state_change, int scheduled_downtime_depth, char *plugin_output){ servicestatus *new_svcstatus=NULL; servicestatus *last_svcstatus=NULL; servicestatus *temp_svcstatus=NULL; int status; int last_hard_state; /* make sure we have what we need */ if(host_name==NULL) return ERROR; if(!strcmp(host_name,"")) return ERROR; if(svc_description==NULL) return ERROR; if(!strcmp(svc_description,"")) return ERROR; if(plugin_output==NULL) return ERROR; if(status_string==NULL) return ERROR; if(last_hard_state_string==NULL) return ERROR; if(current_attempt<0) return ERROR; if(max_attempts<1) return ERROR; if(checks_enabled<0 || checks_enabled>1) return ERROR; if(accept_passive_checks<0 || accept_passive_checks>1) return ERROR; if(event_handler_enabled<0 || event_handler_enabled>1) return ERROR; if(problem_has_been_acknowledged<0 || problem_has_been_acknowledged>1) return ERROR; if(notifications_enabled<0 || notifications_enabled>1) return ERROR; if(flap_detection_enabled<0 || flap_detection_enabled>1) return ERROR; if(is_flapping<0 || is_flapping>1) return ERROR; if(!strcmp(status_string,"WARNING")) status=SERVICE_WARNING; else if(!strcmp(status_string,"UNKNOWN")) status=SERVICE_UNKNOWN; else if(!strcmp(status_string,"CRITICAL")) status=SERVICE_CRITICAL; else if(!strcmp(status_string,"RECOVERY")) status=SERVICE_RECOVERY; else if(!strcmp(status_string,"HOST DOWN")) status=SERVICE_HOST_DOWN; else if(!strcmp(status_string,"UNREACHABLE")) status=SERVICE_UNREACHABLE; else if(!strcmp(status_string,"PENDING")) status=SERVICE_PENDING; else if(!strcmp(status_string,"OK")) status=SERVICE_OK; else return ERROR; if(!strcmp(last_hard_state_string,"WARNING")) last_hard_state=STATE_WARNING; else if(!strcmp(last_hard_state_string,"UNKNOWN")) last_hard_state=STATE_UNKNOWN; else if(!strcmp(last_hard_state_string,"CRITICAL")) last_hard_state=STATE_CRITICAL; else if(!strcmp(last_hard_state_string,"OK")) last_hard_state=STATE_OK; else return ERROR; /* allocate memory for a new service status entry */ new_svcstatus=(servicestatus *)malloc(sizeof(servicestatus)); if(new_svcstatus==NULL) return ERROR; /* host name */ new_svcstatus->host_name=(char *)malloc(strlen(host_name)+1); if(new_svcstatus->host_name==NULL){ free(new_svcstatus); return ERROR; } strcpy(new_svcstatus->host_name,host_name); /* service description */ new_svcstatus->description=(char *)malloc(strlen(svc_description)+1); if(new_svcstatus->description==NULL){ free(new_svcstatus->host_name); free(new_svcstatus); return ERROR; } strcpy(new_svcstatus->description,svc_description); /* status */ new_svcstatus->status=status; /* time this service status info was last updated */ new_svcstatus->last_update=last_update; /* current attempt */ new_svcstatus->current_attempt=current_attempt; /* max attempts */ new_svcstatus->max_attempts=max_attempts; /* state type */ new_svcstatus->state_type=state_type; /* last check time */ new_svcstatus->last_check=last_check; /* next check time */ new_svcstatus->next_check=next_check; /* last check type */ new_svcstatus->check_type=check_type; /* checks enabled */ new_svcstatus->checks_enabled=(checks_enabled>0)?TRUE:FALSE; /* passive checks accepted */ new_svcstatus->accept_passive_service_checks=(accept_passive_checks>0)?TRUE:FALSE; /* event handler enabled */ new_svcstatus->event_handler_enabled=(event_handler_enabled>0)?TRUE:FALSE; /* last state change time */ new_svcstatus->last_state_change=last_state_change; /* acknowledgement */ new_svcstatus->problem_has_been_acknowledged=(problem_has_been_acknowledged>0)?TRUE:FALSE; /* last hard state */ new_svcstatus->last_hard_state=last_hard_state; /* time ok, warning, unknown, and critical */ new_svcstatus->time_ok=time_ok; new_svcstatus->time_warning=time_warning; new_svcstatus->time_unknown=time_unknown; new_svcstatus->time_critical=time_critical; /* last notification time */ new_svcstatus->last_notification=last_notification; /* current notification number */ new_svcstatus->current_notification_number=current_notification_number; /* notifications enabled */ new_svcstatus->notifications_enabled=(notifications_enabled>0)?TRUE:FALSE; /* plugin output */ new_svcstatus->information=(char *)malloc(strlen(plugin_output)+1); if(new_svcstatus->information==NULL){ free(new_svcstatus->description); free(new_svcstatus->host_name); free(new_svcstatus); return ERROR; } strcpy(new_svcstatus->information,plugin_output); /* latency and execution time */ new_svcstatus->latency=latency; new_svcstatus->execution_time=execution_time; /* flap detection enabled */ new_svcstatus->flap_detection_enabled=(flap_detection_enabled>0)?TRUE:FALSE; /* flapping indicator */ new_svcstatus->is_flapping=(is_flapping>0)?TRUE:FALSE; /* percent state change */ new_svcstatus->percent_state_change=percent_state_change; /* scheduled downtime depth */ new_svcstatus->scheduled_downtime_depth=scheduled_downtime_depth; /* add new service status to front of list */ last_svcstatus=servicestatus_list; for(temp_svcstatus=servicestatus_list;temp_svcstatus!=NULL;temp_svcstatus=temp_svcstatus->next){ if(strcmp(new_svcstatus->host_name,temp_svcstatus->host_name)<0){ new_svcstatus->next=temp_svcstatus; if(temp_svcstatus==servicestatus_list) servicestatus_list=new_svcstatus; else last_svcstatus->next=new_svcstatus; break; } else last_svcstatus=temp_svcstatus; } if(servicestatus_list==NULL){ new_svcstatus->next=NULL; servicestatus_list=new_svcstatus; } else if(temp_svcstatus==NULL){ new_svcstatus->next=NULL; last_svcstatus->next=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->information); 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->information); free(this_svcstatus); } /* reset list pointers */ hoststatus_list=NULL; servicestatus_list=NULL; return; } /******************************************************************/ /************************ SEARCH FUNCTIONS ************************/ /******************************************************************/ /* find a host status entry */ hoststatus *find_hoststatus(char *host_name){ hoststatus *temp_hoststatus; for(temp_hoststatus=hoststatus_list;temp_hoststatus!=NULL;temp_hoststatus=temp_hoststatus->next){ if(!strcmp(temp_hoststatus->host_name,host_name)) return temp_hoststatus; } return NULL; } /* find a service status entry */ servicestatus *find_servicestatus(char *host_name,char *svc_desc){ servicestatus *temp_servicestatus; for(temp_servicestatus=servicestatus_list;temp_servicestatus!=NULL;temp_servicestatus=temp_servicestatus->next){ if(!strcmp(temp_servicestatus->host_name,host_name) && !strcmp(temp_servicestatus->description,svc_desc)) 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